diff options
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c')
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c | 109 |
1 files changed, 79 insertions, 30 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c index 2455d210ccf6..5e126fdf6ec1 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c @@ -60,6 +60,7 @@ #include "dml/display_mode_vba.h" #include "dcn30/dcn30_dccg.h" #include "dcn10/dcn10_resource.h" +#include "dc_link_ddc.h" #include "dce/dce_panel_cntl.h" #include "dcn30/dcn30_dwb.h" @@ -354,11 +355,11 @@ static const struct dce_abm_registers abm_regs[] = { }; static const struct dce_abm_shift abm_shift = { - ABM_MASK_SH_LIST_DCN301(__SHIFT) + ABM_MASK_SH_LIST_DCN30(__SHIFT) }; static const struct dce_abm_mask abm_mask = { - ABM_MASK_SH_LIST_DCN301(_MASK) + ABM_MASK_SH_LIST_DCN30(_MASK) }; @@ -932,7 +933,7 @@ static struct dce_aux *dcn30_aux_engine_create( return &aux_engine->base; } -#define i2c_inst_regs(id) { I2C_HW_ENGINE_COMMON_REG_LIST(id) } +#define i2c_inst_regs(id) { I2C_HW_ENGINE_COMMON_REG_LIST_DCN30(id) } static const struct dce_i2c_registers i2c_hw_regs[] = { i2c_inst_regs(1), @@ -944,11 +945,11 @@ static const struct dce_i2c_registers i2c_hw_regs[] = { }; static const struct dce_i2c_shift i2c_shifts = { - I2C_COMMON_MASK_SH_LIST_DCN2(__SHIFT) + I2C_COMMON_MASK_SH_LIST_DCN30(__SHIFT) }; static const struct dce_i2c_mask i2c_masks = { - I2C_COMMON_MASK_SH_LIST_DCN2(_MASK) + I2C_COMMON_MASK_SH_LIST_DCN30(_MASK) }; static struct dce_i2c_hw *dcn30_i2c_hw_create( @@ -1321,6 +1322,9 @@ static void dcn30_resource_destruct(struct dcn30_resource_pool *pool) if (pool->base.dccg != NULL) dcn_dccg_destroy(&pool->base.dccg); + + if (pool->base.oem_device != NULL) + dal_ddc_service_destroy(&pool->base.oem_device); } static struct hubp *dcn30_hubp_create( @@ -1447,12 +1451,13 @@ static struct clock_source *dcn30_clock_source_create( int dcn30_populate_dml_pipes_from_context( struct dc *dc, struct dc_state *context, - display_e2e_pipe_params_st *pipes) + display_e2e_pipe_params_st *pipes, + bool fast_validate) { int i, pipe_cnt; struct resource_context *res_ctx = &context->res_ctx; - dcn20_populate_dml_pipes_from_context(dc, context, pipes); + dcn20_populate_dml_pipes_from_context(dc, context, pipes, fast_validate); for (i = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) { if (!res_ctx->pipe_ctx[i].stream) @@ -1466,7 +1471,7 @@ int dcn30_populate_dml_pipes_from_context( } void dcn30_populate_dml_writeback_from_context( - struct dc *dc, struct resource_context *res_ctx, display_e2e_pipe_params_st *pipes) + struct dc *dc, struct resource_context *res_ctx, display_e2e_pipe_params_st *pipes) { int pipe_cnt, i, j; double max_calc_writeback_dispclk; @@ -1873,11 +1878,22 @@ static bool dcn30_split_stream_for_mpc_or_odm( sec_pipe->next_odm_pipe = pri_pipe->next_odm_pipe; sec_pipe->next_odm_pipe->prev_odm_pipe = sec_pipe; } + if (pri_pipe->top_pipe && pri_pipe->top_pipe->next_odm_pipe) { + pri_pipe->top_pipe->next_odm_pipe->bottom_pipe = sec_pipe; + sec_pipe->top_pipe = pri_pipe->top_pipe->next_odm_pipe; + } + if (pri_pipe->bottom_pipe && pri_pipe->bottom_pipe->next_odm_pipe) { + pri_pipe->bottom_pipe->next_odm_pipe->top_pipe = sec_pipe; + sec_pipe->bottom_pipe = pri_pipe->bottom_pipe->next_odm_pipe; + } pri_pipe->next_odm_pipe = sec_pipe; sec_pipe->prev_odm_pipe = pri_pipe; ASSERT(sec_pipe->top_pipe == NULL); - sec_pipe->stream_res.opp = pool->opps[pipe_idx]; + if (!sec_pipe->top_pipe) + sec_pipe->stream_res.opp = pool->opps[pipe_idx]; + else + sec_pipe->stream_res.opp = sec_pipe->top_pipe->stream_res.opp; if (sec_pipe->stream->timing.flags.DSC == 1) { dcn20_acquire_dsc(dc, res_ctx, &sec_pipe->stream_res.dsc, pipe_idx); ASSERT(sec_pipe->stream_res.dsc); @@ -1941,7 +1957,7 @@ static struct pipe_ctx *dcn30_find_split_pipe( return pipe; } -static bool dcn30_internal_validate_bw( +static noinline bool dcn30_internal_validate_bw( struct dc *dc, struct dc_state *context, display_e2e_pipe_params_st *pipes, @@ -1961,8 +1977,9 @@ static bool dcn30_internal_validate_bw( if (!pipes) return false; - pipe_cnt = dc->res_pool->funcs->populate_dml_pipes(dc, context, pipes); + pipe_cnt = dc->res_pool->funcs->populate_dml_pipes(dc, context, pipes, fast_validate); + DC_FP_START(); if (!pipe_cnt) { out = true; goto validate_out; @@ -2005,20 +2022,6 @@ static bool dcn30_internal_validate_bw( dml_log_mode_support_params(&context->bw_ctx.dml); - /* TODO: Need to check calculated vlevel why that fails validation of below resolutions */ - if (context->res_ctx.pipe_ctx[0].stream != NULL) { - if (context->res_ctx.pipe_ctx[0].stream->timing.h_addressable == 640 && context->res_ctx.pipe_ctx[0].stream->timing.v_addressable == 480) - vlevel = 0; - if (context->res_ctx.pipe_ctx[0].stream->timing.h_addressable == 1280 && context->res_ctx.pipe_ctx[0].stream->timing.v_addressable == 800) - vlevel = 0; - if (context->res_ctx.pipe_ctx[0].stream->timing.h_addressable == 1280 && context->res_ctx.pipe_ctx[0].stream->timing.v_addressable == 768) - vlevel = 0; - if (context->res_ctx.pipe_ctx[0].stream->timing.h_addressable == 1280 && context->res_ctx.pipe_ctx[0].stream->timing.v_addressable == 1024) - vlevel = 0; - if (context->res_ctx.pipe_ctx[0].stream->timing.h_addressable == 2048 && context->res_ctx.pipe_ctx[0].stream->timing.v_addressable == 1536) - vlevel = 0; - } - if (vlevel == context->bw_ctx.dml.soc.num_states) goto validate_fail; @@ -2189,7 +2192,7 @@ static bool dcn30_internal_validate_bw( } if (repopulate_pipes) - pipe_cnt = dc->res_pool->funcs->populate_dml_pipes(dc, context, pipes); + pipe_cnt = dc->res_pool->funcs->populate_dml_pipes(dc, context, pipes, fast_validate); *vlevel_out = vlevel; *pipe_cnt_out = pipe_cnt; @@ -2200,10 +2203,23 @@ validate_fail: out = false; validate_out: + DC_FP_END(); return out; } -void dcn30_calculate_wm_and_dlg( +/* + * This must be noinline to ensure anything that deals with FP registers + * is contained within this call; previously our compiling with hard-float + * would result in fp instructions being emitted outside of the boundaries + * of the DC_FP_START/END macros, which makes sense as the compiler has no + * idea about what is wrapped and what is not + * + * This is largely just a workaround to avoid breakage introduced with 5.6, + * ideally all fp-using code should be moved into its own file, only that + * should be compiled with hard-float, and all code exported from there + * should be strictly wrapped with DC_FP_START/END + */ +static noinline void dcn30_calculate_wm_and_dlg_fp( struct dc *dc, struct dc_state *context, display_e2e_pipe_params_st *pipes, int pipe_cnt, @@ -2249,7 +2265,7 @@ void dcn30_calculate_wm_and_dlg( /* Set D: * DCFCLK: Min Required * FCLK(proportional to UCLK): 1GHz or Max - * sr_enter_exit = 4, sr_exit = 2us + * MALL stutter, sr_enter_exit = 4, sr_exit = 2us */ /* if (dc->clk_mgr->bw_params->wm_table.nv_entries[WM_D].valid) { @@ -2304,7 +2320,7 @@ void dcn30_calculate_wm_and_dlg( * calculate DLG based on dummy p-state latency, and max out the set A p-state watermark */ context->bw_ctx.bw.dcn.watermarks.a = context->bw_ctx.bw.dcn.watermarks.c; - context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns = 0x13FFFF; + context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns = 0; } else { /* Set A: * DCFCLK: Min Required @@ -2359,6 +2375,17 @@ void dcn30_calculate_wm_and_dlg( dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.pstate_latency_us; } +void dcn30_calculate_wm_and_dlg( + struct dc *dc, struct dc_state *context, + display_e2e_pipe_params_st *pipes, + int pipe_cnt, + int vlevel) +{ + DC_FP_START(); + dcn30_calculate_wm_and_dlg_fp(dc, context, pipes, pipe_cnt, vlevel); + DC_FP_END(); +} + bool dcn30_validate_bandwidth(struct dc *dc, struct dc_state *context, bool fast_validate) @@ -2410,7 +2437,7 @@ validate_out: return out; } -static void get_optimal_dcfclk_fclk_for_uclk(unsigned int uclk_mts, +static noinline void get_optimal_dcfclk_fclk_for_uclk(unsigned int uclk_mts, unsigned int *optimal_dcfclk, unsigned int *optimal_fclk) { @@ -2477,8 +2504,10 @@ void dcn30_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params // Calculate optimal dcfclk for each uclk for (i = 0; i < num_uclk_states; i++) { + DC_FP_START(); get_optimal_dcfclk_fclk_for_uclk(bw_params->clk_table.entries[i].memclk_mhz * 16, &optimal_dcfclk_for_uclk[i], NULL); + DC_FP_END(); if (optimal_dcfclk_for_uclk[i] < bw_params->clk_table.entries[0].dcfclk_mhz) { optimal_dcfclk_for_uclk[i] = bw_params->clk_table.entries[0].dcfclk_mhz; } @@ -2580,6 +2609,9 @@ static bool dcn30_resource_construct( int i; struct dc_context *ctx = dc->ctx; struct irq_service_init_data init_data; + struct ddc_service_init_data ddc_init_data; + + DC_FP_START(); ctx->dc_bios->regs = &bios_regs; @@ -2595,7 +2627,9 @@ static bool dcn30_resource_construct( pool->base.mpcc_count = pool->base.res_cap->num_timing_generator; dc->caps.max_downscale_ratio = 600; dc->caps.i2c_speed_in_khz = 100; + dc->caps.i2c_speed_in_khz_hdcp = 100; /*1.4 w/a not applied by default*/ dc->caps.max_cursor_size = 256; + dc->caps.min_horizontal_blanking_period = 80; dc->caps.dmdata_alloc_size = 2048; dc->caps.max_slave_planes = 1; @@ -2616,6 +2650,7 @@ static bool dcn30_resource_construct( dc->caps.color.dpp.dgam_rom_caps.hlg = 1; dc->caps.color.dpp.post_csc = 1; dc->caps.color.dpp.gamma_corr = 1; + dc->caps.color.dpp.dgam_rom_for_yuv = 0; dc->caps.color.dpp.hw_3d_lut = 1; dc->caps.color.dpp.ogam_ram = 1; @@ -2845,10 +2880,24 @@ static bool dcn30_resource_construct( dc->cap_funcs = cap_funcs; + if (dc->ctx->dc_bios->fw_info.oem_i2c_present) { + ddc_init_data.ctx = dc->ctx; + ddc_init_data.link = NULL; + ddc_init_data.id.id = dc->ctx->dc_bios->fw_info.oem_i2c_obj_id; + ddc_init_data.id.enum_id = 0; + ddc_init_data.id.type = OBJECT_TYPE_GENERIC; + pool->base.oem_device = dal_ddc_service_create(&ddc_init_data); + } else { + pool->base.oem_device = NULL; + } + + DC_FP_END(); + return true; create_fail: + DC_FP_END(); dcn30_resource_destruct(pool); return false; |