From 2a0b4d858f7bb3d36d0ca610d9ef02062589edeb Mon Sep 17 00:00:00 2001 From: Martin Tsai Date: Thu, 7 Sep 2017 13:02:05 +0800 Subject: [PATCH 001/155] drm/amd/display: To prevent detecting new sink from spurious HPD Signed-off-by: Martin Tsai Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_link.c | 48 +++++++++++++------ 1 file changed, 34 insertions(+), 14 deletions(-) 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 4a70948c91b1d..ee23b609d7dd3 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c @@ -565,8 +565,6 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason) link->local_sink) return true; - link_disconnect_sink(link); - if (new_connection_type != dc_connection_none) { link->type = new_connection_type; @@ -638,8 +636,8 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason) if (link->dpcd_caps.sink_count.bits.SINK_COUNT) link->dpcd_sink_count = link->dpcd_caps.sink_count. bits.SINK_COUNT; - else - link->dpcd_sink_count = 1; + else + link->dpcd_sink_count = 1; dal_ddc_service_set_transaction_type( link->ddc, @@ -651,16 +649,24 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason) sink_init_data.link = link; sink_init_data.sink_signal = sink_caps.signal; - sink = dc_sink_create(&sink_init_data); - if (!sink) { - DC_ERROR("Failed to create sink!\n"); - return false; - } + if (link->local_sink) { + sink = link->local_sink; + } else { + link_disconnect_sink(link); + + sink_init_data.link = link; + sink_init_data.sink_signal = sink_caps.signal; - sink->dongle_max_pix_clk = sink_caps.max_hdmi_pixel_clock; - sink->converter_disable_audio = converter_disable_audio; + sink = dc_sink_create(&sink_init_data); + if (!sink) { + DC_ERROR("Failed to create sink!\n"); + return false; + } + sink->dongle_max_pix_clk = sink_caps.max_hdmi_pixel_clock; + sink->converter_disable_audio = converter_disable_audio; - link->local_sink = sink; + link->local_sink = sink; + } edid_status = dm_helpers_read_local_edid( link->ctx, @@ -752,8 +758,22 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason) memset(link->mst_stream_alloc_table.stream_allocations, 0, sizeof(link->mst_stream_alloc_table.stream_allocations)); } - link->type = dc_connection_none; - sink_caps.signal = SIGNAL_TYPE_NONE; + if (link->local_sink) { + sink = link->local_sink; + edid_status = dm_helpers_read_local_edid( + link->ctx, + link, + sink); + if (edid_status != EDID_OK) { + link_disconnect_sink(link); + link->type = dc_connection_none; + sink_caps.signal = SIGNAL_TYPE_NONE; + } + } else { + link_disconnect_sink(link); + link->type = dc_connection_none; + sink_caps.signal = SIGNAL_TYPE_NONE; + } } LINK_INFO("link=%d, dc_sink_in=%p is now %s\n", From 6bf520280f3621d458e2ef3bd3c48acb89a39af7 Mon Sep 17 00:00:00 2001 From: Hersen Wu Date: Tue, 5 Sep 2017 12:20:39 -0400 Subject: [PATCH 002/155] drm/amd/display: Driver message to SMU to indicate display off Signed-off-by: Hersen Wu Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc.c | 2 +- .../display/dc/dce110/dce110_hw_sequencer.c | 3 +- .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 38 ++++++++++++------- .../gpu/drm/amd/display/dc/inc/hw_sequencer.h | 2 +- 4 files changed, 28 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index f41f15faf0195..47f16a4b9f271 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -763,7 +763,7 @@ static bool dc_commit_state_no_check(struct dc *dc, struct dc_state *context) if (!dcb->funcs->is_accelerated_mode(dcb)) dc->hwss.enable_accelerated_mode(dc); - dc->hwss.ready_shared_resources(dc); + dc->hwss.ready_shared_resources(dc, context); for (i = 0; i < dc->res_pool->pipe_count; i++) { pipe = &context->res_ctx.pipe_ctx[i]; diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c index de154329b0493..b3448a41718e0 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c @@ -1889,6 +1889,7 @@ enum dc_status dce110_apply_ctx_to_hw( return status; } + /* pplib is notified if disp_num changed */ dc->hwss.set_bandwidth(dc, context, true); /* to save power */ @@ -2683,7 +2684,7 @@ static void program_csc_matrix(struct pipe_ctx *pipe_ctx, } } -static void ready_shared_resources(struct dc *dc) {} +static void ready_shared_resources(struct dc *dc, struct dc_state *context) {} static void optimize_shared_resources(struct dc *dc) {} diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index d3fee15aeb793..e60be00abcf23 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -802,18 +802,14 @@ static void undo_DEGVIDCN10_253_wa(struct dc *dc) IP_REQUEST_EN, 0); } -static void ready_shared_resources(struct dc *dc) -{ - if (dc->current_state->stream_count == 0 && - !dc->debug.disable_stutter) - undo_DEGVIDCN10_253_wa(dc); -} - static void apply_DEGVIDCN10_253_wa(struct dc *dc) { struct dce_hwseq *hws = dc->hwseq; struct mem_input *mi = dc->res_pool->mis[0]; + if (dc->debug.disable_stutter) + return; + REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1); @@ -824,13 +820,6 @@ static void apply_DEGVIDCN10_253_wa(struct dc *dc) mi->funcs->set_hubp_blank_en(mi, false); } -static void optimize_shared_resources(struct dc *dc) -{ - if (dc->current_state->stream_count == 0 && - !dc->debug.disable_stutter) - apply_DEGVIDCN10_253_wa(dc); -} - static void bios_golden_init(struct dc *dc) { struct dc_bios *bp = dc->ctx->dc_bios; @@ -2445,6 +2434,27 @@ static void dcn10_pplib_apply_display_requirements( dc->prev_display_config = *pp_display_cfg; } +static void optimize_shared_resources(struct dc *dc) +{ + if (dc->current_state->stream_count == 0) { + apply_DEGVIDCN10_253_wa(dc); + /* S0i2 message */ + dcn10_pplib_apply_display_requirements(dc, dc->current_state); + } +} + +static void ready_shared_resources(struct dc *dc, struct dc_state *context) +{ + if (dc->current_state->stream_count == 0 && + !dc->debug.disable_stutter) + undo_DEGVIDCN10_253_wa(dc); + + /* S0i2 message */ + if (dc->current_state->stream_count == 0 && + context->stream_count != 0) + dcn10_pplib_apply_display_requirements(dc, context); +} + static void dcn10_apply_ctx_for_surface( struct dc *dc, const struct dc_stream_state *stream, diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h index aae7629b1c08d..1fa2edc6cfb19 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h @@ -174,7 +174,7 @@ struct hw_sequencer_funcs { struct resource_pool *res_pool, struct pipe_ctx *pipe_ctx); - void (*ready_shared_resources)(struct dc *dc); + void (*ready_shared_resources)(struct dc *dc, struct dc_state *context); void (*optimize_shared_resources)(struct dc *dc); }; From 5088cc98f59b922a609078c048a25e30f94b9216 Mon Sep 17 00:00:00 2001 From: Andrew Jiang Date: Wed, 6 Sep 2017 18:56:46 -0400 Subject: [PATCH 003/155] drm/amd/display: Force always scale chroma, set always_scaled to false This allows us to not always have scaling on, which causes issues with validation and causes the text to blur slightly. Signed-off-by: Andrew Jiang Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c | 9 +++++---- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c | 4 ---- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c index 9d9604f050950..f9e43e68fc0c9 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c @@ -159,10 +159,11 @@ bool dpp_get_optimal_number_of_taps( scl_data->taps.h_taps = 1; if (IDENTITY_RATIO(scl_data->ratios.vert)) scl_data->taps.v_taps = 1; - if (IDENTITY_RATIO(scl_data->ratios.horz_c)) - scl_data->taps.h_taps_c = 1; - if (IDENTITY_RATIO(scl_data->ratios.vert_c)) - scl_data->taps.v_taps_c = 1; + /* + * Spreadsheet doesn't handle taps_c is one properly, + * need to force Chroma to always be scaled to pass + * bandwidth validation. + */ } return true; diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c index dc878f77837be..4f124dc303dce 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c @@ -420,10 +420,6 @@ static const struct dc_debug debug_defaults_drv = { .force_abm_enable = false, .timing_trace = false, .clock_trace = true, - /* spread sheet doesn't handle taps_c is one properly, - * need to enable scaler for video surface to pass - * bandwidth validation.*/ - .always_scale = true, .disable_pplib_clock_request = true, .disable_pplib_wm_range = false, #if defined(CONFIG_DRM_AMD_DC_DCN1_0) From 1049e39fa62f443aae64a2fb6057b96abf20e8de Mon Sep 17 00:00:00 2001 From: Eric Yang Date: Thu, 7 Sep 2017 14:53:23 -0400 Subject: [PATCH 004/155] drm/amd/display: fix usb-c dongle regression A previous change moved link_disconnect_sink after dpcd read, this causes the sink count to be overwritten which in turn causes another detection to be triggered in the short pulse handler, which brings down the display. Signed-off-by: Eric Yang Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_link.c | 2 -- 1 file changed, 2 deletions(-) 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 ee23b609d7dd3..d5eaebeaeb89c 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c @@ -652,8 +652,6 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason) if (link->local_sink) { sink = link->local_sink; } else { - link_disconnect_sink(link); - sink_init_data.link = link; sink_init_data.sink_signal = sink_caps.signal; From e008b0bcc63793d3e42fd88f412a90f329a05865 Mon Sep 17 00:00:00 2001 From: Roman Li Date: Thu, 7 Sep 2017 17:02:47 -0400 Subject: [PATCH 005/155] drm/amd/display: Add FBC on/off to front-end programming - Fixing text mode for cases when VT-switch doesn't result in timing change Signed-off-by: Roman Li Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c index b3448a41718e0..590b2ad371059 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c @@ -2554,6 +2554,15 @@ static void dce110_program_front_end_for_pipe( program_scaler(dc, pipe_ctx); +#ifdef ENABLE_FBC + if (dc->fbc_compressor && old_pipe->stream) { + if (plane_state->tiling_info.gfx8.array_mode == DC_ARRAY_LINEAR_GENERAL) + dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor); + else + enable_fbc(dc, dc->current_state); + } +#endif + mi->funcs->mem_input_program_surface_config( mi, plane_state->format, From 7d58e72149fa73504fa13e7044d68e79a39996fb Mon Sep 17 00:00:00 2001 From: Martin Tsai Date: Fri, 8 Sep 2017 19:25:35 +0800 Subject: [PATCH 006/155] drm/amd/display: To prevent detecting new sink from spurious HPD Signed-off-by: Martin Tsai Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_link.c | 33 +++++++++++-------- drivers/gpu/drm/amd/display/dc/dc_types.h | 1 + 2 files changed, 21 insertions(+), 13 deletions(-) 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 d5eaebeaeb89c..c7751a31081a6 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c @@ -649,27 +649,34 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason) sink_init_data.link = link; sink_init_data.sink_signal = sink_caps.signal; - if (link->local_sink) { - sink = link->local_sink; - } else { - sink_init_data.link = link; - sink_init_data.sink_signal = sink_caps.signal; + sink = dc_sink_create(&sink_init_data); + if (!sink) { + DC_ERROR("Failed to create sink!\n"); + return false; + } - sink = dc_sink_create(&sink_init_data); - if (!sink) { - DC_ERROR("Failed to create sink!\n"); - return false; + if (link->local_sink) { + edid_status = dm_helpers_read_local_edid( + link->ctx, + link, + sink); + + if (edid_status == EDID_OK) { + // Edid is not the same, to update the local sink with new sink. + sink->dongle_max_pix_clk = sink_caps.max_hdmi_pixel_clock; + sink->converter_disable_audio = converter_disable_audio; + link->local_sink = sink; } + } else { sink->dongle_max_pix_clk = sink_caps.max_hdmi_pixel_clock; sink->converter_disable_audio = converter_disable_audio; - link->local_sink = sink; - } - edid_status = dm_helpers_read_local_edid( + edid_status = dm_helpers_read_local_edid( link->ctx, link, sink); + } switch (edid_status) { case EDID_BAD_CHECKSUM: @@ -762,7 +769,7 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason) link->ctx, link, sink); - if (edid_status != EDID_OK) { + if (edid_status != EDID_OK && edid_status != EDID_THE_SAME) { link_disconnect_sink(link); link->type = dc_connection_none; sink_caps.signal = SIGNAL_TYPE_NONE; diff --git a/drivers/gpu/drm/amd/display/dc/dc_types.h b/drivers/gpu/drm/amd/display/dc/dc_types.h index 6b891fde400c4..4bd74fc6c782d 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_types.h @@ -151,6 +151,7 @@ enum dc_edid_status { EDID_BAD_INPUT, EDID_NO_RESPONSE, EDID_BAD_CHECKSUM, + EDID_THE_SAME, }; /* audio capability from EDID*/ From 8580d60baed5c8c9f08a5c3b239e563c8966a9dc Mon Sep 17 00:00:00 2001 From: Harry Wentland Date: Thu, 17 Aug 2017 14:58:07 -0400 Subject: [PATCH 007/155] drm/amd/display: Don't report fake sink as connected This was missed in the previous fake sink change. The fake sink allows us to enable a pipe with a disconnected display. We shouldn't report it as connected. Signed-off-by: Harry Wentland Reviewed-by: Andrey Grodzovsky Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 8cc228ebdc9a6..75212f74f027b 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -2453,7 +2453,8 @@ amdgpu_dm_connector_detect(struct drm_connector *connector, bool force) * 2. This interface *is called* in context of user-mode ioctl. Which * makes it a bad place for *any* MST-related activit. */ - if (aconnector->base.force == DRM_FORCE_UNSPECIFIED) + if (aconnector->base.force == DRM_FORCE_UNSPECIFIED && + !aconnector->fake_enable) connected = (aconnector->dc_sink != NULL); else connected = (aconnector->base.force == DRM_FORCE_ON); From 024f0607cfed19a9f6082e4b94267544de4fc584 Mon Sep 17 00:00:00 2001 From: Yue Hin Lau Date: Mon, 11 Sep 2017 14:30:02 -0400 Subject: [PATCH 008/155] drm/amd/display: Refactor dcn10_dpp_cm_helper to dcn10_cm_common Signed-off-by: Yue Hin Lau Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn10/Makefile | 2 +- .../dc/dcn10/{dcn10_dpp_cm_helper.c => dcn10_cm_common.c} | 2 +- .../dc/dcn10/{dcn10_dpp_cm_helper.h => dcn10_cm_common.h} | 4 ++-- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm.c | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) rename drivers/gpu/drm/amd/display/dc/dcn10/{dcn10_dpp_cm_helper.c => dcn10_cm_common.c} (99%) rename drivers/gpu/drm/amd/display/dc/dcn10/{dcn10_dpp_cm_helper.h => dcn10_cm_common.h} (97%) diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/Makefile b/drivers/gpu/drm/amd/display/dc/dcn10/Makefile index 2d6d3a3718588..6b19106f46795 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/Makefile +++ b/drivers/gpu/drm/amd/display/dc/dcn10/Makefile @@ -4,7 +4,7 @@ DCN10 = dcn10_resource.o dcn10_ipp.o dcn10_hw_sequencer.o \ dcn10_dpp.o dcn10_opp.o dcn10_timing_generator.o \ dcn10_mem_input.o dcn10_mpc.o \ - dcn10_dpp_dscl.o dcn10_dpp_cm.o dcn10_dpp_cm_helper.o + dcn10_dpp_dscl.o dcn10_dpp_cm.o dcn10_cm_common.o AMD_DAL_DCN10 = $(addprefix $(AMDDALPATH)/dc/dcn10/,$(DCN10)) diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm_helper.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c similarity index 99% rename from drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm_helper.c rename to drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c index f616e08759de5..7f579cb19f4bb 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm_helper.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c @@ -26,7 +26,7 @@ #include "reg_helper.h" #include "dcn10_dpp.h" -#include "dcn10_dpp_cm_helper.h" +#include "dcn10_cm_common.h" #define REG(reg) reg diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm_helper.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.h similarity index 97% rename from drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm_helper.h rename to drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.h index 1155ee5228980..64836dcf21f22 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm_helper.h +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.h @@ -23,8 +23,8 @@ * */ -#ifndef __DAL_DPP_DCN10_CM_HELPER_H__ -#define __DAL_DPP_DCN10_CM_HELPER_H__ +#ifndef __DAL_DCN10_CM_COMMON_H__ +#define __DAL_DCN10_CM_COMMON_H__ #define TF_HELPER_REG_FIELD_LIST(type) \ type exp_region0_lut_offset; \ diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm.c index d0e72acfc1d5c..61e2a8919e9ce 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm.c @@ -29,8 +29,8 @@ #include "reg_helper.h" #include "dcn10_dpp.h" -#include "dcn10_dpp_cm_helper.h" #include "basics/conversion.h" +#include "dcn10_cm_common.h" #define NUM_PHASES 64 #define HORZ_MAX_TAPS 8 From 98b49c2f9c66cf42b6d762498e2d9f327e439416 Mon Sep 17 00:00:00 2001 From: Roman Li Date: Mon, 11 Sep 2017 16:28:21 -0400 Subject: [PATCH 009/155] drm/amd/display: fix multi-display on CZ - fixed wrong index in dce110_validate_surface_sets() - formatted for better readability Signed-off-by: Roman Li Reviewed-by: Harry Wentland igned-off-by: Alex Deucher --- .../amd/display/dc/dce110/dce110_resource.c | 29 ++++++++++++++----- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c index 28e768de744ce..8e4ec61d59a4b 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c @@ -849,7 +849,7 @@ static bool dce110_validate_bandwidth( static bool dce110_validate_surface_sets( struct dc_state *context) { - int i; + int i, j; for (i = 0; i < context->stream_count; i++) { if (context->stream_status[i].plane_count == 0) @@ -858,14 +858,27 @@ static bool dce110_validate_surface_sets( if (context->stream_status[i].plane_count > 2) return false; - if ((context->stream_status[i].plane_states[i]->format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) && - (context->stream_status[i].plane_states[i]->src_rect.width > 1920 || - context->stream_status[i].plane_states[i]->src_rect.height > 1080)) - return false; + for (j = 0; j < context->stream_status[i].plane_count; j++) { + struct dc_plane_state *plane = + context->stream_status[i].plane_states[j]; - /* irrespective of plane format, stream should be RGB encoded */ - if (context->streams[i]->timing.pixel_encoding != PIXEL_ENCODING_RGB) - return false; + /* underlay validation */ + if (plane->format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) { + + if ((plane->src_rect.width > 1920 || + plane->src_rect.height > 1080)) + return false; + + /* irrespective of plane format, + * stream should be RGB encoded + */ + if (context->streams[i]->timing.pixel_encoding + != PIXEL_ENCODING_RGB) + return false; + + } + + } } return true; From 7f4a7253b112c9ed21022e25c7a740d824c56619 Mon Sep 17 00:00:00 2001 From: Eric Bernstein Date: Mon, 11 Sep 2017 16:56:51 -0400 Subject: [PATCH 010/155] drm/amd/display: update mpc add/remove functions Signed-off-by: Eric Bernstein Reviewed-by: Dmytro Laktyushkin Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 17 +- .../gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c | 173 ++++++++++++------ drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h | 10 +- 3 files changed, 130 insertions(+), 70 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index e60be00abcf23..82a985a981be2 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -881,7 +881,8 @@ static void dcn10_init_hw(struct dc *dc) xfm->funcs->transform_reset(xfm); dc->res_pool->mpc->funcs->remove( - dc->res_pool->mpc, dc->res_pool->opps[i], i); + dc->res_pool->mpc, &(dc->res_pool->opps[i]->mpc_tree), + dc->res_pool->opps[i]->inst, i); /* Blank controller using driver code instead of * command table. @@ -1079,7 +1080,8 @@ static void plane_atomic_disconnect(struct dc *dc, if (dc->debug.sanity_checks) verify_allow_pstate_change_high(dc->hwseq); - mpc->funcs->remove(mpc, dc->res_pool->opps[opp_id], fe_idx); + mpc->funcs->remove(mpc, &(dc->res_pool->opps[opp_id]->mpc_tree), + dc->res_pool->opps[opp_id]->inst, fe_idx); } /* disable HW used by plane. @@ -2299,8 +2301,9 @@ static void update_dchubp_dpp( plane_state->format, EXPANSION_MODE_ZERO); - mpcc_cfg.mi = mi; - mpcc_cfg.opp = pipe_ctx->stream_res.opp; + mpcc_cfg.dpp_id = mi->inst; + mpcc_cfg.opp_id = pipe_ctx->stream_res.opp->inst; + mpcc_cfg.tree_cfg = &(pipe_ctx->stream_res.opp->mpc_tree); for (top_pipe = pipe_ctx->top_pipe; top_pipe; top_pipe = top_pipe->top_pipe) mpcc_cfg.z_index++; if (dc->debug.surface_visual_confirm) @@ -2317,7 +2320,8 @@ static void update_dchubp_dpp( mpcc_cfg.pre_multiplied_alpha = is_rgb_cspace( pipe_ctx->stream->output_color_space) && per_pixel_alpha; - dc->res_pool->mpc->funcs->add(dc->res_pool->mpc, &mpcc_cfg); + mi->mpcc_id = dc->res_pool->mpc->funcs->add(dc->res_pool->mpc, &mpcc_cfg); + mi->opp_id = mpcc_cfg.opp_id; pipe_ctx->plane_res.scl_data.lb_params.alpha_en = per_pixel_alpha; pipe_ctx->plane_res.scl_data.lb_params.depth = LB_PIXEL_DEPTH_30BPP; @@ -2528,7 +2532,8 @@ static void dcn10_apply_ctx_for_surface( /* reset mpc */ dc->res_pool->mpc->funcs->remove( dc->res_pool->mpc, - old_pipe_ctx->stream_res.opp, + &(old_pipe_ctx->stream_res.opp->mpc_tree), + old_pipe_ctx->stream_res.opp->inst, old_pipe_ctx->pipe_idx); old_pipe_ctx->stream_res.opp->mpcc_disconnect_pending[old_pipe_ctx->plane_res.mi->mpcc_id] = true; diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c index 082b39a65e6ad..8e767c84359c7 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c @@ -118,17 +118,19 @@ static void mpc10_assert_mpcc_idle_before_connect(struct dcn10_mpc *mpc10, int i static void mpc10_mpcc_remove( struct mpc *mpc, - struct output_pixel_processor *opp, + struct mpc_tree_cfg *tree_cfg, + int opp_id, int dpp_id) { struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc); int mpcc_id, z_idx; - for (z_idx = 0; z_idx < opp->mpc_tree.num_pipes; z_idx++) - if (opp->mpc_tree.dpp[z_idx] == dpp_id) + /* find z_idx for the dpp to be removed */ + for (z_idx = 0; z_idx < tree_cfg->num_pipes; z_idx++) + if (tree_cfg->dpp[z_idx] == dpp_id) break; - if (z_idx == opp->mpc_tree.num_pipes) { + if (z_idx == tree_cfg->num_pipes) { /* In case of resume from S3/S4, remove mpcc from bios left over */ REG_SET(MPCC_OPP_ID[dpp_id], 0, MPCC_OPP_ID, 0xf); @@ -139,7 +141,7 @@ static void mpc10_mpcc_remove( return; } - mpcc_id = opp->mpc_tree.mpcc[z_idx]; + mpcc_id = tree_cfg->mpcc[z_idx]; REG_SET(MPCC_OPP_ID[mpcc_id], 0, MPCC_OPP_ID, 0xf); @@ -149,82 +151,101 @@ static void mpc10_mpcc_remove( MPCC_BOT_SEL, 0xf); if (z_idx > 0) { - int top_mpcc_id = opp->mpc_tree.mpcc[z_idx - 1]; + int top_mpcc_id = tree_cfg->mpcc[z_idx - 1]; - if (z_idx + 1 < opp->mpc_tree.num_pipes) + if (z_idx + 1 < tree_cfg->num_pipes) + /* mpcc to be removed is in the middle of the tree */ REG_SET(MPCC_BOT_SEL[top_mpcc_id], 0, - MPCC_BOT_SEL, opp->mpc_tree.mpcc[z_idx + 1]); + MPCC_BOT_SEL, tree_cfg->mpcc[z_idx + 1]); else { + /* mpcc to be removed is at the bottom of the tree */ REG_SET(MPCC_BOT_SEL[top_mpcc_id], 0, MPCC_BOT_SEL, 0xf); REG_UPDATE(MPCC_CONTROL[top_mpcc_id], MPCC_MODE, MODE_TOP_ONLY); } - } else if (opp->mpc_tree.num_pipes > 1) - REG_SET(MUX[opp->inst], 0, - MPC_OUT_MUX, opp->mpc_tree.mpcc[z_idx + 1]); + } else if (tree_cfg->num_pipes > 1) + /* mpcc to be removed is at the top of the tree */ + REG_SET(MUX[opp_id], 0, + MPC_OUT_MUX, tree_cfg->mpcc[z_idx + 1]); else - REG_SET(MUX[opp->inst], 0, MPC_OUT_MUX, 0xf); + /* mpcc to be removed is the only one in the tree */ + REG_SET(MUX[opp_id], 0, MPC_OUT_MUX, 0xf); + /* mark this mpcc as not in use */ mpc10->mpcc_in_use_mask &= ~(1 << mpcc_id); - opp->mpc_tree.num_pipes--; - for (; z_idx < opp->mpc_tree.num_pipes; z_idx++) { - opp->mpc_tree.dpp[z_idx] = opp->mpc_tree.dpp[z_idx + 1]; - opp->mpc_tree.mpcc[z_idx] = opp->mpc_tree.mpcc[z_idx + 1]; + tree_cfg->num_pipes--; + for (; z_idx < tree_cfg->num_pipes; z_idx++) { + tree_cfg->dpp[z_idx] = tree_cfg->dpp[z_idx + 1]; + tree_cfg->mpcc[z_idx] = tree_cfg->mpcc[z_idx + 1]; } - opp->mpc_tree.dpp[opp->mpc_tree.num_pipes] = 0xdeadbeef; - opp->mpc_tree.mpcc[opp->mpc_tree.num_pipes] = 0xdeadbeef; + tree_cfg->dpp[tree_cfg->num_pipes] = 0xdeadbeef; + tree_cfg->mpcc[tree_cfg->num_pipes] = 0xdeadbeef; } -static void mpc10_mpcc_add(struct mpc *mpc, struct mpcc_cfg *cfg) +static void mpc10_add_to_tree_cfg( + struct mpc *mpc, + struct mpcc_cfg *cfg, + int mpcc_id) { struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc); + int mpcc_mode = MODE_TOP_ONLY; + int position = cfg->z_index; + struct mpc_tree_cfg *tree_cfg = cfg->tree_cfg; int alpha_blnd_mode = cfg->per_pixel_alpha ? BLND_PP_ALPHA : BLND_GLOBAL_ALPHA; - int mpcc_mode = MODE_TOP_ONLY; - int mpcc_id, z_idx; + int z_idx; - ASSERT(cfg->z_index < mpc10->num_mpcc); + REG_SET(MPCC_OPP_ID[mpcc_id], 0, + MPCC_OPP_ID, cfg->opp_id); - for (z_idx = 0; z_idx < cfg->opp->mpc_tree.num_pipes; z_idx++) - if (cfg->opp->mpc_tree.dpp[z_idx] == cfg->mi->inst) - break; - if (z_idx == cfg->opp->mpc_tree.num_pipes) { - ASSERT(cfg->z_index <= cfg->opp->mpc_tree.num_pipes); - mpcc_id = mpc10_get_idle_mpcc_id(mpc10); - /*todo: remove hack*/ - mpcc_id = cfg->mi->inst; - ASSERT(!(mpc10->mpcc_in_use_mask & 1 << mpcc_id)); + REG_SET(MPCC_TOP_SEL[mpcc_id], 0, + MPCC_TOP_SEL, cfg->dpp_id); - if (mpc->ctx->dc->debug.sanity_checks) - mpc10_assert_mpcc_idle_before_connect(mpc10, mpcc_id); - } else { - ASSERT(cfg->z_index < cfg->opp->mpc_tree.num_pipes); - mpcc_id = cfg->opp->mpc_tree.mpcc[z_idx]; - mpc10_mpcc_remove(mpc, cfg->opp, cfg->mi->inst); - } + if (position == 0) { + /* idle dpp/mpcc is added to the top layer of tree */ - REG_SET(MPCC_OPP_ID[mpcc_id], 0, - MPCC_OPP_ID, cfg->opp->inst); + if (tree_cfg->num_pipes > 0) { + /* get instance of previous top mpcc */ + int prev_top_mpcc_id = tree_cfg->mpcc[0]; - REG_SET(MPCC_TOP_SEL[mpcc_id], 0, - MPCC_TOP_SEL, cfg->mi->inst); + REG_SET(MPCC_BOT_SEL[mpcc_id], 0, + MPCC_BOT_SEL, prev_top_mpcc_id); + mpcc_mode = MODE_BLEND; + } + + /* opp will get new output. from new added mpcc */ + REG_SET(MUX[cfg->opp_id], 0, MPC_OUT_MUX, mpcc_id); + + } else if (position == tree_cfg->num_pipes) { + /* idle dpp/mpcc is added to the bottom layer of tree */ - if (cfg->z_index > 0) { - int top_mpcc_id = cfg->opp->mpc_tree.mpcc[cfg->z_index - 1]; + /* get instance of previous bottom mpcc, set to middle layer */ + int prev_bot_mpcc_id = tree_cfg->mpcc[tree_cfg->num_pipes - 1]; - REG_SET(MPCC_BOT_SEL[top_mpcc_id], 0, + REG_SET(MPCC_BOT_SEL[prev_bot_mpcc_id], 0, MPCC_BOT_SEL, mpcc_id); - REG_UPDATE(MPCC_CONTROL[top_mpcc_id], + REG_UPDATE(MPCC_CONTROL[prev_bot_mpcc_id], MPCC_MODE, MODE_BLEND); - } else - REG_SET(MUX[cfg->opp->inst], 0, MPC_OUT_MUX, mpcc_id); - if (cfg->z_index < cfg->opp->mpc_tree.num_pipes) { - int bot_mpcc_id = cfg->opp->mpc_tree.mpcc[cfg->z_index]; + /* mpcc_id become new bottom mpcc*/ + REG_SET(MPCC_BOT_SEL[mpcc_id], 0, + MPCC_BOT_SEL, 0xf); + + } else { + /* idle dpp/mpcc is added to middle of tree */ + int above_mpcc_id = tree_cfg->mpcc[position - 1]; + int below_mpcc_id = tree_cfg->mpcc[position]; + + /* mpcc above new mpcc_id has new bottom mux*/ + REG_SET(MPCC_BOT_SEL[above_mpcc_id], 0, + MPCC_BOT_SEL, mpcc_id); + REG_UPDATE(MPCC_CONTROL[above_mpcc_id], + MPCC_MODE, MODE_BLEND); + /* mpcc_id bottom mux is from below mpcc*/ REG_SET(MPCC_BOT_SEL[mpcc_id], 0, - MPCC_BOT_SEL, bot_mpcc_id); + MPCC_BOT_SEL, below_mpcc_id); mpcc_mode = MODE_BLEND; } @@ -234,18 +255,50 @@ static void mpc10_mpcc_add(struct mpc *mpc, struct mpcc_cfg *cfg) MPCC_ALPHA_MULTIPLIED_MODE, cfg->pre_multiplied_alpha, MPCC_BLND_ACTIVE_OVERLAP_ONLY, false); + /* update mpc_tree_cfg with new mpcc */ + for (z_idx = tree_cfg->num_pipes; z_idx > position; z_idx--) { + tree_cfg->dpp[z_idx] = tree_cfg->dpp[z_idx - 1]; + tree_cfg->mpcc[z_idx] = tree_cfg->mpcc[z_idx - 1]; + } + tree_cfg->dpp[position] = cfg->dpp_id; + tree_cfg->mpcc[position] = mpcc_id; + tree_cfg->num_pipes++; +} + +static int mpc10_mpcc_add(struct mpc *mpc, struct mpcc_cfg *cfg) +{ + struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc); + int mpcc_id, z_idx; + + ASSERT(cfg->z_index < mpc10->num_mpcc); + + /* check in dpp already exists in mpc tree */ + for (z_idx = 0; z_idx < cfg->tree_cfg->num_pipes; z_idx++) + if (cfg->tree_cfg->dpp[z_idx] == cfg->dpp_id) + break; + if (z_idx == cfg->tree_cfg->num_pipes) { + ASSERT(cfg->z_index <= cfg->tree_cfg->num_pipes); + mpcc_id = mpc10_get_idle_mpcc_id(mpc10); + ASSERT(!(mpc10->mpcc_in_use_mask & 1 << mpcc_id)); + + if (mpc->ctx->dc->debug.sanity_checks) + mpc10_assert_mpcc_idle_before_connect(mpc10, mpcc_id); + } else { + ASSERT(cfg->z_index < cfg->tree_cfg->num_pipes); + mpcc_id = cfg->tree_cfg->mpcc[z_idx]; + mpc10_mpcc_remove(mpc, cfg->tree_cfg, cfg->opp_id, cfg->dpp_id); + } + + /* add dpp/mpcc pair to mpc_tree_cfg and update mpcc registers */ + mpc10_add_to_tree_cfg(mpc, cfg, mpcc_id); + + /* set background color */ mpc10_set_bg_color(mpc10, &cfg->black_color, mpcc_id); + /* mark this mpcc as in use */ mpc10->mpcc_in_use_mask |= 1 << mpcc_id; - for (z_idx = cfg->opp->mpc_tree.num_pipes; z_idx > cfg->z_index; z_idx--) { - cfg->opp->mpc_tree.dpp[z_idx] = cfg->opp->mpc_tree.dpp[z_idx - 1]; - cfg->opp->mpc_tree.mpcc[z_idx] = cfg->opp->mpc_tree.mpcc[z_idx - 1]; - } - cfg->opp->mpc_tree.dpp[cfg->z_index] = cfg->mi->inst; - cfg->opp->mpc_tree.mpcc[cfg->z_index] = mpcc_id; - cfg->opp->mpc_tree.num_pipes++; - cfg->mi->opp_id = cfg->opp->inst; - cfg->mi->mpcc_id = mpcc_id; + + return mpcc_id; } const struct mpc_funcs dcn10_mpc_funcs = { diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h b/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h index 4bbcff48acc81..2d3de5b68e34c 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h @@ -29,8 +29,9 @@ #include "opp.h" struct mpcc_cfg { - struct mem_input *mi; - struct output_pixel_processor *opp; + int dpp_id; + int opp_id; + struct mpc_tree_cfg *tree_cfg; unsigned int z_index; struct tg_color black_color; @@ -44,9 +45,10 @@ struct mpc { }; struct mpc_funcs { - void (*add)(struct mpc *mpc, struct mpcc_cfg *cfg); + int (*add)(struct mpc *mpc, struct mpcc_cfg *cfg); void (*remove)(struct mpc *mpc, - struct output_pixel_processor *opp, + struct mpc_tree_cfg *tree_cfg, + int opp_id, int mpcc_inst); void (*wait_for_idle)(struct mpc *mpc, int id); }; From 4f346e655d24140fb40b46f814506ba17ac34ea1 Mon Sep 17 00:00:00 2001 From: "Leo (Sunpeng) Li" Date: Thu, 7 Sep 2017 17:05:38 -0400 Subject: [PATCH 011/155] drm/amd/display: Match actual state during S3 resume. During system suspend, we: 1. Cache a duplicate of the current DRM atomic state, which calls hooks to duplicate our internal states. 2. Call hooks to disable all functionalities. 3. System suspended. During resume, we attempt to restore the cached state. However, our interal states are now stale, since step 1 was done before step 2. i.e. our cached state does not reflect the disabled nature of things. This change resolves that by destroying all relevant states to reflect the actual state during resume. Signed-off-by: Leo (Sunpeng) Li Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 75212f74f027b..ecca2862407f0 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -648,6 +648,11 @@ int amdgpu_dm_display_resume(struct amdgpu_device *adev) struct drm_connector *connector; struct drm_crtc *crtc; struct drm_crtc_state *new_crtc_state; + struct dm_crtc_state *dm_crtc_state; + struct drm_plane *plane; + struct drm_plane_state *plane_state; + struct dm_plane_state *dm_plane_state; + struct dm_atomic_state *cached_state; int ret = 0; int i; @@ -686,6 +691,37 @@ int amdgpu_dm_display_resume(struct amdgpu_device *adev) for_each_new_crtc_in_state(adev->dm.cached_state, crtc, new_crtc_state, i) new_crtc_state->active_changed = true; + cached_state = to_dm_atomic_state(adev->dm.cached_state); + + /* + * During suspend, the cached state is saved before all streams are + * disabled. Refresh cached state to match actual current state before + * restoring it. + */ + WARN_ON(kref_read(&cached_state->context->refcount) > 1); + dc_release_state(cached_state->context); + + cached_state->context = dc_create_state(); + dc_resource_state_copy_construct_current(adev->dm.dc, cached_state->context); + + for_each_new_crtc_in_state(adev->dm.cached_state, crtc, new_crtc_state, i) { + dm_crtc_state = to_dm_crtc_state(new_crtc_state); + if (dm_crtc_state->stream) { + WARN_ON(kref_read(&dm_crtc_state->stream->refcount) > 1); + dc_stream_release(dm_crtc_state->stream); + dm_crtc_state->stream = NULL; + } + } + + for_each_new_plane_in_state(adev->dm.cached_state, plane, plane_state, i) { + dm_plane_state = to_dm_plane_state(plane_state); + if (dm_plane_state->dc_state) { + WARN_ON(kref_read(&dm_plane_state->dc_state->refcount) > 1); + dc_plane_state_release(dm_plane_state->dc_state); + dm_plane_state->dc_state = NULL; + } + } + ret = drm_atomic_helper_resume(ddev, adev->dm.cached_state); drm_atomic_state_put(adev->dm.cached_state); From eade83503a5381ab0292f9653786bec6a638c523 Mon Sep 17 00:00:00 2001 From: Yue Hin Lau Date: Tue, 12 Sep 2017 12:08:14 -0400 Subject: [PATCH 012/155] drm/amd/display: fixing register includes Signed-off-by: Yue Hin Lau Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/dce/dce_hwseq.h | 89 +++++++++---------- .../amd/display/dc/dcn10/dcn10_mem_input.h | 2 + 2 files changed, 46 insertions(+), 45 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h index 2d3a41f744af1..589332019a830 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h @@ -131,8 +131,6 @@ HWSEQ_PHYPLL_REG_LIST(CRTC) #define HWSEQ_DCN_REG_LIST()\ - HWSEQ_PIXEL_RATE_REG_LIST(OTG), \ - HWSEQ_PHYPLL_REG_LIST(OTG), \ SRII(OTG_GLOBAL_SYNC_STATUS, OTG, 0), \ SRII(OTG_GLOBAL_SYNC_STATUS, OTG, 1), \ SRII(OTG_GLOBAL_SYNC_STATUS, OTG, 2), \ @@ -182,22 +180,6 @@ SR(DCHUBBUB_TEST_DEBUG_INDEX), \ SR(DCHUBBUB_TEST_DEBUG_DATA), \ SR(DC_IP_REQUEST_CNTL), \ - SR(DOMAIN0_PG_CONFIG), \ - SR(DOMAIN1_PG_CONFIG), \ - SR(DOMAIN2_PG_CONFIG), \ - SR(DOMAIN3_PG_CONFIG), \ - SR(DOMAIN4_PG_CONFIG), \ - SR(DOMAIN5_PG_CONFIG), \ - SR(DOMAIN6_PG_CONFIG), \ - SR(DOMAIN7_PG_CONFIG), \ - SR(DOMAIN0_PG_STATUS), \ - SR(DOMAIN1_PG_STATUS), \ - SR(DOMAIN2_PG_STATUS), \ - SR(DOMAIN3_PG_STATUS), \ - SR(DOMAIN4_PG_STATUS), \ - SR(DOMAIN5_PG_STATUS), \ - SR(DOMAIN6_PG_STATUS), \ - SR(DOMAIN7_PG_STATUS), \ SR(DIO_MEM_PWR_CTRL), \ SR(DCCG_GATE_DISABLE_CNTL), \ SR(DCCG_GATE_DISABLE_CNTL2), \ @@ -223,13 +205,30 @@ #define HWSEQ_DCN1_REG_LIST()\ HWSEQ_DCN_REG_LIST(), \ + HWSEQ_PIXEL_RATE_REG_LIST(OTG), \ + HWSEQ_PHYPLL_REG_LIST(OTG), \ SR(DCHUBBUB_SDPIF_FB_TOP),\ SR(DCHUBBUB_SDPIF_FB_BASE),\ SR(DCHUBBUB_SDPIF_FB_OFFSET),\ SR(DCHUBBUB_SDPIF_AGP_BASE),\ SR(DCHUBBUB_SDPIF_AGP_BOT),\ - SR(DCHUBBUB_SDPIF_AGP_TOP) - + SR(DCHUBBUB_SDPIF_AGP_TOP),\ + SR(DOMAIN0_PG_CONFIG), \ + SR(DOMAIN1_PG_CONFIG), \ + SR(DOMAIN2_PG_CONFIG), \ + SR(DOMAIN3_PG_CONFIG), \ + SR(DOMAIN4_PG_CONFIG), \ + SR(DOMAIN5_PG_CONFIG), \ + SR(DOMAIN6_PG_CONFIG), \ + SR(DOMAIN7_PG_CONFIG), \ + SR(DOMAIN0_PG_STATUS), \ + SR(DOMAIN1_PG_STATUS), \ + SR(DOMAIN2_PG_STATUS), \ + SR(DOMAIN3_PG_STATUS), \ + SR(DOMAIN4_PG_STATUS), \ + SR(DOMAIN5_PG_STATUS), \ + SR(DOMAIN6_PG_STATUS), \ + SR(DOMAIN7_PG_STATUS) struct dce_hwseq_registers { uint32_t DCFE_CLOCK_CONTROL[6]; @@ -417,30 +416,6 @@ struct dce_hwseq_registers { HWS_SF(OPP_PIPE0_, OPP_PIPE_CONTROL, OPP_PIPE_CLOCK_EN, mask_sh),\ HWS_SF(, DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_ENABLE, mask_sh), \ HWS_SF(, DC_IP_REQUEST_CNTL, IP_REQUEST_EN, mask_sh), \ - HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN0_POWER_FORCEON, mask_sh), \ - HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN0_POWER_GATE, mask_sh), \ - HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN1_POWER_FORCEON, mask_sh), \ - HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN1_POWER_GATE, mask_sh), \ - HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN2_POWER_FORCEON, mask_sh), \ - HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN2_POWER_GATE, mask_sh), \ - HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN3_POWER_FORCEON, mask_sh), \ - HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN3_POWER_GATE, mask_sh), \ - HWS_SF(, DOMAIN4_PG_CONFIG, DOMAIN4_POWER_FORCEON, mask_sh), \ - HWS_SF(, DOMAIN4_PG_CONFIG, DOMAIN4_POWER_GATE, mask_sh), \ - HWS_SF(, DOMAIN5_PG_CONFIG, DOMAIN5_POWER_FORCEON, mask_sh), \ - HWS_SF(, DOMAIN5_PG_CONFIG, DOMAIN5_POWER_GATE, mask_sh), \ - HWS_SF(, DOMAIN6_PG_CONFIG, DOMAIN6_POWER_FORCEON, mask_sh), \ - HWS_SF(, DOMAIN6_PG_CONFIG, DOMAIN6_POWER_GATE, mask_sh), \ - HWS_SF(, DOMAIN7_PG_CONFIG, DOMAIN7_POWER_FORCEON, mask_sh), \ - HWS_SF(, DOMAIN7_PG_CONFIG, DOMAIN7_POWER_GATE, mask_sh), \ - HWS_SF(, DOMAIN0_PG_STATUS, DOMAIN0_PGFSM_PWR_STATUS, mask_sh), \ - HWS_SF(, DOMAIN1_PG_STATUS, DOMAIN1_PGFSM_PWR_STATUS, mask_sh), \ - HWS_SF(, DOMAIN2_PG_STATUS, DOMAIN2_PGFSM_PWR_STATUS, mask_sh), \ - HWS_SF(, DOMAIN3_PG_STATUS, DOMAIN3_PGFSM_PWR_STATUS, mask_sh), \ - HWS_SF(, DOMAIN4_PG_STATUS, DOMAIN4_PGFSM_PWR_STATUS, mask_sh), \ - HWS_SF(, DOMAIN5_PG_STATUS, DOMAIN5_PGFSM_PWR_STATUS, mask_sh), \ - HWS_SF(, DOMAIN6_PG_STATUS, DOMAIN6_PGFSM_PWR_STATUS, mask_sh), \ - HWS_SF(, DOMAIN7_PG_STATUS, DOMAIN7_PGFSM_PWR_STATUS, mask_sh), \ HWS_SF(, DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL, DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, mask_sh), \ HWS_SF(, DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL, DCHUBBUB_ARB_WATERMARK_CHANGE_DONE_INTERRUPT_DISABLE, mask_sh), \ HWS_SF(, DCHUBBUB_ARB_DRAM_STATE_CNTL, DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_VALUE, mask_sh), \ @@ -468,7 +443,31 @@ struct dce_hwseq_registers { HWS_SF(, VM_L2_PROTECTION_FAULT_DEFAULT_ADDR_LO32, PHYSICAL_PAGE_ADDR_LO32, mask_sh),\ HWS_SF(, MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, PHYSICAL_PAGE_NUMBER_MSB, mask_sh),\ HWS_SF(, MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, PHYSICAL_PAGE_NUMBER_LSB, mask_sh),\ - HWS_SF(, MC_VM_SYSTEM_APERTURE_LOW_ADDR, LOGICAL_ADDR, mask_sh) + HWS_SF(, MC_VM_SYSTEM_APERTURE_LOW_ADDR, LOGICAL_ADDR, mask_sh),\ + HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN0_POWER_FORCEON, mask_sh), \ + HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN0_POWER_GATE, mask_sh), \ + HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN1_POWER_FORCEON, mask_sh), \ + HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN1_POWER_GATE, mask_sh), \ + HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN2_POWER_FORCEON, mask_sh), \ + HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN2_POWER_GATE, mask_sh), \ + HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN3_POWER_FORCEON, mask_sh), \ + HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN3_POWER_GATE, mask_sh), \ + HWS_SF(, DOMAIN4_PG_CONFIG, DOMAIN4_POWER_FORCEON, mask_sh), \ + HWS_SF(, DOMAIN4_PG_CONFIG, DOMAIN4_POWER_GATE, mask_sh), \ + HWS_SF(, DOMAIN5_PG_CONFIG, DOMAIN5_POWER_FORCEON, mask_sh), \ + HWS_SF(, DOMAIN5_PG_CONFIG, DOMAIN5_POWER_GATE, mask_sh), \ + HWS_SF(, DOMAIN6_PG_CONFIG, DOMAIN6_POWER_FORCEON, mask_sh), \ + HWS_SF(, DOMAIN6_PG_CONFIG, DOMAIN6_POWER_GATE, mask_sh), \ + HWS_SF(, DOMAIN7_PG_CONFIG, DOMAIN7_POWER_FORCEON, mask_sh), \ + HWS_SF(, DOMAIN7_PG_CONFIG, DOMAIN7_POWER_GATE, mask_sh), \ + HWS_SF(, DOMAIN0_PG_STATUS, DOMAIN0_PGFSM_PWR_STATUS, mask_sh), \ + HWS_SF(, DOMAIN1_PG_STATUS, DOMAIN1_PGFSM_PWR_STATUS, mask_sh), \ + HWS_SF(, DOMAIN2_PG_STATUS, DOMAIN2_PGFSM_PWR_STATUS, mask_sh), \ + HWS_SF(, DOMAIN3_PG_STATUS, DOMAIN3_PGFSM_PWR_STATUS, mask_sh), \ + HWS_SF(, DOMAIN4_PG_STATUS, DOMAIN4_PGFSM_PWR_STATUS, mask_sh), \ + HWS_SF(, DOMAIN5_PG_STATUS, DOMAIN5_PGFSM_PWR_STATUS, mask_sh), \ + HWS_SF(, DOMAIN6_PG_STATUS, DOMAIN6_PGFSM_PWR_STATUS, mask_sh), \ + HWS_SF(, DOMAIN7_PG_STATUS, DOMAIN7_PGFSM_PWR_STATUS, mask_sh) #define HWSEQ_REG_FIELD_LIST(type) \ type DCFE_CLOCK_ENABLE; \ diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.h index aefd3e7bd7eb2..0b7d4faff82fa 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.h +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.h @@ -120,6 +120,8 @@ SR(DCHUBBUB_SDPIF_FB_BASE),\ SR(DCHUBBUB_SDPIF_FB_OFFSET) + + struct dcn_mi_registers { uint32_t DCHUBP_CNTL; uint32_t HUBPREQ_DEBUG_DB; From f4ac176e62fdc74e52ee58461fb7c8912322fc1c Mon Sep 17 00:00:00 2001 From: Jerry Zuo Date: Fri, 8 Sep 2017 11:52:45 -0400 Subject: [PATCH 013/155] drm/amd/display: Exclude MST from fake sink Needs effort to take care of the fake sink scenario in downstream daisy chain device. Exclude MST from fake sink feature for now. Signed-off-by: Jerry Zuo Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index ecca2862407f0..dfea04fed695b 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -2354,8 +2354,16 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector, drm_connector = &aconnector->base; - if (!aconnector->dc_sink) + if (!aconnector->dc_sink) { + /* + * Exclude MST from creating fake_sink + * TODO: need to enable MST into fake_sink feature + */ + if (aconnector->mst_port) + goto stream_create_fail; + create_fake_sink(aconnector); + } stream = dc_create_stream_for_sink(aconnector->dc_sink); @@ -4376,7 +4384,8 @@ static int dm_update_crtcs_state(struct dc *dc, aconnector = amdgpu_dm_find_first_crtc_matching_connector(state, crtc); /* TODO This hack should go away */ - if (aconnector) { + if (aconnector && enable) { + // Make sure fake sink is created in plug-in scenario new_con_state = drm_atomic_get_connector_state(state, &aconnector->base); From fc17235fe65b0179969e0793a086cba93afcc078 Mon Sep 17 00:00:00 2001 From: Jerry Zuo Date: Fri, 8 Sep 2017 16:40:34 -0400 Subject: [PATCH 014/155] drm/amd/display: Fix NULL pointer on MST chained mode Prevent NULL pointer on new_stream being added to ctx when added MST connectors cannot be found in existing crtc_state in the chained mode Signed-off-by: Jerry Zuo Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index dfea04fed695b..f2724713ddd08 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -4462,6 +4462,13 @@ static int dm_update_crtcs_state(struct dc *dc, *lock_and_validation_needed = true; } else {/* Add stream for any updated/enabled CRTC */ + /* + * Quick fix to prevent NULL pointer on new_stream when + * added MST connectors not found in existing crtc_state in the chained mode + * TODO: need to dig out the root cause of that + */ + if (!aconnector || (!aconnector->dc_sink && aconnector->mst_port)) + continue; if (modereset_required(new_crtc_state)) goto next_crtc; From bc6828e0e6b6c5bcafbb093f9fe475f63dbe47e5 Mon Sep 17 00:00:00 2001 From: Bhawanpreet Lakha Date: Tue, 12 Sep 2017 13:56:57 -0400 Subject: [PATCH 015/155] drm/amd/display: Refactor dc_update_planes_and_stream. Split update_planes_and_stream_state (split Software and Hardware programming) as the state is already build, so we only need to program the hardware Signed-off-by: Andrey Grodzovsky Signed-off-by: Bhawanpreet Lakha Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 21 +- drivers/gpu/drm/amd/display/dc/core/dc.c | 256 ++++-------------- drivers/gpu/drm/amd/display/dc/dc.h | 36 +-- 3 files changed, 87 insertions(+), 226 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index f2724713ddd08..6c04ad1b58598 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -3771,7 +3771,8 @@ static void prepare_flip_isr(struct amdgpu_crtc *acrtc) */ static void amdgpu_dm_do_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, - uint32_t target) + uint32_t target, + struct dc_state *state) { unsigned long flags; uint32_t target_vblank; @@ -3842,7 +3843,13 @@ static void amdgpu_dm_do_flip(struct drm_crtc *crtc, surface_updates->flip_addr = &addr; - dc_update_planes_and_stream(adev->dm.dc, surface_updates, 1, acrtc_state->stream, NULL); + dc_commit_updates_for_stream(adev->dm.dc, + surface_updates, + 1, + acrtc_state->stream, + NULL, + &surface_updates->surface, + state); DRM_DEBUG_DRIVER("%s Flipping to hi: 0x%x, low: 0x%x \n", __func__, @@ -3868,6 +3875,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, struct drm_crtc_state *new_pcrtc_state = drm_atomic_get_new_crtc_state(state, pcrtc); struct dm_crtc_state *acrtc_state = to_dm_crtc_state(new_pcrtc_state); + struct dm_atomic_state *dm_state = to_dm_atomic_state(state); int planes_count = 0; unsigned long flags; @@ -3925,7 +3933,8 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, amdgpu_dm_do_flip( crtc, fb, - drm_crtc_vblank_count(crtc) + *wait_for_vblank); + drm_crtc_vblank_count(crtc) + *wait_for_vblank, + dm_state->context); } } @@ -3945,7 +3954,8 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, if (false == dc_commit_planes_to_stream(dm->dc, plane_states_constructed, planes_count, - dc_stream_attach)) + dc_stream_attach, + dm_state->context)) dm_error("%s: Failed to attach plane!\n", __func__); } else { /*TODO BUG Here should go disable planes on CRTC. */ @@ -4165,7 +4175,8 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) dm->dc, status->plane_states, status->plane_count, - dm_new_crtc_state->stream)) + dm_new_crtc_state->stream, + dm_state->context)) dm_error("%s: Failed to update stream scaling!\n", __func__); } diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 47f16a4b9f271..1ec6df9870da1 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -869,7 +869,8 @@ bool dc_commit_planes_to_stream( struct dc *dc, struct dc_plane_state **plane_states, uint8_t new_plane_count, - struct dc_stream_state *dc_stream) + struct dc_stream_state *dc_stream, + struct dc_state *state) { struct dc_surface_update updates[MAX_SURFACES]; struct dc_flip_addrs flip_addr[MAX_SURFACES]; @@ -920,11 +921,11 @@ bool dc_commit_planes_to_stream( updates[i].scaling_info = &scaling_info[i]; } - dc_update_planes_and_stream( + dc_commit_updates_for_stream( dc, updates, new_plane_count, - dc_stream, stream_update); + dc_stream, stream_update, plane_states, state); dc_post_update_surfaces_to_stream(dc); @@ -1150,192 +1151,20 @@ static struct dc_stream_status *stream_get_status( static const enum surface_update_type update_surface_trace_level = UPDATE_TYPE_FULL; -void dc_update_planes_and_stream(struct dc *dc, - struct dc_surface_update *srf_updates, int surface_count, + +static void commit_planes_for_stream(struct dc *dc, + struct dc_surface_update *srf_updates, + int surface_count, struct dc_stream_state *stream, - struct dc_stream_update *stream_update) + struct dc_stream_update *stream_update, + enum surface_update_type update_type, + struct dc_state *context) { - struct dc_state *context; int i, j; - enum surface_update_type update_type; - const struct dc_stream_status *stream_status; - struct dc_context *dc_ctx = dc->ctx; - - stream_status = dc_stream_get_status(stream); - - ASSERT(stream_status); - if (!stream_status) - return; /* Cannot commit surface to stream that is not committed */ - -#ifdef ENABLE_FBC - if (srf_updates->flip_addr) { - if (srf_updates->flip_addr->address.grph.addr.low_part == 0) - ASSERT(0); - } -#endif - context = dc->current_state; - - /* update current stream with the new updates */ - if (stream_update) { - if ((stream_update->src.height != 0) && - (stream_update->src.width != 0)) - stream->src = stream_update->src; - - if ((stream_update->dst.height != 0) && - (stream_update->dst.width != 0)) - stream->dst = stream_update->dst; - - if (stream_update->out_transfer_func && - stream_update->out_transfer_func != - stream->out_transfer_func) { - if (stream->out_transfer_func != NULL) - dc_transfer_func_release(stream->out_transfer_func); - dc_transfer_func_retain(stream_update->out_transfer_func); - stream->out_transfer_func = - stream_update->out_transfer_func; - } - } - - /* do not perform surface update if surface has invalid dimensions - * (all zero) and no scaling_info is provided - */ - if (surface_count > 0 && - srf_updates->surface->src_rect.width == 0 && - srf_updates->surface->src_rect.height == 0 && - srf_updates->surface->dst_rect.width == 0 && - srf_updates->surface->dst_rect.height == 0 && - !srf_updates->scaling_info) { - ASSERT(false); - return; - } - - update_type = dc_check_update_surfaces_for_stream( - dc, srf_updates, surface_count, stream_update, stream_status); - - if (update_type >= update_surface_trace_level) - update_surface_trace(dc, srf_updates, surface_count); - - if (update_type >= UPDATE_TYPE_FULL) { - struct dc_plane_state *new_planes[MAX_SURFACES] = {0}; - - for (i = 0; i < surface_count; i++) - new_planes[i] = srf_updates[i].surface; - - /* initialize scratch memory for building context */ - context = dc_create_state(); - if (context == NULL) { - DC_ERROR("Failed to allocate new validate context!\n"); - return; - } - - dc_resource_state_copy_construct( - dc->current_state, context); - - /*remove old surfaces from context */ - if (!dc_rem_all_planes_for_stream(dc, stream, context)) { - - BREAK_TO_DEBUGGER(); - goto fail; - } - - /* add surface to context */ - if (!dc_add_all_planes_for_stream(dc, stream, new_planes, surface_count, context)) { - - BREAK_TO_DEBUGGER(); - goto fail; - } - } - - /* save update parameters into surface */ - for (i = 0; i < surface_count; i++) { - struct dc_plane_state *surface = srf_updates[i].surface; - - if (srf_updates[i].flip_addr) { - surface->address = srf_updates[i].flip_addr->address; - surface->flip_immediate = - srf_updates[i].flip_addr->flip_immediate; - } - - if (srf_updates[i].scaling_info) { - surface->scaling_quality = - srf_updates[i].scaling_info->scaling_quality; - surface->dst_rect = - srf_updates[i].scaling_info->dst_rect; - surface->src_rect = - srf_updates[i].scaling_info->src_rect; - surface->clip_rect = - srf_updates[i].scaling_info->clip_rect; - } - - if (srf_updates[i].plane_info) { - surface->color_space = - srf_updates[i].plane_info->color_space; - surface->format = - srf_updates[i].plane_info->format; - surface->plane_size = - srf_updates[i].plane_info->plane_size; - surface->rotation = - srf_updates[i].plane_info->rotation; - surface->horizontal_mirror = - srf_updates[i].plane_info->horizontal_mirror; - surface->stereo_format = - srf_updates[i].plane_info->stereo_format; - surface->tiling_info = - srf_updates[i].plane_info->tiling_info; - surface->visible = - srf_updates[i].plane_info->visible; - surface->per_pixel_alpha = - srf_updates[i].plane_info->per_pixel_alpha; - surface->dcc = - srf_updates[i].plane_info->dcc; - } - - if (update_type >= UPDATE_TYPE_MED) { - for (j = 0; j < dc->res_pool->pipe_count; j++) { - struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j]; - - if (pipe_ctx->plane_state != surface) - continue; - - resource_build_scaling_params(pipe_ctx); - } - } - - if (srf_updates[i].gamma && - srf_updates[i].gamma != surface->gamma_correction) { - if (surface->gamma_correction != NULL) - dc_gamma_release(&surface->gamma_correction); - - dc_gamma_retain(srf_updates[i].gamma); - surface->gamma_correction = srf_updates[i].gamma; - } - - if (srf_updates[i].in_transfer_func && - srf_updates[i].in_transfer_func != surface->in_transfer_func) { - if (surface->in_transfer_func != NULL) - dc_transfer_func_release( - surface-> - in_transfer_func); - - dc_transfer_func_retain( - srf_updates[i].in_transfer_func); - surface->in_transfer_func = - srf_updates[i].in_transfer_func; - } - - if (srf_updates[i].hdr_static_metadata) - surface->hdr_static_ctx = - *(srf_updates[i].hdr_static_metadata); - } if (update_type == UPDATE_TYPE_FULL) { - if (!dc->res_pool->funcs->validate_bandwidth(dc, context)) { - BREAK_TO_DEBUGGER(); - goto fail; - } else { - dc->hwss.set_bandwidth(dc, context, false); - context_clock_trace(dc, context); - } + dc->hwss.set_bandwidth(dc, context, false); + context_clock_trace(dc, context); } if (update_type > UPDATE_TYPE_FAST) { @@ -1459,27 +1288,60 @@ void dc_update_planes_and_stream(struct dc *dc, break; } } +} + +void dc_commit_updates_for_stream(struct dc *dc, + struct dc_surface_update *srf_updates, + int surface_count, + struct dc_stream_state *stream, + struct dc_stream_update *stream_update, + struct dc_plane_state **plane_states, + struct dc_state *state) +{ + const struct dc_stream_status *stream_status; + enum surface_update_type update_type; + struct dc_state *context; + int i; - if (dc->current_state != context) { + stream_status = dc_stream_get_status(stream); + context = dc->current_state; + + update_type = dc_check_update_surfaces_for_stream( + dc, srf_updates, surface_count, stream_update, stream_status); + + if (update_type >= update_surface_trace_level) + update_surface_trace(dc, srf_updates, surface_count); - /* Since memory free requires elevated IRQL, an interrupt - * request is generated by mem free. If this happens - * between freeing and reassigning the context, our vsync - * interrupt will call into dc and cause a memory - * corruption BSOD. Hence, we first reassign the context, - * then free the old context. - */ - struct dc_state *old = dc->current_state; + if (update_type >= UPDATE_TYPE_FULL) + dc_resource_state_copy_construct(state, context); - dc->current_state = context; - dc_release_state(old); + + for (i = 0; i < surface_count; i++) { + struct dc_plane_state *surface = srf_updates[i].surface; + + /* TODO: On flip we don't build the state, so it still has the + * old address. Which is why we are updating the address here + */ + if (srf_updates[i].flip_addr) + surface->address = srf_updates[i].flip_addr->address; } + + + commit_planes_for_stream( + dc, + srf_updates, + surface_count, + stream, + stream_update, + update_type, + context); + + dc_post_update_surfaces_to_stream(dc); + return; -fail: - dc_release_state(context); } uint8_t dc_get_current_stream_count(struct dc *dc) diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 4ff543826476c..50440731f83c7 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -449,23 +449,6 @@ struct dc_flip_addrs { /* TODO: add flip duration for FreeSync */ }; -/* - * Set up surface attributes and associate to a stream - * The surfaces parameter is an absolute set of all surface active for the stream. - * If no surfaces are provided, the stream will be blanked; no memory read. - * Any flip related attribute changes must be done through this interface. - * - * After this call: - * Surfaces attributes are programmed and configured to be composed into stream. - * This does not trigger a flip. No surface address is programmed. - */ - -bool dc_commit_planes_to_stream( - struct dc *dc, - struct dc_plane_state **plane_states, - uint8_t new_plane_count, - struct dc_stream_state *stream); - bool dc_post_update_surfaces_to_stream( struct dc *dc); @@ -571,9 +554,6 @@ bool dc_is_stream_unchanged( struct dc_stream_state *old_stream, struct dc_stream_state *stream); /* - * Setup stream attributes if no stream updates are provided - * there will be no impact on the stream parameters - * * Set up surface attributes and associate to a stream * The surfaces parameter is an absolute set of all surface active for the stream. * If no surfaces are provided, the stream will be blanked; no memory read. @@ -582,14 +562,22 @@ bool dc_is_stream_unchanged( * After this call: * Surfaces attributes are programmed and configured to be composed into stream. * This does not trigger a flip. No surface address is programmed. - * */ -void dc_update_planes_and_stream(struct dc *dc, - struct dc_surface_update *surface_updates, int surface_count, +bool dc_commit_planes_to_stream( + struct dc *dc, + struct dc_plane_state **plane_states, + uint8_t new_plane_count, struct dc_stream_state *dc_stream, - struct dc_stream_update *stream_update); + struct dc_state *state); +void dc_commit_updates_for_stream(struct dc *dc, + struct dc_surface_update *srf_updates, + int surface_count, + struct dc_stream_state *stream, + struct dc_stream_update *stream_update, + struct dc_plane_state **plane_states, + struct dc_state *state); /* * Log the current stream state. */ From 4b7e7e2b1bb2c7308ee3ccbef3f67cb9ce52e954 Mon Sep 17 00:00:00 2001 From: ShihChen Chen Date: Tue, 12 Sep 2017 11:10:12 +0800 Subject: [PATCH 016/155] drm/amd/display: make tile changing run at ISR Signed-off-by: ShihChen Chen Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 1ec6df9870da1..2cea8de9c9be0 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -1031,7 +1031,6 @@ static enum surface_update_type get_plane_info_update_type( temp_plane_info.plane_size = u->surface->plane_size; temp_plane_info.rotation = u->surface->rotation; temp_plane_info.stereo_format = u->surface->stereo_format; - temp_plane_info.tiling_info = u->surface->tiling_info; if (surface_index == 0) temp_plane_info.visible = u->plane_info->visible; @@ -1044,10 +1043,26 @@ static enum surface_update_type get_plane_info_update_type( if (pixel_format_to_bpp(u->plane_info->format) != pixel_format_to_bpp(u->surface->format)) { + /* different bytes per element will require full bandwidth + * and DML calculation + */ return UPDATE_TYPE_FULL; - } else { - return UPDATE_TYPE_MED; } + + if (memcmp(&u->plane_info->tiling_info, &u->surface->tiling_info, + sizeof(union dc_tiling_info)) != 0) { + /* todo: below are HW dependent, we should add a hook to + * DCE/N resource and validated there. + */ + if (u->plane_info->tiling_info.gfx9.swizzle != DC_SW_LINEAR) { + /* swizzled mode requires RQ to be setup properly, + * thus need to run DML to calculate RQ settings + */ + return UPDATE_TYPE_FULL; + } + } + + return UPDATE_TYPE_MED; } static enum surface_update_type get_scaling_info_update_type( From 68d77dd8214e5186d535ec7af29722aaad621824 Mon Sep 17 00:00:00 2001 From: Andrew Jiang Date: Wed, 13 Sep 2017 11:36:34 -0400 Subject: [PATCH 017/155] drm/amd/display: power_down_Hw need signal type to turnoff backlight Signed-off-by: Charlene Liu Reviewed-by: Anthony Koo Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c index 590b2ad371059..d83a330712f7c 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c @@ -1171,6 +1171,7 @@ static void power_down_encoders(struct dc *dc) { int i; enum connector_id connector_id; + enum signal_type signal = SIGNAL_TYPE_NONE; for (i = 0; i < dc->link_count; i++) { connector_id = dal_graphics_object_id_get_connector_id(dc->links[i]->link_id); if ((connector_id == CONNECTOR_ID_DISPLAY_PORT) || @@ -1178,10 +1179,12 @@ static void power_down_encoders(struct dc *dc) if (!dc->links[i]->wa_flags.dp_keep_receiver_powered) dp_receiver_power_ctrl(dc->links[i], false); + if (connector_id == CONNECTOR_ID_EDP) + signal = SIGNAL_TYPE_EDP; } dc->links[i]->link_enc->funcs->disable_output( - dc->links[i]->link_enc, SIGNAL_TYPE_NONE); + dc->links[i]->link_enc, signal); } } From d53d7866a795410f7b6a16b1ef0b37825edc794e Mon Sep 17 00:00:00 2001 From: Yue Hin Lau Date: Thu, 14 Sep 2017 11:27:34 -0400 Subject: [PATCH 018/155] drm/amd/display: removing remaining register definitions work around Signed-off-by: Yue Hin Lau Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/dce/dce_hwseq.h | 16 +++++++------- .../drm/amd/display/dc/dce/dce_link_encoder.h | 21 ++++++++++++------- .../display/dc/dcn10/dcn10_timing_generator.h | 11 +--------- 3 files changed, 23 insertions(+), 25 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h index 589332019a830..5798001da770b 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h @@ -179,16 +179,11 @@ SR(DCHUBBUB_GLOBAL_TIMER_CNTL), \ SR(DCHUBBUB_TEST_DEBUG_INDEX), \ SR(DCHUBBUB_TEST_DEBUG_DATA), \ - SR(DC_IP_REQUEST_CNTL), \ SR(DIO_MEM_PWR_CTRL), \ SR(DCCG_GATE_DISABLE_CNTL), \ SR(DCCG_GATE_DISABLE_CNTL2), \ SR(DCFCLK_CNTL),\ SR(DCFCLK_CNTL), \ - SR(D1VGA_CONTROL), \ - SR(D2VGA_CONTROL), \ - SR(D3VGA_CONTROL), \ - SR(D4VGA_CONTROL), \ /* todo: get these from GVM instead of reading registers ourselves */\ MMHUB_SR(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32),\ MMHUB_SR(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32),\ @@ -228,7 +223,12 @@ SR(DOMAIN4_PG_STATUS), \ SR(DOMAIN5_PG_STATUS), \ SR(DOMAIN6_PG_STATUS), \ - SR(DOMAIN7_PG_STATUS) + SR(DOMAIN7_PG_STATUS), \ + SR(D1VGA_CONTROL), \ + SR(D2VGA_CONTROL), \ + SR(D3VGA_CONTROL), \ + SR(D4VGA_CONTROL), \ + SR(DC_IP_REQUEST_CNTL) struct dce_hwseq_registers { uint32_t DCFE_CLOCK_CONTROL[6]; @@ -415,7 +415,6 @@ struct dce_hwseq_registers { HWS_SF(DPP_TOP0_, DPP_CONTROL, DPP_CLOCK_ENABLE, mask_sh), \ HWS_SF(OPP_PIPE0_, OPP_PIPE_CONTROL, OPP_PIPE_CLOCK_EN, mask_sh),\ HWS_SF(, DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_ENABLE, mask_sh), \ - HWS_SF(, DC_IP_REQUEST_CNTL, IP_REQUEST_EN, mask_sh), \ HWS_SF(, DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL, DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, mask_sh), \ HWS_SF(, DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL, DCHUBBUB_ARB_WATERMARK_CHANGE_DONE_INTERRUPT_DISABLE, mask_sh), \ HWS_SF(, DCHUBBUB_ARB_DRAM_STATE_CNTL, DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_VALUE, mask_sh), \ @@ -467,7 +466,8 @@ struct dce_hwseq_registers { HWS_SF(, DOMAIN4_PG_STATUS, DOMAIN4_PGFSM_PWR_STATUS, mask_sh), \ HWS_SF(, DOMAIN5_PG_STATUS, DOMAIN5_PGFSM_PWR_STATUS, mask_sh), \ HWS_SF(, DOMAIN6_PG_STATUS, DOMAIN6_PGFSM_PWR_STATUS, mask_sh), \ - HWS_SF(, DOMAIN7_PG_STATUS, DOMAIN7_PGFSM_PWR_STATUS, mask_sh) + HWS_SF(, DOMAIN7_PG_STATUS, DOMAIN7_PGFSM_PWR_STATUS, mask_sh), \ + HWS_SF(, DC_IP_REQUEST_CNTL, IP_REQUEST_EN, mask_sh) #define HWSEQ_REG_FIELD_LIST(type) \ type DCFE_CLOCK_ENABLE; \ diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h index be0a45bdc5e2f..05463df7e6360 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h @@ -44,8 +44,6 @@ SRI(DC_HPD_CONTROL, HPD, id) #define LE_COMMON_REG_LIST_BASE(id) \ - SR(LVTMA_PWRSEQ_CNTL), \ - SR(LVTMA_PWRSEQ_STATE), \ SR(DMCU_RAM_ACCESS_CTRL), \ SR(DMCU_IRAM_RD_CTRL), \ SR(DMCU_IRAM_RD_DATA), \ @@ -71,6 +69,10 @@ SRI(DP_DPHY_FAST_TRAINING, DP, id), \ SRI(DP_SEC_CNTL1, DP, id) +#define LE_EDP_REG_LIST(id)\ + SR(LVTMA_PWRSEQ_CNTL), \ + SR(LVTMA_PWRSEQ_STATE) + #define LE_COMMON_REG_LIST(id)\ LE_COMMON_REG_LIST_BASE(id), \ SRI(DP_DPHY_BS_SR_SWAP_CNTL, DP, id), \ @@ -79,33 +81,38 @@ #define LE_DCE80_REG_LIST(id)\ SRI(DP_DPHY_INTERNAL_CTRL, DP, id), \ - LE_COMMON_REG_LIST_BASE(id) + LE_COMMON_REG_LIST_BASE(id), \ + LE_EDP_REG_LIST(id) #define LE_DCE100_REG_LIST(id)\ LE_COMMON_REG_LIST_BASE(id), \ SRI(DP_DPHY_BS_SR_SWAP_CNTL, DP, id), \ SRI(DP_DPHY_INTERNAL_CTRL, DP, id), \ - SR(DCI_MEM_PWR_STATUS) + SR(DCI_MEM_PWR_STATUS), \ + LE_EDP_REG_LIST(id) #define LE_DCE110_REG_LIST(id)\ LE_COMMON_REG_LIST_BASE(id), \ SRI(DP_DPHY_BS_SR_SWAP_CNTL, DP, id), \ SRI(DP_DPHY_INTERNAL_CTRL, DP, id), \ SRI(DP_DPHY_HBR2_PATTERN_CONTROL, DP, id), \ - SR(DCI_MEM_PWR_STATUS) + SR(DCI_MEM_PWR_STATUS), \ + LE_EDP_REG_LIST(id) #define LE_DCE120_REG_LIST(id)\ LE_COMMON_REG_LIST_BASE(id), \ SRI(DP_DPHY_BS_SR_SWAP_CNTL, DP, id), \ SRI(DP_DPHY_HBR2_PATTERN_CONTROL, DP, id), \ - SR(DCI_MEM_PWR_STATUS) + SR(DCI_MEM_PWR_STATUS), \ + LE_EDP_REG_LIST(id) #define LE_DCN10_REG_LIST(id)\ LE_COMMON_REG_LIST_BASE(id), \ SRI(DP_DPHY_BS_SR_SWAP_CNTL, DP, id), \ SRI(DP_DPHY_INTERNAL_CTRL, DP, id), \ SRI(DP_DPHY_HBR2_PATTERN_CONTROL, DP, id), \ - SR(DMU_MEM_PWR_CNTL) + SR(DMU_MEM_PWR_CNTL), \ + LE_EDP_REG_LIST(id) struct dce110_link_enc_aux_registers { uint32_t AUX_CONTROL; diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.h index 69da293e9b4a9..0826d73b98093 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.h +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.h @@ -71,11 +71,7 @@ SRI(OPTC_INPUT_GLOBAL_CONTROL, ODM, inst),\ SRI(OPPBUF_CONTROL, OPPBUF, inst),\ SRI(OPPBUF_3D_PARAMETERS_0, OPPBUF, inst),\ - SRI(CONTROL, VTG, inst),\ - SR(D1VGA_CONTROL),\ - SR(D2VGA_CONTROL),\ - SR(D3VGA_CONTROL),\ - SR(D4VGA_CONTROL) + SRI(CONTROL, VTG, inst) #define TG_COMMON_REG_LIST_DCN1_0(inst) \ TG_COMMON_REG_LIST_DCN(inst),\ @@ -128,11 +124,6 @@ struct dcn_tg_registers { uint32_t OPPBUF_CONTROL; uint32_t OPPBUF_3D_PARAMETERS_0; uint32_t CONTROL; - /*todo: move VGA to HWSS */ - uint32_t D1VGA_CONTROL; - uint32_t D2VGA_CONTROL; - uint32_t D3VGA_CONTROL; - uint32_t D4VGA_CONTROL; }; #define TG_COMMON_MASK_SH_LIST_DCN(mask_sh)\ From 25bab0da8f61e7d8f717e4f9be34e97a1aaa0ccc Mon Sep 17 00:00:00 2001 From: Wenjing Liu Date: Thu, 14 Sep 2017 18:50:32 -0400 Subject: [PATCH 019/155] drm/amd/display: set cp25201 to use TPS4 [Description] hbr2 compliance eye output is unstable (toggling on and off) with debugger break. This caueses intermittent PHY automation failure. Need to look into the root cause later Signed-off-by: Wenjing Liu Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) 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 b735782b8fe02..ced42484dcfc7 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 @@ -1700,6 +1700,12 @@ static void dp_test_send_link_training(struct dc_link *link) dp_retrain_link_dp_test(link, &link_settings, false); } +/* TODO hbr2 compliance eye output is unstable + * (toggling on and off) with debugger break + * This caueses intermittent PHY automation failure + * Need to look into the root cause */ +static uint8_t force_tps4_for_cp2520 = 1; + static void dp_test_send_phy_test_pattern(struct dc_link *link) { union phy_test_pattern dpcd_test_pattern; @@ -1758,10 +1764,16 @@ static void dp_test_send_phy_test_pattern(struct dc_link *link) test_pattern = DP_TEST_PATTERN_80BIT_CUSTOM; break; case PHY_TEST_PATTERN_CP2520_1: - test_pattern = DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE; + /* CP2520 pattern is unstable, temporarily use TPS4 instead */ + test_pattern = (force_tps4_for_cp2520 == 1) ? + DP_TEST_PATTERN_TRAINING_PATTERN4 : + DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE; break; case PHY_TEST_PATTERN_CP2520_2: - test_pattern = DP_TEST_PATTERN_CP2520_2; + /* CP2520 pattern is unstable, temporarily use TPS4 instead */ + test_pattern = (force_tps4_for_cp2520 == 1) ? + DP_TEST_PATTERN_TRAINING_PATTERN4 : + DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE; break; case PHY_TEST_PATTERN_CP2520_3: test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN4; From 904aa42e77aa7fb5f95408b4d1ffb4b2c3a805d7 Mon Sep 17 00:00:00 2001 From: Eric Yang Date: Thu, 14 Sep 2017 19:03:04 -0400 Subject: [PATCH 020/155] drm/amd/display: add back removed hack for mpcc add A previous changed removed the hack to match mpcc_idd with mi instance. This causes pstate hang on resume from hibernate for yet unknown reason. Add the hack back for now to work around the issue. More debugging required in init_hw to root cause the hang. Signed-off-by: Eric Yang Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c index 8e767c84359c7..6e56fa3a135b9 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c @@ -279,6 +279,18 @@ static int mpc10_mpcc_add(struct mpc *mpc, struct mpcc_cfg *cfg) if (z_idx == cfg->tree_cfg->num_pipes) { ASSERT(cfg->z_index <= cfg->tree_cfg->num_pipes); mpcc_id = mpc10_get_idle_mpcc_id(mpc10); + + /* + * TODO: remove hack + * Note: currently there is a bug in init_hw such that + * on resume from hibernate, BIOS sets up MPCC0, and + * we do mpcc_remove but the mpcc cannot go to idle + * after remove. This cause us to pick mpcc1 here, + * which causes a pstate hang for yet unknown reason. + */ + mpcc_id = cfg->dpp_id; + /* end hack*/ + ASSERT(!(mpc10->mpcc_in_use_mask & 1 << mpcc_id)); if (mpc->ctx->dc->debug.sanity_checks) From 62bf6e9b292212b9a821bd3c24adff57ff4b4bd7 Mon Sep 17 00:00:00 2001 From: Eric Bernstein Date: Thu, 14 Sep 2017 18:01:40 -0400 Subject: [PATCH 021/155] drm/amd/display: update blending mode and set output denorm Signed-off-by: Eric Bernstein Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c | 27 ++++++++++++++++++- drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h | 4 +++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c index 6e56fa3a135b9..334f072cea1df 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c @@ -313,10 +313,34 @@ static int mpc10_mpcc_add(struct mpc *mpc, struct mpcc_cfg *cfg) return mpcc_id; } +static void mpc10_update_blend_mode( + struct mpc *mpc, + struct mpcc_cfg *cfg) +{ + struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc); + int mpcc_id, z_idx; + int alpha_blnd_mode = cfg->per_pixel_alpha ? + BLND_PP_ALPHA : BLND_GLOBAL_ALPHA; + + /* find z_idx for the dpp that requires blending mode update*/ + for (z_idx = 0; z_idx < cfg->tree_cfg->num_pipes; z_idx++) + if (cfg->tree_cfg->dpp[z_idx] == cfg->dpp_id) + break; + + ASSERT(z_idx < cfg->tree_cfg->num_pipes); + mpcc_id = cfg->tree_cfg->mpcc[z_idx]; + + REG_UPDATE_2(MPCC_CONTROL[mpcc_id], + MPCC_ALPHA_BLND_MODE, alpha_blnd_mode, + MPCC_ALPHA_MULTIPLIED_MODE, cfg->pre_multiplied_alpha); +} + const struct mpc_funcs dcn10_mpc_funcs = { .add = mpc10_mpcc_add, .remove = mpc10_mpcc_remove, - .wait_for_idle = mpc10_assert_idle_mpcc + .wait_for_idle = mpc10_assert_idle_mpcc, + .set_denorm = NULL, + .update_blend_mode = mpc10_update_blend_mode }; void dcn10_mpc_construct(struct dcn10_mpc *mpc10, @@ -337,3 +361,4 @@ void dcn10_mpc_construct(struct dcn10_mpc *mpc10, mpc10->mpcc_in_use_mask = 0; mpc10->num_mpcc = num_mpcc; } + diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h b/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h index 2d3de5b68e34c..fb590f5353a04 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h @@ -51,6 +51,10 @@ struct mpc_funcs { int opp_id, int mpcc_inst); void (*wait_for_idle)(struct mpc *mpc, int id); + void (*set_denorm)(struct mpc *mpc, + int opp_id, + enum dc_color_depth output_depth); + void (*update_blend_mode)(struct mpc *mpc, struct mpcc_cfg *cfg); }; #endif From 5eefbc40173644b5f74d7e074ba6cd8de5563e05 Mon Sep 17 00:00:00 2001 From: Yue Hin Lau Date: Fri, 15 Sep 2017 17:42:20 -0400 Subject: [PATCH 022/155] drm/amd/display: moving backlight registers to hwsequencer Signed-off-by: Yue Hin Lau Reviewed-by: Dmytro Laktyushkin Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_link.c | 2 +- .../drm/amd/display/dc/core/dc_link_hwss.c | 11 +- .../gpu/drm/amd/display/dc/dce/dce_hwseq.h | 47 ++++++-- .../drm/amd/display/dc/dce/dce_link_encoder.c | 79 +------------- .../drm/amd/display/dc/dce/dce_link_encoder.h | 27 ++--- .../display/dc/dce110/dce110_hw_sequencer.c | 103 +++++++++++++++++- .../drm/amd/display/dc/inc/hw/link_encoder.h | 4 +- .../gpu/drm/amd/display/dc/inc/hw_sequencer.h | 4 + .../display/dc/virtual/virtual_link_encoder.c | 8 +- 9 files changed, 158 insertions(+), 127 deletions(-) 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 c7751a31081a6..976f0f136f29d 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c @@ -1807,7 +1807,7 @@ static void disable_link(struct dc_link *link, enum signal_type signal) else dp_disable_link_phy_mst(link, signal); } else - link->link_enc->funcs->disable_output(link->link_enc, signal); + link->link_enc->funcs->disable_output(link->link_enc, signal, link); } enum dc_status dc_link_validate_mode_timing( 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 5f815cab94b57..fa2250554be50 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 @@ -94,7 +94,7 @@ void dp_enable_link_phy( link_enc, link_settings, clock_source); - link_enc->funcs->backlight_control(link_enc, true); + link->dc->hwss.backlight_control(link, true); } else link_enc->funcs->enable_dp_output( link_enc, @@ -138,12 +138,12 @@ void dp_disable_link_phy(struct dc_link *link, enum signal_type signal) dp_receiver_power_ctrl(link, false); if (signal == SIGNAL_TYPE_EDP) { - link->link_enc->funcs->backlight_control(link->link_enc, false); + link->dc->hwss.backlight_control(link, false); edp_receiver_ready_T9(link); - link->link_enc->funcs->disable_output(link->link_enc, signal); + link->link_enc->funcs->disable_output(link->link_enc, signal, link); link->link_enc->funcs->power_control(link->link_enc, false); } else - link->link_enc->funcs->disable_output(link->link_enc, signal); + link->link_enc->funcs->disable_output(link->link_enc, signal, link); /* Clear current link setting.*/ memset(&link->cur_link_settings, 0, @@ -286,7 +286,8 @@ void dp_retrain_link_dp_test(struct dc_link *link, link->link_enc->funcs->disable_output( link->link_enc, - SIGNAL_TYPE_DISPLAY_PORT); + SIGNAL_TYPE_DISPLAY_PORT, + link); /* Clear current link setting. */ memset(&link->cur_link_settings, 0, diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h index 5798001da770b..227c9b655b655 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h @@ -27,6 +27,10 @@ #include "hw_sequencer.h" +#define BL_REG_LIST()\ + SR(LVTMA_PWRSEQ_CNTL), \ + SR(LVTMA_PWRSEQ_STATE) + #define HWSEQ_DCEF_REG_LIST_DCE8() \ .DCFE_CLOCK_CONTROL[0] = mmCRTC0_CRTC_DCFE_CLOCK_CONTROL, \ .DCFE_CLOCK_CONTROL[1] = mmCRTC1_CRTC_DCFE_CLOCK_CONTROL, \ @@ -86,24 +90,27 @@ SRII(BLND_CONTROL, BLND, 0),\ SRII(BLND_CONTROL, BLND, 1),\ SR(BLNDV_CONTROL),\ - HWSEQ_PIXEL_RATE_REG_LIST(CRTC) + HWSEQ_PIXEL_RATE_REG_LIST(CRTC),\ + BL_REG_LIST() #define HWSEQ_DCE8_REG_LIST() \ HWSEQ_DCEF_REG_LIST_DCE8(), \ HWSEQ_BLND_REG_LIST(), \ - HWSEQ_PIXEL_RATE_REG_LIST(CRTC) + HWSEQ_PIXEL_RATE_REG_LIST(CRTC),\ + BL_REG_LIST() #define HWSEQ_DCE10_REG_LIST() \ HWSEQ_DCEF_REG_LIST(), \ HWSEQ_BLND_REG_LIST(), \ - HWSEQ_PIXEL_RATE_REG_LIST(CRTC) + HWSEQ_PIXEL_RATE_REG_LIST(CRTC), \ + BL_REG_LIST() #define HWSEQ_ST_REG_LIST() \ HWSEQ_DCE11_REG_LIST_BASE(), \ .DCFE_CLOCK_CONTROL[2] = mmDCFEV_CLOCK_CONTROL, \ .CRTC_H_BLANK_START_END[2] = mmCRTCV_H_BLANK_START_END, \ .BLND_V_UPDATE_LOCK[2] = mmBLNDV_V_UPDATE_LOCK, \ - .BLND_CONTROL[2] = mmBLNDV_CONTROL, + .BLND_CONTROL[2] = mmBLNDV_CONTROL #define HWSEQ_CZ_REG_LIST() \ HWSEQ_DCE11_REG_LIST_BASE(), \ @@ -123,12 +130,14 @@ SR(DCHUB_FB_LOCATION),\ SR(DCHUB_AGP_BASE),\ SR(DCHUB_AGP_BOT),\ - SR(DCHUB_AGP_TOP) + SR(DCHUB_AGP_TOP), \ + BL_REG_LIST() #define HWSEQ_DCE112_REG_LIST() \ HWSEQ_DCE10_REG_LIST(), \ HWSEQ_PIXEL_RATE_REG_LIST(CRTC), \ - HWSEQ_PHYPLL_REG_LIST(CRTC) + HWSEQ_PHYPLL_REG_LIST(CRTC), \ + BL_REG_LIST() #define HWSEQ_DCN_REG_LIST()\ SRII(OTG_GLOBAL_SYNC_STATUS, OTG, 0), \ @@ -228,9 +237,15 @@ SR(D2VGA_CONTROL), \ SR(D3VGA_CONTROL), \ SR(D4VGA_CONTROL), \ - SR(DC_IP_REQUEST_CNTL) + SR(DC_IP_REQUEST_CNTL), \ + BL_REG_LIST() struct dce_hwseq_registers { + + /* Backlight registers */ + uint32_t LVTMA_PWRSEQ_CNTL; + uint32_t LVTMA_PWRSEQ_STATE; + uint32_t DCFE_CLOCK_CONTROL[6]; uint32_t DCFEV_CLOCK_CONTROL; uint32_t DC_MEM_GLOBAL_PWR_REQ_CNTL; @@ -375,20 +390,24 @@ struct dce_hwseq_registers { HWS_SF(BLND_, V_UPDATE_LOCK, BLND_SCL_V_UPDATE_LOCK, mask_sh),\ HWS_SF(BLND_, V_UPDATE_LOCK, BLND_DCP_GRPH_SURF_V_UPDATE_LOCK, mask_sh),\ HWS_SF(BLND_, CONTROL, BLND_MODE, mask_sh),\ + HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh),\ HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, CRTC0_) #define HWSEQ_DCE10_MASK_SH_LIST(mask_sh)\ HWSEQ_DCEF_MASK_SH_LIST(mask_sh, DCFE_),\ HWSEQ_BLND_MASK_SH_LIST(mask_sh, BLND_),\ - HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, CRTC0_) + HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, CRTC0_), \ + HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh) #define HWSEQ_DCE11_MASK_SH_LIST(mask_sh)\ HWSEQ_DCE10_MASK_SH_LIST(mask_sh),\ SF(DCFEV_CLOCK_CONTROL, DCFEV_CLOCK_ENABLE, mask_sh),\ + HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh),\ HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, CRTC0_) #define HWSEQ_DCE112_MASK_SH_LIST(mask_sh)\ HWSEQ_DCE10_MASK_SH_LIST(mask_sh),\ + HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh),\ HWSEQ_PHYPLL_MASK_SH_LIST(mask_sh, CRTC0_) #define HWSEQ_GFX9_DCHUB_MASK_SH_LIST(mask_sh)\ @@ -396,14 +415,16 @@ struct dce_hwseq_registers { SF(DCHUB_FB_LOCATION, FB_BASE, mask_sh),\ SF(DCHUB_AGP_BASE, AGP_BASE, mask_sh),\ SF(DCHUB_AGP_BOT, AGP_BOT, mask_sh),\ - SF(DCHUB_AGP_TOP, AGP_TOP, mask_sh) + SF(DCHUB_AGP_TOP, AGP_TOP, mask_sh), \ + HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh) #define HWSEQ_DCE12_MASK_SH_LIST(mask_sh)\ HWSEQ_DCEF_MASK_SH_LIST(mask_sh, DCFE0_DCFE_),\ HWSEQ_BLND_MASK_SH_LIST(mask_sh, BLND0_BLND_),\ HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, CRTC0_),\ HWSEQ_PHYPLL_MASK_SH_LIST(mask_sh, CRTC0_),\ - HWSEQ_GFX9_DCHUB_MASK_SH_LIST(mask_sh) + HWSEQ_GFX9_DCHUB_MASK_SH_LIST(mask_sh), \ + HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh) #define HWSEQ_DCN_MASK_SH_LIST(mask_sh)\ HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, OTG0_),\ @@ -467,7 +488,8 @@ struct dce_hwseq_registers { HWS_SF(, DOMAIN5_PG_STATUS, DOMAIN5_PGFSM_PWR_STATUS, mask_sh), \ HWS_SF(, DOMAIN6_PG_STATUS, DOMAIN6_PGFSM_PWR_STATUS, mask_sh), \ HWS_SF(, DOMAIN7_PG_STATUS, DOMAIN7_PGFSM_PWR_STATUS, mask_sh), \ - HWS_SF(, DC_IP_REQUEST_CNTL, IP_REQUEST_EN, mask_sh) + HWS_SF(, DC_IP_REQUEST_CNTL, IP_REQUEST_EN, mask_sh), \ + HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh) #define HWSEQ_REG_FIELD_LIST(type) \ type DCFE_CLOCK_ENABLE; \ @@ -497,7 +519,8 @@ struct dce_hwseq_registers { type PHYSICAL_PAGE_NUMBER_LSB;\ type LOGICAL_ADDR; \ type ENABLE_L1_TLB;\ - type SYSTEM_ACCESS_MODE; + type SYSTEM_ACCESS_MODE;\ + type LVTMA_BLON; #define HWSEQ_DCN_REG_FIELD_LIST(type) \ type VUPDATE_NO_LOCK_EVENT_CLEAR; \ diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c index 37aeddfb74317..1cb727bdaa562 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c @@ -122,7 +122,6 @@ static const struct link_encoder_funcs dce110_lnk_enc_funcs = { .psr_program_dp_dphy_fast_training = dce110_psr_program_dp_dphy_fast_training, .psr_program_secondary_packet = dce110_psr_program_secondary_packet, - .backlight_control = dce110_link_encoder_edp_backlight_control, .power_control = dce110_link_encoder_edp_power_control, .connect_dig_be_to_fe = dce110_link_encoder_connect_dig_be_to_fe, .enable_hpd = dce110_link_encoder_enable_hpd, @@ -674,16 +673,6 @@ static void aux_initialize( } -/*todo: cloned in stream enc, fix*/ -static bool is_panel_backlight_on(struct dce110_link_encoder *enc110) -{ - uint32_t value; - - REG_GET(LVTMA_PWRSEQ_CNTL, LVTMA_BLON, &value); - - return value; -} - void dce110_psr_program_dp_dphy_fast_training(struct link_encoder *enc, bool exit_link_training_required) { @@ -718,69 +707,6 @@ void dce110_psr_program_secondary_packet(struct link_encoder *enc, DP_SEC_GSP0_PRIORITY, 1); } -/*todo: cloned in stream enc, fix*/ -/* - * @brief - * eDP only. Control the backlight of the eDP panel - */ -void dce110_link_encoder_edp_backlight_control( - struct link_encoder *enc, - bool enable) -{ - struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc); - struct dc_context *ctx = enc110->base.ctx; - struct bp_transmitter_control cntl = { 0 }; - - if (dal_graphics_object_id_get_connector_id(enc110->base.connector) - != CONNECTOR_ID_EDP) { - BREAK_TO_DEBUGGER(); - return; - } - - if (enable && is_panel_backlight_on(enc110)) { - dm_logger_write(ctx->logger, LOG_HW_RESUME_S3, - "%s: panel already powered up. Do nothing.\n", - __func__); - return; - } - - if (!enable && !is_panel_backlight_on(enc110)) { - dm_logger_write(ctx->logger, LOG_HW_RESUME_S3, - "%s: panel already powered down. Do nothing.\n", - __func__); - return; - } - - /* Send VBIOS command to control eDP panel backlight */ - - dm_logger_write(ctx->logger, LOG_HW_RESUME_S3, - "%s: backlight action: %s\n", - __func__, (enable ? "On":"Off")); - - cntl.action = enable ? - TRANSMITTER_CONTROL_BACKLIGHT_ON : - TRANSMITTER_CONTROL_BACKLIGHT_OFF; - /*cntl.engine_id = ctx->engine;*/ - cntl.transmitter = enc110->base.transmitter; - cntl.connector_obj_id = enc110->base.connector; - /*todo: unhardcode*/ - cntl.lanes_number = LANE_COUNT_FOUR; - cntl.hpd_sel = enc110->base.hpd_source; - - /* For eDP, the following delays might need to be considered - * after link training completed: - * idle period - min. accounts for required BS-Idle pattern, - * max. allows for source frame synchronization); - * 50 msec max. delay from valid video data from source - * to video on dislpay or backlight enable. - * - * Disable the delay for now. - * Enable it in the future if necessary. - */ - /* dc_service_sleep_in_milliseconds(50); */ - link_transmitter_control(enc110, &cntl); -} - static bool is_dig_enabled(const struct dce110_link_encoder *enc110) { uint32_t value; @@ -1279,7 +1205,8 @@ void dce110_link_encoder_enable_dp_mst_output( */ void dce110_link_encoder_disable_output( struct link_encoder *enc, - enum signal_type signal) + enum signal_type signal, + struct dc_link *link) { struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc); struct dc_context *ctx = enc110->base.ctx; @@ -1291,7 +1218,7 @@ void dce110_link_encoder_disable_output( return; } if (enc110->base.connector.id == CONNECTOR_ID_EDP) - dce110_link_encoder_edp_backlight_control(enc, false); + ctx->dc->hwss.backlight_control(link, false); /* Power-down RX and disable GPU PHY should be paired. * Disabling PHY without powering down RX may cause * symbol lock loss, on which we will get DP Sink interrupt. */ diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h index 05463df7e6360..c65def5f6a441 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h @@ -69,10 +69,6 @@ SRI(DP_DPHY_FAST_TRAINING, DP, id), \ SRI(DP_SEC_CNTL1, DP, id) -#define LE_EDP_REG_LIST(id)\ - SR(LVTMA_PWRSEQ_CNTL), \ - SR(LVTMA_PWRSEQ_STATE) - #define LE_COMMON_REG_LIST(id)\ LE_COMMON_REG_LIST_BASE(id), \ SRI(DP_DPHY_BS_SR_SWAP_CNTL, DP, id), \ @@ -81,38 +77,32 @@ #define LE_DCE80_REG_LIST(id)\ SRI(DP_DPHY_INTERNAL_CTRL, DP, id), \ - LE_COMMON_REG_LIST_BASE(id), \ - LE_EDP_REG_LIST(id) + LE_COMMON_REG_LIST_BASE(id) #define LE_DCE100_REG_LIST(id)\ LE_COMMON_REG_LIST_BASE(id), \ SRI(DP_DPHY_BS_SR_SWAP_CNTL, DP, id), \ SRI(DP_DPHY_INTERNAL_CTRL, DP, id), \ - SR(DCI_MEM_PWR_STATUS), \ - LE_EDP_REG_LIST(id) + SR(DCI_MEM_PWR_STATUS) #define LE_DCE110_REG_LIST(id)\ LE_COMMON_REG_LIST_BASE(id), \ SRI(DP_DPHY_BS_SR_SWAP_CNTL, DP, id), \ SRI(DP_DPHY_INTERNAL_CTRL, DP, id), \ SRI(DP_DPHY_HBR2_PATTERN_CONTROL, DP, id), \ - SR(DCI_MEM_PWR_STATUS), \ - LE_EDP_REG_LIST(id) + SR(DCI_MEM_PWR_STATUS) #define LE_DCE120_REG_LIST(id)\ LE_COMMON_REG_LIST_BASE(id), \ SRI(DP_DPHY_BS_SR_SWAP_CNTL, DP, id), \ SRI(DP_DPHY_HBR2_PATTERN_CONTROL, DP, id), \ - SR(DCI_MEM_PWR_STATUS), \ - LE_EDP_REG_LIST(id) + SR(DCI_MEM_PWR_STATUS) #define LE_DCN10_REG_LIST(id)\ LE_COMMON_REG_LIST_BASE(id), \ SRI(DP_DPHY_BS_SR_SWAP_CNTL, DP, id), \ SRI(DP_DPHY_INTERNAL_CTRL, DP, id), \ - SRI(DP_DPHY_HBR2_PATTERN_CONTROL, DP, id), \ - SR(DMU_MEM_PWR_CNTL), \ - LE_EDP_REG_LIST(id) + SRI(DP_DPHY_HBR2_PATTERN_CONTROL, DP, id) struct dce110_link_enc_aux_registers { uint32_t AUX_CONTROL; @@ -243,7 +233,8 @@ void dce110_link_encoder_enable_dp_mst_output( /* disable PHY output */ void dce110_link_encoder_disable_output( struct link_encoder *link_enc, - enum signal_type signal); + enum signal_type signal, + struct dc_link *link); /* set DP lane settings */ void dce110_link_encoder_dp_set_lane_settings( @@ -259,10 +250,6 @@ void dce110_link_encoder_update_mst_stream_allocation_table( struct link_encoder *enc, const struct link_mst_stream_allocation_table *table); -void dce110_link_encoder_edp_backlight_control( - struct link_encoder *enc, - bool enable); - void dce110_link_encoder_edp_power_control( struct link_encoder *enc, bool power_up); diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c index d83a330712f7c..9fc43bcac5bc0 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c @@ -56,6 +56,15 @@ #include "dce/dce_11_0_sh_mask.h" #include "custom_float.h" +#define CTX \ + hws->ctx +#define REG(reg)\ + hws->regs->reg + +#undef FN +#define FN(reg_name, field_name) \ + hws->shifts->field_name, hws->masks->field_name + struct dce110_hw_seq_reg_offsets { uint32_t crtc; }; @@ -761,6 +770,92 @@ void dce110_enable_stream(struct pipe_ctx *pipe_ctx) } +/*todo: cloned in stream enc, fix*/ +static bool is_panel_backlight_on(struct dce_hwseq *hws) +{ + uint32_t value; + + REG_GET(LVTMA_PWRSEQ_CNTL, LVTMA_BLON, &value); + + return value; +} + +static enum bp_result link_transmitter_control( + struct dc_link *link, + struct bp_transmitter_control *cntl) +{ + enum bp_result result; + struct dc_bios *bp = link->dc->ctx->dc_bios; + + result = bp->funcs->transmitter_control(bp, cntl); + + return result; +} + + +/*todo: cloned in stream enc, fix*/ +/* + * @brief + * eDP only. Control the backlight of the eDP panel + */ +void hwss_blacklight_control( + struct dc_link *link, + bool enable) +{ + struct dce_hwseq *hws = link->dc->hwseq; + struct dc_context *ctx = link->dc->ctx; + struct bp_transmitter_control cntl = { 0 }; + + if (dal_graphics_object_id_get_connector_id(link->link_id) + != CONNECTOR_ID_EDP) { + BREAK_TO_DEBUGGER(); + return; + } + + if (enable && is_panel_backlight_on(hws)) { + dm_logger_write(ctx->logger, LOG_HW_RESUME_S3, + "%s: panel already powered up. Do nothing.\n", + __func__); + return; + } + + if (!enable && !is_panel_backlight_on(hws)) { + dm_logger_write(ctx->logger, LOG_HW_RESUME_S3, + "%s: panel already powered down. Do nothing.\n", + __func__); + return; + } + + /* Send VBIOS command to control eDP panel backlight */ + + dm_logger_write(ctx->logger, LOG_HW_RESUME_S3, + "%s: backlight action: %s\n", + __func__, (enable ? "On":"Off")); + + cntl.action = enable ? + TRANSMITTER_CONTROL_BACKLIGHT_ON : + TRANSMITTER_CONTROL_BACKLIGHT_OFF; + /*cntl.engine_id = ctx->engine;*/ + cntl.transmitter = link->link_enc->transmitter; + cntl.connector_obj_id = link->link_enc->connector; + /*todo: unhardcode*/ + cntl.lanes_number = LANE_COUNT_FOUR; + cntl.hpd_sel = link->link_enc->hpd_source; + + /* For eDP, the following delays might need to be considered + * after link training completed: + * idle period - min. accounts for required BS-Idle pattern, + * max. allows for source frame synchronization); + * 50 msec max. delay from valid video data from source + * to video on dislpay or backlight enable. + * + * Disable the delay for now. + * Enable it in the future if necessary. + */ + /* dc_service_sleep_in_milliseconds(50); */ + link_transmitter_control(link, &cntl); +} + void dce110_disable_stream(struct pipe_ctx *pipe_ctx) { struct dc_stream_state *stream = pipe_ctx->stream; @@ -798,7 +893,7 @@ void dce110_disable_stream(struct pipe_ctx *pipe_ctx) /* blank at encoder level */ if (dc_is_dp_signal(pipe_ctx->stream->signal)) { if (pipe_ctx->stream->sink->link->connector_signal == SIGNAL_TYPE_EDP) - link->link_enc->funcs->backlight_control(link->link_enc, false); + hwss_blacklight_control(link, false); pipe_ctx->stream_res.stream_enc->funcs->dp_blank(pipe_ctx->stream_res.stream_enc); } link->link_enc->funcs->connect_dig_be_to_fe( @@ -820,7 +915,7 @@ void dce110_unblank_stream(struct pipe_ctx *pipe_ctx, params.link_settings.link_rate = link_settings->link_rate; pipe_ctx->stream_res.stream_enc->funcs->dp_unblank(pipe_ctx->stream_res.stream_enc, ¶ms); if (link->connector_signal == SIGNAL_TYPE_EDP) - link->link_enc->funcs->backlight_control(link->link_enc, true); + hwss_blacklight_control(link, true); } @@ -1184,7 +1279,7 @@ static void power_down_encoders(struct dc *dc) } dc->links[i]->link_enc->funcs->disable_output( - dc->links[i]->link_enc, signal); + dc->links[i]->link_enc, signal, dc->links[i]); } } @@ -2733,7 +2828,7 @@ static const struct hw_sequencer_funcs dce110_funcs = { .wait_for_mpcc_disconnect = dce110_wait_for_mpcc_disconnect, .ready_shared_resources = ready_shared_resources, .optimize_shared_resources = optimize_shared_resources, - + .backlight_control = hwss_blacklight_control }; void dce110_hw_sequencer_construct(struct dc *dc) diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h b/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h index 961bbcc9202c5..6cd6bc7d15fbe 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h @@ -111,7 +111,7 @@ struct link_encoder_funcs { const struct dc_link_settings *link_settings, enum clock_source_id clock_source); void (*disable_output)(struct link_encoder *link_enc, - enum signal_type signal); + enum signal_type signal, struct dc_link *link); void (*dp_set_lane_settings)(struct link_encoder *enc, const struct link_training_settings *link_settings); void (*dp_set_phy_pattern)(struct link_encoder *enc, @@ -123,8 +123,6 @@ struct link_encoder_funcs { bool exit_link_training_required); void (*psr_program_secondary_packet)(struct link_encoder *enc, unsigned int sdp_transmit_line_num_deadline); - void (*backlight_control) (struct link_encoder *enc, - bool enable); void (*power_control) (struct link_encoder *enc, bool power_up); void (*connect_dig_be_to_fe)(struct link_encoder *enc, diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h index 1fa2edc6cfb19..210874f37722a 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h @@ -176,6 +176,10 @@ struct hw_sequencer_funcs { void (*ready_shared_resources)(struct dc *dc, struct dc_state *context); void (*optimize_shared_resources)(struct dc *dc); + + void (*backlight_control)( + struct dc_link *link, + bool enable); }; void color_space_to_black_color( diff --git a/drivers/gpu/drm/amd/display/dc/virtual/virtual_link_encoder.c b/drivers/gpu/drm/amd/display/dc/virtual/virtual_link_encoder.c index db513abd735a8..4f405348130f2 100644 --- a/drivers/gpu/drm/amd/display/dc/virtual/virtual_link_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/virtual/virtual_link_encoder.c @@ -58,7 +58,8 @@ static void virtual_link_encoder_enable_dp_mst_output( static void virtual_link_encoder_disable_output( struct link_encoder *link_enc, - enum signal_type signal) {} + enum signal_type signal, + struct dc_link *link) {} static void virtual_link_encoder_dp_set_lane_settings( struct link_encoder *enc, @@ -72,10 +73,6 @@ static void virtual_link_encoder_update_mst_stream_allocation_table( struct link_encoder *enc, const struct link_mst_stream_allocation_table *table) {} -static void virtual_link_encoder_edp_backlight_control( - struct link_encoder *enc, - bool enable) {} - static void virtual_link_encoder_edp_power_control( struct link_encoder *enc, bool power_up) {} @@ -105,7 +102,6 @@ static const struct link_encoder_funcs virtual_lnk_enc_funcs = { .dp_set_phy_pattern = virtual_link_encoder_dp_set_phy_pattern, .update_mst_stream_allocation_table = virtual_link_encoder_update_mst_stream_allocation_table, - .backlight_control = virtual_link_encoder_edp_backlight_control, .power_control = virtual_link_encoder_edp_power_control, .connect_dig_be_to_fe = virtual_link_encoder_connect_dig_be_to_fe, .destroy = virtual_link_encoder_destroy From dbaed8037c6c606456c182f5fc327f9d405a7ffe Mon Sep 17 00:00:00 2001 From: Yue Hin Lau Date: Tue, 19 Sep 2017 11:35:23 -0400 Subject: [PATCH 023/155] drm/amd/display: edp backlight regression fix Signed-off-by: Yue Hin Lau Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h | 5 +++++ drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 1 + 2 files changed, 6 insertions(+) diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h index db6c19cd15eb1..3e95f7f92c737 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h @@ -68,5 +68,10 @@ void dce110_fill_display_configs( uint32_t dce110_get_min_vblank_time_us(const struct dc_state *context); void dp_receiver_power_ctrl(struct dc_link *link, bool on); + +void hwss_blacklight_control( + struct dc_link *link, + bool enable); + #endif /* __DC_HWSS_DCE110_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index 82a985a981be2..bf5c9243ba7ab 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -2897,6 +2897,7 @@ static const struct hw_sequencer_funcs dcn10_funcs = { .wait_for_mpcc_disconnect = dcn10_wait_for_mpcc_disconnect, .ready_shared_resources = ready_shared_resources, .optimize_shared_resources = optimize_shared_resources, + .backlight_control = hwss_blacklight_control }; From 5df921d4c0e3e2065b961ac8d4269be68f80801d Mon Sep 17 00:00:00 2001 From: Ken Chalmers Date: Wed, 20 Sep 2017 11:48:47 -0400 Subject: [PATCH 024/155] drm/amd/display: fix ASSERT() caused by missing registers. Signed-off-by: Ken Chalmers Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 42 ++++++++++--------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index bf5c9243ba7ab..cdaed0c0a70c4 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -771,14 +771,16 @@ static void power_on_plane( struct dce_hwseq *hws, int plane_id) { - REG_SET(DC_IP_REQUEST_CNTL, 0, - IP_REQUEST_EN, 1); - dpp_pg_control(hws, plane_id, true); - hubp_pg_control(hws, plane_id, true); - REG_SET(DC_IP_REQUEST_CNTL, 0, - IP_REQUEST_EN, 0); - dm_logger_write(hws->ctx->logger, LOG_DEBUG, - "Un-gated front end for pipe %d\n", plane_id); + if (REG(DC_IP_REQUEST_CNTL)) { + REG_SET(DC_IP_REQUEST_CNTL, 0, + IP_REQUEST_EN, 1); + dpp_pg_control(hws, plane_id, true); + hubp_pg_control(hws, plane_id, true); + REG_SET(DC_IP_REQUEST_CNTL, 0, + IP_REQUEST_EN, 0); + dm_logger_write(hws->ctx->logger, LOG_DEBUG, + "Un-gated front end for pipe %d\n", plane_id); + } } static void undo_DEGVIDCN10_253_wa(struct dc *dc) @@ -1130,18 +1132,20 @@ static void plane_atomic_power_down(struct dc *dc, int fe_idx) struct dce_hwseq *hws = dc->hwseq; struct transform *xfm = dc->res_pool->transforms[fe_idx]; - REG_SET(DC_IP_REQUEST_CNTL, 0, - IP_REQUEST_EN, 1); - dpp_pg_control(hws, fe_idx, false); - hubp_pg_control(hws, fe_idx, false); - xfm->funcs->transform_reset(xfm); - REG_SET(DC_IP_REQUEST_CNTL, 0, - IP_REQUEST_EN, 0); - dm_logger_write(dc->ctx->logger, LOG_DEBUG, - "Power gated front end %d\n", fe_idx); + if (REG(DC_IP_REQUEST_CNTL)) { + REG_SET(DC_IP_REQUEST_CNTL, 0, + IP_REQUEST_EN, 1); + dpp_pg_control(hws, fe_idx, false); + hubp_pg_control(hws, fe_idx, false); + xfm->funcs->transform_reset(xfm); + REG_SET(DC_IP_REQUEST_CNTL, 0, + IP_REQUEST_EN, 0); + dm_logger_write(dc->ctx->logger, LOG_DEBUG, + "Power gated front end %d\n", fe_idx); - if (dc->debug.sanity_checks) - verify_allow_pstate_change_high(dc->hwseq); + if (dc->debug.sanity_checks) + verify_allow_pstate_change_high(dc->hwseq); + } } From 19af33aca4384f840838a781f105726bb24c604f Mon Sep 17 00:00:00 2001 From: Charlene Liu Date: Wed, 20 Sep 2017 14:06:24 -0400 Subject: [PATCH 025/155] drm/amd/display: make sure BL off to mainlink off has enough time Signed-off-by: Charlene Liu Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c index 9fc43bcac5bc0..f28fce6e6ba4e 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c @@ -819,13 +819,6 @@ void hwss_blacklight_control( return; } - if (!enable && !is_panel_backlight_on(hws)) { - dm_logger_write(ctx->logger, LOG_HW_RESUME_S3, - "%s: panel already powered down. Do nothing.\n", - __func__); - return; - } - /* Send VBIOS command to control eDP panel backlight */ dm_logger_write(ctx->logger, LOG_HW_RESUME_S3, From 6d732e7917064195b65303cab9591f311b621034 Mon Sep 17 00:00:00 2001 From: Charlene Liu Date: Wed, 20 Sep 2017 16:15:18 -0400 Subject: [PATCH 026/155] drm/amd/display: add hubp/dpp pg debug key Signed-off-by: Charlene Liu Reviewed-by: Anthony Koo Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 50440731f83c7..2e77885fc1ead 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -191,6 +191,8 @@ struct dc_debug { bool disable_dmcu; bool disable_psr; bool force_abm_enable; + bool disable_hbup_pg; + bool disable_dpp_pg; }; struct dc_state; struct resource_pool; From e750d56d2c62875c81f52344afab44220300388d Mon Sep 17 00:00:00 2001 From: Yongqiang Sun Date: Wed, 20 Sep 2017 17:06:18 -0400 Subject: [PATCH 027/155] drm/amd/display: Fixed validation return wrong result. Signed-off-by: Yongqiang Sun Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 +- drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 2 +- drivers/gpu/drm/amd/display/dc/dc.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 6c04ad1b58598..0707bec111a53 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -4748,7 +4748,7 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, if (ret) goto fail; - if (!dc_validate_global_state(dc, dm_state->context)) { + if (dc_validate_global_state(dc, dm_state->context) != DC_OK) { ret = -EINVAL; goto fail; } 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 77b3474a7c9e0..d9a2d09a1f4f3 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -1716,7 +1716,7 @@ void dc_resource_state_construct( dst_ctx->dis_clk = dc->res_pool->display_clock; } -bool dc_validate_global_state( +enum dc_status dc_validate_global_state( struct dc *dc, struct dc_state *new_ctx) { diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 2e77885fc1ead..1e49b8f9c66ec 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -654,7 +654,7 @@ bool dc_validate_stream(struct dc *dc, struct dc_stream_state *stream); bool dc_validate_plane(struct dc *dc, const struct dc_plane_state *plane_state); -bool dc_validate_global_state( +enum dc_status dc_validate_global_state( struct dc *dc, struct dc_state *new_ctx); From 4d1a562659e1414ccb010bea56286ba4302e84e5 Mon Sep 17 00:00:00 2001 From: Tony Cheng Date: Tue, 5 Sep 2017 21:13:55 -0400 Subject: [PATCH 028/155] drm/amd/display: version 3.1.02 Signed-off-by: Tony Cheng Reviewed-by: Tony Cheng Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 1e49b8f9c66ec..12601ffc0fe48 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -38,7 +38,7 @@ #include "inc/compressor.h" #include "dml/display_mode_lib.h" -#define DC_VER "3.1.01" +#define DC_VER "3.1.02" #define MAX_SURFACES 3 #define MAX_STREAMS 6 From 4f4ee68686c74bf1dfde6fa9fb7124104ff6f283 Mon Sep 17 00:00:00 2001 From: Hersen Wu Date: Wed, 20 Sep 2017 16:30:44 -0400 Subject: [PATCH 029/155] drm/amd/display: screen flickers when connected to ext monitor in clone Signed-off-by: Hersen Wu Signed-off-by: Tony Cheng Reviewed-by: Hersen Wu Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c | 8 ++++++++ drivers/gpu/drm/amd/display/dc/dc.h | 1 + drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c | 3 +++ 3 files changed, 12 insertions(+) diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c index 8ca6c3e4e65ad..cc99073b7a545 100644 --- a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c +++ b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c @@ -1018,9 +1018,17 @@ bool dcn_validate_bandwidth( context->bw.dcn.calc_clk.min_active_dram_ccm_us = (int)(v->min_active_dram_clock_change_margin); context->bw.dcn.calc_clk.dcfclk_deep_sleep_khz = (int)(v->dcf_clk_deep_sleep * 1000); context->bw.dcn.calc_clk.dcfclk_khz = (int)(v->dcfclk * 1000); + context->bw.dcn.calc_clk.dispclk_khz = (int)(v->dispclk * 1000); if (dc->debug.max_disp_clk == true) context->bw.dcn.calc_clk.dispclk_khz = (int)(dc->dcn_soc->max_dispclk_vmax0p9 * 1000); + + if (context->bw.dcn.calc_clk.dispclk_khz < + dc->debug.min_disp_clk_khz) { + context->bw.dcn.calc_clk.dispclk_khz = + dc->debug.min_disp_clk_khz; + } + context->bw.dcn.calc_clk.dppclk_div = (int)(v->dispclk_dppclk_ratio) == 2; for (i = 0, input_idx = 0; i < pool->pipe_count; i++) { diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 12601ffc0fe48..7a3a48179452e 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -178,6 +178,7 @@ struct dc_debug { bool disable_pplib_wm_range; bool use_dml_wm; bool disable_pipe_split; + unsigned int min_disp_clk_khz; int sr_exit_time_dpm0_ns; int sr_enter_plus_exit_time_dpm0_ns; int sr_exit_time_ns; diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c index 4f124dc303dce..82c82b6310ca5 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c @@ -420,6 +420,9 @@ static const struct dc_debug debug_defaults_drv = { .force_abm_enable = false, .timing_trace = false, .clock_trace = true, + + .min_disp_clk_khz = 300000, + .disable_pplib_clock_request = true, .disable_pplib_wm_range = false, #if defined(CONFIG_DRM_AMD_DC_DCN1_0) From d596e5d08da0a25be789432ed821e63db9ef72ac Mon Sep 17 00:00:00 2001 From: Yongqiang Sun Date: Thu, 21 Sep 2017 10:46:33 -0400 Subject: [PATCH 030/155] drm/amd/display: Fixed incorrect return value for validaton Signed-off-by: Yongqiang Sun Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) 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 d9a2d09a1f4f3..bbfec7cb2ad19 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -1723,10 +1723,11 @@ enum dc_status dc_validate_global_state( enum dc_status result = DC_ERROR_UNEXPECTED; int i, j; - if (dc->res_pool->funcs->validate_global && - dc->res_pool->funcs->validate_global( - dc, new_ctx) != DC_OK) - return false; + if (dc->res_pool->funcs->validate_global) { + result = dc->res_pool->funcs->validate_global(dc, new_ctx); + if (result != DC_OK) + return result; + } for (i = 0; new_ctx && i < new_ctx->stream_count; i++) { struct dc_stream_state *stream = new_ctx->streams[i]; From fcbbe3da0ab65dc114937857fce81902e3fa2a97 Mon Sep 17 00:00:00 2001 From: Eric Yang Date: Thu, 21 Sep 2017 18:16:01 -0400 Subject: [PATCH 031/155] drm/amd/display: Use active + border for bw validation When doing SLS, KMD gives us clipped v_addressable with border. This results in bw validation failure. Signed-off-by: Eric Yang Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c index cc99073b7a545..319450d9cfc1b 100644 --- a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c +++ b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c @@ -364,7 +364,8 @@ static void pipe_ctx_to_e2e_pipe_params ( } - input->dest.vactive = pipe->stream->timing.v_addressable; + input->dest.vactive = pipe->stream->timing.v_addressable + pipe->stream->timing.v_border_top + + pipe->stream->timing.v_border_bottom; input->dest.recout_width = pipe->plane_res.scl_data.recout.width; input->dest.recout_height = pipe->plane_res.scl_data.recout.height; @@ -882,10 +883,11 @@ bool dcn_validate_bandwidth( v->htotal[input_idx] = pipe->stream->timing.h_total; v->vtotal[input_idx] = pipe->stream->timing.v_total; + v->vactive[input_idx] = pipe->stream->timing.v_addressable + + pipe->stream->timing.v_border_top + pipe->stream->timing.v_border_bottom; v->v_sync_plus_back_porch[input_idx] = pipe->stream->timing.v_total - - pipe->stream->timing.v_addressable + - v->vactive[input_idx] - pipe->stream->timing.v_front_porch; - v->vactive[input_idx] = pipe->stream->timing.v_addressable; v->pixel_clock[input_idx] = pipe->stream->timing.pix_clk_khz / 1000.0f; if (!pipe->plane_state) { From e4ba6335cd91367f31978db1fc62d6bac0489672 Mon Sep 17 00:00:00 2001 From: Wenjing Liu Date: Thu, 21 Sep 2017 18:53:40 -0400 Subject: [PATCH 032/155] drm/amd/display: update link type to mst before topology discovery [Description] link type is not updated before mst topology discovery. This causes issue when branch device response to link address after before the start topology discovery event finishes. [Solution] update link type to mst before topology discovery Signed-off-by: Wenjing Liu Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_link.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 976f0f136f29d..a58e61b6e9f9a 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c @@ -496,6 +496,7 @@ static void detect_dp( } if (is_mst_supported(link)) { sink_caps->signal = SIGNAL_TYPE_DISPLAY_PORT_MST; + link->type = dc_connection_mst_branch; /* * This call will initiate MST topology discovery. Which @@ -524,12 +525,11 @@ static void detect_dp( if (reason == DETECT_REASON_BOOT) boot = true; - if (dm_helpers_dp_mst_start_top_mgr( + if (!dm_helpers_dp_mst_start_top_mgr( link->ctx, link, boot)) { - link->type = dc_connection_mst_branch; - } else { /* MST not supported */ + link->type = dc_connection_single; sink_caps->signal = SIGNAL_TYPE_DISPLAY_PORT; } } From 69b516c91cbf459e5fd4b8b6e97cfdfa7ea25126 Mon Sep 17 00:00:00 2001 From: SivapiriyanKumarasamy Date: Fri, 22 Sep 2017 12:48:54 -0400 Subject: [PATCH 033/155] drm/amd/display: Program stream's csc matrix instead of using default Signed-off-by: SivapiriyanKumarasamy Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index cdaed0c0a70c4..4e4f20ba5643a 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -2259,7 +2259,6 @@ static void update_dchubp_dpp( struct transform *xfm = pipe_ctx->plane_res.xfm; struct dc_plane_state *plane_state = pipe_ctx->plane_state; union plane_size size = plane_state->plane_size; - struct default_adjustment ocsc = {0}; struct mpcc_cfg mpcc_cfg = {0}; struct pipe_ctx *top_pipe; bool per_pixel_alpha = plane_state->per_pixel_alpha && pipe_ctx->bottom_pipe; @@ -2338,9 +2337,9 @@ static void update_dchubp_dpp( /*gamut remap*/ program_gamut_remap(pipe_ctx); - /*TODO add adjustments parameters*/ - ocsc.out_color_space = pipe_ctx->stream->output_color_space; - pipe_ctx->plane_res.xfm->funcs->opp_set_csc_default(pipe_ctx->plane_res.xfm, &ocsc); + program_csc_matrix(pipe_ctx, + pipe_ctx->stream->output_color_space, + pipe_ctx->stream->csc_color_matrix.matrix); mi->funcs->mem_input_program_surface_config( mi, From 671a6246e0d3652c024f99d5641c7cf427b0b5a5 Mon Sep 17 00:00:00 2001 From: Yongqiang Sun Date: Fri, 22 Sep 2017 13:41:13 -0400 Subject: [PATCH 034/155] drm/amd/display: Early return when turn off a plane. In case of two monitor connected and turn off one of the monitors, OTG0 is locked after graphic plane off due to redundant programming front end regs. Signed-off-by: Yongqiang Sun Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 2cea8de9c9be0..ffc36f5ac50c0 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -1190,8 +1190,14 @@ static void commit_planes_for_stream(struct dc *dc, } } - if (surface_count == 0) + if (surface_count == 0) { + /* + * In case of turning off screen, no need to program front end a second time. + * just return after program front end. + */ dc->hwss.apply_ctx_for_surface(dc, stream, surface_count, context); + return; + } /* Lock pipes for provided surfaces, or all active if full update*/ for (i = 0; i < surface_count; i++) { From 56e6ed4561f2962d1220c16bbd2709ced7a84be8 Mon Sep 17 00:00:00 2001 From: Yongqiang Sun Date: Fri, 22 Sep 2017 16:06:04 -0400 Subject: [PATCH 035/155] drm/amd/display: Only reset top pipe back end. Signed-off-by: Yongqiang Sun Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index 4e4f20ba5643a..014911ebdbd6f 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -1270,6 +1270,9 @@ static void reset_hw_ctx_wrap( if (!pipe_ctx_old->stream) continue; + if (pipe_ctx_old->top_pipe) + continue; + if (!pipe_ctx->stream || pipe_need_reprogram(pipe_ctx_old, pipe_ctx)) { struct clock_source *old_clk = pipe_ctx_old->clock_source; From 544276514760f293eadb68461f1b45b6ccec073e Mon Sep 17 00:00:00 2001 From: Jerry Zuo Date: Wed, 20 Sep 2017 15:04:52 -0400 Subject: [PATCH 036/155] drm/amd/display: Fix MST daisy chain SST not light up In SST daisy chain scenario, edid is getting read in mst hotplug routine. It is getting conflict with drm send_enum_path_resources kernel thread in terms of i2c bus which is getting locked up in such case. Have edid being read in get_mode hook, instead of in hotplug routine. Signed-off-by: Jerry Zuo Reviewed-by: Roman Li Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../display/amdgpu_dm/amdgpu_dm_mst_types.c | 110 ++++++++---------- 1 file changed, 49 insertions(+), 61 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c index dfcfb5a722e01..610375b2a04b9 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c @@ -174,14 +174,60 @@ static const struct drm_connector_funcs dm_dp_mst_connector_funcs = { .atomic_get_property = amdgpu_dm_connector_atomic_get_property }; +static int dm_connector_update_modes(struct drm_connector *connector, + struct edid *edid) +{ + int ret; + + ret = drm_add_edid_modes(connector, edid); + drm_edid_to_eld(connector, edid); + + return ret; +} + static int dm_dp_mst_get_modes(struct drm_connector *connector) { struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); int ret = 0; - ret = drm_add_edid_modes(&aconnector->base, aconnector->edid); + if (!aconnector) + return dm_connector_update_modes(connector, NULL); + + if (!aconnector->edid) { + struct edid *edid; + struct dc_sink *dc_sink; + struct dc_sink_init_data init_params = { + .link = aconnector->dc_link, + .sink_signal = SIGNAL_TYPE_DISPLAY_PORT_MST }; + edid = drm_dp_mst_get_edid(connector, &aconnector->mst_port->mst_mgr, aconnector->port); - drm_edid_to_eld(&aconnector->base, aconnector->edid); + if (!edid) { + drm_mode_connector_update_edid_property( + &aconnector->base, + NULL); + return ret; + } + + aconnector->edid = edid; + + dc_sink = dc_link_add_remote_sink( + aconnector->dc_link, + (uint8_t *)edid, + (edid->extensions + 1) * EDID_LENGTH, + &init_params); + + dc_sink->priv = aconnector; + aconnector->dc_sink = dc_sink; + + if (aconnector->dc_sink) + amdgpu_dm_add_sink_to_freesync_module( + connector, edid); + + drm_mode_connector_update_edid_property( + &aconnector->base, edid); + } + + ret = dm_connector_update_modes(connector, aconnector->edid); return ret; } @@ -343,66 +389,8 @@ static void dm_dp_mst_hotplug(struct drm_dp_mst_topology_mgr *mgr) { struct amdgpu_dm_connector *master = container_of(mgr, struct amdgpu_dm_connector, mst_mgr); struct drm_device *dev = master->base.dev; - struct amdgpu_device *adev = dev->dev_private; - struct drm_connector *connector; - struct amdgpu_dm_connector *aconnector; - struct edid *edid; - struct dc_sink *dc_sink; - - drm_modeset_lock_all(dev); - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - aconnector = to_amdgpu_dm_connector(connector); - if (aconnector->port && - aconnector->port->pdt != DP_PEER_DEVICE_NONE && - aconnector->port->pdt != DP_PEER_DEVICE_MST_BRANCHING && - !aconnector->dc_sink) { - /* - * This is plug in case, where port has been created but - * sink hasn't been created yet - */ - if (!aconnector->edid) { - struct dc_sink_init_data init_params = { - .link = aconnector->dc_link, - .sink_signal = SIGNAL_TYPE_DISPLAY_PORT_MST}; - edid = drm_dp_mst_get_edid(connector, &aconnector->mst_port->mst_mgr, aconnector->port); - - if (!edid) { - drm_mode_connector_update_edid_property( - &aconnector->base, - NULL); - continue; - } - - aconnector->edid = edid; - - dc_sink = dc_link_add_remote_sink( - aconnector->dc_link, - (uint8_t *)edid, - (edid->extensions + 1) * EDID_LENGTH, - &init_params); - - dc_sink->priv = aconnector; - aconnector->dc_sink = dc_sink; - - if (aconnector->dc_sink) - amdgpu_dm_add_sink_to_freesync_module( - connector, - edid); - - dm_restore_drm_connector_state(connector->dev, connector); - } else - edid = aconnector->edid; - - DRM_DEBUG_KMS("edid retrieved %p\n", edid); - - drm_mode_connector_update_edid_property( - &aconnector->base, - aconnector->edid); - } - } - drm_modeset_unlock_all(dev); - schedule_work(&adev->dm.mst_hotplug_work); + drm_kms_helper_hotplug_event(dev); } static void dm_dp_mst_register_connector(struct drm_connector *connector) From e778915c916229475ba76267534b70834ba8de8d Mon Sep 17 00:00:00 2001 From: Charlene Liu Date: Mon, 25 Sep 2017 15:52:49 -0400 Subject: [PATCH 037/155] drm/amd/display: temp disable DCC on high res. Signed-off-by: Charlene Liu Reviewed-by: Yongqiang Sun Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c index 82c82b6310ca5..dd3ff5114d427 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c @@ -1133,20 +1133,27 @@ static bool get_dcc_compression_cap(const struct dc *dc, output->grph.rgb.max_uncompressed_blk_size = 256; output->grph.rgb.max_compressed_blk_size = 256; output->grph.rgb.independent_64b_blks = false; + output->capable = true; + output->const_color_support = false; break; case dcc_control__128_128_xxx: output->grph.rgb.max_uncompressed_blk_size = 128; output->grph.rgb.max_compressed_blk_size = 128; output->grph.rgb.independent_64b_blks = false; + /*temp: not allow dcc on high res*/ + output->capable = false; + output->const_color_support = false; break; case dcc_control__256_64_64: output->grph.rgb.max_uncompressed_blk_size = 256; output->grph.rgb.max_compressed_blk_size = 64; output->grph.rgb.independent_64b_blks = true; + /*temp: not allow dcc on high res*/ + output->capable = false; + output->const_color_support = false; break; } - output->capable = true; - output->const_color_support = false; + return true; } From db64fbe73288f0b5f2a36ecdd48c9bae978406e0 Mon Sep 17 00:00:00 2001 From: Tony Cheng Date: Mon, 25 Sep 2017 10:52:07 -0400 Subject: [PATCH 038/155] drm/amd/display: enable optional pipe split for single display also refactor debug option. now pipe_split_policy are dynamic = no hack around dcn_calcs. will split based on HW recommendation avoid = avoid split if we can support the config with higher voltage avoid_multi_display = allow split with single display output. force_single_disp_pipe_split force single display to pipe split to improve stutter efficiency by using DET buffers using 2 HUBP. Signed-off-by: Tony Cheng Reviewed-by: Yongqiang Sun Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/calcs/dcn_calcs.c | 44 +++++++++++++++++-- drivers/gpu/drm/amd/display/dc/dc.h | 9 +++- .../drm/amd/display/dc/dcn10/dcn10_resource.c | 8 +--- 3 files changed, 51 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c index 319450d9cfc1b..aa56243f25226 100644 --- a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c +++ b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c @@ -720,6 +720,46 @@ static bool dcn_bw_apply_registry_override(struct dc *dc) return updated; } +void hack_disable_optional_pipe_split(struct dcn_bw_internal_vars *v) +{ + /* + * disable optional pipe split by lower dispclk bounding box + * at DPM0 + */ + v->max_dispclk[0] = v->max_dppclk_vmin0p65; +} + +void hack_force_pipe_split(struct dcn_bw_internal_vars *v, + unsigned int pixel_rate_khz) +{ + /* + * force enabling pipe split by lower dpp clock for DPM0 to just + * below the specify pixel_rate, so bw calc would split pipe. + */ + v->max_dppclk[0] = pixel_rate_khz / 1000; +} + +void hack_bounding_box(struct dcn_bw_internal_vars *v, + struct dc_debug *dbg, + struct dc_state *context) +{ + if (dbg->pipe_split_policy == MPC_SPLIT_AVOID) { + hack_disable_optional_pipe_split(v); + } + + if (dbg->pipe_split_policy == MPC_SPLIT_AVOID_MULT_DISP && + context->stream_count >= 2) { + hack_disable_optional_pipe_split(v); + } + + if (context->stream_count == 1 && + dbg->force_single_disp_pipe_split) { + struct dc_stream_state *stream0 = context->streams[0]; + + hack_force_pipe_split(v, stream0->timing.pix_clk_khz); + } +} + bool dcn_validate_bandwidth( struct dc *dc, struct dc_state *context) @@ -851,9 +891,7 @@ bool dcn_validate_bandwidth( v->phyclk_per_state[1] = v->phyclkv_mid0p72; v->phyclk_per_state[0] = v->phyclkv_min0p65; - if (dc->debug.disable_pipe_split) { - v->max_dispclk[0] = v->max_dppclk_vmin0p65; - } + hack_bounding_box(v, &dc->debug, context); if (v->voltage_override == dcn_bw_v_max0p9) { v->voltage_override_level = number_of_states - 1; diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 7a3a48179452e..622488efa9e6b 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -162,6 +162,12 @@ struct dc_config { bool disable_disp_pll_sharing; }; +enum pipe_split_policy { + MPC_SPLIT_DYNAMIC = 0, + MPC_SPLIT_AVOID = 1, + MPC_SPLIT_AVOID_MULT_DISP = 2, +}; + struct dc_debug { bool surface_visual_confirm; bool sanity_checks; @@ -177,7 +183,8 @@ struct dc_debug { bool disable_hubp_power_gate; bool disable_pplib_wm_range; bool use_dml_wm; - bool disable_pipe_split; + enum pipe_split_policy pipe_split_policy; + bool force_single_disp_pipe_split; unsigned int min_disp_clk_khz; int sr_exit_time_dpm0_ns; int sr_enter_plus_exit_time_dpm0_ns; diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c index dd3ff5114d427..bd7c86e5800e9 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c @@ -425,10 +425,9 @@ static const struct dc_debug debug_defaults_drv = { .disable_pplib_clock_request = true, .disable_pplib_wm_range = false, -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) .use_dml_wm = false, - .disable_pipe_split = true -#endif + + .pipe_split_policy = MPC_SPLIT_AVOID_MULT_DISP, }; static const struct dc_debug debug_defaults_diags = { @@ -437,12 +436,9 @@ static const struct dc_debug debug_defaults_diags = { .timing_trace = true, .clock_trace = true, .disable_stutter = true, -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) .disable_pplib_clock_request = true, .disable_pplib_wm_range = true, .use_dml_wm = false, - .disable_pipe_split = false -#endif }; static void dcn10_dpp_destroy(struct transform **xfm) From a32a7708ae8b01c191768d503c1af33b85b369d0 Mon Sep 17 00:00:00 2001 From: Tony Cheng Date: Mon, 25 Sep 2017 18:06:11 -0400 Subject: [PATCH 039/155] drm/amd/display: add option to disable DCC for DCC 128b request 1. reverts commit e67f51012740 ("dc: temp disable DCC on high res.") - default still DCC enabled 2. add debug options to decide how DCC is disabled - disable DCC - disable DCC if DCC requires 128b (aka. half) request -- observed compressed data corruption result in screen corruption in full (256b) request while half (128b) would cause DCN to hang, result in DF hang Signed-off-by: Tony Cheng Reviewed-by: Yongqiang Sun Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc.h | 11 ++++++++--- .../drm/amd/display/dc/dcn10/dcn10_resource.c | 18 ++++++++---------- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 622488efa9e6b..d7afbcfb33cea 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -56,11 +56,10 @@ struct dc_caps { uint32_t max_planes; uint32_t max_downscale_ratio; uint32_t i2c_speed_in_khz; - unsigned int max_cursor_size; + bool dcc_const_color; }; - struct dc_dcc_surface_param { struct dc_size surface_size; enum surface_pixel_format format; @@ -162,6 +161,12 @@ struct dc_config { bool disable_disp_pll_sharing; }; +enum dcc_option { + DCC_ENABLE = 0, + DCC_DISABLE = 1, + DCC_HALF_REQ_DISALBE = 2, +}; + enum pipe_split_policy { MPC_SPLIT_DYNAMIC = 0, MPC_SPLIT_AVOID = 1, @@ -177,7 +182,7 @@ struct dc_debug { bool clock_trace; bool validation_trace; bool disable_stutter; - bool disable_dcc; + enum dcc_option disable_dcc; bool disable_dfs_bypass; bool disable_dpp_power_gate; bool disable_hubp_power_gate; diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c index bd7c86e5800e9..30c275e057964 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c @@ -414,7 +414,6 @@ static const struct resource_caps res_cap = { }; static const struct dc_debug debug_defaults_drv = { - .disable_dcc = false, .sanity_checks = true, .disable_dmcu = true, .force_abm_enable = false, @@ -428,6 +427,7 @@ static const struct dc_debug debug_defaults_drv = { .use_dml_wm = false, .pipe_split_policy = MPC_SPLIT_AVOID_MULT_DISP, + .disable_dcc = DCC_ENABLE, }; static const struct dc_debug debug_defaults_diags = { @@ -1080,7 +1080,7 @@ static bool get_dcc_compression_cap(const struct dc *dc, memset(output, 0, sizeof(*output)); - if (dc->debug.disable_dcc) + if (dc->debug.disable_dcc == DCC_DISABLE) return false; if (!dcc_support_pixel_format(input->format, @@ -1124,32 +1124,30 @@ static bool get_dcc_compression_cap(const struct dc *dc, dcc_control = dcc_control__128_128_xxx; } + if (dc->debug.disable_dcc == DCC_HALF_REQ_DISALBE && + dcc_control != dcc_control__256_256_xxx) + return false; + switch (dcc_control) { case dcc_control__256_256_xxx: output->grph.rgb.max_uncompressed_blk_size = 256; output->grph.rgb.max_compressed_blk_size = 256; output->grph.rgb.independent_64b_blks = false; - output->capable = true; - output->const_color_support = false; break; case dcc_control__128_128_xxx: output->grph.rgb.max_uncompressed_blk_size = 128; output->grph.rgb.max_compressed_blk_size = 128; output->grph.rgb.independent_64b_blks = false; - /*temp: not allow dcc on high res*/ - output->capable = false; - output->const_color_support = false; break; case dcc_control__256_64_64: output->grph.rgb.max_uncompressed_blk_size = 256; output->grph.rgb.max_compressed_blk_size = 64; output->grph.rgb.independent_64b_blks = true; - /*temp: not allow dcc on high res*/ - output->capable = false; - output->const_color_support = false; break; } + output->capable = true; + output->const_color_support = false; return true; } From 966869d07aae2d1becfcb16b55cafd4aae3c6627 Mon Sep 17 00:00:00 2001 From: Tony Cheng Date: Tue, 26 Sep 2017 01:56:00 -0400 Subject: [PATCH 040/155] drm/amd/display: option to maximize lb usage experimental change for testing if max line buffer result in better stutter efficiency for 1080p, LB can hold up to 9 line at 10bpcc, potentially add 10 line time of latency hiding. Signed-off-by: Tony Cheng Reviewed-by: Yongqiang Sun Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc.h | 8 ++++++-- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c | 3 +++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index d7afbcfb33cea..427ccbc28f510 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -181,15 +181,19 @@ struct dc_debug { bool timing_trace; bool clock_trace; bool validation_trace; + + /* stutter efficiency related */ bool disable_stutter; + bool use_max_lb; enum dcc_option disable_dcc; + enum pipe_split_policy pipe_split_policy; + bool force_single_disp_pipe_split; + bool disable_dfs_bypass; bool disable_dpp_power_gate; bool disable_hubp_power_gate; bool disable_pplib_wm_range; bool use_dml_wm; - enum pipe_split_policy pipe_split_policy; - bool force_single_disp_pipe_split; unsigned int min_disp_clk_khz; int sr_exit_time_dpm0_ns; int sr_enter_plus_exit_time_dpm0_ns; diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c index 82b8887d49730..fa2ab9952388f 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c @@ -507,6 +507,9 @@ static enum lb_memory_config find_lb_memory_config(struct dcn10_dpp *xfm, { enum lb_memory_config mem_cfg = LB_MEMORY_CONFIG_0; + if (xfm->base.ctx->dc->debug.use_max_lb) + return mem_cfg; + if (xfm->tf_mask->PIXEL_DEPTH) { mem_cfg = dpp10_find_lb_memory_config(scl_data); } From 9f945eab797b042930553388d37c12fed38f3396 Mon Sep 17 00:00:00 2001 From: Tony Cheng Date: Tue, 26 Sep 2017 10:16:34 -0400 Subject: [PATCH 041/155] drm/amd/display: fix bug in force_single_disp_pipe_split should only lower dpp clock. Signed-off-by: Tony Cheng Reviewed-by: Yongqiang Sun Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c index aa56243f25226..cf474eb1cde87 100644 --- a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c +++ b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c @@ -732,11 +732,14 @@ void hack_disable_optional_pipe_split(struct dcn_bw_internal_vars *v) void hack_force_pipe_split(struct dcn_bw_internal_vars *v, unsigned int pixel_rate_khz) { + float pixel_rate_mhz = pixel_rate_khz / 1000; + /* * force enabling pipe split by lower dpp clock for DPM0 to just * below the specify pixel_rate, so bw calc would split pipe. */ - v->max_dppclk[0] = pixel_rate_khz / 1000; + if (pixel_rate_mhz < v->max_dppclk[0]) + v->max_dppclk[0] = pixel_rate_mhz; } void hack_bounding_box(struct dcn_bw_internal_vars *v, From 2e1cc334631849b035b24897d6be59d2a57b6f1c Mon Sep 17 00:00:00 2001 From: Tony Cheng Date: Tue, 26 Sep 2017 17:06:26 -0400 Subject: [PATCH 042/155] drm/amd/display: dal 3.1.03 Signed-off-by: Tony Cheng Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 427ccbc28f510..cf9cd108539fc 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -38,7 +38,7 @@ #include "inc/compressor.h" #include "dml/display_mode_lib.h" -#define DC_VER "3.1.02" +#define DC_VER "3.1.03" #define MAX_SURFACES 3 #define MAX_STREAMS 6 From 60d671db1c0c02f31bcff3ea5dee244d26b8ed77 Mon Sep 17 00:00:00 2001 From: Jerry Zuo Date: Mon, 25 Sep 2017 16:39:45 -0400 Subject: [PATCH 043/155] drm/amd/display: Fix ref_count messed up issue In the full update type, need to add ref_count to the newly created dc_state->stream. It made mistake to add ref_count to dc->current_state->stream which keeps adding up without release. Signed-off-by: Jerry Zuo Reviewed-by: Roman Li Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index ffc36f5ac50c0..3439bc46a4a24 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -1322,6 +1322,7 @@ void dc_commit_updates_for_stream(struct dc *dc, const struct dc_stream_status *stream_status; enum surface_update_type update_type; struct dc_state *context; + struct dc_context *dc_ctx = dc->ctx; int i; stream_status = dc_stream_get_status(stream); @@ -1334,8 +1335,17 @@ void dc_commit_updates_for_stream(struct dc *dc, update_surface_trace(dc, srf_updates, surface_count); - if (update_type >= UPDATE_TYPE_FULL) + if (update_type >= UPDATE_TYPE_FULL) { + + /* initialize scratch memory for building context */ + context = dc_create_state(); + if (context == NULL) { + DC_ERROR("Failed to allocate new validate context!\n"); + return; + } + dc_resource_state_copy_construct(state, context); + } for (i = 0; i < surface_count; i++) { @@ -1361,6 +1371,15 @@ void dc_commit_updates_for_stream(struct dc *dc, dc_post_update_surfaces_to_stream(dc); + if (dc->current_state != context) { + + struct dc_state *old = dc->current_state; + + dc->current_state = context; + dc_release_state(old); + + } + return; } From b87d78d6aa104b207ff588d2cfd13633c2385994 Mon Sep 17 00:00:00 2001 From: Yue Hin Lau Date: Tue, 19 Sep 2017 17:29:28 -0400 Subject: [PATCH 044/155] drm/amd/display: moving cursor functions from ipp to mem_input Signed-off-by: Yue Hin Lau Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/core/dc_stream.c | 32 ++- drivers/gpu/drm/amd/display/dc/dce/dce_ipp.c | 2 + .../gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c | 51 +++++ .../gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h | 15 +- .../gpu/drm/amd/display/dc/dcn10/dcn10_ipp.c | 189 ------------------ .../amd/display/dc/dcn10/dcn10_mem_input.c | 163 +++++++++++++++ .../amd/display/dc/dcn10/dcn10_mem_input.h | 57 +++++- .../gpu/drm/amd/display/dc/inc/hw/mem_input.h | 10 + .../gpu/drm/amd/display/dc/inc/hw/transform.h | 11 + 9 files changed, 329 insertions(+), 201 deletions(-) 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 23df7bc020d2a..c19b478bcdc77 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c @@ -195,13 +195,23 @@ bool dc_stream_set_cursor_attributes( for (i = 0; i < MAX_PIPES; i++) { struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i]; - if (pipe_ctx->stream != stream || !pipe_ctx->plane_res.ipp) + if (pipe_ctx->stream != stream || !pipe_ctx->plane_res.mi || !pipe_ctx->plane_res.xfm) continue; if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state) continue; - pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes( - pipe_ctx->plane_res.ipp, attributes); + + if (pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes != NULL) + pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes( + pipe_ctx->plane_res.ipp, attributes); + + if (pipe_ctx->plane_res.mi->funcs->set_cursor_attributes != NULL) + pipe_ctx->plane_res.mi->funcs->set_cursor_attributes( + pipe_ctx->plane_res.mi, attributes); + + if (pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes != NULL) + pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes( + pipe_ctx->plane_res.xfm, attributes); } return true; @@ -231,6 +241,8 @@ bool dc_stream_set_cursor_position( for (i = 0; i < MAX_PIPES; i++) { struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i]; struct input_pixel_processor *ipp = pipe_ctx->plane_res.ipp; + struct mem_input *mi = pipe_ctx->plane_res.mi; + struct transform *xfm = pipe_ctx->plane_res.xfm; struct dc_cursor_position pos_cpy = *position; struct dc_cursor_mi_param param = { .pixel_clk_khz = stream->timing.pix_clk_khz, @@ -241,7 +253,9 @@ bool dc_stream_set_cursor_position( }; if (pipe_ctx->stream != stream || - !pipe_ctx->plane_res.ipp || !pipe_ctx->plane_state) + !pipe_ctx->plane_res.mi || + !pipe_ctx->plane_state || + !pipe_ctx->plane_res.xfm) continue; if (pipe_ctx->plane_state->address.type @@ -251,7 +265,15 @@ bool dc_stream_set_cursor_position( if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state) pos_cpy.enable = false; - ipp->funcs->ipp_cursor_set_position(ipp, &pos_cpy, ¶m); + + if (ipp->funcs->ipp_cursor_set_position != NULL) + ipp->funcs->ipp_cursor_set_position(ipp, &pos_cpy, ¶m); + + if (mi->funcs->set_cursor_attributes != NULL) + mi->funcs->set_cursor_position(mi, &pos_cpy, ¶m); + + if (xfm->funcs->set_cursor_attributes != NULL) + xfm->funcs->set_cursor_position(xfm, &pos_cpy, ¶m, mi->curs_attr.width); } return true; diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_ipp.c b/drivers/gpu/drm/amd/display/dc/dce/dce_ipp.c index fa481d481132d..d618fdd0cc821 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_ipp.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_ipp.c @@ -37,6 +37,7 @@ #define CTX \ ipp_dce->base.ctx + static void dce_ipp_cursor_set_position( struct input_pixel_processor *ipp, const struct dc_cursor_position *position, @@ -133,6 +134,7 @@ static void dce_ipp_cursor_set_attributes( REG_UPDATE(CUR_UPDATE, CURSOR_UPDATE_LOCK, false); } + static void dce_ipp_program_prescale( struct input_pixel_processor *ipp, struct ipp_prescale_params *params) diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c index f9e43e68fc0c9..05df3b2229459 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c @@ -372,6 +372,55 @@ void ippn10_cnv_setup ( } } +void dcn10_set_cursor_attributes( + struct transform *xfm_base, + const struct dc_cursor_attributes *attr) +{ + struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); + enum dc_cursor_color_format color_format = attr->color_format; + + REG_UPDATE_2(CURSOR0_CONTROL, + CUR0_MODE, color_format, + CUR0_EXPANSION_MODE, 0); + + if (color_format == CURSOR_MODE_MONO) { + /* todo: clarify what to program these to */ + REG_UPDATE(CURSOR0_COLOR0, + CUR0_COLOR0, 0x00000000); + REG_UPDATE(CURSOR0_COLOR1, + CUR0_COLOR1, 0xFFFFFFFF); + } + + /* TODO: Fixed vs float */ + + REG_UPDATE_3(FORMAT_CONTROL, + CNVC_BYPASS, 0, + FORMAT_CONTROL__ALPHA_EN, 1, + FORMAT_EXPANSION_MODE, 0); +} + + +void dcn10_set_cursor_position( + struct transform *xfm_base, + const struct dc_cursor_position *pos, + const struct dc_cursor_mi_param *param, + uint32_t width) +{ + struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); + int src_x_offset = pos->x - pos->x_hotspot - param->viewport_x_start; + uint32_t cur_en = pos->enable ? 1 : 0; + + if (src_x_offset >= (int)param->viewport_width) + cur_en = 0; /* not visible beyond right edge*/ + + if (src_x_offset + (int)width < 0) + cur_en = 0; /* not visible beyond left edge*/ + + REG_UPDATE(CURSOR0_CONTROL, + CUR0_ENABLE, cur_en); + +} + static const struct transform_funcs dcn10_dpp_funcs = { .transform_reset = dpp_reset, .transform_set_scaler = dcn10_dpp_dscl_set_scaler_manual_scale, @@ -391,6 +440,8 @@ static const struct transform_funcs dcn10_dpp_funcs = { .ipp_program_degamma_pwl = ippn10_set_degamma_pwl, .ipp_setup = ippn10_cnv_setup, .ipp_full_bypass = ippn10_full_bypass, + .set_cursor_attributes = dcn10_set_cursor_attributes, + .set_cursor_position = dcn10_set_cursor_position, }; diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h index a1f6b01a2eb41..7fecdb19761d0 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h @@ -112,7 +112,10 @@ SRI(CM_DGAM_CONTROL, CM, id), \ SRI(FORMAT_CONTROL, CNVC_CFG, id), \ SRI(CNVC_SURFACE_PIXEL_FORMAT, CNVC_CFG, id), \ - SRI(CURSOR0_CONTROL, CNVC_CUR, id) + SRI(CURSOR0_CONTROL, CNVC_CUR, id), \ + SRI(CURSOR0_CONTROL, CNVC_CUR, id), \ + SRI(CURSOR0_COLOR0, CNVC_CUR, id), \ + SRI(CURSOR0_COLOR1, CNVC_CUR, id) @@ -302,7 +305,9 @@ TF_SF(CNVC_CFG0_CNVC_SURFACE_PIXEL_FORMAT, CNVC_SURFACE_PIXEL_FORMAT, mask_sh), \ TF_SF(CNVC_CUR0_CURSOR0_CONTROL, CUR0_MODE, mask_sh), \ TF_SF(CNVC_CUR0_CURSOR0_CONTROL, CUR0_EXPANSION_MODE, mask_sh), \ - TF_SF(CNVC_CUR0_CURSOR0_CONTROL, CUR0_ENABLE, mask_sh) + TF_SF(CNVC_CUR0_CURSOR0_CONTROL, CUR0_ENABLE, mask_sh), \ + TF_SF(CNVC_CUR0_CURSOR0_COLOR0, CUR0_COLOR0, mask_sh), \ + TF_SF(CNVC_CUR0_CURSOR0_COLOR1, CUR0_COLOR1, mask_sh) #define TF_REG_LIST_SH_MASK_DCN10(mask_sh)\ TF_REG_LIST_SH_MASK_DCN(mask_sh),\ @@ -989,7 +994,9 @@ type CUR0_EXPANSION_MODE; \ type CUR0_ENABLE; \ type CM_BYPASS; \ - type FORMAT_CONTROL__ALPHA_EN + type FORMAT_CONTROL__ALPHA_EN; \ + type CUR0_COLOR0; \ + type CUR0_COLOR1 @@ -1237,6 +1244,8 @@ struct dcn_dpp_registers { uint32_t CNVC_SURFACE_PIXEL_FORMAT; uint32_t CURSOR_CONTROL; uint32_t CURSOR0_CONTROL; + uint32_t CURSOR0_COLOR0; + uint32_t CURSOR0_COLOR1; }; struct dcn10_dpp { diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_ipp.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_ipp.c index 67bd6a738fe90..08db1e6b51668 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_ipp.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_ipp.c @@ -37,188 +37,6 @@ #define CTX \ ippn10->base.ctx -static bool ippn10_cursor_program_control( - struct dcn10_ipp *ippn10, - bool pixel_data_invert, - enum dc_cursor_color_format color_format) -{ - if (REG(CURSOR_SETTINS)) - REG_SET_2(CURSOR_SETTINS, 0, - /* no shift of the cursor HDL schedule */ - CURSOR0_DST_Y_OFFSET, 0, - /* used to shift the cursor chunk request deadline */ - CURSOR0_CHUNK_HDL_ADJUST, 3); - else - REG_SET_2(CURSOR_SETTINGS, 0, - /* no shift of the cursor HDL schedule */ - CURSOR0_DST_Y_OFFSET, 0, - /* used to shift the cursor chunk request deadline */ - CURSOR0_CHUNK_HDL_ADJUST, 3); - - REG_UPDATE_2(CURSOR0_CONTROL, - CUR0_MODE, color_format, - CUR0_EXPANSION_MODE, 0); - - if (color_format == CURSOR_MODE_MONO) { - /* todo: clarify what to program these to */ - REG_UPDATE(CURSOR0_COLOR0, - CUR0_COLOR0, 0x00000000); - REG_UPDATE(CURSOR0_COLOR1, - CUR0_COLOR1, 0xFFFFFFFF); - } - - /* TODO: Fixed vs float */ - - REG_UPDATE_3(FORMAT_CONTROL, - CNVC_BYPASS, 0, - ALPHA_EN, 1, - FORMAT_EXPANSION_MODE, 0); - - return true; -} - -enum cursor_pitch { - CURSOR_PITCH_64_PIXELS = 0, - CURSOR_PITCH_128_PIXELS, - CURSOR_PITCH_256_PIXELS -}; - -enum cursor_lines_per_chunk { - CURSOR_LINE_PER_CHUNK_2 = 1, - CURSOR_LINE_PER_CHUNK_4, - CURSOR_LINE_PER_CHUNK_8, - CURSOR_LINE_PER_CHUNK_16 -}; - -static enum cursor_pitch ippn10_get_cursor_pitch( - unsigned int pitch) -{ - enum cursor_pitch hw_pitch; - - switch (pitch) { - case 64: - hw_pitch = CURSOR_PITCH_64_PIXELS; - break; - case 128: - hw_pitch = CURSOR_PITCH_128_PIXELS; - break; - case 256: - hw_pitch = CURSOR_PITCH_256_PIXELS; - break; - default: - DC_ERR("Invalid cursor pitch of %d. " - "Only 64/128/256 is supported on DCN.\n", pitch); - hw_pitch = CURSOR_PITCH_64_PIXELS; - break; - } - return hw_pitch; -} - -static enum cursor_lines_per_chunk ippn10_get_lines_per_chunk( - unsigned int cur_width, - enum dc_cursor_color_format format) -{ - enum cursor_lines_per_chunk line_per_chunk; - - if (format == CURSOR_MODE_MONO) - /* impl B. expansion in CUR Buffer reader */ - line_per_chunk = CURSOR_LINE_PER_CHUNK_16; - else if (cur_width <= 32) - line_per_chunk = CURSOR_LINE_PER_CHUNK_16; - else if (cur_width <= 64) - line_per_chunk = CURSOR_LINE_PER_CHUNK_8; - else if (cur_width <= 128) - line_per_chunk = CURSOR_LINE_PER_CHUNK_4; - else - line_per_chunk = CURSOR_LINE_PER_CHUNK_2; - - return line_per_chunk; -} - -static void ippn10_cursor_set_attributes( - struct input_pixel_processor *ipp, - const struct dc_cursor_attributes *attr) -{ - struct dcn10_ipp *ippn10 = TO_DCN10_IPP(ipp); - enum cursor_pitch hw_pitch = ippn10_get_cursor_pitch(attr->pitch); - enum cursor_lines_per_chunk lpc = ippn10_get_lines_per_chunk( - attr->width, attr->color_format); - - ippn10->curs_attr = *attr; - - REG_UPDATE(CURSOR_SURFACE_ADDRESS_HIGH, - CURSOR_SURFACE_ADDRESS_HIGH, attr->address.high_part); - REG_UPDATE(CURSOR_SURFACE_ADDRESS, - CURSOR_SURFACE_ADDRESS, attr->address.low_part); - - REG_UPDATE_2(CURSOR_SIZE, - CURSOR_WIDTH, attr->width, - CURSOR_HEIGHT, attr->height); - REG_UPDATE_3(CURSOR_CONTROL, - CURSOR_MODE, attr->color_format, - CURSOR_PITCH, hw_pitch, - CURSOR_LINES_PER_CHUNK, lpc); - ippn10_cursor_program_control(ippn10, - attr->attribute_flags.bits.INVERT_PIXEL_DATA, - attr->color_format); -} - -static void ippn10_cursor_set_position( - struct input_pixel_processor *ipp, - const struct dc_cursor_position *pos, - const struct dc_cursor_mi_param *param) -{ - struct dcn10_ipp *ippn10 = TO_DCN10_IPP(ipp); - int src_x_offset = pos->x - pos->x_hotspot - param->viewport_x_start; - uint32_t cur_en = pos->enable ? 1 : 0; - uint32_t dst_x_offset = (src_x_offset >= 0) ? src_x_offset : 0; - - /* - * Guard aganst cursor_set_position() from being called with invalid - * attributes - * - * TODO: Look at combining cursor_set_position() and - * cursor_set_attributes() into cursor_update() - */ - if (ippn10->curs_attr.address.quad_part == 0) - return; - - dst_x_offset *= param->ref_clk_khz; - dst_x_offset /= param->pixel_clk_khz; - - ASSERT(param->h_scale_ratio.value); - - if (param->h_scale_ratio.value) - dst_x_offset = dal_fixed31_32_floor(dal_fixed31_32_div( - dal_fixed31_32_from_int(dst_x_offset), - param->h_scale_ratio)); - - if (src_x_offset >= (int)param->viewport_width) - cur_en = 0; /* not visible beyond right edge*/ - - if (src_x_offset + (int)ippn10->curs_attr.width < 0) - cur_en = 0; /* not visible beyond left edge*/ - - if (cur_en && REG_READ(CURSOR_SURFACE_ADDRESS) == 0) - ippn10_cursor_set_attributes(ipp, &ippn10->curs_attr); - REG_UPDATE(CURSOR_CONTROL, - CURSOR_ENABLE, cur_en); - REG_UPDATE(CURSOR0_CONTROL, - CUR0_ENABLE, cur_en); - - REG_SET_2(CURSOR_POSITION, 0, - CURSOR_X_POSITION, pos->x, - CURSOR_Y_POSITION, pos->y); - - REG_SET_2(CURSOR_HOT_SPOT, 0, - CURSOR_HOT_SPOT_X, pos->x_hotspot, - CURSOR_HOT_SPOT_Y, pos->y_hotspot); - - REG_SET(CURSOR_DST_OFFSET, 0, - CURSOR_DST_X_OFFSET, dst_x_offset); - /* TODO Handle surface pixel formats other than 4:4:4 */ -} - /*****************************************/ /* Constructor, Destructor */ /*****************************************/ @@ -230,13 +48,6 @@ static void dcn10_ipp_destroy(struct input_pixel_processor **ipp) } static const struct ipp_funcs dcn10_ipp_funcs = { - .ipp_cursor_set_attributes = ippn10_cursor_set_attributes, - .ipp_cursor_set_position = ippn10_cursor_set_position, - .ipp_set_degamma = NULL, - .ipp_program_input_lut = NULL, - .ipp_full_bypass = NULL, - .ipp_setup = NULL, - .ipp_program_degamma_pwl = NULL, .ipp_destroy = dcn10_ipp_destroy }; diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.c index a28495d95a159..efa1aca187adf 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.c @@ -766,6 +766,167 @@ void dcn10_mem_input_read_state(struct dcn10_mem_input *mi, QoS_LEVEL_HIGH_WM, &s->qos_level_high_wm); } +enum cursor_pitch { + CURSOR_PITCH_64_PIXELS = 0, + CURSOR_PITCH_128_PIXELS, + CURSOR_PITCH_256_PIXELS +}; + +enum cursor_lines_per_chunk { + CURSOR_LINE_PER_CHUNK_2 = 1, + CURSOR_LINE_PER_CHUNK_4, + CURSOR_LINE_PER_CHUNK_8, + CURSOR_LINE_PER_CHUNK_16 +}; + +static bool ippn10_cursor_program_control( + struct dcn10_mem_input *mi, + bool pixel_data_invert, + enum dc_cursor_color_format color_format) +{ + if (REG(CURSOR_SETTINS)) + REG_SET_2(CURSOR_SETTINS, 0, + /* no shift of the cursor HDL schedule */ + CURSOR0_DST_Y_OFFSET, 0, + /* used to shift the cursor chunk request deadline */ + CURSOR0_CHUNK_HDL_ADJUST, 3); + else + REG_SET_2(CURSOR_SETTINGS, 0, + /* no shift of the cursor HDL schedule */ + CURSOR0_DST_Y_OFFSET, 0, + /* used to shift the cursor chunk request deadline */ + CURSOR0_CHUNK_HDL_ADJUST, 3); + + return true; +} + +static enum cursor_pitch ippn10_get_cursor_pitch( + unsigned int pitch) +{ + enum cursor_pitch hw_pitch; + + switch (pitch) { + case 64: + hw_pitch = CURSOR_PITCH_64_PIXELS; + break; + case 128: + hw_pitch = CURSOR_PITCH_128_PIXELS; + break; + case 256: + hw_pitch = CURSOR_PITCH_256_PIXELS; + break; + default: + DC_ERR("Invalid cursor pitch of %d. " + "Only 64/128/256 is supported on DCN.\n", pitch); + hw_pitch = CURSOR_PITCH_64_PIXELS; + break; + } + return hw_pitch; +} + +static enum cursor_lines_per_chunk ippn10_get_lines_per_chunk( + unsigned int cur_width, + enum dc_cursor_color_format format) +{ + enum cursor_lines_per_chunk line_per_chunk; + + if (format == CURSOR_MODE_MONO) + /* impl B. expansion in CUR Buffer reader */ + line_per_chunk = CURSOR_LINE_PER_CHUNK_16; + else if (cur_width <= 32) + line_per_chunk = CURSOR_LINE_PER_CHUNK_16; + else if (cur_width <= 64) + line_per_chunk = CURSOR_LINE_PER_CHUNK_8; + else if (cur_width <= 128) + line_per_chunk = CURSOR_LINE_PER_CHUNK_4; + else + line_per_chunk = CURSOR_LINE_PER_CHUNK_2; + + return line_per_chunk; +} + +static void ippn10_cursor_set_attributes( + struct mem_input *mem_input, + const struct dc_cursor_attributes *attr) +{ + struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input); + enum cursor_pitch hw_pitch = ippn10_get_cursor_pitch(attr->pitch); + enum cursor_lines_per_chunk lpc = ippn10_get_lines_per_chunk( + attr->width, attr->color_format); + + mem_input->curs_attr = *attr; + + REG_UPDATE(CURSOR_SURFACE_ADDRESS_HIGH, + CURSOR_SURFACE_ADDRESS_HIGH, attr->address.high_part); + REG_UPDATE(CURSOR_SURFACE_ADDRESS, + CURSOR_SURFACE_ADDRESS, attr->address.low_part); + + REG_UPDATE_2(CURSOR_SIZE, + CURSOR_WIDTH, attr->width, + CURSOR_HEIGHT, attr->height); + REG_UPDATE_3(CURSOR_CONTROL, + CURSOR_MODE, attr->color_format, + CURSOR_PITCH, hw_pitch, + CURSOR_LINES_PER_CHUNK, lpc); + ippn10_cursor_program_control(mi, + attr->attribute_flags.bits.INVERT_PIXEL_DATA, + attr->color_format); +} + +static void ippn10_cursor_set_position( + struct mem_input *mem_input, + const struct dc_cursor_position *pos, + const struct dc_cursor_mi_param *param) +{ + struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input); + int src_x_offset = pos->x - pos->x_hotspot - param->viewport_x_start; + uint32_t cur_en = pos->enable ? 1 : 0; + uint32_t dst_x_offset = (src_x_offset >= 0) ? src_x_offset : 0; + + /* + * Guard aganst cursor_set_position() from being called with invalid + * attributes + * + * TODO: Look at combining cursor_set_position() and + * cursor_set_attributes() into cursor_update() + */ + if (mem_input->curs_attr.address.quad_part == 0) + return; + + dst_x_offset *= param->ref_clk_khz; + dst_x_offset /= param->pixel_clk_khz; + + ASSERT(param->h_scale_ratio.value); + + if (param->h_scale_ratio.value) + dst_x_offset = dal_fixed31_32_floor(dal_fixed31_32_div( + dal_fixed31_32_from_int(dst_x_offset), + param->h_scale_ratio)); + + if (src_x_offset >= (int)param->viewport_width) + cur_en = 0; /* not visible beyond right edge*/ + + if (src_x_offset + (int)mem_input->curs_attr.width < 0) + cur_en = 0; /* not visible beyond left edge*/ + + if (cur_en && REG_READ(CURSOR_SURFACE_ADDRESS) == 0) + ippn10_cursor_set_attributes(mem_input, &mem_input->curs_attr); + REG_UPDATE(CURSOR_CONTROL, + CURSOR_ENABLE, cur_en); + + REG_SET_2(CURSOR_POSITION, 0, + CURSOR_X_POSITION, pos->x, + CURSOR_Y_POSITION, pos->y); + + REG_SET_2(CURSOR_HOT_SPOT, 0, + CURSOR_HOT_SPOT_X, pos->x_hotspot, + CURSOR_HOT_SPOT_Y, pos->y_hotspot); + + REG_SET(CURSOR_DST_OFFSET, 0, + CURSOR_DST_X_OFFSET, dst_x_offset); + /* TODO Handle surface pixel formats other than 4:4:4 */ +} + static struct mem_input_funcs dcn10_mem_input_funcs = { .mem_input_program_display_marks = min10_program_display_marks, .mem_input_program_surface_flip_and_addr = @@ -780,6 +941,8 @@ static struct mem_input_funcs dcn10_mem_input_funcs = { .dcc_control = min10_dcc_control, .mem_program_viewport = min_set_viewport, .set_hubp_blank_en = min10_set_hubp_blank_en, + .set_cursor_attributes = ippn10_cursor_set_attributes, + .set_cursor_position = ippn10_cursor_set_position, }; /*****************************************/ diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.h index 0b7d4faff82fa..2c79d7aa3f915 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.h +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.h @@ -30,7 +30,6 @@ #define TO_DCN10_MEM_INPUT(mi)\ container_of(mi, struct dcn10_mem_input, base) - #define MI_REG_LIST_DCN(id)\ SRI(DCHUBP_CNTL, HUBP, id),\ SRI(HUBPREQ_DEBUG_DB, HUBP, id),\ @@ -118,7 +117,15 @@ SRI(DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_MSB, HUBPREQ, id),\ SRI(DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_LSB, HUBPREQ, id),\ SR(DCHUBBUB_SDPIF_FB_BASE),\ - SR(DCHUBBUB_SDPIF_FB_OFFSET) + SR(DCHUBBUB_SDPIF_FB_OFFSET),\ + SRI(CURSOR_SETTINS, HUBPREQ, id), \ + SRI(CURSOR_SURFACE_ADDRESS_HIGH, CURSOR, id), \ + SRI(CURSOR_SURFACE_ADDRESS, CURSOR, id), \ + SRI(CURSOR_SIZE, CURSOR, id), \ + SRI(CURSOR_CONTROL, CURSOR, id), \ + SRI(CURSOR_POSITION, CURSOR, id), \ + SRI(CURSOR_HOT_SPOT, CURSOR, id), \ + SRI(CURSOR_DST_OFFSET, CURSOR, id) @@ -217,6 +224,15 @@ struct dcn_mi_registers { uint32_t DCN_VM_AGP_BASE; uint32_t DCN_VM_AGP_BOT; uint32_t DCN_VM_AGP_TOP; + uint32_t CURSOR_SETTINS; + uint32_t CURSOR_SETTINGS; + uint32_t CURSOR_SURFACE_ADDRESS_HIGH; + uint32_t CURSOR_SURFACE_ADDRESS; + uint32_t CURSOR_SIZE; + uint32_t CURSOR_CONTROL; + uint32_t CURSOR_POSITION; + uint32_t CURSOR_HOT_SPOT; + uint32_t CURSOR_DST_OFFSET; }; #define MI_SF(reg_name, field_name, post_fix)\ @@ -362,7 +378,23 @@ struct dcn_mi_registers { MI_SF(DCHUBBUB_SDPIF_FB_OFFSET, SDPIF_FB_OFFSET, mask_sh),\ MI_SF(HUBPREQ0_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, MC_VM_SYSTEM_APERTURE_DEFAULT_SYSTEM, mask_sh),\ MI_SF(HUBPREQ0_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, mask_sh),\ - MI_SF(HUBPREQ0_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, mask_sh) + MI_SF(HUBPREQ0_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, mask_sh),\ + MI_SF(HUBPREQ0_CURSOR_SETTINS, CURSOR0_DST_Y_OFFSET, mask_sh), \ + MI_SF(HUBPREQ0_CURSOR_SETTINS, CURSOR0_CHUNK_HDL_ADJUST, mask_sh), \ + MI_SF(CURSOR0_CURSOR_SURFACE_ADDRESS_HIGH, CURSOR_SURFACE_ADDRESS_HIGH, mask_sh), \ + MI_SF(CURSOR0_CURSOR_SURFACE_ADDRESS, CURSOR_SURFACE_ADDRESS, mask_sh), \ + MI_SF(CURSOR0_CURSOR_SIZE, CURSOR_WIDTH, mask_sh), \ + MI_SF(CURSOR0_CURSOR_SIZE, CURSOR_HEIGHT, mask_sh), \ + MI_SF(CURSOR0_CURSOR_CONTROL, CURSOR_MODE, mask_sh), \ + MI_SF(CURSOR0_CURSOR_CONTROL, CURSOR_2X_MAGNIFY, mask_sh), \ + MI_SF(CURSOR0_CURSOR_CONTROL, CURSOR_PITCH, mask_sh), \ + MI_SF(CURSOR0_CURSOR_CONTROL, CURSOR_LINES_PER_CHUNK, mask_sh), \ + MI_SF(CURSOR0_CURSOR_CONTROL, CURSOR_ENABLE, mask_sh), \ + MI_SF(CURSOR0_CURSOR_POSITION, CURSOR_X_POSITION, mask_sh), \ + MI_SF(CURSOR0_CURSOR_POSITION, CURSOR_Y_POSITION, mask_sh), \ + MI_SF(CURSOR0_CURSOR_HOT_SPOT, CURSOR_HOT_SPOT_X, mask_sh), \ + MI_SF(CURSOR0_CURSOR_HOT_SPOT, CURSOR_HOT_SPOT_Y, mask_sh), \ + MI_SF(CURSOR0_CURSOR_DST_OFFSET, CURSOR_DST_X_OFFSET, mask_sh) #define DCN_MI_REG_FIELD_LIST(type) \ type HUBP_BLANK_EN;\ @@ -523,7 +555,24 @@ struct dcn_mi_registers { type PHYSICAL_PAGE_ADDR_LO32;\ type PHYSICAL_PAGE_NUMBER_MSB;\ type PHYSICAL_PAGE_NUMBER_LSB;\ - type LOGICAL_ADDR + type LOGICAL_ADDR;\ + type CURSOR0_DST_Y_OFFSET; \ + type CURSOR0_CHUNK_HDL_ADJUST; \ + type CURSOR_SURFACE_ADDRESS_HIGH; \ + type CURSOR_SURFACE_ADDRESS; \ + type CURSOR_WIDTH; \ + type CURSOR_HEIGHT; \ + type CURSOR_MODE; \ + type CURSOR_2X_MAGNIFY; \ + type CURSOR_PITCH; \ + type CURSOR_LINES_PER_CHUNK; \ + type CURSOR_ENABLE; \ + type CURSOR_X_POSITION; \ + type CURSOR_Y_POSITION; \ + type CURSOR_HOT_SPOT_X; \ + type CURSOR_HOT_SPOT_Y; \ + type CURSOR_DST_X_OFFSET; \ + type OUTPUT_FP struct dcn_mi_shift { DCN_MI_REG_FIELD_LIST(uint8_t); diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/mem_input.h b/drivers/gpu/drm/amd/display/dc/inc/hw/mem_input.h index 6cef9ad0af916..5c8e45ba8f45c 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/mem_input.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/mem_input.h @@ -72,6 +72,7 @@ struct mem_input { int opp_id; int mpcc_id; struct stutter_modes stutter_mode; + struct dc_cursor_attributes curs_attr; }; struct vm_system_aperture_param { @@ -163,6 +164,15 @@ struct mem_input_funcs { void (*set_blank)(struct mem_input *mi, bool blank); void (*set_hubp_blank_en)(struct mem_input *mi, bool blank); + void (*set_cursor_attributes)( + struct mem_input *mem_input, + const struct dc_cursor_attributes *attr); + + void (*set_cursor_position)( + struct mem_input *mem_input, + const struct dc_cursor_position *pos, + const struct dc_cursor_mi_param *param); + }; #endif diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/transform.h b/drivers/gpu/drm/amd/display/dc/inc/hw/transform.h index 785d397068320..f95621dfd4d48 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/transform.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/transform.h @@ -238,6 +238,17 @@ struct transform_funcs { void (*ipp_full_bypass)(struct transform *xfm_base); + void (*set_cursor_attributes)( + struct transform *xfm_base, + const struct dc_cursor_attributes *attr); + + void (*set_cursor_position)( + struct transform *xfm_base, + const struct dc_cursor_position *pos, + const struct dc_cursor_mi_param *param, + uint32_t width + ); + }; const uint16_t *get_filter_2tap_16p(void); From 8740196935625dfb171ab115120315060e4a8a41 Mon Sep 17 00:00:00 2001 From: Andrew Jiang Date: Mon, 25 Sep 2017 18:03:14 -0400 Subject: [PATCH 045/155] drm/amd/display: Move power control from link encoder to hwsequencer A recent commit moved the backlight control code along with the register defines, but did not move the power control code. This along with remnant fields in the dce110_link_enc_registers struct made it so that the code still compiled, but any attempts to access the LVTMA_PWRSEQ_STATE register led to reading from an address of 0. This patch corrects that. Also, rename blacklight_control to edp_backlight_control (Typo fix). Signed-off-by: Andrew Jiang Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_link.c | 17 +- .../drm/amd/display/dc/core/dc_link_hwss.c | 8 +- .../gpu/drm/amd/display/dc/dce/dce_hwseq.h | 18 +- .../drm/amd/display/dc/dce/dce_link_encoder.c | 171 +----------------- .../drm/amd/display/dc/dce/dce_link_encoder.h | 8 - .../display/dc/dce110/dce110_hw_sequencer.c | 155 +++++++++++++++- .../display/dc/dce110/dce110_hw_sequencer.h | 6 +- .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 3 +- .../drm/amd/display/dc/inc/hw/link_encoder.h | 2 - .../gpu/drm/amd/display/dc/inc/hw_sequencer.h | 7 +- .../gpu/drm/amd/display/dc/inc/link_hwss.h | 4 + .../display/dc/virtual/virtual_link_encoder.c | 5 - 12 files changed, 190 insertions(+), 214 deletions(-) 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 a58e61b6e9f9a..feb10be0ce4ca 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c @@ -78,14 +78,15 @@ static void destruct(struct dc_link *link) dc_sink_release(link->remote_sinks[i]); } -static struct gpio *get_hpd_gpio(const struct dc_link *link) +struct gpio *get_hpd_gpio(struct dc_bios *dcb, + struct graphics_object_id link_id, + struct gpio_service *gpio_service) { enum bp_result bp_result; - struct dc_bios *dcb = link->ctx->dc_bios; struct graphics_object_hpd_info hpd_info; struct gpio_pin_info pin_info; - if (dcb->funcs->get_hpd_info(dcb, link->link_id, &hpd_info) != BP_RESULT_OK) + if (dcb->funcs->get_hpd_info(dcb, link_id, &hpd_info) != BP_RESULT_OK) return NULL; bp_result = dcb->funcs->get_gpio_pin_info(dcb, @@ -97,7 +98,7 @@ static struct gpio *get_hpd_gpio(const struct dc_link *link) } return dal_gpio_service_create_irq( - link->ctx->gpio_service, + gpio_service, pin_info.offset, pin_info.mask); } @@ -153,7 +154,7 @@ static bool program_hpd_filter( } /* Obtain HPD handle */ - hpd = get_hpd_gpio(link); + hpd = get_hpd_gpio(link->ctx->dc_bios, link->link_id, link->ctx->gpio_service); if (!hpd) return result; @@ -186,7 +187,7 @@ static bool detect_sink(struct dc_link *link, enum dc_connection_type *type) struct gpio *hpd_pin; /* todo: may need to lock gpio access */ - hpd_pin = get_hpd_gpio(link); + hpd_pin = get_hpd_gpio(link->ctx->dc_bios, link->link_id, link->ctx->gpio_service); if (hpd_pin == NULL) goto hpd_gpio_failure; @@ -795,7 +796,7 @@ static enum hpd_source_id get_hpd_line( struct gpio *hpd; enum hpd_source_id hpd_id = HPD_SOURCEID_UNKNOWN; - hpd = get_hpd_gpio(link); + hpd = get_hpd_gpio(link->ctx->dc_bios, link->link_id, link->ctx->gpio_service); if (hpd) { switch (dal_irq_get_source(hpd)) { @@ -965,7 +966,7 @@ static bool construct( goto create_fail; } - hpd_gpio = get_hpd_gpio(link); + hpd_gpio = get_hpd_gpio(link->ctx->dc_bios, link->link_id, link->ctx->gpio_service); if (hpd_gpio != NULL) link->irq_source_hpd = dal_irq_get_source(hpd_gpio); 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 fa2250554be50..34b6d1cb151ee 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 @@ -89,12 +89,12 @@ void dp_enable_link_phy( if (dc_is_dp_sst_signal(signal)) { if (signal == SIGNAL_TYPE_EDP) { - link_enc->funcs->power_control(link_enc, true); + link->dc->hwss.edp_power_control(link->link_enc, true); link_enc->funcs->enable_dp_output( link_enc, link_settings, clock_source); - link->dc->hwss.backlight_control(link, true); + link->dc->hwss.edp_backlight_control(link, true); } else link_enc->funcs->enable_dp_output( link_enc, @@ -138,10 +138,10 @@ void dp_disable_link_phy(struct dc_link *link, enum signal_type signal) dp_receiver_power_ctrl(link, false); if (signal == SIGNAL_TYPE_EDP) { - link->dc->hwss.backlight_control(link, false); + link->dc->hwss.edp_backlight_control(link, false); edp_receiver_ready_T9(link); link->link_enc->funcs->disable_output(link->link_enc, signal, link); - link->link_enc->funcs->power_control(link->link_enc, false); + link->dc->hwss.edp_power_control(link->link_enc, false); } else link->link_enc->funcs->disable_output(link->link_enc, signal, link); diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h index 227c9b655b655..0a058e0c3fec8 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h @@ -391,23 +391,27 @@ struct dce_hwseq_registers { HWS_SF(BLND_, V_UPDATE_LOCK, BLND_DCP_GRPH_SURF_V_UPDATE_LOCK, mask_sh),\ HWS_SF(BLND_, CONTROL, BLND_MODE, mask_sh),\ HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh),\ + HWS_SF(, LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, mask_sh),\ HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, CRTC0_) #define HWSEQ_DCE10_MASK_SH_LIST(mask_sh)\ HWSEQ_DCEF_MASK_SH_LIST(mask_sh, DCFE_),\ HWSEQ_BLND_MASK_SH_LIST(mask_sh, BLND_),\ HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, CRTC0_), \ - HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh) + HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh), \ + HWS_SF(, LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, mask_sh) #define HWSEQ_DCE11_MASK_SH_LIST(mask_sh)\ HWSEQ_DCE10_MASK_SH_LIST(mask_sh),\ SF(DCFEV_CLOCK_CONTROL, DCFEV_CLOCK_ENABLE, mask_sh),\ HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh),\ + HWS_SF(, LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, mask_sh),\ HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, CRTC0_) #define HWSEQ_DCE112_MASK_SH_LIST(mask_sh)\ HWSEQ_DCE10_MASK_SH_LIST(mask_sh),\ HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh),\ + HWS_SF(, LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, mask_sh),\ HWSEQ_PHYPLL_MASK_SH_LIST(mask_sh, CRTC0_) #define HWSEQ_GFX9_DCHUB_MASK_SH_LIST(mask_sh)\ @@ -416,7 +420,8 @@ struct dce_hwseq_registers { SF(DCHUB_AGP_BASE, AGP_BASE, mask_sh),\ SF(DCHUB_AGP_BOT, AGP_BOT, mask_sh),\ SF(DCHUB_AGP_TOP, AGP_TOP, mask_sh), \ - HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh) + HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh), \ + HWS_SF(, LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, mask_sh) #define HWSEQ_DCE12_MASK_SH_LIST(mask_sh)\ HWSEQ_DCEF_MASK_SH_LIST(mask_sh, DCFE0_DCFE_),\ @@ -424,7 +429,8 @@ struct dce_hwseq_registers { HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, CRTC0_),\ HWSEQ_PHYPLL_MASK_SH_LIST(mask_sh, CRTC0_),\ HWSEQ_GFX9_DCHUB_MASK_SH_LIST(mask_sh), \ - HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh) + HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh), \ + HWS_SF(, LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, mask_sh) #define HWSEQ_DCN_MASK_SH_LIST(mask_sh)\ HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, OTG0_),\ @@ -489,7 +495,8 @@ struct dce_hwseq_registers { HWS_SF(, DOMAIN6_PG_STATUS, DOMAIN6_PGFSM_PWR_STATUS, mask_sh), \ HWS_SF(, DOMAIN7_PG_STATUS, DOMAIN7_PGFSM_PWR_STATUS, mask_sh), \ HWS_SF(, DC_IP_REQUEST_CNTL, IP_REQUEST_EN, mask_sh), \ - HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh) + HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh), \ + HWS_SF(, LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, mask_sh) #define HWSEQ_REG_FIELD_LIST(type) \ type DCFE_CLOCK_ENABLE; \ @@ -520,7 +527,8 @@ struct dce_hwseq_registers { type LOGICAL_ADDR; \ type ENABLE_L1_TLB;\ type SYSTEM_ACCESS_MODE;\ - type LVTMA_BLON; + type LVTMA_BLON;\ + type LVTMA_PWRSEQ_TARGET_STATE_R; #define HWSEQ_DCN_REG_FIELD_LIST(type) \ type VUPDATE_NO_LOCK_EVENT_CLEAR; \ diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c index 1cb727bdaa562..0cf0fff74d44f 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c @@ -82,13 +82,6 @@ #define DCE110_DIG_FE_SOURCE_SELECT_DIGF 0x20 #define DCE110_DIG_FE_SOURCE_SELECT_DIGG 0x40 -/* all values are in milliseconds */ -/* For eDP, after power-up/power/down, - * 300/500 msec max. delay from LCDVCC to black video generation */ -#define PANEL_POWER_UP_TIMEOUT 300 -#define PANEL_POWER_DOWN_TIMEOUT 500 -#define HPD_CHECK_INTERVAL 10 - /* Minimum pixel clock, in KHz. For TMDS signal is 25.00 MHz */ #define TMDS_MIN_PIXEL_CLOCK 25000 /* Maximum pixel clock, in KHz. For TMDS signal is 165.00 MHz */ @@ -122,7 +115,6 @@ static const struct link_encoder_funcs dce110_lnk_enc_funcs = { .psr_program_dp_dphy_fast_training = dce110_psr_program_dp_dphy_fast_training, .psr_program_secondary_packet = dce110_psr_program_secondary_packet, - .power_control = dce110_link_encoder_edp_power_control, .connect_dig_be_to_fe = dce110_link_encoder_connect_dig_be_to_fe, .enable_hpd = dce110_link_encoder_enable_hpd, .disable_hpd = dce110_link_encoder_disable_hpd, @@ -492,165 +484,6 @@ static void configure_encoder( REG_UPDATE(DP_DPHY_SCRAM_CNTL, DPHY_SCRAMBLER_ADVANCE, 1); } -static bool is_panel_powered_on(struct dce110_link_encoder *enc110) -{ - bool ret; - uint32_t value; - - REG_GET(LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, &value); - ret = value; - - return ret == 1; -} - - -/* TODO duplicate of dc_link.c version */ -static struct gpio *get_hpd_gpio(const struct link_encoder *enc) -{ - enum bp_result bp_result; - struct dc_bios *dcb = enc->ctx->dc_bios; - struct graphics_object_hpd_info hpd_info; - struct gpio_pin_info pin_info; - - if (dcb->funcs->get_hpd_info(dcb, enc->connector, &hpd_info) != BP_RESULT_OK) - return NULL; - - bp_result = dcb->funcs->get_gpio_pin_info(dcb, - hpd_info.hpd_int_gpio_uid, &pin_info); - - if (bp_result != BP_RESULT_OK) { - ASSERT(bp_result == BP_RESULT_NORECORD); - return NULL; - } - - return dal_gpio_service_create_irq( - enc->ctx->gpio_service, - pin_info.offset, - pin_info.mask); -} - -/* - * @brief - * eDP only. - */ -static void link_encoder_edp_wait_for_hpd_ready( - struct dce110_link_encoder *enc110, - bool power_up) -{ - struct dc_context *ctx = enc110->base.ctx; - struct graphics_object_id connector = enc110->base.connector; - struct gpio *hpd; - bool edp_hpd_high = false; - uint32_t time_elapsed = 0; - uint32_t timeout = power_up ? - PANEL_POWER_UP_TIMEOUT : PANEL_POWER_DOWN_TIMEOUT; - - if (dal_graphics_object_id_get_connector_id(connector) != - CONNECTOR_ID_EDP) { - BREAK_TO_DEBUGGER(); - return; - } - - if (!power_up) - /* from KV, we will not HPD low after turning off VCC - - * instead, we will check the SW timer in power_up(). */ - return; - - /* when we power on/off the eDP panel, - * we need to wait until SENSE bit is high/low */ - - /* obtain HPD */ - /* TODO what to do with this? */ - hpd = get_hpd_gpio(&enc110->base); - - if (!hpd) { - BREAK_TO_DEBUGGER(); - return; - } - - dal_gpio_open(hpd, GPIO_MODE_INTERRUPT); - - /* wait until timeout or panel detected */ - - do { - uint32_t detected = 0; - - dal_gpio_get_value(hpd, &detected); - - if (!(detected ^ power_up)) { - edp_hpd_high = true; - break; - } - - msleep(HPD_CHECK_INTERVAL); - - time_elapsed += HPD_CHECK_INTERVAL; - } while (time_elapsed < timeout); - - dal_gpio_close(hpd); - - dal_gpio_destroy_irq(&hpd); - - if (false == edp_hpd_high) { - dm_logger_write(ctx->logger, LOG_ERROR, - "%s: wait timed out!\n", __func__); - } -} - -/* - * @brief - * eDP only. Control the power of the eDP panel. - */ -void dce110_link_encoder_edp_power_control( - struct link_encoder *enc, - bool power_up) -{ - struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc); - struct dc_context *ctx = enc110->base.ctx; - struct bp_transmitter_control cntl = { 0 }; - enum bp_result bp_result; - - if (dal_graphics_object_id_get_connector_id(enc110->base.connector) != - CONNECTOR_ID_EDP) { - BREAK_TO_DEBUGGER(); - return; - } - - if ((power_up && !is_panel_powered_on(enc110)) || - (!power_up && is_panel_powered_on(enc110))) { - - /* Send VBIOS command to prompt eDP panel power */ - - dm_logger_write(ctx->logger, LOG_HW_RESUME_S3, - "%s: Panel Power action: %s\n", - __func__, (power_up ? "On":"Off")); - - cntl.action = power_up ? - TRANSMITTER_CONTROL_POWER_ON : - TRANSMITTER_CONTROL_POWER_OFF; - cntl.transmitter = enc110->base.transmitter; - cntl.connector_obj_id = enc110->base.connector; - cntl.coherent = false; - cntl.lanes_number = LANE_COUNT_FOUR; - cntl.hpd_sel = enc110->base.hpd_source; - - bp_result = link_transmitter_control(enc110, &cntl); - - if (BP_RESULT_OK != bp_result) { - - dm_logger_write(ctx->logger, LOG_ERROR, - "%s: Panel Power bp_result: %d\n", - __func__, bp_result); - } - } else { - dm_logger_write(ctx->logger, LOG_HW_RESUME_S3, - "%s: Skipping Panel Power action: %s\n", - __func__, (power_up ? "On":"Off")); - } - - link_encoder_edp_wait_for_hpd_ready(enc110, true); -} - static void aux_initialize( struct dce110_link_encoder *enc110) { @@ -1018,7 +851,7 @@ void dce110_link_encoder_hw_init( ASSERT(result == BP_RESULT_OK); } else if (enc110->base.connector.id == CONNECTOR_ID_EDP) { - enc->funcs->power_control(&enc110->base, true); + ctx->dc->hwss.edp_power_control(enc, true); } aux_initialize(enc110); @@ -1218,7 +1051,7 @@ void dce110_link_encoder_disable_output( return; } if (enc110->base.connector.id == CONNECTOR_ID_EDP) - ctx->dc->hwss.backlight_control(link, false); + ctx->dc->hwss.edp_backlight_control(link, false); /* Power-down RX and disable GPU PHY should be paired. * Disabling PHY without powering down RX may cause * symbol lock loss, on which we will get DP Sink interrupt. */ diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h index c65def5f6a441..494067dedd03a 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h @@ -114,10 +114,6 @@ struct dce110_link_enc_hpd_registers { }; struct dce110_link_enc_registers { - /* Backlight registers */ - uint32_t LVTMA_PWRSEQ_CNTL; - uint32_t LVTMA_PWRSEQ_STATE; - /* DMCU registers */ uint32_t MASTER_COMM_DATA_REG1; uint32_t MASTER_COMM_DATA_REG2; @@ -250,10 +246,6 @@ void dce110_link_encoder_update_mst_stream_allocation_table( struct link_encoder *enc, const struct link_mst_stream_allocation_table *table); -void dce110_link_encoder_edp_power_control( - struct link_encoder *enc, - bool power_up); - void dce110_link_encoder_connect_dig_be_to_fe( struct link_encoder *enc, enum engine_id engine, diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c index f28fce6e6ba4e..a891e387ed7b5 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c @@ -32,6 +32,7 @@ #include "dce110_hw_sequencer.h" #include "dce110_timing_generator.h" #include "dce/dce_hwseq.h" +#include "gpio_service_interface.h" #ifdef ENABLE_FBC #include "dce110_compressor.h" @@ -45,10 +46,10 @@ #include "transform.h" #include "stream_encoder.h" #include "link_encoder.h" +#include "link_hwss.h" #include "clock_source.h" #include "abm.h" #include "audio.h" -#include "dce/dce_hwseq.h" #include "reg_helper.h" /* include DCE11 register header files */ @@ -56,6 +57,15 @@ #include "dce/dce_11_0_sh_mask.h" #include "custom_float.h" +/* + * All values are in milliseconds; + * For eDP, after power-up/power/down, + * 300/500 msec max. delay from LCDVCC to black video generation + */ +#define PANEL_POWER_UP_TIMEOUT 300 +#define PANEL_POWER_DOWN_TIMEOUT 500 +#define HPD_CHECK_INTERVAL 10 + #define CTX \ hws->ctx #define REG(reg)\ @@ -780,25 +790,150 @@ static bool is_panel_backlight_on(struct dce_hwseq *hws) return value; } +static bool is_panel_powered_on(struct dce_hwseq *hws) +{ + uint32_t value; + + REG_GET(LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, &value); + return value == 1; +} + static enum bp_result link_transmitter_control( - struct dc_link *link, + struct dc_bios *bios, struct bp_transmitter_control *cntl) { enum bp_result result; - struct dc_bios *bp = link->dc->ctx->dc_bios; - result = bp->funcs->transmitter_control(bp, cntl); + result = bios->funcs->transmitter_control(bios, cntl); return result; } +/* + * @brief + * eDP only. + */ +void hwss_edp_wait_for_hpd_ready( + struct link_encoder *enc, + bool power_up) +{ + struct dc_context *ctx = enc->ctx; + struct graphics_object_id connector = enc->connector; + struct gpio *hpd; + bool edp_hpd_high = false; + uint32_t time_elapsed = 0; + uint32_t timeout = power_up ? + PANEL_POWER_UP_TIMEOUT : PANEL_POWER_DOWN_TIMEOUT; + + if (dal_graphics_object_id_get_connector_id(connector) + != CONNECTOR_ID_EDP) { + BREAK_TO_DEBUGGER(); + return; + } + + if (!power_up) + /* + * From KV, we will not HPD low after turning off VCC - + * instead, we will check the SW timer in power_up(). + */ + return; + + /* + * When we power on/off the eDP panel, + * we need to wait until SENSE bit is high/low. + */ + + /* obtain HPD */ + /* TODO what to do with this? */ + hpd = get_hpd_gpio(ctx->dc_bios, connector, ctx->gpio_service); + + if (!hpd) { + BREAK_TO_DEBUGGER(); + return; + } + + dal_gpio_open(hpd, GPIO_MODE_INTERRUPT); + + /* wait until timeout or panel detected */ + + do { + uint32_t detected = 0; + + dal_gpio_get_value(hpd, &detected); + + if (!(detected ^ power_up)) { + edp_hpd_high = true; + break; + } + + msleep(HPD_CHECK_INTERVAL); + + time_elapsed += HPD_CHECK_INTERVAL; + } while (time_elapsed < timeout); + + dal_gpio_close(hpd); + + dal_gpio_destroy_irq(&hpd); + + if (false == edp_hpd_high) { + dm_logger_write(ctx->logger, LOG_ERROR, + "%s: wait timed out!\n", __func__); + } +} + +void hwss_edp_power_control( + struct link_encoder *enc, + bool power_up) +{ + struct dc_context *ctx = enc->ctx; + struct dce_hwseq *hwseq = ctx->dc->hwseq; + struct bp_transmitter_control cntl = { 0 }; + enum bp_result bp_result; + + + if (dal_graphics_object_id_get_connector_id(enc->connector) + != CONNECTOR_ID_EDP) { + BREAK_TO_DEBUGGER(); + return; + } + + if (power_up != is_panel_powered_on(hwseq)) { + /* Send VBIOS command to prompt eDP panel power */ + + dm_logger_write(ctx->logger, LOG_HW_RESUME_S3, + "%s: Panel Power action: %s\n", + __func__, (power_up ? "On":"Off")); + + cntl.action = power_up ? + TRANSMITTER_CONTROL_POWER_ON : + TRANSMITTER_CONTROL_POWER_OFF; + cntl.transmitter = enc->transmitter; + cntl.connector_obj_id = enc->connector; + cntl.coherent = false; + cntl.lanes_number = LANE_COUNT_FOUR; + cntl.hpd_sel = enc->hpd_source; + + bp_result = link_transmitter_control(ctx->dc_bios, &cntl); + + if (bp_result != BP_RESULT_OK) + dm_logger_write(ctx->logger, LOG_ERROR, + "%s: Panel Power bp_result: %d\n", + __func__, bp_result); + } else { + dm_logger_write(ctx->logger, LOG_HW_RESUME_S3, + "%s: Skipping Panel Power action: %s\n", + __func__, (power_up ? "On":"Off")); + } + + hwss_edp_wait_for_hpd_ready(enc, true); +} /*todo: cloned in stream enc, fix*/ /* * @brief * eDP only. Control the backlight of the eDP panel */ -void hwss_blacklight_control( +void hwss_edp_backlight_control( struct dc_link *link, bool enable) { @@ -828,6 +963,7 @@ void hwss_blacklight_control( cntl.action = enable ? TRANSMITTER_CONTROL_BACKLIGHT_ON : TRANSMITTER_CONTROL_BACKLIGHT_OFF; + /*cntl.engine_id = ctx->engine;*/ cntl.transmitter = link->link_enc->transmitter; cntl.connector_obj_id = link->link_enc->connector; @@ -846,7 +982,7 @@ void hwss_blacklight_control( * Enable it in the future if necessary. */ /* dc_service_sleep_in_milliseconds(50); */ - link_transmitter_control(link, &cntl); + link_transmitter_control(link->dc->ctx->dc_bios, &cntl); } void dce110_disable_stream(struct pipe_ctx *pipe_ctx) @@ -886,7 +1022,7 @@ void dce110_disable_stream(struct pipe_ctx *pipe_ctx) /* blank at encoder level */ if (dc_is_dp_signal(pipe_ctx->stream->signal)) { if (pipe_ctx->stream->sink->link->connector_signal == SIGNAL_TYPE_EDP) - hwss_blacklight_control(link, false); + hwss_edp_backlight_control(link, false); pipe_ctx->stream_res.stream_enc->funcs->dp_blank(pipe_ctx->stream_res.stream_enc); } link->link_enc->funcs->connect_dig_be_to_fe( @@ -908,7 +1044,7 @@ void dce110_unblank_stream(struct pipe_ctx *pipe_ctx, params.link_settings.link_rate = link_settings->link_rate; pipe_ctx->stream_res.stream_enc->funcs->dp_unblank(pipe_ctx->stream_res.stream_enc, ¶ms); if (link->connector_signal == SIGNAL_TYPE_EDP) - hwss_blacklight_control(link, true); + hwss_edp_backlight_control(link, true); } @@ -2821,7 +2957,8 @@ static const struct hw_sequencer_funcs dce110_funcs = { .wait_for_mpcc_disconnect = dce110_wait_for_mpcc_disconnect, .ready_shared_resources = ready_shared_resources, .optimize_shared_resources = optimize_shared_resources, - .backlight_control = hwss_blacklight_control + .edp_backlight_control = hwss_edp_backlight_control, + .edp_power_control = hwss_edp_power_control, }; void dce110_hw_sequencer_construct(struct dc *dc) diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h index 3e95f7f92c737..a1e964af60ac1 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h @@ -69,7 +69,11 @@ uint32_t dce110_get_min_vblank_time_us(const struct dc_state *context); void dp_receiver_power_ctrl(struct dc_link *link, bool on); -void hwss_blacklight_control( +void hwss_edp_power_control( + struct link_encoder *enc, + bool power_up); + +void hwss_edp_backlight_control( struct dc_link *link, bool enable); diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index 014911ebdbd6f..efa3f6f97bafb 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -2903,7 +2903,8 @@ static const struct hw_sequencer_funcs dcn10_funcs = { .wait_for_mpcc_disconnect = dcn10_wait_for_mpcc_disconnect, .ready_shared_resources = ready_shared_resources, .optimize_shared_resources = optimize_shared_resources, - .backlight_control = hwss_blacklight_control + .edp_backlight_control = hwss_edp_backlight_control, + .edp_power_control = hwss_edp_power_control }; diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h b/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h index 6cd6bc7d15fbe..3d33bcda70594 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h @@ -123,8 +123,6 @@ struct link_encoder_funcs { bool exit_link_training_required); void (*psr_program_secondary_packet)(struct link_encoder *enc, unsigned int sdp_transmit_line_num_deadline); - void (*power_control) (struct link_encoder *enc, - bool power_up); void (*connect_dig_be_to_fe)(struct link_encoder *enc, enum engine_id engine, bool connect); diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h index 210874f37722a..bf3ab5d7398e3 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h @@ -28,6 +28,7 @@ #include "dc_types.h" #include "clock_source.h" #include "inc/hw/timing_generator.h" +#include "inc/hw/link_encoder.h" #include "core_status.h" enum pipe_gating_control { @@ -176,8 +177,10 @@ struct hw_sequencer_funcs { void (*ready_shared_resources)(struct dc *dc, struct dc_state *context); void (*optimize_shared_resources)(struct dc *dc); - - void (*backlight_control)( + void (*edp_power_control)( + struct link_encoder *enc, + bool enable); + void (*edp_backlight_control)( struct dc_link *link, bool enable); }; diff --git a/drivers/gpu/drm/amd/display/dc/inc/link_hwss.h b/drivers/gpu/drm/amd/display/dc/inc/link_hwss.h index f7994cfc850d6..f2b8c9a376d5a 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/link_hwss.h +++ b/drivers/gpu/drm/amd/display/dc/inc/link_hwss.h @@ -40,6 +40,10 @@ enum dc_status core_link_write_dpcd( const uint8_t *data, uint32_t size); +struct gpio *get_hpd_gpio(struct dc_bios *dcb, + struct graphics_object_id link_id, + struct gpio_service *gpio_service); + void dp_enable_link_phy( struct dc_link *link, enum signal_type signal, diff --git a/drivers/gpu/drm/amd/display/dc/virtual/virtual_link_encoder.c b/drivers/gpu/drm/amd/display/dc/virtual/virtual_link_encoder.c index 4f405348130f2..88c2bde3f0392 100644 --- a/drivers/gpu/drm/amd/display/dc/virtual/virtual_link_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/virtual/virtual_link_encoder.c @@ -73,10 +73,6 @@ static void virtual_link_encoder_update_mst_stream_allocation_table( struct link_encoder *enc, const struct link_mst_stream_allocation_table *table) {} -static void virtual_link_encoder_edp_power_control( - struct link_encoder *enc, - bool power_up) {} - static void virtual_link_encoder_connect_dig_be_to_fe( struct link_encoder *enc, enum engine_id engine, @@ -102,7 +98,6 @@ static const struct link_encoder_funcs virtual_lnk_enc_funcs = { .dp_set_phy_pattern = virtual_link_encoder_dp_set_phy_pattern, .update_mst_stream_allocation_table = virtual_link_encoder_update_mst_stream_allocation_table, - .power_control = virtual_link_encoder_edp_power_control, .connect_dig_be_to_fe = virtual_link_encoder_connect_dig_be_to_fe, .destroy = virtual_link_encoder_destroy }; From 6512387a54357c5d3fbea8995d8879ea817a5ec6 Mon Sep 17 00:00:00 2001 From: Tony Cheng Date: Wed, 27 Sep 2017 09:20:51 -0400 Subject: [PATCH 046/155] drm/amd/display: align DCLK to voltage level in past program SMU will use all voltage headroom. RV does not if DAL need higher voltage for DCFCLK or DISPCLK, also increase FCLK to improve stutter as voltage is already Signed-off-by: Tony Cheng Reviewed-by: Charlene Liu Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c | 4 ++++ drivers/gpu/drm/amd/display/dc/dc.h | 1 + drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c | 1 + 3 files changed, 6 insertions(+) diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c index cf474eb1cde87..9337ccadc3211 100644 --- a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c +++ b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c @@ -1049,6 +1049,10 @@ bool dcn_validate_bandwidth( else bw_consumed = v->fabric_and_dram_bandwidth_vmax0p9; + if (bw_consumed < v->fabric_and_dram_bandwidth) + if (dc->debug.voltage_align_fclk) + bw_consumed = v->fabric_and_dram_bandwidth; + display_pipe_configuration(v); calc_wm_sets_and_perf_params(context, v); context->bw.dcn.calc_clk.fclk_khz = (int)(bw_consumed * 1000000 / diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index cf9cd108539fc..dbbe1d621bee2 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -188,6 +188,7 @@ struct dc_debug { enum dcc_option disable_dcc; enum pipe_split_policy pipe_split_policy; bool force_single_disp_pipe_split; + bool voltage_align_fclk; bool disable_dfs_bypass; bool disable_dpp_power_gate; diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c index 30c275e057964..4018e831eb4ba 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c @@ -428,6 +428,7 @@ static const struct dc_debug debug_defaults_drv = { .pipe_split_policy = MPC_SPLIT_AVOID_MULT_DISP, .disable_dcc = DCC_ENABLE, + .voltage_align_fclk = true, }; static const struct dc_debug debug_defaults_diags = { From dcf298c3137ace22b92c584781e6092e4eb273fb Mon Sep 17 00:00:00 2001 From: Wenjing Liu Date: Mon, 25 Sep 2017 14:53:14 -0400 Subject: [PATCH 047/155] drm/amd/display: disconnect on HPD low even if edid is the same [Description] There are many occasions we need to retrieve sink capability and notify connectivity change to os even if edid is not changed on a HPD toggle. (HDMI2.0 display needs re-enable link on every hpd, display changes other capability outside from edid need to be queried again and possibly reset the mode, etc.) In these cases we cannot keep the same sink without letting DM know. Signed-off-by: Wenjing Liu Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_link.c | 42 ++++--------------- 1 file changed, 9 insertions(+), 33 deletions(-) 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 feb10be0ce4ca..e414e4770789f 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c @@ -566,6 +566,8 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason) link->local_sink) return true; + link_disconnect_sink(link); + if (new_connection_type != dc_connection_none) { link->type = new_connection_type; @@ -656,28 +658,15 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason) return false; } - if (link->local_sink) { - edid_status = dm_helpers_read_local_edid( - link->ctx, - link, - sink); + sink->dongle_max_pix_clk = sink_caps.max_hdmi_pixel_clock; + sink->converter_disable_audio = converter_disable_audio; - if (edid_status == EDID_OK) { - // Edid is not the same, to update the local sink with new sink. - sink->dongle_max_pix_clk = sink_caps.max_hdmi_pixel_clock; - sink->converter_disable_audio = converter_disable_audio; - link->local_sink = sink; - } - } else { - sink->dongle_max_pix_clk = sink_caps.max_hdmi_pixel_clock; - sink->converter_disable_audio = converter_disable_audio; - link->local_sink = sink; + link->local_sink = sink; - edid_status = dm_helpers_read_local_edid( + edid_status = dm_helpers_read_local_edid( link->ctx, link, sink); - } switch (edid_status) { case EDID_BAD_CHECKSUM: @@ -758,28 +747,15 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason) if (link->type == dc_connection_mst_branch) { LINK_INFO("link=%d, mst branch is now Disconnected\n", link->link_index); + dm_helpers_dp_mst_stop_top_mgr(link->ctx, link); link->mst_stream_alloc_table.stream_count = 0; memset(link->mst_stream_alloc_table.stream_allocations, 0, sizeof(link->mst_stream_alloc_table.stream_allocations)); } - if (link->local_sink) { - sink = link->local_sink; - edid_status = dm_helpers_read_local_edid( - link->ctx, - link, - sink); - if (edid_status != EDID_OK && edid_status != EDID_THE_SAME) { - link_disconnect_sink(link); - link->type = dc_connection_none; - sink_caps.signal = SIGNAL_TYPE_NONE; - } - } else { - link_disconnect_sink(link); - link->type = dc_connection_none; - sink_caps.signal = SIGNAL_TYPE_NONE; - } + link->type = dc_connection_none; + sink_caps.signal = SIGNAL_TYPE_NONE; } LINK_INFO("link=%d, dc_sink_in=%p is now %s\n", From 441ad741739e9092f6af231a539781118e23d6df Mon Sep 17 00:00:00 2001 From: Eric Yang Date: Wed, 27 Sep 2017 11:44:43 -0400 Subject: [PATCH 048/155] drm/amd/display: Add override for reporting wm ranges For verification of watermark select with SMU team, proper implementation will follow Signed-off-by: Eric Yang Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/calcs/dcn_calcs.c | 47 +++++++++++++++++++ drivers/gpu/drm/amd/display/dc/dc.h | 6 +++ .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 3 ++ .../drm/amd/display/dc/dcn10/dcn10_resource.c | 1 + 4 files changed, 57 insertions(+) diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c index 9337ccadc3211..6318f9f69c928 100644 --- a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c +++ b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c @@ -1441,6 +1441,53 @@ void dcn_bw_notify_pplib_of_wm_ranges(struct dc *dc) ranges.writer_wm_sets[3].min_drain_clk_khz = max_fclk_khz; ranges.writer_wm_sets[3].max_drain_clk_khz = max_fclk_khz; + if (dc->debug.pplib_wm_report_mode == WM_REPORT_OVERRIDE) { + ranges.reader_wm_sets[0].wm_inst = WM_A; + ranges.reader_wm_sets[0].min_drain_clk_khz = 300000; + ranges.reader_wm_sets[0].max_drain_clk_khz = 654000; + ranges.reader_wm_sets[0].min_fill_clk_khz = 800000; + ranges.reader_wm_sets[0].max_fill_clk_khz = 800000; + ranges.writer_wm_sets[0].wm_inst = WM_A; + ranges.writer_wm_sets[0].min_fill_clk_khz = 200000; + ranges.writer_wm_sets[0].max_fill_clk_khz = 757000; + ranges.writer_wm_sets[0].min_drain_clk_khz = 800000; + ranges.writer_wm_sets[0].max_drain_clk_khz = 800000; + + ranges.reader_wm_sets[1].wm_inst = WM_B; + ranges.reader_wm_sets[1].min_drain_clk_khz = 300000; + ranges.reader_wm_sets[1].max_drain_clk_khz = 654000; + ranges.reader_wm_sets[1].min_fill_clk_khz = 933000; + ranges.reader_wm_sets[1].max_fill_clk_khz = 933000; + ranges.writer_wm_sets[1].wm_inst = WM_B; + ranges.writer_wm_sets[1].min_fill_clk_khz = 200000; + ranges.writer_wm_sets[1].max_fill_clk_khz = 757000; + ranges.writer_wm_sets[1].min_drain_clk_khz = 933000; + ranges.writer_wm_sets[1].max_drain_clk_khz = 933000; + + + ranges.reader_wm_sets[2].wm_inst = WM_C; + ranges.reader_wm_sets[2].min_drain_clk_khz = 300000; + ranges.reader_wm_sets[2].max_drain_clk_khz = 654000; + ranges.reader_wm_sets[2].min_fill_clk_khz = 1067000; + ranges.reader_wm_sets[2].max_fill_clk_khz = 1067000; + ranges.writer_wm_sets[2].wm_inst = WM_C; + ranges.writer_wm_sets[2].min_fill_clk_khz = 200000; + ranges.writer_wm_sets[2].max_fill_clk_khz = 757000; + ranges.writer_wm_sets[2].min_drain_clk_khz = 1067000; + ranges.writer_wm_sets[2].max_drain_clk_khz = 1067000; + + ranges.reader_wm_sets[3].wm_inst = WM_D; + ranges.reader_wm_sets[3].min_drain_clk_khz = 300000; + ranges.reader_wm_sets[3].max_drain_clk_khz = 654000; + ranges.reader_wm_sets[3].min_fill_clk_khz = 1200000; + ranges.reader_wm_sets[3].max_fill_clk_khz = 1200000; + ranges.writer_wm_sets[3].wm_inst = WM_D; + ranges.writer_wm_sets[3].min_fill_clk_khz = 200000; + ranges.writer_wm_sets[3].max_fill_clk_khz = 757000; + ranges.writer_wm_sets[3].min_drain_clk_khz = 1200000; + ranges.writer_wm_sets[3].max_drain_clk_khz = 1200000; + } + /* Notify PP Lib/SMU which Watermarks to use for which clock ranges */ pp->set_wm_ranges(&pp->pp_smu, &ranges); } diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index dbbe1d621bee2..d624554efbc7c 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -173,6 +173,11 @@ enum pipe_split_policy { MPC_SPLIT_AVOID_MULT_DISP = 2, }; +enum wm_report_mode { + WM_REPORT_DEFAULT = 0, + WM_REPORT_OVERRIDE = 1, +}; + struct dc_debug { bool surface_visual_confirm; bool sanity_checks; @@ -194,6 +199,7 @@ struct dc_debug { bool disable_dpp_power_gate; bool disable_hubp_power_gate; bool disable_pplib_wm_range; + enum wm_report_mode pplib_wm_report_mode; bool use_dml_wm; unsigned int min_disp_clk_khz; int sr_exit_time_dpm0_ns; diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index efa3f6f97bafb..86cfab33feea8 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -2451,6 +2451,9 @@ static void optimize_shared_resources(struct dc *dc) /* S0i2 message */ dcn10_pplib_apply_display_requirements(dc, dc->current_state); } + + if (dc->debug.pplib_wm_report_mode == WM_REPORT_OVERRIDE) + dcn_bw_notify_pplib_of_wm_ranges(dc); } static void ready_shared_resources(struct dc *dc, struct dc_state *context) diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c index 4018e831eb4ba..5d618e68a744d 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c @@ -424,6 +424,7 @@ static const struct dc_debug debug_defaults_drv = { .disable_pplib_clock_request = true, .disable_pplib_wm_range = false, + .pplib_wm_report_mode = WM_REPORT_DEFAULT, .use_dml_wm = false, .pipe_split_policy = MPC_SPLIT_AVOID_MULT_DISP, From ed23cba20d011e1867dea69a45bda88a088585b6 Mon Sep 17 00:00:00 2001 From: Charlene Liu Date: Wed, 27 Sep 2017 16:08:47 -0400 Subject: [PATCH 049/155] drm/amd/display: soc_bound_box -update DML based on HW. Signed-off-by: Charlene Liu Reviewed-by: Anthony Koo Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.c b/drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.c index 0745366d80bca..d40f6ae9622c5 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.c +++ b/drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.c @@ -68,7 +68,6 @@ double dml_socbb_return_bw_mhz(struct _vcs_dpi_soc_bounding_box_st *box, enum vo return_bw = dml_min( ((double) box->return_bus_width_bytes) * state.dcfclk_mhz, - state.dram_bw_per_chan_gbps * 1000.0 * (double) box->num_chans - * box->ideal_dram_bw_after_urgent_percent / 100.0); + state.dram_bw_per_chan_gbps * 1000.0 * box->ideal_dram_bw_after_urgent_percent / 100.0); return return_bw; } From c73b046f86d0ceac52bfa0a035796c8c017a2de5 Mon Sep 17 00:00:00 2001 From: Yue Hin Lau Date: Wed, 27 Sep 2017 15:34:35 -0400 Subject: [PATCH 050/155] drm/amd/display: Expose some mem_input functions for reuse Signed-off-by: Yue Hin Lau Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h | 1 - .../amd/display/dc/dcn10/dcn10_mem_input.c | 26 ++++---- .../amd/display/dc/dcn10/dcn10_mem_input.h | 60 +++++++++++++++++++ 3 files changed, 73 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h index 7fecdb19761d0..889f91cf47cf7 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h @@ -113,7 +113,6 @@ SRI(FORMAT_CONTROL, CNVC_CFG, id), \ SRI(CNVC_SURFACE_PIXEL_FORMAT, CNVC_CFG, id), \ SRI(CURSOR0_CONTROL, CNVC_CUR, id), \ - SRI(CURSOR0_CONTROL, CNVC_CUR, id), \ SRI(CURSOR0_COLOR0, CNVC_CUR, id), \ SRI(CURSOR0_COLOR1, CNVC_CUR, id) diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.c index efa1aca187adf..b61f41c613589 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.c @@ -38,7 +38,7 @@ #define FN(reg_name, field_name) \ mi->mi_shift->field_name, mi->mi_mask->field_name -static void min10_set_blank(struct mem_input *mem_input, bool blank) +void min10_set_blank(struct mem_input *mem_input, bool blank) { struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input); uint32_t blank_en = blank ? 1 : 0; @@ -87,7 +87,7 @@ static void min10_vready_workaround(struct mem_input *mem_input, REG_WRITE(HUBPREQ_DEBUG_DB, value); } -static void min10_program_tiling( +void min10_program_tiling( struct dcn10_mem_input *mi, const union dc_tiling_info *info, const enum surface_pixel_format pixel_format) @@ -107,7 +107,7 @@ static void min10_program_tiling( PIPE_ALIGNED, info->gfx9.pipe_aligned); } -static void min10_program_size_and_rotation( +void min10_program_size_and_rotation( struct dcn10_mem_input *mi, enum dc_rotation_angle rotation, enum surface_pixel_format format, @@ -169,7 +169,7 @@ static void min10_program_size_and_rotation( H_MIRROR_EN, mirror); } -static void min10_program_pixel_format( +void min10_program_pixel_format( struct dcn10_mem_input *mi, enum surface_pixel_format format) { @@ -245,7 +245,7 @@ static void min10_program_pixel_format( /* don't see the need of program the xbar in DCN 1.0 */ } -static bool min10_program_surface_flip_and_addr( +bool min10_program_surface_flip_and_addr( struct mem_input *mem_input, const struct dc_plane_address *address, bool flip_immediate) @@ -395,7 +395,7 @@ static bool min10_program_surface_flip_and_addr( return true; } -static void min10_dcc_control(struct mem_input *mem_input, bool enable, +void min10_dcc_control(struct mem_input *mem_input, bool enable, bool independent_64b_blks) { uint32_t dcc_en = enable ? 1 : 0; @@ -425,7 +425,7 @@ static void min10_program_surface_config( min10_program_pixel_format(mi, format); } -static void min10_program_requestor( +void min10_program_requestor( struct mem_input *mem_input, struct _vcs_dpi_display_rq_regs_st *rq_regs) { @@ -459,7 +459,7 @@ static void min10_program_requestor( } -static void min10_program_deadline( +void min10_program_deadline( struct mem_input *mem_input, struct _vcs_dpi_display_dlg_regs_st *dlg_attr, struct _vcs_dpi_display_ttu_regs_st *ttu_attr) @@ -595,7 +595,7 @@ static void min10_setup( min10_vready_workaround(mem_input, pipe_dest); } -static void min10_program_display_marks( +void min10_program_display_marks( struct mem_input *mem_input, struct dce_watermarks nbp, struct dce_watermarks stutter, @@ -607,7 +607,7 @@ static void min10_program_display_marks( */ } -static bool min10_is_flip_pending(struct mem_input *mem_input) +bool min10_is_flip_pending(struct mem_input *mem_input) { uint32_t flip_pending = 0; struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input); @@ -696,7 +696,7 @@ static void min10_set_vm_context0_settings(struct mem_input *mem_input, SYSTEM_ACCESS_MODE, 3); } -static void min_set_viewport( +void min_set_viewport( struct mem_input *mem_input, const struct rect *viewport, const struct rect *viewport_c) @@ -845,7 +845,7 @@ static enum cursor_lines_per_chunk ippn10_get_lines_per_chunk( return line_per_chunk; } -static void ippn10_cursor_set_attributes( +void ippn10_cursor_set_attributes( struct mem_input *mem_input, const struct dc_cursor_attributes *attr) { @@ -873,7 +873,7 @@ static void ippn10_cursor_set_attributes( attr->color_format); } -static void ippn10_cursor_set_position( +void ippn10_cursor_set_position( struct mem_input *mem_input, const struct dc_cursor_position *pos, const struct dc_cursor_mi_param *param) diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.h index 2c79d7aa3f915..fdeb0e87463e5 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.h +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.h @@ -589,6 +589,65 @@ struct dcn10_mem_input { const struct dcn_mi_mask *mi_mask; }; +void min10_program_deadline( + struct mem_input *mem_input, + struct _vcs_dpi_display_dlg_regs_st *dlg_attr, + struct _vcs_dpi_display_ttu_regs_st *ttu_attr); + +void min10_program_requestor( + struct mem_input *mem_input, + struct _vcs_dpi_display_rq_regs_st *rq_regs); + +void min10_program_pixel_format( + struct dcn10_mem_input *mi, + enum surface_pixel_format format); + +void min10_program_size_and_rotation( + struct dcn10_mem_input *mi, + enum dc_rotation_angle rotation, + enum surface_pixel_format format, + const union plane_size *plane_size, + struct dc_plane_dcc_param *dcc, + bool horizontal_mirror); + +void min10_program_tiling( + struct dcn10_mem_input *mi, + const union dc_tiling_info *info, + const enum surface_pixel_format pixel_format); + +void min10_dcc_control(struct mem_input *mem_input, + bool enable, + bool independent_64b_blks); + +void min10_program_display_marks( + struct mem_input *mem_input, + struct dce_watermarks nbp, + struct dce_watermarks stutter, + struct dce_watermarks urgent, + uint32_t total_dest_line_time_ns); + +bool min10_program_surface_flip_and_addr( + struct mem_input *mem_input, + const struct dc_plane_address *address, + bool flip_immediate); + +bool min10_is_flip_pending(struct mem_input *mem_input); + +void ippn10_cursor_set_attributes( + struct mem_input *mem_input, + const struct dc_cursor_attributes *attr); + +void ippn10_cursor_set_position( + struct mem_input *mem_input, + const struct dc_cursor_position *pos, + const struct dc_cursor_mi_param *param); + +void min10_set_blank(struct mem_input *mem_input, bool blank); + +void min_set_viewport(struct mem_input *mem_input, + const struct rect *viewport, + const struct rect *viewport_c); + void dcn10_mem_input_construct( struct dcn10_mem_input *mi, struct dc_context *ctx, @@ -597,6 +656,7 @@ void dcn10_mem_input_construct( const struct dcn_mi_shift *mi_shift, const struct dcn_mi_mask *mi_mask); + struct dcn_hubp_state { uint32_t pixel_format; uint32_t inuse_addr_hi; From 07e9266593e64f6897996c37dcfb28cb21a612c6 Mon Sep 17 00:00:00 2001 From: Harry Wentland Date: Mon, 16 Oct 2017 22:10:19 -0400 Subject: [PATCH 051/155] Revert "amdgpu/dc: inline dml_round_to_multiple" This reverts commit d8c893b44b2199f5935fe8667708253c38353782. Unfortunately these clash with our DML update from the HW guys. Will attempt to reroll them after. Signed-off-by: Alex Deucher --- .../drm/amd/display/dc/dml/dml_common_defs.c | 19 +++++++++++++++++++ .../drm/amd/display/dc/dml/dml_common_defs.h | 2 ++ .../drm/amd/display/dc/dml/dml_inline_defs.h | 19 ------------------- 3 files changed, 21 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.c b/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.c index df2d5099b90e7..7c0eb52b91b87 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.c @@ -39,4 +39,23 @@ double dml_round(double a) return floor; } +unsigned int dml_round_to_multiple( + unsigned int num, + unsigned int multiple, + bool up) +{ + unsigned int remainder; + + if (multiple == 0) + return num; + + remainder = num % multiple; + if (remainder == 0) + return num; + + if (up) + return (num + multiple - remainder); + else + return (num - remainder); +} diff --git a/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.h b/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.h index 81c53d879a16b..a2da3da5ef8f0 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.h +++ b/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.h @@ -33,5 +33,7 @@ #define DTRACE(str, ...) dm_logger_write(mode_lib->logger, LOG_DML, str, ##__VA_ARGS__); double dml_round(double a); +unsigned int dml_round_to_multiple( + unsigned int num, unsigned int multiple, bool up); #endif /* __DC_COMMON_DEFS_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/dml/dml_inline_defs.h b/drivers/gpu/drm/amd/display/dc/dml/dml_inline_defs.h index a91b4a6c61543..1c6c631daad40 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dml_inline_defs.h +++ b/drivers/gpu/drm/amd/display/dc/dml/dml_inline_defs.h @@ -58,23 +58,4 @@ static inline double dml_log(double x, double base) return (double) dcn_bw_log(x, base); } -static inline unsigned int dml_round_to_multiple(unsigned int num, - unsigned int multiple, - bool up) -{ - unsigned int remainder; - - if (multiple == 0) - return num; - - remainder = num % multiple; - - if (remainder == 0) - return num; - - if (up) - return (num + multiple - remainder); - else - return (num - remainder); -} #endif From 78109d230b797077d58600694ca427b9830eb600 Mon Sep 17 00:00:00 2001 From: Harry Wentland Date: Mon, 16 Oct 2017 22:10:31 -0400 Subject: [PATCH 052/155] Revert "amdgpu/dc: drop dml display_mode_support.c (v2)" This reverts commit 5e0adbff084f33202db36be798c583a115990392. Unfortunately these clash with our DML update from the HW guys. Will attempt to reroll them after. Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dml/Makefile | 4 +- .../amd/display/dc/dml/display_mode_support.c | 2327 +++++++++++++++++ .../amd/display/dc/dml/display_mode_support.h | 5 + 3 files changed, 2335 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/amd/display/dc/dml/display_mode_support.c diff --git a/drivers/gpu/drm/amd/display/dc/dml/Makefile b/drivers/gpu/drm/amd/display/dc/dml/Makefile index ec712d7276650..a6bf36466497f 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/Makefile +++ b/drivers/gpu/drm/amd/display/dc/dml/Makefile @@ -10,10 +10,12 @@ CFLAGS_display_rq_dlg_helpers.o := -mhard-float -msse -mpreferred-stack-boundary CFLAGS_display_watermark.o := -mhard-float -msse -mpreferred-stack-boundary=4 CFLAGS_soc_bounding_box.o := -mhard-float -msse -mpreferred-stack-boundary=4 CFLAGS_dml_common_defs.o := -mhard-float -msse -mpreferred-stack-boundary=4 +CFLAGS_display_mode_support.o := -mhard-float -msse -mpreferred-stack-boundary=4 + DML = display_mode_lib.o display_rq_dlg_calc.o \ display_rq_dlg_helpers.o display_watermark.o \ - soc_bounding_box.o dml_common_defs.o + soc_bounding_box.o dml_common_defs.o display_mode_support.o AMD_DAL_DML = $(addprefix $(AMDDALPATH)/dc/dml/,$(DML)) diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_support.c b/drivers/gpu/drm/amd/display/dc/dml/display_mode_support.c new file mode 100644 index 0000000000000..ac573568c10ae --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_support.c @@ -0,0 +1,2327 @@ +/* + * Copyright 2017 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: AMD + * + */ + +#include "display_mode_support.h" +#include "display_mode_lib.h" + +#include "dml_inline_defs.h" +int dml_ms_check( + struct display_mode_lib *mode_lib, + struct _vcs_dpi_display_e2e_pipe_params_st *e2e, + int num_pipes) +{ + struct _vcs_dpi_ip_params_st *ip; + struct _vcs_dpi_soc_bounding_box_st *soc; + struct _vcs_dpi_mode_evaluation_st *me; + struct dml_ms_internal_vars *v; + int num_planes, i, j, ij, k, ijk; + + ip = &(mode_lib->ip); + soc = &(mode_lib->soc); + me = &(mode_lib->me); + v = &(mode_lib->vars); + num_planes = dml_wm_e2e_to_wm(mode_lib, e2e, num_pipes, v->planes); + + //instantiating variables to zero + v->MacroTileBlockWidthC = 0; + v->SwathWidthGranularityC = 0; + + v->DCFCLKPerState[5] = 0; + v->DCFCLKPerState[4] = 0; + v->DCFCLKPerState[3] = 0; + v->DCFCLKPerState[2] = 0; + v->DCFCLKPerState[1] = 0; + v->DCFCLKPerState[0] = 0; + + if (soc->vmin.dcfclk_mhz > 0) { + v->DCFCLKPerState[5] = soc->vmin.dcfclk_mhz; + v->DCFCLKPerState[4] = soc->vmin.dcfclk_mhz; + v->DCFCLKPerState[3] = soc->vmin.dcfclk_mhz; + v->DCFCLKPerState[2] = soc->vmin.dcfclk_mhz; + v->DCFCLKPerState[1] = soc->vmin.dcfclk_mhz; + v->DCFCLKPerState[0] = soc->vmin.dcfclk_mhz; + } + + if (soc->vmid.dcfclk_mhz > 0) { + v->DCFCLKPerState[5] = soc->vmid.dcfclk_mhz; + v->DCFCLKPerState[4] = soc->vmid.dcfclk_mhz; + v->DCFCLKPerState[3] = soc->vmid.dcfclk_mhz; + v->DCFCLKPerState[2] = soc->vmid.dcfclk_mhz; + v->DCFCLKPerState[1] = soc->vmid.dcfclk_mhz; + } + + if (soc->vnom.dcfclk_mhz > 0) { + v->DCFCLKPerState[5] = soc->vnom.dcfclk_mhz; + v->DCFCLKPerState[4] = soc->vnom.dcfclk_mhz; + v->DCFCLKPerState[3] = soc->vnom.dcfclk_mhz; + v->DCFCLKPerState[2] = soc->vnom.dcfclk_mhz; + } + + if (soc->vmax.dcfclk_mhz > 0) { + v->DCFCLKPerState[5] = soc->vmax.dcfclk_mhz; + v->DCFCLKPerState[4] = soc->vmax.dcfclk_mhz; + v->DCFCLKPerState[3] = soc->vmax.dcfclk_mhz; + } + + v->FabricAndDRAMBandwidthPerState[5] = 0; + v->FabricAndDRAMBandwidthPerState[4] = 0; + v->FabricAndDRAMBandwidthPerState[3] = 0; + v->FabricAndDRAMBandwidthPerState[2] = 0; + v->FabricAndDRAMBandwidthPerState[1] = 0; + v->FabricAndDRAMBandwidthPerState[0] = 0; + + if (soc->vmin.dram_bw_per_chan_gbps > 0) { + v->FabricAndDRAMBandwidthPerState[5] = soc->vmin.dram_bw_per_chan_gbps; + v->FabricAndDRAMBandwidthPerState[4] = soc->vmin.dram_bw_per_chan_gbps; + v->FabricAndDRAMBandwidthPerState[3] = soc->vmin.dram_bw_per_chan_gbps; + v->FabricAndDRAMBandwidthPerState[2] = soc->vmin.dram_bw_per_chan_gbps; + v->FabricAndDRAMBandwidthPerState[1] = soc->vmin.dram_bw_per_chan_gbps; + v->FabricAndDRAMBandwidthPerState[0] = soc->vmin.dram_bw_per_chan_gbps; + } + + if (soc->vmid.dram_bw_per_chan_gbps > 0) { + v->FabricAndDRAMBandwidthPerState[5] = soc->vmid.dram_bw_per_chan_gbps; + v->FabricAndDRAMBandwidthPerState[4] = soc->vmid.dram_bw_per_chan_gbps; + v->FabricAndDRAMBandwidthPerState[3] = soc->vmid.dram_bw_per_chan_gbps; + v->FabricAndDRAMBandwidthPerState[2] = soc->vmid.dram_bw_per_chan_gbps; + v->FabricAndDRAMBandwidthPerState[1] = soc->vmid.dram_bw_per_chan_gbps; + } + + if (soc->vnom.dram_bw_per_chan_gbps > 0) { + v->FabricAndDRAMBandwidthPerState[5] = soc->vnom.dram_bw_per_chan_gbps; + v->FabricAndDRAMBandwidthPerState[4] = soc->vnom.dram_bw_per_chan_gbps; + v->FabricAndDRAMBandwidthPerState[3] = soc->vnom.dram_bw_per_chan_gbps; + v->FabricAndDRAMBandwidthPerState[2] = soc->vnom.dram_bw_per_chan_gbps; + } + + if (soc->vmax.dram_bw_per_chan_gbps > 0) { + v->FabricAndDRAMBandwidthPerState[5] = soc->vmax.dram_bw_per_chan_gbps; + v->FabricAndDRAMBandwidthPerState[4] = soc->vmax.dram_bw_per_chan_gbps; + v->FabricAndDRAMBandwidthPerState[3] = soc->vmax.dram_bw_per_chan_gbps; + } + + v->PHYCLKPerState[5] = 0; + v->PHYCLKPerState[4] = 0; + v->PHYCLKPerState[3] = 0; + v->PHYCLKPerState[2] = 0; + v->PHYCLKPerState[1] = 0; + v->PHYCLKPerState[0] = 0; + + if (soc->vmin.phyclk_mhz > 0) { + v->PHYCLKPerState[5] = soc->vmin.phyclk_mhz; + v->PHYCLKPerState[4] = soc->vmin.phyclk_mhz; + v->PHYCLKPerState[3] = soc->vmin.phyclk_mhz; + v->PHYCLKPerState[2] = soc->vmin.phyclk_mhz; + v->PHYCLKPerState[1] = soc->vmin.phyclk_mhz; + v->PHYCLKPerState[0] = soc->vmin.phyclk_mhz; + } + + if (soc->vmid.phyclk_mhz > 0) { + v->PHYCLKPerState[5] = soc->vmid.phyclk_mhz; + v->PHYCLKPerState[4] = soc->vmid.phyclk_mhz; + v->PHYCLKPerState[3] = soc->vmid.phyclk_mhz; + v->PHYCLKPerState[2] = soc->vmid.phyclk_mhz; + v->PHYCLKPerState[1] = soc->vmid.phyclk_mhz; + } + + if (soc->vnom.phyclk_mhz > 0) { + v->PHYCLKPerState[5] = soc->vnom.phyclk_mhz; + v->PHYCLKPerState[4] = soc->vnom.phyclk_mhz; + v->PHYCLKPerState[3] = soc->vnom.phyclk_mhz; + v->PHYCLKPerState[2] = soc->vnom.phyclk_mhz; + } + + if (soc->vmax.phyclk_mhz > 0) { + v->PHYCLKPerState[5] = soc->vmax.phyclk_mhz; + v->PHYCLKPerState[4] = soc->vmax.phyclk_mhz; + v->PHYCLKPerState[3] = soc->vmax.phyclk_mhz; + } + + v->MaxDispclk[5] = 0; + v->MaxDispclk[4] = 0; + v->MaxDispclk[3] = 0; + v->MaxDispclk[2] = 0; + v->MaxDispclk[1] = 0; + v->MaxDispclk[0] = 0; + + if (soc->vmin.dispclk_mhz > 0) { + v->MaxDispclk[5] = soc->vmin.dispclk_mhz; + v->MaxDispclk[4] = soc->vmin.dispclk_mhz; + v->MaxDispclk[3] = soc->vmin.dispclk_mhz; + v->MaxDispclk[2] = soc->vmin.dispclk_mhz; + v->MaxDispclk[1] = soc->vmin.dispclk_mhz; + v->MaxDispclk[0] = soc->vmin.dispclk_mhz; + } + + if (soc->vmid.dispclk_mhz > 0) { + v->MaxDispclk[5] = soc->vmid.dispclk_mhz; + v->MaxDispclk[4] = soc->vmid.dispclk_mhz; + v->MaxDispclk[3] = soc->vmid.dispclk_mhz; + v->MaxDispclk[2] = soc->vmid.dispclk_mhz; + v->MaxDispclk[1] = soc->vmid.dispclk_mhz; + } + + if (soc->vnom.dispclk_mhz > 0) { + v->MaxDispclk[5] = soc->vnom.dispclk_mhz; + v->MaxDispclk[4] = soc->vnom.dispclk_mhz; + v->MaxDispclk[3] = soc->vnom.dispclk_mhz; + v->MaxDispclk[2] = soc->vnom.dispclk_mhz; + } + + if (soc->vmax.dispclk_mhz > 0) { + v->MaxDispclk[5] = soc->vmax.dispclk_mhz; + v->MaxDispclk[4] = soc->vmax.dispclk_mhz; + v->MaxDispclk[3] = soc->vmax.dispclk_mhz; + } + + v->MaxDppclk[5] = 0; + v->MaxDppclk[4] = 0; + v->MaxDppclk[3] = 0; + v->MaxDppclk[2] = 0; + v->MaxDppclk[1] = 0; + v->MaxDppclk[0] = 0; + + if (soc->vmin.dppclk_mhz > 0) { + v->MaxDppclk[5] = soc->vmin.dppclk_mhz; + v->MaxDppclk[4] = soc->vmin.dppclk_mhz; + v->MaxDppclk[3] = soc->vmin.dppclk_mhz; + v->MaxDppclk[2] = soc->vmin.dppclk_mhz; + v->MaxDppclk[1] = soc->vmin.dppclk_mhz; + v->MaxDppclk[0] = soc->vmin.dppclk_mhz; + } + + if (soc->vmid.dppclk_mhz > 0) { + v->MaxDppclk[5] = soc->vmid.dppclk_mhz; + v->MaxDppclk[4] = soc->vmid.dppclk_mhz; + v->MaxDppclk[3] = soc->vmid.dppclk_mhz; + v->MaxDppclk[2] = soc->vmid.dppclk_mhz; + v->MaxDppclk[1] = soc->vmid.dppclk_mhz; + } + + if (soc->vnom.dppclk_mhz > 0) { + v->MaxDppclk[5] = soc->vnom.dppclk_mhz; + v->MaxDppclk[4] = soc->vnom.dppclk_mhz; + v->MaxDppclk[3] = soc->vnom.dppclk_mhz; + v->MaxDppclk[2] = soc->vnom.dppclk_mhz; + } + + if (soc->vmax.dppclk_mhz > 0) { + v->MaxDppclk[5] = soc->vmax.dppclk_mhz; + v->MaxDppclk[4] = soc->vmax.dppclk_mhz; + v->MaxDppclk[3] = soc->vmax.dppclk_mhz; + } + + if (me->voltage_override == dm_vmax) { + v->VoltageOverrideLevel = NumberOfStates - 1; + } else if (me->voltage_override == dm_vnom) { + v->VoltageOverrideLevel = NumberOfStates - 2; + } else if (me->voltage_override == dm_vmid) { + v->VoltageOverrideLevel = NumberOfStates - 3; + } else { + v->VoltageOverrideLevel = 0; + } + + // Scale Ratio Support Check + + v->ScaleRatioSupport = 1; + + for (k = 0; k < num_planes; k++) { + struct _vcs_dpi_scaler_ratio_depth_st scale_ratio_depth = + e2e[v->planes[k].e2e_index].pipe.scale_ratio_depth; + struct _vcs_dpi_scaler_taps_st scale_taps = + e2e[v->planes[k].e2e_index].pipe.scale_taps; + struct _vcs_dpi_display_pipe_source_params_st src = + e2e[v->planes[k].e2e_index].pipe.src; + + if (scale_ratio_depth.hscl_ratio > ip->max_hscl_ratio + || scale_ratio_depth.vscl_ratio > ip->max_vscl_ratio + || scale_ratio_depth.hscl_ratio > scale_taps.htaps + || scale_ratio_depth.vscl_ratio > scale_taps.vtaps + || (src.source_format != dm_444_64 && src.source_format != dm_444_32 + && src.source_format != dm_444_16 + && ((scale_ratio_depth.hscl_ratio / 2 + > scale_taps.htaps_c) + || (scale_ratio_depth.vscl_ratio / 2 + > scale_taps.vtaps_c)))) + + { + v->ScaleRatioSupport = 0; + } + } + + // Source Format, Pixel Format and Scan Support Check + + v->SourceFormatPixelAndScanSupport = 1; + + for (k = 0; k < num_planes; k++) { + struct _vcs_dpi_display_pipe_source_params_st src = + e2e[v->planes[k].e2e_index].pipe.src; + + if ((src.sw_mode == dm_sw_linear && src.source_scan != dm_horz) + || ((src.sw_mode == dm_sw_4kb_d || src.sw_mode == dm_sw_4kb_d_x + || src.sw_mode == dm_sw_64kb_d + || src.sw_mode == dm_sw_64kb_d_t + || src.sw_mode == dm_sw_64kb_d_x + || src.sw_mode == dm_sw_var_d + || src.sw_mode == dm_sw_var_d_x) + && (src.source_format != dm_444_64))) { + v->SourceFormatPixelAndScanSupport = 0; + } + } + + // Bandwidth Support Check + + for (k = 0; k < num_planes; k++) { + struct _vcs_dpi_display_pipe_source_params_st src = + e2e[v->planes[k].e2e_index].pipe.src; + + if (src.source_scan == dm_horz) { + v->SwathWidthYSingleDPP[k] = src.viewport_width; + } else { + v->SwathWidthYSingleDPP[k] = src.viewport_height; + } + + if (src.source_format == dm_444_64) { + v->BytePerPixelInDETY[k] = 8; + v->BytePerPixelInDETC[k] = 0; + } else if (src.source_format == dm_444_32) { + v->BytePerPixelInDETY[k] = 4; + v->BytePerPixelInDETC[k] = 0; + } else if (src.source_format == dm_444_16) { + v->BytePerPixelInDETY[k] = 2; + v->BytePerPixelInDETC[k] = 0; + } else if (src.source_format == dm_420_8) { + v->BytePerPixelInDETY[k] = 1; + v->BytePerPixelInDETC[k] = 2; + } else { + v->BytePerPixelInDETY[k] = 4.00 / 3.00; + v->BytePerPixelInDETC[k] = 8.00 / 3.00; + } + } + + v->TotalReadBandwidthConsumedGBytePerSecond = 0; + + for (k = 0; k < num_planes; k++) { + struct _vcs_dpi_display_pipe_source_params_st src = + e2e[v->planes[k].e2e_index].pipe.src; + struct _vcs_dpi_display_pipe_dest_params_st dest = + e2e[v->planes[k].e2e_index].pipe.dest; + struct _vcs_dpi_scaler_ratio_depth_st scale_ratio_depth = + e2e[v->planes[k].e2e_index].pipe.scale_ratio_depth; + + v->ReadBandwidth[k] = + v->SwathWidthYSingleDPP[k] + * (dml_ceil_ex(v->BytePerPixelInDETY[k], 1) + * scale_ratio_depth.vscl_ratio + + (dml_ceil_ex( + v->BytePerPixelInDETC[k], + 2) / 2) + * (scale_ratio_depth.vscl_ratio + / 2)) + / (dest.htotal / dest.pixel_rate_mhz); + + if (src.dcc == 1) { + v->ReadBandwidth[k] = v->ReadBandwidth[k] * (1 + 1 / 256); + } + + if (ip->pte_enable == 1 && src.source_scan != dm_horz + && (src.sw_mode == dm_sw_4kb_s || src.sw_mode == dm_sw_4kb_s_x + || src.sw_mode == dm_sw_4kb_d + || src.sw_mode == dm_sw_4kb_d_x)) { + v->ReadBandwidth[k] = v->ReadBandwidth[k] * (1 + 1 / 64); + } else if (ip->pte_enable == 1 && src.source_scan == dm_horz + && (src.source_format == dm_444_64 || src.source_format == dm_444_32) + && (src.sw_mode == dm_sw_64kb_s || src.sw_mode == dm_sw_64kb_s_t + || src.sw_mode == dm_sw_64kb_s_x + || src.sw_mode == dm_sw_64kb_d + || src.sw_mode == dm_sw_64kb_d_t + || src.sw_mode == dm_sw_64kb_d_x)) { + v->ReadBandwidth[k] = v->ReadBandwidth[k] * (1 + 1 / 256); + } else if (ip->pte_enable == 1) { + v->ReadBandwidth[k] = v->ReadBandwidth[k] * (1 + 1 / 512); + } + + v->TotalReadBandwidthConsumedGBytePerSecond = + v->TotalReadBandwidthConsumedGBytePerSecond + + v->ReadBandwidth[k] / 1000; + } + + v->TotalWriteBandwidthConsumedGBytePerSecond = 0; + + for (k = 0; k < num_planes; k++) { + struct _vcs_dpi_display_pipe_dest_params_st dest = + e2e[v->planes[k].e2e_index].pipe.dest; + struct _vcs_dpi_display_output_params_st dout = e2e[v->planes[k].e2e_index].dout; + + if (dout.output_type == dm_wb && dout.output_format == dm_444) { + v->WriteBandwidth[k] = dest.recout_width + / (dest.htotal / dest.pixel_rate_mhz) * 4; + } else if (dout.output_type == dm_wb) { + v->WriteBandwidth[k] = dest.recout_width + / (dest.htotal / dest.pixel_rate_mhz) * 1.5; + } else { + v->WriteBandwidth[k] = 0; + } + + v->TotalWriteBandwidthConsumedGBytePerSecond = + v->TotalWriteBandwidthConsumedGBytePerSecond + + v->WriteBandwidth[k] / 1000; + } + + v->TotalBandwidthConsumedGBytePerSecond = v->TotalReadBandwidthConsumedGBytePerSecond + + v->TotalWriteBandwidthConsumedGBytePerSecond; + + v->DCCEnabledInAnyPlane = 0; + + for (k = 0; k < num_planes; k++) { + struct _vcs_dpi_display_pipe_source_params_st src = + e2e[v->planes[k].e2e_index].pipe.src; + + if (src.dcc == 1) { + v->DCCEnabledInAnyPlane = 1; + } + } + + for (i = 0; i < NumberOfStatesPlusTwo; i++) { + v->ReturnBWToDCNPerState = dml_min( + soc->return_bus_width_bytes * v->DCFCLKPerState[i], + v->FabricAndDRAMBandwidthPerState[i] * 1000 + * soc->ideal_dram_bw_after_urgent_percent / 100); + + v->ReturnBWPerState[i] = v->ReturnBWToDCNPerState; + + if (v->DCCEnabledInAnyPlane == 1 + && v->ReturnBWToDCNPerState + > (v->DCFCLKPerState[i] + * soc->return_bus_width_bytes / 4)) { + v->ReturnBWPerState[i] = + dml_min( + v->ReturnBWPerState[i], + v->ReturnBWToDCNPerState * 4 + * (1 + - soc->urgent_latency_us + / ((ip->rob_buffer_size_kbytes + - ip->pixel_chunk_size_kbytes) + * 1024 + / (v->ReturnBWToDCNPerState + - v->DCFCLKPerState[i] + * soc->return_bus_width_bytes + / 4) + + soc->urgent_latency_us))); + } + + v->CriticalPoint = 2 * soc->return_bus_width_bytes * v->DCFCLKPerState[i] + * soc->urgent_latency_us + / (v->ReturnBWToDCNPerState * soc->urgent_latency_us + + (ip->rob_buffer_size_kbytes + - ip->pixel_chunk_size_kbytes) + * 1024); + + if (v->DCCEnabledInAnyPlane == 1 && v->CriticalPoint > 1 && v->CriticalPoint < 4) { + v->ReturnBWPerState[i] = + dml_min( + v->ReturnBWPerState[i], + 4 * v->ReturnBWToDCNPerState + * (ip->rob_buffer_size_kbytes + - ip->pixel_chunk_size_kbytes) + * 1024 + * soc->return_bus_width_bytes + * v->DCFCLKPerState[i] + * soc->urgent_latency_us + / dml_pow( + (v->ReturnBWToDCNPerState + * soc->urgent_latency_us + + (ip->rob_buffer_size_kbytes + - ip->pixel_chunk_size_kbytes) + * 1024), + 2)); + } + + v->ReturnBWToDCNPerState = dml_min( + soc->return_bus_width_bytes * v->DCFCLKPerState[i], + v->FabricAndDRAMBandwidthPerState[i] * 1000); + + if (v->DCCEnabledInAnyPlane == 1 + && v->ReturnBWToDCNPerState + > (v->DCFCLKPerState[i] + * soc->return_bus_width_bytes / 4)) { + v->ReturnBWPerState[i] = + dml_min( + v->ReturnBWPerState[i], + v->ReturnBWToDCNPerState * 4 + * (1 + - soc->urgent_latency_us + / ((ip->rob_buffer_size_kbytes + - ip->pixel_chunk_size_kbytes) + * 1024 + / (v->ReturnBWToDCNPerState + - v->DCFCLKPerState[i] + * soc->return_bus_width_bytes + / 4) + + soc->urgent_latency_us))); + } + + v->CriticalPoint = 2 * soc->return_bus_width_bytes * v->DCFCLKPerState[i] + * soc->urgent_latency_us + / (v->ReturnBWToDCNPerState * soc->urgent_latency_us + + (ip->rob_buffer_size_kbytes + - ip->pixel_chunk_size_kbytes) + * 1024); + + if (v->DCCEnabledInAnyPlane == 1 && v->CriticalPoint > 1 && v->CriticalPoint < 4) { + v->ReturnBWPerState[i] = + dml_min( + v->ReturnBWPerState[i], + 4 * v->ReturnBWToDCNPerState + * (ip->rob_buffer_size_kbytes + - ip->pixel_chunk_size_kbytes) + * 1024 + * soc->return_bus_width_bytes + * v->DCFCLKPerState[i] + * soc->urgent_latency_us + / dml_pow( + (v->ReturnBWToDCNPerState + * soc->urgent_latency_us + + (ip->rob_buffer_size_kbytes + - ip->pixel_chunk_size_kbytes) + * 1024), + 2)); + } + } + + for (i = 0; i < NumberOfStatesPlusTwo; i++) { + if ((v->TotalReadBandwidthConsumedGBytePerSecond * 1000 <= v->ReturnBWPerState[i]) + && (v->TotalBandwidthConsumedGBytePerSecond * 1000 + <= v->FabricAndDRAMBandwidthPerState[i] * 1000 + * soc->ideal_dram_bw_after_urgent_percent + / 100)) { + v->BandwidthSupport[i] = 1; + } else { + v->BandwidthSupport[i] = 0; + } + } + + // Writeback Latency support check + + v->WritebackLatencySupport = 1; + + for (k = 0; k < num_planes; k++) { + struct _vcs_dpi_display_pipe_dest_params_st dest = + e2e[v->planes[k].e2e_index].pipe.dest; + struct _vcs_dpi_display_output_params_st dout = e2e[v->planes[k].e2e_index].dout; + + if (dout.output_type == dm_wb && dout.output_format == dm_444 + && (dest.recout_width / (dest.htotal / dest.pixel_rate_mhz) * 4) + > ((ip->writeback_luma_buffer_size_kbytes + + ip->writeback_chroma_buffer_size_kbytes) + * 1024 / soc->writeback_latency_us)) { + v->WritebackLatencySupport = 0; + } else if (dout.output_type == dm_wb + && (dest.recout_width / (dest.htotal / dest.pixel_rate_mhz)) + > (dml_min( + ip->writeback_luma_buffer_size_kbytes, + 2 + * ip->writeback_chroma_buffer_size_kbytes) + * 1024 / soc->writeback_latency_us)) { + v->WritebackLatencySupport = 0; + } + } + + // Re-ordering Buffer Support Check + + for (i = 0; i < NumberOfStatesPlusTwo; i++) { + v->UrgentRoundTripAndOutOfOrderLatencyPerState[i] = + (soc->round_trip_ping_latency_dcfclk_cycles + 32) + / v->DCFCLKPerState[i] + + soc->urgent_out_of_order_return_per_channel_bytes + * soc->num_chans + / v->ReturnBWPerState[i]; + + if ((ip->rob_buffer_size_kbytes - ip->pixel_chunk_size_kbytes) * 1024 + / v->ReturnBWPerState[i] + > v->UrgentRoundTripAndOutOfOrderLatencyPerState[i]) { + v->ROBSupport[i] = 1; + } else { + v->ROBSupport[i] = 0; + } + } + + // Display IO Support Check + + for (k = 0; k < num_planes; k++) { + struct _vcs_dpi_display_pipe_dest_params_st dest = + e2e[v->planes[k].e2e_index].pipe.dest; + struct _vcs_dpi_display_output_params_st dout = e2e[v->planes[k].e2e_index].dout; + + if (dout.output_format == dm_420) { + v->RequiredOutputBW = dest.pixel_rate_mhz * 3 / 2; + } else { + v->RequiredOutputBW = dest.pixel_rate_mhz * 3; + } + + if (dout.output_type == dm_hdmi) { + v->RequiredPHYCLK[k] = v->RequiredOutputBW / 3; + } else if (dout.output_type == dm_dp) { + v->RequiredPHYCLK[k] = v->RequiredOutputBW / 4; + } else { + v->RequiredPHYCLK[k] = 0; + } + } + + for (i = 0; i < NumberOfStatesPlusTwo; i++) { + v->DIOSupport[i] = 1; + + for (k = 0; k < num_planes; k++) { + struct _vcs_dpi_display_output_params_st dout = + e2e[v->planes[k].e2e_index].dout; + + if ((v->RequiredPHYCLK[k] > v->PHYCLKPerState[i]) + || (dout.output_type == dm_hdmi + && v->RequiredPHYCLK[k] > 600)) { + v->DIOSupport[i] = 0; + } + } + } + + // Total Available Writeback Support Check + + v->TotalNumberOfActiveWriteback = 0; + + for (k = 0; k < num_planes; k++) { + struct _vcs_dpi_display_output_params_st dout = e2e[v->planes[k].e2e_index].dout; + + if (dout.output_type == dm_wb) { + v->TotalNumberOfActiveWriteback = v->TotalNumberOfActiveWriteback + 1; + } + } + + if (v->TotalNumberOfActiveWriteback <= ip->max_num_wb) { + v->TotalAvailableWritebackSupport = 1; + } else { + v->TotalAvailableWritebackSupport = 0; + } + + // Maximum DISPCLK/DPPCLK Support check + + for (k = 0; k < num_planes; k++) { + struct _vcs_dpi_display_pipe_dest_params_st dest = + e2e[v->planes[k].e2e_index].pipe.dest; + struct _vcs_dpi_scaler_ratio_depth_st scale_ratio_depth = + e2e[v->planes[k].e2e_index].pipe.scale_ratio_depth; + struct _vcs_dpi_scaler_taps_st scale_taps = + e2e[v->planes[k].e2e_index].pipe.scale_taps; + + if (scale_ratio_depth.hscl_ratio > 1) { + v->PSCL_FACTOR[k] = dml_min( + ip->max_dchub_pscl_bw_pix_per_clk, + ip->max_pscl_lb_bw_pix_per_clk + * scale_ratio_depth.hscl_ratio + / dml_ceil_ex(scale_taps.htaps / 6, 1)); + } else { + v->PSCL_FACTOR[k] = dml_min( + ip->max_dchub_pscl_bw_pix_per_clk, + ip->max_pscl_lb_bw_pix_per_clk); + } + + if (v->BytePerPixelInDETC[k] == 0) { + v->PSCL_FACTOR_CHROMA[k] = 0; + v->MinDPPCLKUsingSingleDPP[k] = + dest.pixel_rate_mhz + * dml_max( + scale_taps.vtaps / 6 + * dml_min( + 1, + scale_ratio_depth.hscl_ratio), + dml_max( + scale_ratio_depth.hscl_ratio + * scale_ratio_depth.vscl_ratio + / v->PSCL_FACTOR[k], + 1)); + + } else { + if (scale_ratio_depth.hscl_ratio / 2 > 1) { + v->PSCL_FACTOR_CHROMA[k] = dml_min( + ip->max_dchub_pscl_bw_pix_per_clk, + ip->max_pscl_lb_bw_pix_per_clk + * scale_ratio_depth.hscl_ratio / 2 + / dml_ceil_ex( + scale_taps.htaps_c + / 6, + 1)); + } else { + v->PSCL_FACTOR_CHROMA[k] = dml_min( + ip->max_dchub_pscl_bw_pix_per_clk, + ip->max_pscl_lb_bw_pix_per_clk); + } + v->MinDPPCLKUsingSingleDPP[k] = + dest.pixel_rate_mhz + * dml_max( + dml_max( + scale_taps.vtaps + / 6 + * dml_min( + 1, + scale_ratio_depth.hscl_ratio), + scale_ratio_depth.hscl_ratio + * scale_ratio_depth.vscl_ratio + / v->PSCL_FACTOR[k]), + dml_max( + dml_max( + scale_taps.vtaps_c + / 6 + * dml_min( + 1, + scale_ratio_depth.hscl_ratio + / 2), + scale_ratio_depth.hscl_ratio + * scale_ratio_depth.vscl_ratio + / 4 + / v->PSCL_FACTOR_CHROMA[k]), + 1)); + + } + } + + for (k = 0; k < num_planes; k++) { + struct _vcs_dpi_display_pipe_source_params_st src = + e2e[v->planes[k].e2e_index].pipe.src; + struct _vcs_dpi_scaler_ratio_depth_st scale_ratio_depth = + e2e[v->planes[k].e2e_index].pipe.scale_ratio_depth; + struct _vcs_dpi_scaler_taps_st scale_taps = + e2e[v->planes[k].e2e_index].pipe.scale_taps; + + if (src.source_format == dm_444_64 || src.source_format == dm_444_32 + || src.source_format == dm_444_16) { + if (src.sw_mode == dm_sw_linear) { + v->Read256BlockHeightY[k] = 1; + } else if (src.source_format == dm_444_64) { + v->Read256BlockHeightY[k] = 4; + } else { + v->Read256BlockHeightY[k] = 8; + } + + v->Read256BlockWidthY[k] = 256 / dml_ceil_ex(v->BytePerPixelInDETY[k], 1) + / v->Read256BlockHeightY[k]; + v->Read256BlockHeightC[k] = 0; + v->Read256BlockWidthC[k] = 0; + } else { + if (src.sw_mode == dm_sw_linear) { + v->Read256BlockHeightY[k] = 1; + v->Read256BlockHeightC[k] = 1; + } else if (src.source_format == dm_420_8) { + v->Read256BlockHeightY[k] = 16; + v->Read256BlockHeightC[k] = 8; + } else { + v->Read256BlockHeightY[k] = 8; + v->Read256BlockHeightC[k] = 8; + } + + v->Read256BlockWidthY[k] = 256 / dml_ceil_ex(v->BytePerPixelInDETY[k], 1) + / v->Read256BlockHeightY[k]; + v->Read256BlockWidthC[k] = 256 / dml_ceil_ex(v->BytePerPixelInDETC[k], 2) + / v->Read256BlockHeightC[k]; + } + + if (src.source_scan == dm_horz) { + v->MaxSwathHeightY[k] = v->Read256BlockHeightY[k]; + v->MaxSwathHeightC[k] = v->Read256BlockHeightC[k]; + } else { + v->MaxSwathHeightY[k] = v->Read256BlockWidthY[k]; + v->MaxSwathHeightC[k] = v->Read256BlockWidthC[k]; + } + + if (src.source_format == dm_444_64 || src.source_format == dm_444_32 + || src.source_format == dm_444_16) { + if (src.sw_mode == dm_sw_linear + || (src.source_format == dm_444_64 + && (src.sw_mode == dm_sw_4kb_s + || src.sw_mode + == dm_sw_4kb_s_x + || src.sw_mode + == dm_sw_64kb_s + || src.sw_mode + == dm_sw_64kb_s_t + || src.sw_mode + == dm_sw_64kb_s_x + || src.sw_mode + == dm_sw_var_s + || src.sw_mode + == dm_sw_var_s_x) + && src.source_scan == dm_horz)) { + v->MinSwathHeightY[k] = v->MaxSwathHeightY[k]; + } else { + v->MinSwathHeightY[k] = v->MaxSwathHeightY[k] / 2; + } + v->MinSwathHeightC[k] = v->MaxSwathHeightC[k]; + } else { + if (src.sw_mode == dm_sw_linear) { + v->MinSwathHeightY[k] = v->MaxSwathHeightY[k]; + v->MinSwathHeightC[k] = v->MaxSwathHeightC[k]; + } else if (src.source_format == dm_420_8 && src.source_scan == dm_horz) { + v->MinSwathHeightY[k] = v->MaxSwathHeightY[k] / 2; + if (ip->bug_forcing_LC_req_same_size_fixed == 1) { + v->MinSwathHeightC[k] = v->MaxSwathHeightC[k]; + } else { + v->MinSwathHeightC[k] = v->MaxSwathHeightC[k] / 2; + } + } else if (src.source_format == dm_420_10 && src.source_scan == dm_horz) { + v->MinSwathHeightC[k] = v->MaxSwathHeightC[k] / 2; + if (ip->bug_forcing_LC_req_same_size_fixed == 1) { + v->MinSwathHeightY[k] = v->MaxSwathHeightY[k]; + } else { + v->MinSwathHeightY[k] = v->MaxSwathHeightY[k] / 2; + } + } else { + v->MinSwathHeightY[k] = v->MaxSwathHeightY[k]; + v->MinSwathHeightC[k] = v->MaxSwathHeightC[k]; + } + } + + if (src.sw_mode == dm_sw_linear) { + v->MaximumSwathWidth = 8192; + } else { + v->MaximumSwathWidth = 5120; + } + + v->NumberOfDPPRequiredForDETSize = + dml_ceil_ex( + v->SwathWidthYSingleDPP[k] + / dml_min( + v->MaximumSwathWidth, + ip->det_buffer_size_kbytes + * 1024 + / 2 + / (v->BytePerPixelInDETY[k] + * v->MinSwathHeightY[k] + + v->BytePerPixelInDETC[k] + / 2 + * v->MinSwathHeightC[k])), + 1); + + if (v->BytePerPixelInDETC[k] == 0) { + v->NumberOfDPPRequiredForLBSize = + dml_ceil_ex( + (scale_taps.vtaps + + dml_max( + dml_ceil_ex( + scale_ratio_depth.vscl_ratio, + 1) + - 2, + 0)) + * v->SwathWidthYSingleDPP[k] + / dml_max( + scale_ratio_depth.hscl_ratio, + 1) + * scale_ratio_depth.lb_depth + / ip->line_buffer_size_bits, + 1); + } else { + v->NumberOfDPPRequiredForLBSize = + dml_max( + dml_ceil_ex( + (scale_taps.vtaps + + dml_max( + dml_ceil_ex( + scale_ratio_depth.vscl_ratio, + 1) + - 2, + 0)) + * v->SwathWidthYSingleDPP[k] + / dml_max( + scale_ratio_depth.hscl_ratio, + 1) + * scale_ratio_depth.lb_depth + / ip->line_buffer_size_bits, + 1), + dml_ceil_ex( + (scale_taps.vtaps_c + + dml_max( + dml_ceil_ex( + scale_ratio_depth.vscl_ratio + / 2, + 1) + - 2, + 0)) + * v->SwathWidthYSingleDPP[k] + / 2 + / dml_max( + scale_ratio_depth.hscl_ratio + / 2, + 1) + * scale_ratio_depth.lb_depth + / ip->line_buffer_size_bits, + 1)); + } + + v->NumberOfDPPRequiredForDETAndLBSize[k] = dml_max( + v->NumberOfDPPRequiredForDETSize, + v->NumberOfDPPRequiredForLBSize); + + } + + for (i = 0; i < NumberOfStatesPlusTwo; i++) { + for (j = 0; j < 2; j++) { + v->TotalNumberOfActiveDPP[j * NumberOfStatesPlusTwo + i] = 0; + v->RequiredDISPCLK[j * NumberOfStatesPlusTwo + i] = 0; + v->DISPCLK_DPPCLK_Support[j * NumberOfStatesPlusTwo + i] = 1; + + for (k = 0; k < num_planes; k++) { + struct _vcs_dpi_display_pipe_dest_params_st dest = + e2e[v->planes[k].e2e_index].pipe.dest; + ijk = k * 2 * NumberOfStatesPlusTwo + j * NumberOfStatesPlusTwo + i; + + v->MinDispclkUsingSingleDPP = dml_max( + dest.pixel_rate_mhz, + v->MinDPPCLKUsingSingleDPP[k] * (j + 1)) + * (1 + soc->downspread_percent / 100); + v->MinDispclkUsingDualDPP = dml_max( + dest.pixel_rate_mhz, + v->MinDPPCLKUsingSingleDPP[k] / 2 * (j + 1)) + * (1 + soc->downspread_percent / 100); + + if (i < NumberOfStates) { + v->MinDispclkUsingSingleDPP = + v->MinDispclkUsingSingleDPP + * (1 + + ip->dispclk_ramp_margin_percent + / 100); + v->MinDispclkUsingDualDPP = + v->MinDispclkUsingDualDPP + * (1 + + ip->dispclk_ramp_margin_percent + / 100); + } + + if (v->MinDispclkUsingSingleDPP + <= dml_min( + v->MaxDispclk[i], + (j + 1) * v->MaxDppclk[i]) + && v->NumberOfDPPRequiredForDETAndLBSize[k] <= 1) { + v->NoOfDPP[ijk] = 1; + v->RequiredDISPCLK[j * NumberOfStatesPlusTwo + i] = dml_max( + v->RequiredDISPCLK[j * NumberOfStatesPlusTwo + + i], + v->MinDispclkUsingSingleDPP); + } else if (v->MinDispclkUsingDualDPP + <= dml_min( + v->MaxDispclk[i], + (j + 1) * v->MaxDppclk[i])) { + v->NoOfDPP[ijk] = 2; + v->RequiredDISPCLK[j * NumberOfStatesPlusTwo + i] = dml_max( + v->RequiredDISPCLK[j * NumberOfStatesPlusTwo + + i], + v->MinDispclkUsingDualDPP); + } else { + v->NoOfDPP[ijk] = 2; + v->RequiredDISPCLK[j * NumberOfStatesPlusTwo + i] = dml_max( + v->RequiredDISPCLK[j * NumberOfStatesPlusTwo + + i], + v->MinDispclkUsingDualDPP); + v->DISPCLK_DPPCLK_Support[j * NumberOfStatesPlusTwo + i] = + 0; + } + + v->TotalNumberOfActiveDPP[j * NumberOfStatesPlusTwo + i] = + v->TotalNumberOfActiveDPP[j * NumberOfStatesPlusTwo + + i] + v->NoOfDPP[ijk]; + } + + if (v->TotalNumberOfActiveDPP[j * NumberOfStatesPlusTwo + i] + > ip->max_num_dpp) { + v->TotalNumberOfActiveDPP[j * NumberOfStatesPlusTwo + i] = 0; + v->RequiredDISPCLK[j * NumberOfStatesPlusTwo + i] = 0; + v->DISPCLK_DPPCLK_Support[j * NumberOfStatesPlusTwo + i] = 1; + + for (k = 0; k < num_planes; k++) { + struct _vcs_dpi_display_pipe_dest_params_st dest = + e2e[v->planes[k].e2e_index].pipe.dest; + ijk = k * 2 * NumberOfStatesPlusTwo + + j * NumberOfStatesPlusTwo + i; + + v->MinDispclkUsingSingleDPP = dml_max( + dest.pixel_rate_mhz, + v->MinDPPCLKUsingSingleDPP[k] * (j + 1)) + * (1 + soc->downspread_percent / 100); + v->MinDispclkUsingDualDPP = dml_max( + dest.pixel_rate_mhz, + v->MinDPPCLKUsingSingleDPP[k] / 2 * (j + 1)) + * (1 + soc->downspread_percent / 100); + + if (i < NumberOfStates) { + v->MinDispclkUsingSingleDPP = + v->MinDispclkUsingSingleDPP + * (1 + + ip->dispclk_ramp_margin_percent + / 100); + v->MinDispclkUsingDualDPP = + v->MinDispclkUsingDualDPP + * (1 + + ip->dispclk_ramp_margin_percent + / 100); + } + + if (v->NumberOfDPPRequiredForDETAndLBSize[k] <= 1) { + v->NoOfDPP[ijk] = 1; + v->RequiredDISPCLK[j * NumberOfStatesPlusTwo + i] = + dml_max( + v->RequiredDISPCLK[j + * NumberOfStatesPlusTwo + + i], + v->MinDispclkUsingSingleDPP); + if (v->MinDispclkUsingSingleDPP + > dml_min( + v->MaxDispclk[i], + (j + 1) + * v->MaxDppclk[i])) { + v->DISPCLK_DPPCLK_Support[j + * NumberOfStatesPlusTwo + i] = + 0; + } + } else { + v->NoOfDPP[ijk] = 2; + v->RequiredDISPCLK[j * NumberOfStatesPlusTwo + i] = + dml_max( + v->RequiredDISPCLK[j + * NumberOfStatesPlusTwo + + i], + v->MinDispclkUsingDualDPP); + if (v->MinDispclkUsingDualDPP + > dml_min( + v->MaxDispclk[i], + (j + 1) + * v->MaxDppclk[i])) { + v->DISPCLK_DPPCLK_Support[j + * NumberOfStatesPlusTwo + i] = + 0; + } + } + v->TotalNumberOfActiveDPP[j * NumberOfStatesPlusTwo + i] = + v->TotalNumberOfActiveDPP[j + * NumberOfStatesPlusTwo + i] + + v->NoOfDPP[ijk]; + } + } + } + } + + // Viewport Size Check + + v->ViewportSizeSupport = 1; + + for (k = 0; k < num_planes; k++) { + if (v->NumberOfDPPRequiredForDETAndLBSize[k] > 2) { + v->ViewportSizeSupport = 0; + } + } + + // Total Available Pipes Support Check + + for (i = 0; i < NumberOfStatesPlusTwo; i++) { + for (j = 0; j < 2; j++) { + if (v->TotalNumberOfActiveDPP[j * NumberOfStatesPlusTwo + i] + <= ip->max_num_dpp) { + v->TotalAvailablePipesSupport[j * NumberOfStatesPlusTwo + i] = 1; + } else { + v->TotalAvailablePipesSupport[j * NumberOfStatesPlusTwo + i] = 0; + } + } + } + + // Urgent Latency Support Check + + for (j = 0; j < 2; j++) { + for (i = 0; i < NumberOfStatesPlusTwo; i++) { + ij = j * NumberOfStatesPlusTwo + i; + for (k = 0; k < num_planes; k++) { + struct _vcs_dpi_display_pipe_source_params_st src = + e2e[v->planes[k].e2e_index].pipe.src; + struct _vcs_dpi_display_pipe_dest_params_st dest = + e2e[v->planes[k].e2e_index].pipe.dest; + struct _vcs_dpi_scaler_ratio_depth_st scale_ratio_depth = + e2e[v->planes[k].e2e_index].pipe.scale_ratio_depth; + struct _vcs_dpi_scaler_taps_st scale_taps = + e2e[v->planes[k].e2e_index].pipe.scale_taps; + ijk = k * 2 * NumberOfStatesPlusTwo + j * NumberOfStatesPlusTwo + i; + + v->SwathWidthYPerState[ijk] = v->SwathWidthYSingleDPP[k] + / v->NoOfDPP[ijk]; + + v->SwathWidthGranularityY = 256 + / dml_ceil_ex(v->BytePerPixelInDETY[k], 1) + / v->MaxSwathHeightY[k]; + v->RoundedUpMaxSwathSizeBytesY = (dml_ceil_ex( + v->SwathWidthYPerState[ijk] - 1, + v->SwathWidthGranularityY) + + v->SwathWidthGranularityY) + * v->BytePerPixelInDETY[k] * v->MaxSwathHeightY[k]; + if (src.source_format == dm_420_10) { + v->RoundedUpMaxSwathSizeBytesY = dml_ceil_ex( + v->RoundedUpMaxSwathSizeBytesY, + 256) + 256; + } + if (v->MaxSwathHeightC[k] > 0) { + v->SwathWidthGranularityC = 256 + / dml_ceil_ex(v->BytePerPixelInDETC[k], 2) + / v->MaxSwathHeightC[k]; + } + v->RoundedUpMaxSwathSizeBytesC = (dml_ceil_ex( + v->SwathWidthYPerState[ijk] / 2 - 1, + v->SwathWidthGranularityC) + + v->SwathWidthGranularityC) + * v->BytePerPixelInDETC[k] * v->MaxSwathHeightC[k]; + if (src.source_format == dm_420_10) { + v->RoundedUpMaxSwathSizeBytesC = dml_ceil_ex( + v->RoundedUpMaxSwathSizeBytesC, + 256) + 256; + } + + if (v->RoundedUpMaxSwathSizeBytesY + v->RoundedUpMaxSwathSizeBytesC + <= ip->det_buffer_size_kbytes * 1024 / 2) { + v->SwathHeightYPerState[ijk] = v->MaxSwathHeightY[k]; + v->SwathHeightCPerState[ijk] = v->MaxSwathHeightC[k]; + } else { + v->SwathHeightYPerState[ijk] = v->MinSwathHeightY[k]; + v->SwathHeightCPerState[ijk] = v->MinSwathHeightC[k]; + } + + if (v->BytePerPixelInDETC[k] == 0) { + v->LinesInDETLuma = ip->det_buffer_size_kbytes * 1024 + / v->BytePerPixelInDETY[k] + / v->SwathWidthYPerState[ijk]; + + v->LinesInDETChroma = 0; + } else if (v->SwathHeightYPerState[ijk] + <= v->SwathHeightCPerState[ijk]) { + v->LinesInDETLuma = ip->det_buffer_size_kbytes * 1024 / 2 + / v->BytePerPixelInDETY[k] + / v->SwathWidthYPerState[ijk]; + v->LinesInDETChroma = ip->det_buffer_size_kbytes * 1024 / 2 + / v->BytePerPixelInDETC[k] + / (v->SwathWidthYPerState[ijk] / 2); + } else { + v->LinesInDETLuma = ip->det_buffer_size_kbytes * 1024 * 2 + / 3 / v->BytePerPixelInDETY[k] + / v->SwathWidthYPerState[ijk]; + v->LinesInDETChroma = ip->det_buffer_size_kbytes * 1024 / 3 + / v->BytePerPixelInDETY[k] + / (v->SwathWidthYPerState[ijk] / 2); + } + + v->EffectiveLBLatencyHidingSourceLinesLuma = + dml_min( + ip->max_line_buffer_lines, + dml_floor_ex( + ip->line_buffer_size_bits + / scale_ratio_depth.lb_depth + / (v->SwathWidthYPerState[ijk] + / dml_max( + scale_ratio_depth.hscl_ratio, + 1)), + 1)) + - (scale_taps.vtaps - 1); + + v->EffectiveLBLatencyHidingSourceLinesChroma = + dml_min( + ip->max_line_buffer_lines, + dml_floor_ex( + ip->line_buffer_size_bits + / scale_ratio_depth.lb_depth + / (v->SwathWidthYPerState[ijk] + / 2 + / dml_max( + scale_ratio_depth.hscl_ratio + / 2, + 1)), + 1)) + - (scale_taps.vtaps_c - 1); + + v->EffectiveDETLBLinesLuma = + dml_floor_ex( + v->LinesInDETLuma + + dml_min( + v->LinesInDETLuma + * v->RequiredDISPCLK[ij] + * v->BytePerPixelInDETY[k] + * v->PSCL_FACTOR[k] + / v->ReturnBWPerState[i], + v->EffectiveLBLatencyHidingSourceLinesLuma), + v->SwathHeightYPerState[ijk]); + + v->EffectiveDETLBLinesChroma = + dml_floor_ex( + v->LinesInDETChroma + + dml_min( + v->LinesInDETChroma + * v->RequiredDISPCLK[ij] + * v->BytePerPixelInDETC[k] + * v->PSCL_FACTOR_CHROMA[k] + / v->ReturnBWPerState[i], + v->EffectiveLBLatencyHidingSourceLinesChroma), + v->SwathHeightCPerState[ijk]); + + if (v->BytePerPixelInDETC[k] == 0) { + v->UrgentLatencySupportUsPerState[ijk] = + v->EffectiveDETLBLinesLuma + * (dest.htotal + / dest.pixel_rate_mhz) + / scale_ratio_depth.vscl_ratio + - v->EffectiveDETLBLinesLuma + * v->SwathWidthYPerState[ijk] + * dml_ceil_ex( + v->BytePerPixelInDETY[k], + 1) + / (v->ReturnBWPerState[i] + / v->NoOfDPP[ijk]); + } else { + v->UrgentLatencySupportUsPerState[ijk] = + dml_min( + v->EffectiveDETLBLinesLuma + * (dest.htotal + / dest.pixel_rate_mhz) + / scale_ratio_depth.vscl_ratio + - v->EffectiveDETLBLinesLuma + * v->SwathWidthYPerState[ijk] + * dml_ceil_ex( + v->BytePerPixelInDETY[k], + 1) + / (v->ReturnBWPerState[i] + / v->NoOfDPP[ijk]), + v->EffectiveDETLBLinesChroma + * (dest.htotal + / dest.pixel_rate_mhz) + / (scale_ratio_depth.vscl_ratio + / 2) + - v->EffectiveDETLBLinesChroma + * v->SwathWidthYPerState[ijk] + / 2 + * dml_ceil_ex( + v->BytePerPixelInDETC[k], + 2) + / (v->ReturnBWPerState[i] + / v->NoOfDPP[ijk])); + } + + } + } + } + + for (i = 0; i < NumberOfStatesPlusTwo; i++) { + for (j = 0; j < 2; j++) { + ij = j * NumberOfStatesPlusTwo + i; + + v->UrgentLatencySupport[ij] = 1; + for (k = 0; k < num_planes; k++) { + ijk = k * 2 * NumberOfStatesPlusTwo + j * NumberOfStatesPlusTwo + i; + + if (v->UrgentLatencySupportUsPerState[ijk] + < soc->urgent_latency_us / 1) { + v->UrgentLatencySupport[ij] = 0; + } + } + } + } + + // Prefetch Check + + for (i = 0; i < NumberOfStatesPlusTwo; i++) { + for (j = 0; j < 2; j++) { + ij = j * NumberOfStatesPlusTwo + i; + + v->TotalNumberOfDCCActiveDPP[ij] = 0; + for (k = 0; k < num_planes; k++) { + struct _vcs_dpi_display_pipe_source_params_st src = + e2e[v->planes[k].e2e_index].pipe.src; + ijk = k * 2 * NumberOfStatesPlusTwo + j * NumberOfStatesPlusTwo + i; + + if (src.dcc == 1) { + v->TotalNumberOfDCCActiveDPP[ij] = + v->TotalNumberOfDCCActiveDPP[ij] + + v->NoOfDPP[ijk]; + } + } + } + } + + for (i = 0; i < NumberOfStatesPlusTwo; i++) { + for (j = 0; j < 2; j++) { + ij = j * NumberOfStatesPlusTwo + i; + + v->ProjectedDCFCLKDeepSleep = 8; + + for (k = 0; k < num_planes; k++) { + struct _vcs_dpi_display_pipe_dest_params_st dest = + e2e[v->planes[k].e2e_index].pipe.dest; + struct _vcs_dpi_scaler_ratio_depth_st scale_ratio_depth = + e2e[v->planes[k].e2e_index].pipe.scale_ratio_depth; + ijk = k * 2 * NumberOfStatesPlusTwo + j * NumberOfStatesPlusTwo + i; + + v->ProjectedDCFCLKDeepSleep = dml_max( + v->ProjectedDCFCLKDeepSleep, + dest.pixel_rate_mhz / 16); + if (v->BytePerPixelInDETC[k] == 0) { + if (scale_ratio_depth.vscl_ratio <= 1) { + v->ProjectedDCFCLKDeepSleep = + dml_max( + v->ProjectedDCFCLKDeepSleep, + 1.1 + * dml_ceil_ex( + v->BytePerPixelInDETY[k], + 1) + / 64 + * scale_ratio_depth.hscl_ratio + * dest.pixel_rate_mhz + / v->NoOfDPP[ijk]); + } else { + v->ProjectedDCFCLKDeepSleep = + dml_max( + v->ProjectedDCFCLKDeepSleep, + 1.1 + * dml_ceil_ex( + v->BytePerPixelInDETY[k], + 1) + / 64 + * v->PSCL_FACTOR[k] + * v->RequiredDISPCLK[ij] + / (1 + + j)); + } + + } else { + if (scale_ratio_depth.vscl_ratio <= 1) { + v->ProjectedDCFCLKDeepSleep = + dml_max( + v->ProjectedDCFCLKDeepSleep, + 1.1 + * dml_ceil_ex( + v->BytePerPixelInDETY[k], + 1) + / 32 + * scale_ratio_depth.hscl_ratio + * dest.pixel_rate_mhz + / v->NoOfDPP[ijk]); + } else { + v->ProjectedDCFCLKDeepSleep = + dml_max( + v->ProjectedDCFCLKDeepSleep, + 1.1 + * dml_ceil_ex( + v->BytePerPixelInDETY[k], + 1) + / 32 + * v->PSCL_FACTOR[k] + * v->RequiredDISPCLK[ij] + / (1 + + j)); + } + if ((scale_ratio_depth.vscl_ratio / 2) <= 1) { + v->ProjectedDCFCLKDeepSleep = + dml_max( + v->ProjectedDCFCLKDeepSleep, + 1.1 + * dml_ceil_ex( + v->BytePerPixelInDETC[k], + 2) + / 32 + * scale_ratio_depth.hscl_ratio + / 2 + * dest.pixel_rate_mhz + / v->NoOfDPP[ijk]); + } else { + v->ProjectedDCFCLKDeepSleep = + dml_max( + v->ProjectedDCFCLKDeepSleep, + 1.1 + * dml_ceil_ex( + v->BytePerPixelInDETC[k], + 2) + / 32 + * v->PSCL_FACTOR_CHROMA[k] + * v->RequiredDISPCLK[ij] + / (1 + + j)); + } + + } + } + + for (k = 0; k < num_planes; k++) { + struct _vcs_dpi_display_pipe_source_params_st src = + e2e[v->planes[k].e2e_index].pipe.src; + struct _vcs_dpi_display_pipe_dest_params_st dest = + e2e[v->planes[k].e2e_index].pipe.dest; + struct _vcs_dpi_scaler_ratio_depth_st scale_ratio_depth = + e2e[v->planes[k].e2e_index].pipe.scale_ratio_depth; + struct _vcs_dpi_scaler_taps_st scale_taps = + e2e[v->planes[k].e2e_index].pipe.scale_taps; + struct _vcs_dpi_display_output_params_st dout = + e2e[v->planes[k].e2e_index].dout; + ijk = k * 2 * NumberOfStatesPlusTwo + j * NumberOfStatesPlusTwo + i; + + if (src.dcc == 1) { + v->MetaReqHeightY = 8 * v->Read256BlockHeightY[k]; + v->MetaReqWidthY = 64 * 256 + / dml_ceil_ex(v->BytePerPixelInDETY[k], 1) + / v->MetaReqHeightY; + v->MetaSurfaceWidthY = dml_ceil_ex( + src.viewport_width / v->NoOfDPP[ijk] - 1, + v->MetaReqWidthY) + v->MetaReqWidthY; + v->MetaSurfaceHeightY = dml_ceil_ex( + src.viewport_height - 1, + v->MetaReqHeightY) + v->MetaReqHeightY; + if (ip->pte_enable == 1) { + v->MetaPteBytesPerFrameY = + (dml_ceil_ex( + (v->MetaSurfaceWidthY + * v->MetaSurfaceHeightY + * dml_ceil_ex( + v->BytePerPixelInDETY[k], + 1) + / 256.0 + - 4096) + / 8 + / 4096, + 1) + 1) * 64; + } else { + v->MetaPteBytesPerFrameY = 0; + } + if (src.source_scan == dm_horz) { + v->MetaRowBytesY = + v->MetaSurfaceWidthY + * v->MetaReqHeightY + * dml_ceil_ex( + v->BytePerPixelInDETY[k], + 1) + / 256; + } else { + v->MetaRowBytesY = + v->MetaSurfaceHeightY + * v->MetaReqWidthY + * dml_ceil_ex( + v->BytePerPixelInDETY[k], + 1) + / 256; + } + } else { + v->MetaPteBytesPerFrameY = 0; + v->MetaRowBytesY = 0; + } + + if (ip->pte_enable == 1) { + if (src.sw_mode == dm_sw_linear) { + v->MacroTileBlockSizeBytesY = 256; + v->MacroTileBlockHeightY = 1; + } else if (src.sw_mode == dm_sw_4kb_s + || src.sw_mode == dm_sw_4kb_s_x + || src.sw_mode == dm_sw_4kb_d + || src.sw_mode == dm_sw_4kb_d_x) { + v->MacroTileBlockSizeBytesY = 4096; + v->MacroTileBlockHeightY = 4 + * v->Read256BlockHeightY[k]; + } else if (src.sw_mode == dm_sw_64kb_s + || src.sw_mode == dm_sw_64kb_s_t + || src.sw_mode == dm_sw_64kb_s_x + || src.sw_mode == dm_sw_64kb_d + || src.sw_mode == dm_sw_64kb_d_t + || src.sw_mode == dm_sw_64kb_d_x) { + v->MacroTileBlockSizeBytesY = 64 * 1024; + v->MacroTileBlockHeightY = 16 + * v->Read256BlockHeightY[k]; + } else { + v->MacroTileBlockSizeBytesY = 256 * 1024; + v->MacroTileBlockHeightY = 32 + * v->Read256BlockHeightY[k]; + } + if (v->MacroTileBlockSizeBytesY <= 65536) { + v->DataPTEReqHeightY = v->MacroTileBlockHeightY; + } else { + v->DataPTEReqHeightY = 16 + * v->Read256BlockHeightY[k]; + } + v->DataPTEReqWidthY = 4096 + / dml_ceil_ex(v->BytePerPixelInDETY[k], 1) + / v->DataPTEReqHeightY * 8; + if (src.sw_mode == dm_sw_linear) { + v->DPTEBytesPerRowY = + 64 + * (dml_ceil_ex( + (src.viewport_width + / v->NoOfDPP[ijk] + * dml_min( + 128, + dml_pow( + 2, + dml_floor_ex( + dml_log( + ip->dpte_buffer_size_in_pte_reqs + * v->DataPTEReqWidthY + / (src.viewport_width + / v->NoOfDPP[ijk]), + 2), + 1))) + - 1) + / v->DataPTEReqWidthY, + 1) + + 1); + } else if (src.source_scan == dm_horz) { + v->DPTEBytesPerRowY = + 64 + * (dml_ceil_ex( + (src.viewport_width + / v->NoOfDPP[ijk] + - 1) + / v->DataPTEReqWidthY, + 1) + + 1); + } else { + v->DPTEBytesPerRowY = + 64 + * (dml_ceil_ex( + (src.viewport_height + - 1) + / v->DataPTEReqHeightY, + 1) + + 1); + } + } else { + v->DPTEBytesPerRowY = 0; + } + + if (src.source_format != dm_444_64 && src.source_format != dm_444_32 + && src.source_format != dm_444_16) { + if (src.dcc == 1) { + v->MetaReqHeightC = 8 * v->Read256BlockHeightC[k]; + v->MetaReqWidthC = + 64 * 256 + / dml_ceil_ex( + v->BytePerPixelInDETC[k], + 2) + / v->MetaReqHeightC; + v->MetaSurfaceWidthC = dml_ceil_ex( + src.viewport_width / v->NoOfDPP[ijk] + / 2 - 1, + v->MetaReqWidthC) + + v->MetaReqWidthC; + v->MetaSurfaceHeightC = dml_ceil_ex( + src.viewport_height / 2 - 1, + v->MetaReqHeightC) + + v->MetaReqHeightC; + if (ip->pte_enable == 1) { + v->MetaPteBytesPerFrameC = + (dml_ceil_ex( + (v->MetaSurfaceWidthC + * v->MetaSurfaceHeightC + * dml_ceil_ex( + v->BytePerPixelInDETC[k], + 2) + / 256.0 + - 4096) + / 8 + / 4096, + 1) + 1) + * 64; + } else { + v->MetaPteBytesPerFrameC = 0; + } + if (src.source_scan == dm_horz) { + v->MetaRowBytesC = + v->MetaSurfaceWidthC + * v->MetaReqHeightC + * dml_ceil_ex( + v->BytePerPixelInDETC[k], + 2) + / 256; + } else { + v->MetaRowBytesC = + v->MetaSurfaceHeightC + * v->MetaReqWidthC + * dml_ceil_ex( + v->BytePerPixelInDETC[k], + 2) + / 256; + } + } else { + v->MetaPteBytesPerFrameC = 0; + v->MetaRowBytesC = 0; + } + + if (ip->pte_enable == 1) { + if (src.sw_mode == dm_sw_linear) { + v->MacroTileBlockSizeBytesC = 256; + v->MacroTileBlockHeightC = 1; + } else if (src.sw_mode == dm_sw_4kb_s + || src.sw_mode == dm_sw_4kb_s_x + || src.sw_mode == dm_sw_4kb_d + || src.sw_mode == dm_sw_4kb_d_x) { + v->MacroTileBlockSizeBytesC = 4096; + v->MacroTileBlockHeightC = 4 + * v->Read256BlockHeightC[k]; + } else if (src.sw_mode == dm_sw_64kb_s + || src.sw_mode == dm_sw_64kb_s_t + || src.sw_mode == dm_sw_64kb_s_x + || src.sw_mode == dm_sw_64kb_d + || src.sw_mode == dm_sw_64kb_d_t + || src.sw_mode == dm_sw_64kb_d_x) { + v->MacroTileBlockSizeBytesC = 64 * 1024; + v->MacroTileBlockHeightC = 16 + * v->Read256BlockHeightC[k]; + } else { + v->MacroTileBlockSizeBytesC = 256 * 1024; + v->MacroTileBlockHeightC = 32 + * v->Read256BlockHeightC[k]; + } + v->MacroTileBlockWidthC = + v->MacroTileBlockSizeBytesC + / dml_ceil_ex( + v->BytePerPixelInDETC[k], + 2) + / v->MacroTileBlockHeightC; + if (v->MacroTileBlockSizeBytesC <= 65536) { + v->DataPTEReqHeightC = + v->MacroTileBlockHeightC; + } else { + v->DataPTEReqHeightC = 16 + * v->Read256BlockHeightC[k]; + } + v->DataPTEReqWidthC = + 4096 + / dml_ceil_ex( + v->BytePerPixelInDETC[k], + 2) + / v->DataPTEReqHeightC + * 8; + if (src.sw_mode == dm_sw_linear) { + v->DPTEBytesPerRowC = + 64 + * (dml_ceil_ex( + (src.viewport_width + / v->NoOfDPP[ijk] + / 2 + * dml_min( + 128, + dml_pow( + 2, + dml_floor_ex( + dml_log( + ip->dpte_buffer_size_in_pte_reqs + * v->DataPTEReqWidthC + / (src.viewport_width + / v->NoOfDPP[ijk] + / 2), + 2), + 1))) + - 1) + / v->DataPTEReqWidthC, + 1) + + 1); + } else if (src.source_scan == dm_horz) { + v->DPTEBytesPerRowC = + 64 + * (dml_ceil_ex( + (src.viewport_width + / v->NoOfDPP[ijk] + / 2 + - 1) + / v->DataPTEReqWidthC, + 1) + + 1); + } else { + v->DPTEBytesPerRowC = + 64 + * (dml_ceil_ex( + (src.viewport_height + / 2 + - 1) + / v->DataPTEReqHeightC, + 1) + + 1); + } + } else { + v->DPTEBytesPerRowC = 0; + } + } else { + v->DPTEBytesPerRowC = 0; + v->MetaPteBytesPerFrameC = 0; + v->MetaRowBytesC = 0; + } + + v->DPTEBytesPerRow[k] = v->DPTEBytesPerRowY + v->DPTEBytesPerRowC; + v->MetaPTEBytesPerFrame[k] = v->MetaPteBytesPerFrameY + + v->MetaPteBytesPerFrameC; + v->MetaRowBytes[k] = v->MetaRowBytesY + v->MetaRowBytesC; + + v->VInitY = (scale_ratio_depth.vscl_ratio + scale_taps.vtaps + 1 + + dest.interlaced * 0.5 + * scale_ratio_depth.vscl_ratio) + / 2.0; + v->PrefillY[k] = dml_floor_ex(v->VInitY, 1); + v->MaxNumSwY[k] = dml_ceil_ex( + (v->PrefillY[k] - 1.0) + / v->SwathHeightYPerState[ijk], + 1) + 1.0; + + if (v->PrefillY[k] > 1) { + v->MaxPartialSwY = ((int) (v->PrefillY[k] - 2)) + % ((int) v->SwathHeightYPerState[ijk]); + } else { + v->MaxPartialSwY = ((int) (v->PrefillY[k] + + v->SwathHeightYPerState[ijk] - 2)) + % ((int) v->SwathHeightYPerState[ijk]); + } + v->MaxPartialSwY = dml_max(1, v->MaxPartialSwY); + + v->PrefetchLinesY[k] = v->MaxNumSwY[k] + * v->SwathHeightYPerState[ijk] + v->MaxPartialSwY; + + if (src.source_format != dm_444_64 && src.source_format != dm_444_32 + && src.source_format != dm_444_16) { + v->VInitC = + (scale_ratio_depth.vscl_ratio / 2 + + scale_taps.vtaps + 1 + + dest.interlaced * 0.5 + * scale_ratio_depth.vscl_ratio + / 2) / 2.0; + v->PrefillC[k] = dml_floor_ex(v->VInitC, 1); + v->MaxNumSwC[k] = + dml_ceil_ex( + (v->PrefillC[k] - 1.0) + / v->SwathHeightCPerState[ijk], + 1) + 1.0; + if (v->PrefillC[k] > 1) { + v->MaxPartialSwC = + ((int) (v->PrefillC[k] - 2)) + % ((int) v->SwathHeightCPerState[ijk]); + } else { + v->MaxPartialSwC = + ((int) (v->PrefillC[k] + + v->SwathHeightCPerState[ijk] + - 2)) + % ((int) v->SwathHeightCPerState[ijk]); + } + v->MaxPartialSwC = dml_max(1, v->MaxPartialSwC); + + v->PrefetchLinesC[k] = v->MaxNumSwC[k] + * v->SwathHeightCPerState[ijk] + + v->MaxPartialSwC; + } else { + v->PrefetchLinesC[k] = 0; + } + + v->dst_x_after_scaler = 90 * dest.pixel_rate_mhz + / (v->RequiredDISPCLK[ij] / (j + 1)) + + 42 * dest.pixel_rate_mhz / v->RequiredDISPCLK[ij]; + if (v->NoOfDPP[ijk] > 1) { + v->dst_x_after_scaler = v->dst_x_after_scaler + + dest.recout_width / 2.0; + } + + if (dout.output_format == dm_420) { + v->dst_y_after_scaler = 1; + } else { + v->dst_y_after_scaler = 0; + } + + v->TimeCalc = 24 / v->ProjectedDCFCLKDeepSleep; + + v->VUpdateOffset = dml_ceil_ex(dest.htotal / 4, 1); + v->TotalRepeaterDelay = ip->max_inter_dcn_tile_repeaters + * (2 / (v->RequiredDISPCLK[ij] / (j + 1)) + + 3 / v->RequiredDISPCLK[ij]); + v->VUpdateWidth = (14 / v->ProjectedDCFCLKDeepSleep + + 12 / (v->RequiredDISPCLK[ij] / (j + 1)) + + v->TotalRepeaterDelay) * dest.pixel_rate_mhz; + v->VReadyOffset = + dml_max( + 150 + / (v->RequiredDISPCLK[ij] + / (j + + 1)), + v->TotalRepeaterDelay + + 20 + / v->ProjectedDCFCLKDeepSleep + + 10 + / (v->RequiredDISPCLK[ij] + / (j + + 1))) + * dest.pixel_rate_mhz; + + v->TimeSetup = + (v->VUpdateOffset + v->VUpdateWidth + + v->VReadyOffset) + / dest.pixel_rate_mhz; + + v->ExtraLatency = + v->UrgentRoundTripAndOutOfOrderLatencyPerState[i] + + (v->TotalNumberOfActiveDPP[ij] + * ip->pixel_chunk_size_kbytes + + v->TotalNumberOfDCCActiveDPP[ij] + * ip->meta_chunk_size_kbytes) + * 1024 + / v->ReturnBWPerState[i]; + + if (ip->pte_enable == 1) { + v->ExtraLatency = v->ExtraLatency + + v->TotalNumberOfActiveDPP[ij] + * ip->pte_chunk_size_kbytes + * 1024 + / v->ReturnBWPerState[i]; + } + + if (ip->can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one + == 1) { + v->MaximumVStartup = dest.vtotal - dest.vactive - 1; + } else { + v->MaximumVStartup = dest.vsync_plus_back_porch - 1; + } + + v->LineTimesForPrefetch[k] = + v->MaximumVStartup + - soc->urgent_latency_us + / (dest.htotal + / dest.pixel_rate_mhz) + - (v->TimeCalc + v->TimeSetup) + / (dest.htotal + / dest.pixel_rate_mhz) + - (v->dst_y_after_scaler + + v->dst_x_after_scaler + / dest.htotal); + + v->LineTimesForPrefetch[k] = dml_floor_ex( + 4.0 * (v->LineTimesForPrefetch[k] + 0.125), + 1) / 4; + + v->PrefetchBW[k] = + (v->MetaPTEBytesPerFrame[k] + 2 * v->MetaRowBytes[k] + + 2 * v->DPTEBytesPerRow[k] + + v->PrefetchLinesY[k] + * v->SwathWidthYPerState[ijk] + * dml_ceil_ex( + v->BytePerPixelInDETY[k], + 1) + + v->PrefetchLinesC[k] + * v->SwathWidthYPerState[ijk] + / 2 + * dml_ceil_ex( + v->BytePerPixelInDETC[k], + 2)) + / (v->LineTimesForPrefetch[k] + * dest.htotal + / dest.pixel_rate_mhz); + } + + v->BWAvailableForImmediateFlip = v->ReturnBWPerState[i]; + + for (k = 0; k < num_planes; k++) { + v->BWAvailableForImmediateFlip = v->BWAvailableForImmediateFlip + - dml_max(v->ReadBandwidth[k], v->PrefetchBW[k]); + } + + v->TotalImmediateFlipBytes = 0; + + for (k = 0; k < num_planes; k++) { + struct _vcs_dpi_display_pipe_source_params_st src = + e2e[v->planes[k].e2e_index].pipe.src; + + if (src.source_format != dm_420_8 + && src.source_format != dm_420_10) { + v->TotalImmediateFlipBytes = v->TotalImmediateFlipBytes + + v->MetaPTEBytesPerFrame[k] + + v->MetaRowBytes[k] + + v->DPTEBytesPerRow[k]; + } + } + + for (k = 0; k < num_planes; k++) { + struct _vcs_dpi_display_pipe_source_params_st src = + e2e[v->planes[k].e2e_index].pipe.src; + struct _vcs_dpi_display_pipe_dest_params_st dest = + e2e[v->planes[k].e2e_index].pipe.dest; + ijk = k * 2 * NumberOfStatesPlusTwo + j * NumberOfStatesPlusTwo + i; + + if (ip->pte_enable == 1 && src.dcc == 1) { + v->TimeForMetaPTEWithImmediateFlip = + dml_max( + v->MetaPTEBytesPerFrame[k] + / v->PrefetchBW[k], + dml_max( + v->MetaPTEBytesPerFrame[k] + * v->TotalImmediateFlipBytes + / (v->BWAvailableForImmediateFlip + * (v->MetaPTEBytesPerFrame[k] + + v->MetaRowBytes[k] + + v->DPTEBytesPerRow[k])), + dml_max( + v->ExtraLatency, + dml_max( + soc->urgent_latency_us, + dest.htotal + / dest.pixel_rate_mhz + / 4)))); + + v->TimeForMetaPTEWithoutImmediateFlip = + dml_max( + v->MetaPTEBytesPerFrame[k] + / v->PrefetchBW[k], + dml_max( + v->ExtraLatency, + dest.htotal + / dest.pixel_rate_mhz + / 4)); + } else { + v->TimeForMetaPTEWithImmediateFlip = dest.htotal + / dest.pixel_rate_mhz / 4; + v->TimeForMetaPTEWithoutImmediateFlip = dest.htotal + / dest.pixel_rate_mhz / 4; + } + + if (ip->pte_enable == 1 || src.dcc == 1) { + v->TimeForMetaAndDPTERowWithImmediateFlip = + dml_max( + (v->MetaRowBytes[k] + + v->DPTEBytesPerRow[k]) + / v->PrefetchBW[k], + dml_max( + (v->MetaRowBytes[k] + + v->DPTEBytesPerRow[k]) + * v->TotalImmediateFlipBytes + / (v->BWAvailableForImmediateFlip + * (v->MetaPTEBytesPerFrame[k] + + v->MetaRowBytes[k] + + v->DPTEBytesPerRow[k])), + dml_max( + dest.htotal + / dest.pixel_rate_mhz + - v->TimeForMetaPTEWithImmediateFlip, + dml_max( + v->ExtraLatency, + 2 + * soc->urgent_latency_us)))); + + v->TimeForMetaAndDPTERowWithoutImmediateFlip = + dml_max( + (v->MetaRowBytes[k] + + v->DPTEBytesPerRow[k]) + / v->PrefetchBW[k], + dml_max( + dest.htotal + / dest.pixel_rate_mhz + - v->TimeForMetaPTEWithoutImmediateFlip, + v->ExtraLatency)); + } else { + v->TimeForMetaAndDPTERowWithImmediateFlip = + dml_max( + dest.htotal + / dest.pixel_rate_mhz + - v->TimeForMetaPTEWithImmediateFlip, + v->ExtraLatency + - v->TimeForMetaPTEWithImmediateFlip); + v->TimeForMetaAndDPTERowWithoutImmediateFlip = + dml_max( + dest.htotal + / dest.pixel_rate_mhz + - v->TimeForMetaPTEWithoutImmediateFlip, + v->ExtraLatency + - v->TimeForMetaPTEWithoutImmediateFlip); + } + + v->LinesForMetaPTEWithImmediateFlip[k] = + dml_floor_ex( + 4.0 + * (v->TimeForMetaPTEWithImmediateFlip + / (dest.htotal + / dest.pixel_rate_mhz) + + 0.125), + 1) / 4.0; + + v->LinesForMetaPTEWithoutImmediateFlip[k] = + dml_floor_ex( + 4.0 + * (v->TimeForMetaPTEWithoutImmediateFlip + / (dest.htotal + / dest.pixel_rate_mhz) + + 0.125), + 1) / 4.0; + + v->LinesForMetaAndDPTERowWithImmediateFlip[k] = + dml_floor_ex( + 4.0 + * (v->TimeForMetaAndDPTERowWithImmediateFlip + / (dest.htotal + / dest.pixel_rate_mhz) + + 0.125), + 1) / 4.0; + + v->LinesForMetaAndDPTERowWithoutImmediateFlip[k] = + dml_floor_ex( + 4.0 + * (v->TimeForMetaAndDPTERowWithoutImmediateFlip + / (dest.htotal + / dest.pixel_rate_mhz) + + 0.125), + 1) / 4.0; + + v->LineTimesToRequestPrefetchPixelDataWithImmediateFlip = + v->LineTimesForPrefetch[k] + - v->LinesForMetaPTEWithImmediateFlip[k] + - v->LinesForMetaAndDPTERowWithImmediateFlip[k]; + + v->LineTimesToRequestPrefetchPixelDataWithoutImmediateFlip = + v->LineTimesForPrefetch[k] + - v->LinesForMetaPTEWithoutImmediateFlip[k] + - v->LinesForMetaAndDPTERowWithoutImmediateFlip[k]; + + if (v->LineTimesToRequestPrefetchPixelDataWithImmediateFlip > 0) { + v->VRatioPreYWithImmediateFlip[ijk] = + v->PrefetchLinesY[k] + / v->LineTimesToRequestPrefetchPixelDataWithImmediateFlip; + if (v->SwathHeightYPerState[ijk] > 4) { + if (v->LineTimesToRequestPrefetchPixelDataWithImmediateFlip + - (v->PrefillY[k] - 3.0) / 2.0 + > 0) { + v->VRatioPreYWithImmediateFlip[ijk] = + dml_max( + v->VRatioPreYWithImmediateFlip[ijk], + (v->MaxNumSwY[k] + * v->SwathHeightYPerState[ijk]) + / (v->LineTimesToRequestPrefetchPixelDataWithImmediateFlip + - (v->PrefillY[k] + - 3.0) + / 2.0)); + } else { + v->VRatioPreYWithImmediateFlip[ijk] = + 999999; + } + } + v->VRatioPreCWithImmediateFlip[ijk] = + v->PrefetchLinesC[k] + / v->LineTimesToRequestPrefetchPixelDataWithImmediateFlip; + if (v->SwathHeightCPerState[ijk] > 4) { + if (v->LineTimesToRequestPrefetchPixelDataWithImmediateFlip + - (v->PrefillC[k] - 3.0) / 2.0 + > 0) { + v->VRatioPreCWithImmediateFlip[ijk] = + dml_max( + v->VRatioPreCWithImmediateFlip[ijk], + (v->MaxNumSwC[k] + * v->SwathHeightCPerState[ijk]) + / (v->LineTimesToRequestPrefetchPixelDataWithImmediateFlip + - (v->PrefillC[k] + - 3.0) + / 2.0)); + } else { + v->VRatioPreCWithImmediateFlip[ijk] = + 999999; + } + } + + v->RequiredPrefetchPixelDataBWWithImmediateFlip[ijk] = + v->NoOfDPP[ijk] + * (v->PrefetchLinesY[k] + / v->LineTimesToRequestPrefetchPixelDataWithImmediateFlip + * dml_ceil_ex( + v->BytePerPixelInDETY[k], + 1) + + v->PrefetchLinesC[k] + / v->LineTimesToRequestPrefetchPixelDataWithImmediateFlip + * dml_ceil_ex( + v->BytePerPixelInDETC[k], + 2) + / 2) + * v->SwathWidthYPerState[ijk] + / (dest.htotal + / dest.pixel_rate_mhz); + } else { + v->VRatioPreYWithImmediateFlip[ijk] = 999999; + v->VRatioPreCWithImmediateFlip[ijk] = 999999; + v->RequiredPrefetchPixelDataBWWithImmediateFlip[ijk] = + 999999; + } + + if (v->LineTimesToRequestPrefetchPixelDataWithoutImmediateFlip + > 0) { + v->VRatioPreYWithoutImmediateFlip[ijk] = + v->PrefetchLinesY[k] + / v->LineTimesToRequestPrefetchPixelDataWithoutImmediateFlip; + if (v->SwathHeightYPerState[ijk] > 4) { + if (v->LineTimesToRequestPrefetchPixelDataWithoutImmediateFlip + - (v->PrefillY[k] - 3.0) / 2.0 + > 0) { + v->VRatioPreYWithoutImmediateFlip[ijk] = + dml_max( + v->VRatioPreYWithoutImmediateFlip[ijk], + (v->MaxNumSwY[k] + * v->SwathHeightYPerState[ijk]) + / (v->LineTimesToRequestPrefetchPixelDataWithoutImmediateFlip + - (v->PrefillY[k] + - 3.0) + / 2.0)); + } else { + v->VRatioPreYWithoutImmediateFlip[ijk] = + 999999; + } + } + v->VRatioPreCWithoutImmediateFlip[ijk] = + v->PrefetchLinesC[k] + / v->LineTimesToRequestPrefetchPixelDataWithoutImmediateFlip; + if (v->SwathHeightCPerState[ijk] > 4) { + if (v->LineTimesToRequestPrefetchPixelDataWithoutImmediateFlip + - (v->PrefillC[k] - 3.0) / 2.0 + > 0) { + v->VRatioPreCWithoutImmediateFlip[ijk] = + dml_max( + v->VRatioPreCWithoutImmediateFlip[ijk], + (v->MaxNumSwC[k] + * v->SwathHeightCPerState[ijk]) + / (v->LineTimesToRequestPrefetchPixelDataWithoutImmediateFlip + - (v->PrefillC[k] + - 3.0) + / 2.0)); + } else { + v->VRatioPreCWithoutImmediateFlip[ijk] = + 999999; + } + } + + v->RequiredPrefetchPixelDataBWWithoutImmediateFlip[ijk] = + v->NoOfDPP[ijk] + * (v->PrefetchLinesY[k] + / v->LineTimesToRequestPrefetchPixelDataWithoutImmediateFlip + * dml_ceil_ex( + v->BytePerPixelInDETY[k], + 1) + + v->PrefetchLinesC[k] + / v->LineTimesToRequestPrefetchPixelDataWithoutImmediateFlip + * dml_ceil_ex( + v->BytePerPixelInDETC[k], + 2) + / 2) + * v->SwathWidthYPerState[ijk] + / (dest.htotal + / dest.pixel_rate_mhz); + } else { + v->VRatioPreYWithoutImmediateFlip[ijk] = 999999; + v->VRatioPreCWithoutImmediateFlip[ijk] = 999999; + v->RequiredPrefetchPixelDataBWWithoutImmediateFlip[ijk] = + 999999; + } + } + + v->MaximumReadBandwidthWithPrefetchWithImmediateFlip = 0; + + for (k = 0; k < num_planes; k++) { + struct _vcs_dpi_display_pipe_source_params_st src = + e2e[v->planes[k].e2e_index].pipe.src; + struct _vcs_dpi_display_pipe_dest_params_st dest = + e2e[v->planes[k].e2e_index].pipe.dest; + ijk = k * 2 * NumberOfStatesPlusTwo + j * NumberOfStatesPlusTwo + i; + + if (src.source_format != dm_420_8 + && src.source_format != dm_420_10) { + v->MaximumReadBandwidthWithPrefetchWithImmediateFlip = + v->MaximumReadBandwidthWithPrefetchWithImmediateFlip + + dml_max( + v->ReadBandwidth[k], + v->RequiredPrefetchPixelDataBWWithImmediateFlip[ijk]) + + dml_max( + v->MetaPTEBytesPerFrame[k] + / (v->LinesForMetaPTEWithImmediateFlip[k] + * dest.htotal + / dest.pixel_rate_mhz), + (v->MetaRowBytes[k] + + v->DPTEBytesPerRow[k]) + / (v->LinesForMetaAndDPTERowWithImmediateFlip[k] + * dest.htotal + / dest.pixel_rate_mhz)); + } else { + v->MaximumReadBandwidthWithPrefetchWithImmediateFlip = + v->MaximumReadBandwidthWithPrefetchWithImmediateFlip + + dml_max( + v->ReadBandwidth[k], + v->RequiredPrefetchPixelDataBWWithoutImmediateFlip[ijk]); + } + } + + v->MaximumReadBandwidthWithPrefetchWithoutImmediateFlip = 0; + + for (k = 0; k < num_planes; k++) { + ijk = k * 2 * NumberOfStatesPlusTwo + j * NumberOfStatesPlusTwo + i; + + v->MaximumReadBandwidthWithPrefetchWithoutImmediateFlip = + v->MaximumReadBandwidthWithPrefetchWithoutImmediateFlip + + dml_max( + v->ReadBandwidth[k], + v->RequiredPrefetchPixelDataBWWithoutImmediateFlip[ijk]); + } + + v->PrefetchSupportedWithImmediateFlip[ij] = 1; + if (v->MaximumReadBandwidthWithPrefetchWithImmediateFlip + > v->ReturnBWPerState[i]) { + v->PrefetchSupportedWithImmediateFlip[ij] = 0; + } + for (k = 0; k < num_planes; k++) { + if (v->LineTimesForPrefetch[k] < 2 + || v->LinesForMetaPTEWithImmediateFlip[k] >= 8 + || v->LinesForMetaAndDPTERowWithImmediateFlip[k] + >= 16) { + v->PrefetchSupportedWithImmediateFlip[ij] = 0; + } + } + + v->PrefetchSupportedWithoutImmediateFlip[ij] = 1; + if (v->MaximumReadBandwidthWithPrefetchWithoutImmediateFlip + > v->ReturnBWPerState[i]) { + v->PrefetchSupportedWithoutImmediateFlip[ij] = 0; + } + for (k = 0; k < num_planes; k++) { + if (v->LineTimesForPrefetch[k] < 2 + || v->LinesForMetaPTEWithoutImmediateFlip[k] >= 8 + || v->LinesForMetaAndDPTERowWithoutImmediateFlip[k] + >= 16) { + v->PrefetchSupportedWithoutImmediateFlip[ij] = 0; + } + } + } + } + + for (i = 0; i < NumberOfStatesPlusTwo; i++) { + for (j = 0; j < 2; j++) { + ij = j * NumberOfStatesPlusTwo + i; + + v->VRatioInPrefetchSupportedWithImmediateFlip[ij] = 1; + for (k = 0; k < num_planes; k++) { + struct _vcs_dpi_display_pipe_source_params_st src = + e2e[v->planes[k].e2e_index].pipe.src; + ijk = k * 2 * NumberOfStatesPlusTwo + j * NumberOfStatesPlusTwo + i; + + if (((src.source_format != dm_420_8 + && src.source_format != dm_420_10) + && (v->VRatioPreYWithImmediateFlip[ijk] > 4 + || v->VRatioPreCWithImmediateFlip[ijk] + > 4)) + || ((src.source_format == dm_420_8 + || src.source_format == dm_420_10) + && (v->VRatioPreYWithoutImmediateFlip[ijk] + > 4 + || v->VRatioPreCWithoutImmediateFlip[ijk] + > 4))) { + v->VRatioInPrefetchSupportedWithImmediateFlip[ij] = 0; + } + } + v->VRatioInPrefetchSupportedWithoutImmediateFlip[ij] = 1; + for (k = 0; k < num_planes; k++) { + ijk = k * 2 * NumberOfStatesPlusTwo + j * NumberOfStatesPlusTwo + i; + + if (v->VRatioPreYWithoutImmediateFlip[ijk] > 4 + || v->VRatioPreCWithoutImmediateFlip[ijk] > 4) { + v->VRatioInPrefetchSupportedWithoutImmediateFlip[ij] = 0; + } + } + } + } + + // Mode Support, Voltage State and SOC Configuration + + for (i = (NumberOfStatesPlusTwo - 1); i >= 0; i--) // use int type here + { + for (j = 0; j < 2; j++) { + ij = j * NumberOfStatesPlusTwo + i; + + if (v->ScaleRatioSupport == 1 && v->SourceFormatPixelAndScanSupport == 1 + && v->ViewportSizeSupport == 1 + && v->BandwidthSupport[i] == 1 && v->DIOSupport[i] == 1 + && v->UrgentLatencySupport[ij] == 1 && v->ROBSupport[i] == 1 + && v->DISPCLK_DPPCLK_Support[ij] == 1 + && v->TotalAvailablePipesSupport[ij] == 1 + && v->TotalAvailableWritebackSupport == 1 + && v->WritebackLatencySupport == 1) { + if (v->PrefetchSupportedWithImmediateFlip[ij] == 1 + && v->VRatioInPrefetchSupportedWithImmediateFlip[ij] + == 1) { + v->ModeSupportWithImmediateFlip[ij] = 1; + } else { + v->ModeSupportWithImmediateFlip[ij] = 0; + } + if (v->PrefetchSupportedWithoutImmediateFlip[ij] == 1 + && v->VRatioInPrefetchSupportedWithoutImmediateFlip[ij] + == 1) { + v->ModeSupportWithoutImmediateFlip[ij] = 1; + } else { + v->ModeSupportWithoutImmediateFlip[ij] = 0; + } + } else { + v->ModeSupportWithImmediateFlip[ij] = 0; + v->ModeSupportWithoutImmediateFlip[ij] = 0; + } + } + } + + for (i = (NumberOfStatesPlusTwo - 1); i >= 0; i--) // use int type here + { + if ((i == (NumberOfStatesPlusTwo - 1) + || v->ModeSupportWithImmediateFlip[1 * NumberOfStatesPlusTwo + i] + == 1 + || v->ModeSupportWithImmediateFlip[0 * NumberOfStatesPlusTwo + i] + == 1) && i >= v->VoltageOverrideLevel) { + v->VoltageLevelWithImmediateFlip = i; + } + } + + for (i = (NumberOfStatesPlusTwo - 1); i >= 0; i--) // use int type here + { + if ((i == (NumberOfStatesPlusTwo - 1) + || v->ModeSupportWithoutImmediateFlip[1 * NumberOfStatesPlusTwo + i] + == 1 + || v->ModeSupportWithoutImmediateFlip[0 * NumberOfStatesPlusTwo + i] + == 1) && i >= v->VoltageOverrideLevel) { + v->VoltageLevelWithoutImmediateFlip = i; + } + } + + if (v->VoltageLevelWithImmediateFlip == (NumberOfStatesPlusTwo - 1)) { + v->ImmediateFlipSupported = 0; + v->VoltageLevel = v->VoltageLevelWithoutImmediateFlip; + } else { + v->ImmediateFlipSupported = 1; + v->VoltageLevel = v->VoltageLevelWithImmediateFlip; + } + + v->DCFCLK = v->DCFCLKPerState[(int) v->VoltageLevel]; + v->FabricAndDRAMBandwidth = v->FabricAndDRAMBandwidthPerState[(int) v->VoltageLevel]; + + for (j = 0; j < 2; j++) { + v->RequiredDISPCLKPerRatio[j] = v->RequiredDISPCLK[j * NumberOfStatesPlusTwo + + (int) v->VoltageLevel]; + for (k = 0; k < num_planes; k++) { + v->DPPPerPlanePerRatio[k * 2 + j] = v->NoOfDPP[k * 2 * NumberOfStatesPlusTwo + + j * NumberOfStatesPlusTwo + (int) v->VoltageLevel]; + } + v->DISPCLK_DPPCLK_SupportPerRatio[j] = v->DISPCLK_DPPCLK_Support[j + * NumberOfStatesPlusTwo + (int) v->VoltageLevel]; + } + + ASSERT(v->ImmediateFlipSupported || v->MacroTileBlockWidthC || v->DCFCLK || v->FabricAndDRAMBandwidth); + + return (v->VoltageLevel); +} + diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_support.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_support.h index d4ea0371cde20..ead4942f998c2 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_support.h +++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_support.h @@ -191,4 +191,9 @@ struct dml_ms_internal_vars { struct _vcs_dpi_wm_calc_pipe_params_st planes[DC__NUM_PIPES__MAX]; }; +int dml_ms_check( + struct display_mode_lib *mode_lib, + struct _vcs_dpi_display_e2e_pipe_params_st *e2e, + int num_pipes); + #endif From e168df36a807dff8e5cc78c1daeb9dec89e4118c Mon Sep 17 00:00:00 2001 From: Harry Wentland Date: Mon, 16 Oct 2017 22:10:54 -0400 Subject: [PATCH 053/155] Revert "amdgpu/dc: drop dml_util_is_420" This reverts commit e5bcf3d83e40cc7acc9d111519b7bacaf4a01070. Unfortunately these clash with our DML update from the HW guys. Will attempt to reroll them after. Signed-off-by: Alex Deucher --- .../drm/amd/display/dc/dml/dml_common_defs.c | 33 +++++++++++++++++++ .../drm/amd/display/dc/dml/dml_common_defs.h | 1 + 2 files changed, 34 insertions(+) diff --git a/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.c b/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.c index 7c0eb52b91b87..c242b8d41b8a2 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.c @@ -59,3 +59,36 @@ unsigned int dml_round_to_multiple( else return (num - remainder); } + +bool dml_util_is_420(enum source_format_class sorce_format) +{ + bool val = false; + + switch (sorce_format) { + case dm_444_16: + val = false; + break; + case dm_444_32: + val = false; + break; + case dm_444_64: + val = false; + break; + case dm_420_8: + val = true; + break; + case dm_420_10: + val = true; + break; + case dm_422_8: + val = false; + break; + case dm_422_10: + val = false; + break; + default: + BREAK_TO_DEBUGGER(); + } + + return val; +} diff --git a/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.h b/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.h index a2da3da5ef8f0..c621f8321b03a 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.h +++ b/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.h @@ -32,6 +32,7 @@ #define DTRACE(str, ...) dm_logger_write(mode_lib->logger, LOG_DML, str, ##__VA_ARGS__); +bool dml_util_is_420(enum source_format_class sorce_format); double dml_round(double a); unsigned int dml_round_to_multiple( unsigned int num, unsigned int multiple, bool up); From 711b55f3fca418de8c6484a1aa38bcc241acc536 Mon Sep 17 00:00:00 2001 From: Harry Wentland Date: Mon, 16 Oct 2017 22:11:04 -0400 Subject: [PATCH 054/155] Revert "amdgpu/dc: inline a bunch of the dml wrappers." This reverts commit 3e8c3108dab197858e74dbb740c5312ae636ea9b. Unfortunately these clash with our DML update from the HW guys. Will attempt to reroll them after. Signed-off-by: Alex Deucher --- .../amd/display/dc/dml/display_mode_support.c | 1 - .../amd/display/dc/dml/display_rq_dlg_calc.c | 2 - .../amd/display/dc/dml/display_watermark.c | 1 - .../drm/amd/display/dc/dml/dml_common_defs.c | 56 ++++++++++++++++- .../drm/amd/display/dc/dml/dml_common_defs.h | 11 ++++ .../drm/amd/display/dc/dml/dml_inline_defs.h | 61 ------------------- .../drm/amd/display/dc/dml/soc_bounding_box.c | 1 - 7 files changed, 66 insertions(+), 67 deletions(-) delete mode 100644 drivers/gpu/drm/amd/display/dc/dml/dml_inline_defs.h diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_support.c b/drivers/gpu/drm/amd/display/dc/dml/display_mode_support.c index ac573568c10ae..3b4ee74527f50 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_support.c +++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_support.c @@ -26,7 +26,6 @@ #include "display_mode_support.h" #include "display_mode_lib.h" -#include "dml_inline_defs.h" int dml_ms_check( struct display_mode_lib *mode_lib, struct _vcs_dpi_display_e2e_pipe_params_st *e2e, diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_calc.c b/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_calc.c index 7a5fb1cef303c..9fccbbffe1295 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_calc.c +++ b/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_calc.c @@ -25,8 +25,6 @@ #include "display_rq_dlg_calc.h" #include "display_mode_lib.h" -#include "dml_inline_defs.h" - static unsigned int get_bytes_per_element(enum source_format_class source_format, bool is_chroma) { unsigned int ret_val = 0; diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_watermark.c b/drivers/gpu/drm/amd/display/dc/dml/display_watermark.c index 142a3284ac44a..390f093914339 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_watermark.c +++ b/drivers/gpu/drm/amd/display/dc/dml/display_watermark.c @@ -24,7 +24,6 @@ */ #include "display_watermark.h" #include "display_mode_lib.h" -#include "dml_inline_defs.h" static void get_bytes_per_pixel( enum source_format_class format, diff --git a/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.c b/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.c index c242b8d41b8a2..21349a022de3b 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.c @@ -26,7 +26,26 @@ #include "dml_common_defs.h" #include "../calcs/dcn_calc_math.h" -#include "dml_inline_defs.h" +double dml_min(double a, double b) +{ + return (double) dcn_bw_min2(a, b); +} + +double dml_max(double a, double b) +{ + return (double) dcn_bw_max2(a, b); +} + +double dml_ceil(double a) +{ + return (double) dcn_bw_ceil2(a, 1); +} + +double dml_floor(double a) +{ + return (double) dcn_bw_floor2(a, 1); +} + double dml_round(double a) { double round_pt = 0.5; @@ -39,6 +58,16 @@ double dml_round(double a) return floor; } +int dml_log2(double x) +{ + return dml_round((double)dcn_bw_log(x, 2)); +} + +double dml_pow(double a, int exp) +{ + return (double) dcn_bw_pow(a, exp); +} + unsigned int dml_round_to_multiple( unsigned int num, unsigned int multiple, @@ -60,6 +89,16 @@ unsigned int dml_round_to_multiple( return (num - remainder); } +double dml_fmod(double f, int val) +{ + return (double) dcn_bw_mod(f, val); +} + +double dml_ceil_2(double f) +{ + return (double) dcn_bw_ceil2(f, 2); +} + bool dml_util_is_420(enum source_format_class sorce_format) { bool val = false; @@ -92,3 +131,18 @@ bool dml_util_is_420(enum source_format_class sorce_format) return val; } + +double dml_ceil_ex(double x, double granularity) +{ + return (double) dcn_bw_ceil2(x, granularity); +} + +double dml_floor_ex(double x, double granularity) +{ + return (double) dcn_bw_floor2(x, granularity); +} + +double dml_log(double x, double base) +{ + return (double) dcn_bw_log(x, base); +} diff --git a/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.h b/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.h index c621f8321b03a..c5340d41eedb7 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.h +++ b/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.h @@ -32,9 +32,20 @@ #define DTRACE(str, ...) dm_logger_write(mode_lib->logger, LOG_DML, str, ##__VA_ARGS__); +double dml_min(double a, double b); +double dml_max(double a, double b); bool dml_util_is_420(enum source_format_class sorce_format); +double dml_ceil_ex(double x, double granularity); +double dml_floor_ex(double x, double granularity); +double dml_log(double x, double base); +double dml_ceil(double a); +double dml_floor(double a); double dml_round(double a); +int dml_log2(double x); +double dml_pow(double a, int exp); unsigned int dml_round_to_multiple( unsigned int num, unsigned int multiple, bool up); +double dml_fmod(double f, int val); +double dml_ceil_2(double f); #endif /* __DC_COMMON_DEFS_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/dml/dml_inline_defs.h b/drivers/gpu/drm/amd/display/dc/dml/dml_inline_defs.h deleted file mode 100644 index 1c6c631daad40..0000000000000 --- a/drivers/gpu/drm/amd/display/dc/dml/dml_inline_defs.h +++ /dev/null @@ -1,61 +0,0 @@ -#ifndef __DML_INLINE_DEFS_H__ -#define __DML_INLINE_DEFS_H__ -#include "dml_common_defs.h" -#include "../calcs/dcn_calc_math.h" - -static inline double dml_min(double a, double b) -{ - return (double) dcn_bw_min2(a, b); -} - -static inline double dml_max(double a, double b) -{ - return (double) dcn_bw_max2(a, b); -} - -static inline double dml_ceil(double a) -{ - return (double) dcn_bw_ceil2(a, 1); -} - -static inline double dml_floor(double a) -{ - return (double) dcn_bw_floor2(a, 1); -} - -static inline int dml_log2(double x) -{ - return dml_round((double)dcn_bw_log(x, 2)); -} - -static inline double dml_pow(double a, int exp) -{ - return (double) dcn_bw_pow(a, exp); -} - -static inline double dml_fmod(double f, int val) -{ - return (double) dcn_bw_mod(f, val); -} - -static inline double dml_ceil_2(double f) -{ - return (double) dcn_bw_ceil2(f, 2); -} - -static inline double dml_ceil_ex(double x, double granularity) -{ - return (double) dcn_bw_ceil2(x, granularity); -} - -static inline double dml_floor_ex(double x, double granularity) -{ - return (double) dcn_bw_floor2(x, granularity); -} - -static inline double dml_log(double x, double base) -{ - return (double) dcn_bw_log(x, base); -} - -#endif diff --git a/drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.c b/drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.c index d40f6ae9622c5..112b0b728b4d4 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.c +++ b/drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.c @@ -25,7 +25,6 @@ #include "soc_bounding_box.h" #include "display_mode_lib.h" -#include "dml_inline_defs.h" void dml_socbb_set_latencies( struct display_mode_lib *mode_lib, struct _vcs_dpi_soc_bounding_box_st *from_box) From 378c4a2d609dfc048c4416a387ddec06994cc307 Mon Sep 17 00:00:00 2001 From: Harry Wentland Date: Mon, 16 Oct 2017 22:11:18 -0400 Subject: [PATCH 055/155] Revert "amdgpu/dc: drop display_pipe_clocks.c." This reverts commit b3fbdcec5e6c16c93867289ae0960a64c423eb34. Unfortunately these clash with our DML update from the HW guys as it's starting to get used now. Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dml/Makefile | 2 +- .../drm/amd/display/dc/dml/display_mode_lib.h | 1 + .../amd/display/dc/dml/display_pipe_clocks.c | 367 ++++++++++++++++++ .../amd/display/dc/dml/display_pipe_clocks.h | 41 ++ 4 files changed, 410 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/amd/display/dc/dml/display_pipe_clocks.c create mode 100644 drivers/gpu/drm/amd/display/dc/dml/display_pipe_clocks.h diff --git a/drivers/gpu/drm/amd/display/dc/dml/Makefile b/drivers/gpu/drm/amd/display/dc/dml/Makefile index a6bf36466497f..9d7791d00e973 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/Makefile +++ b/drivers/gpu/drm/amd/display/dc/dml/Makefile @@ -13,7 +13,7 @@ CFLAGS_dml_common_defs.o := -mhard-float -msse -mpreferred-stack-boundary=4 CFLAGS_display_mode_support.o := -mhard-float -msse -mpreferred-stack-boundary=4 -DML = display_mode_lib.o display_rq_dlg_calc.o \ +DML = display_mode_lib.o display_pipe_clocks.o display_rq_dlg_calc.o \ display_rq_dlg_helpers.o display_watermark.o \ soc_bounding_box.o dml_common_defs.o display_mode_support.o diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.h index eb1c8e6e7f237..e2e311138358b 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.h +++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.h @@ -28,6 +28,7 @@ #include "dml_common_defs.h" #include "soc_bounding_box.h" #include "display_watermark.h" +#include "display_pipe_clocks.h" #include "display_rq_dlg_calc.h" #include "display_mode_support.h" diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_pipe_clocks.c b/drivers/gpu/drm/amd/display/dc/dml/display_pipe_clocks.c new file mode 100644 index 0000000000000..2e4dc57cafa09 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/dml/display_pipe_clocks.c @@ -0,0 +1,367 @@ +/* + * Copyright 2017 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: AMD + * + */ + +#include "display_pipe_clocks.h" +#include "display_mode_lib.h" +#include "soc_bounding_box.h" + +static enum voltage_state power_state( + struct display_mode_lib *mode_lib, + double dispclk, + double dppclk) +{ + enum voltage_state state1; + enum voltage_state state2; + + if (dispclk <= mode_lib->soc.vmin.dispclk_mhz) + state1 = dm_vmin; + else if (dispclk <= mode_lib->soc.vnom.dispclk_mhz) + state1 = dm_vnom; + else if (dispclk <= mode_lib->soc.vmax.dispclk_mhz) + state1 = dm_vmax; + else + state1 = dm_vmax_exceeded; + + if (dppclk <= mode_lib->soc.vmin.dppclk_mhz) + state2 = dm_vmin; + else if (dppclk <= mode_lib->soc.vnom.dppclk_mhz) + state2 = dm_vnom; + else if (dppclk <= mode_lib->soc.vmax.dppclk_mhz) + state2 = dm_vmax; + else + state2 = dm_vmax_exceeded; + + if (state1 > state2) + return state1; + else + return state2; +} + +static unsigned int dpp_in_grp( + struct _vcs_dpi_display_e2e_pipe_params_st *e2e, + unsigned int num_pipes, + unsigned int hsplit_grp) +{ + unsigned int num_dpp = 0; + unsigned int i; + + for (i = 0; i < num_pipes; i++) { + if (e2e[i].pipe.src.is_hsplit) { + if (e2e[i].pipe.src.hsplit_grp == hsplit_grp) { + num_dpp++; + } + } + } + + if (0 == num_dpp) + num_dpp = 1; + + return num_dpp; +} + +static void calculate_pipe_clk_requirement( + struct display_mode_lib *mode_lib, + struct _vcs_dpi_display_e2e_pipe_params_st *e2e, + unsigned int num_dpp_in_grp, + double *dppclk, + double *dispclk, + bool *dppdiv) +{ + double pscl_throughput = 0.0; + double max_hratio = e2e->pipe.scale_ratio_depth.hscl_ratio; + double max_vratio = e2e->pipe.scale_ratio_depth.vscl_ratio; + double max_htaps = e2e->pipe.scale_taps.htaps; + double max_vtaps = e2e->pipe.scale_taps.vtaps; + double dpp_clock_divider = (double) num_dpp_in_grp; + double dispclk_dppclk_ratio; + double dispclk_ramp_margin_percent; + + if (max_hratio > 1.0) { + double pscl_to_lb = ((double) mode_lib->ip.max_pscl_lb_bw_pix_per_clk * max_hratio) + / dml_ceil(max_htaps / 6.0); + pscl_throughput = dml_min( + pscl_to_lb, + (double) mode_lib->ip.max_dchub_pscl_bw_pix_per_clk); + } else { + pscl_throughput = dml_min( + (double) mode_lib->ip.max_pscl_lb_bw_pix_per_clk, + (double) mode_lib->ip.max_dchub_pscl_bw_pix_per_clk); + } + + DTRACE("pscl_throughput: %f pix per clk", pscl_throughput); + DTRACE("vtaps: %f hratio: %f vratio: %f", max_vtaps, max_hratio, max_vratio); + *dppclk = dml_max( + max_vtaps / 6.0 * dml_min(1.0, max_hratio), + max_hratio * max_vratio / pscl_throughput); + DTRACE("pixel rate multiplier: %f", *dppclk); + *dppclk = dml_max(*dppclk, 1.0); + DTRACE("pixel rate multiplier clamped: %f", *dppclk); + *dppclk = *dppclk * e2e->pipe.dest.pixel_rate_mhz; + + *dppclk = *dppclk / dpp_clock_divider; + DTRACE("dppclk after split: %f", *dppclk); + + if (dpp_clock_divider > 1.0 && (*dppclk < e2e->pipe.dest.pixel_rate_mhz)) { + dispclk_dppclk_ratio = 2.0; + *dppdiv = true; + } else { + dispclk_dppclk_ratio = 1.0; + *dppdiv = false; + } + + dispclk_ramp_margin_percent = mode_lib->ip.dispclk_ramp_margin_percent; + + /* Comment this out because of Gabes possible bug in spreadsheet, + * just to make other cases evident during debug + * + *if(e2e->clks_cfg.voltage == dm_vmax) + * dispclk_ramp_margin_percent = 0.0; + */ + + /* account for ramping margin and downspread */ + *dispclk = dml_max(*dppclk * dispclk_dppclk_ratio, e2e->pipe.dest.pixel_rate_mhz) + * (1.0 + (double) mode_lib->soc.downspread_percent / 100.0) + * (1.0 + (double) dispclk_ramp_margin_percent / 100.0); + + return; +} + +bool dml_clks_pipe_clock_requirement_fit_power_constraint( + struct display_mode_lib *mode_lib, + struct _vcs_dpi_display_e2e_pipe_params_st *e2e, + unsigned int num_dpp_in_grp) +{ + double dppclk = 0; + double dispclk = 0; + bool dppdiv = 0; + + calculate_pipe_clk_requirement(mode_lib, e2e, num_dpp_in_grp, &dppclk, &dispclk, &dppdiv); + + if (power_state(mode_lib, dispclk, dppclk) > e2e->clks_cfg.voltage) { + return false; + } + + return true; +} + +static void get_plane_clks( + struct display_mode_lib *mode_lib, + struct _vcs_dpi_display_e2e_pipe_params_st *e2e, + unsigned int num_pipes, + double *dppclks, + double *dispclks, + bool *dppdiv) +{ + /* it is assumed that the scale ratios passed into the e2e pipe params have already been calculated + * for any split pipe configurations, where extra pixels inthe overlap region do not contribute to + * the scale ratio. This means that we can simply calculate the dppclk for each dpp independently + * and we would expect the same result on any split pipes, which would be handled + */ + unsigned int i; + + for (i = 0; i < num_pipes; i++) { + double num_dpp_in_grp; + double dispclk_ramp_margin_percent; + double dispclk_margined; + + if (e2e[i].pipe.src.is_hsplit) + num_dpp_in_grp = (double) dpp_in_grp( + e2e, + num_pipes, + e2e[i].pipe.src.hsplit_grp); + else + num_dpp_in_grp = 1; + + calculate_pipe_clk_requirement( + mode_lib, + &e2e[i], + num_dpp_in_grp, + &dppclks[i], + &dispclks[i], + &dppdiv[i]); + + dispclk_ramp_margin_percent = mode_lib->ip.dispclk_ramp_margin_percent; + + dispclk_margined = e2e[i].pipe.dest.pixel_rate_mhz + * (1.0 + (double) mode_lib->soc.downspread_percent / 100.0) + * (1.0 + (double) dispclk_ramp_margin_percent / 100.0); + + DTRACE("p%d: requested power state: %d", i, (int) e2e[0].clks_cfg.voltage); + + if (power_state(mode_lib, dispclks[i], dppclks[i]) + > power_state(mode_lib, dispclk_margined, dispclk_margined) + && dispclk_margined > dppclks[i]) { + if (power_state(mode_lib, dispclks[i], dppclks[i]) + > e2e[0].clks_cfg.voltage) { + dispclks[i] = dispclk_margined; + dppclks[i] = dispclk_margined; + dppdiv[i] = false; + } + } + + DTRACE("p%d: dispclk: %f", i, dispclks[i]); + } +} + +static void get_dcfclk( + struct display_mode_lib *mode_lib, + struct _vcs_dpi_display_e2e_pipe_params_st *e2e, + unsigned int num_pipes, + double *dcfclk_mhz) +{ + double bytes_per_pixel_det_y[DC__NUM_PIPES__MAX]; + double bytes_per_pixel_det_c[DC__NUM_PIPES__MAX]; + double swath_width_y[DC__NUM_PIPES__MAX]; + unsigned int i; + double total_read_bandwidth_gbps = 0.0; + + for (i = 0; i < num_pipes; i++) { + if (e2e[i].pipe.src.source_scan == dm_horz) { + swath_width_y[i] = e2e[i].pipe.src.viewport_width * 1.0; + } else { + swath_width_y[i] = e2e[i].pipe.src.viewport_height * 1.0; + } + + switch (e2e[i].pipe.src.source_format) { + case dm_444_64: + bytes_per_pixel_det_y[i] = 8.0; + bytes_per_pixel_det_c[i] = 0.0; + break; + case dm_444_32: + bytes_per_pixel_det_y[i] = 4.0; + bytes_per_pixel_det_c[i] = 0.0; + break; + case dm_444_16: + bytes_per_pixel_det_y[i] = 2.0; + bytes_per_pixel_det_c[i] = 0.0; + break; + case dm_422_8: + bytes_per_pixel_det_y[i] = 2.0; + bytes_per_pixel_det_c[i] = 0.0; + break; + case dm_422_10: + bytes_per_pixel_det_y[i] = 4.0; + bytes_per_pixel_det_c[i] = 0.0; + break; + case dm_420_8: + bytes_per_pixel_det_y[i] = 1.0; + bytes_per_pixel_det_c[i] = 2.0; + break; + case dm_420_10: + bytes_per_pixel_det_y[i] = 4.0 / 3.0; + bytes_per_pixel_det_c[i] = 8.0 / 3.0; + break; + default: + BREAK_TO_DEBUGGER(); /* invalid src_format in get_dcfclk */ + } + } + + for (i = 0; i < num_pipes; i++) { + double read_bandwidth_plane_mbps = 0.0; + read_bandwidth_plane_mbps = (double) swath_width_y[i] + * ((double) bytes_per_pixel_det_y[i] + + (double) bytes_per_pixel_det_c[i] / 2.0) + / ((double) e2e[i].pipe.dest.htotal + / (double) e2e[i].pipe.dest.pixel_rate_mhz) + * e2e[i].pipe.scale_ratio_depth.vscl_ratio; + + if (e2e[i].pipe.src.dcc) { + read_bandwidth_plane_mbps += (read_bandwidth_plane_mbps / 1000.0 / 256.0); + } + + if (e2e[i].pipe.src.vm) { + read_bandwidth_plane_mbps += (read_bandwidth_plane_mbps / 1000.0 / 512.0); + } + + total_read_bandwidth_gbps = total_read_bandwidth_gbps + + read_bandwidth_plane_mbps / 1000.0; + } + + DTRACE("total bandwidth = %f gbps", total_read_bandwidth_gbps); + + (*dcfclk_mhz) = (total_read_bandwidth_gbps * 1000.0) / mode_lib->soc.return_bus_width_bytes; + + DTRACE( + "minimum theoretical dcfclk without stutter and full utilization = %f MHz", + (*dcfclk_mhz)); + +} + +struct _vcs_dpi_display_pipe_clock_st dml_clks_get_pipe_clocks( + struct display_mode_lib *mode_lib, + struct _vcs_dpi_display_e2e_pipe_params_st *e2e, + unsigned int num_pipes) +{ + struct _vcs_dpi_display_pipe_clock_st clocks; + double max_dispclk = 0.0; + double dcfclk; + double dispclks[DC__NUM_PIPES__MAX]; + double dppclks[DC__NUM_PIPES__MAX]; + bool dppdiv[DC__NUM_PIPES__MAX]; + unsigned int i; + + DTRACE("Calculating pipe clocks..."); + + /* this is the theoretical minimum, have to adjust based on valid values for soc */ + get_dcfclk(mode_lib, e2e, num_pipes, &dcfclk); + + /* if(dcfclk > soc.vnom.dcfclk_mhz) + * dcfclk = soc.vmax.dcfclk_mhz; + * else if(dcfclk > soc.vmin.dcfclk_mhz) + * dcfclk = soc.vnom.dcfclk_mhz; + * else + * dcfclk = soc.vmin.dcfclk_mhz; + */ + + dcfclk = dml_socbb_voltage_scaling( + &mode_lib->soc, + (enum voltage_state) e2e[0].clks_cfg.voltage).dcfclk_mhz; + clocks.dcfclk_mhz = dcfclk; + + get_plane_clks(mode_lib, e2e, num_pipes, dppclks, dispclks, dppdiv); + + for (i = 0; i < num_pipes; i++) { + max_dispclk = dml_max(max_dispclk, dispclks[i]); + } + + clocks.dispclk_mhz = max_dispclk; + DTRACE("dispclk: %f Mhz", clocks.dispclk_mhz); + DTRACE("dcfclk: %f Mhz", clocks.dcfclk_mhz); + + for (i = 0; i < num_pipes; i++) { + if (dppclks[i] * 2 < max_dispclk) + dppdiv[i] = 1; + + if (dppdiv[i]) + clocks.dppclk_div[i] = 1; + else + clocks.dppclk_div[i] = 0; + + clocks.dppclk_mhz[i] = max_dispclk / ((dppdiv[i]) ? 2.0 : 1.0); + DTRACE("dppclk%d: %f Mhz", i, clocks.dppclk_mhz[i]); + } + + return clocks; +} diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_pipe_clocks.h b/drivers/gpu/drm/amd/display/dc/dml/display_pipe_clocks.h new file mode 100644 index 0000000000000..aed5f33bb04f6 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/dml/display_pipe_clocks.h @@ -0,0 +1,41 @@ +/* + * Copyright 2017 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: AMD + * + */ +#ifndef __DISPLAY_PIPE_CLOCKS_H__ +#define __DISPLAY_PIPE_CLOCKS_H__ + +#include "dml_common_defs.h" + +struct display_mode_lib; + +struct _vcs_dpi_display_pipe_clock_st dml_clks_get_pipe_clocks( + struct display_mode_lib *mode_lib, + struct _vcs_dpi_display_e2e_pipe_params_st *e2e, + unsigned int num_pipes); + +bool dml_clks_pipe_clock_requirement_fit_power_constraint( + struct display_mode_lib *mode_lib, + struct _vcs_dpi_display_e2e_pipe_params_st *e2e, + unsigned int num_dpp_in_grp); +#endif From 19b7fe4a48efbe0f7e8c496b040c4eb16ff02313 Mon Sep 17 00:00:00 2001 From: Harry Wentland Date: Mon, 16 Oct 2017 22:15:57 -0400 Subject: [PATCH 056/155] Revert "amdgpu/dc: inline a bunch of float operations." This reverts commit d1209512e028a917e6e70b13297ff185234ba24d. Unfortunately these clash with our DML update from the HW guys. Rerolling this after the fact won't save us anything anymore, unfortunately so we're back to non-inline for this. Signed-off-by: Alex Deucher --- .../drm/amd/display/dc/calcs/dcn_calc_math.c | 29 +++++++++++++++ .../drm/amd/display/dc/calcs/dcn_calc_math.h | 36 ++++--------------- 2 files changed, 35 insertions(+), 30 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_math.c b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_math.c index 05cf5f77ec603..a18474437990a 100644 --- a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_math.c +++ b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_math.c @@ -25,6 +25,25 @@ #include "dcn_calc_math.h" +float dcn_bw_mod(const float arg1, const float arg2) +{ + return arg1 - arg1 * ((int) (arg1 / arg2)); +} + +float dcn_bw_min2(const float arg1, const float arg2) +{ + return arg1 < arg2 ? arg1 : arg2; +} + +unsigned int dcn_bw_max(const unsigned int arg1, const unsigned int arg2) +{ + return arg1 > arg2 ? arg1 : arg2; +} +float dcn_bw_max2(const float arg1, const float arg2) +{ + return arg1 > arg2 ? arg1 : arg2; +} + float dcn_bw_floor2(const float arg, const float significance) { if (significance == 0) @@ -40,6 +59,16 @@ float dcn_bw_ceil2(const float arg, const float significance) return flr + 0.00001 >= arg ? arg : flr + significance; } +float dcn_bw_max3(float v1, float v2, float v3) +{ + return v3 > dcn_bw_max2(v1, v2) ? v3 : dcn_bw_max2(v1, v2); +} + +float dcn_bw_max5(float v1, float v2, float v3, float v4, float v5) +{ + return dcn_bw_max3(v1, v2, v3) > dcn_bw_max2(v4, v5) ? dcn_bw_max3(v1, v2, v3) : dcn_bw_max2(v4, v5); +} + float dcn_bw_pow(float a, float exp) { float temp; diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_math.h b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_math.h index 6f66d9d164d1a..f46ab0e24ca13 100644 --- a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_math.h +++ b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_math.h @@ -26,38 +26,14 @@ #ifndef _DCN_CALC_MATH_H_ #define _DCN_CALC_MATH_H_ -static inline float dcn_bw_mod(const float arg1, const float arg2) -{ - return arg1 - arg1 * ((int) (arg1 / arg2)); -} - -static inline float dcn_bw_min2(const float arg1, const float arg2) -{ - return arg1 < arg2 ? arg1 : arg2; -} - -static inline unsigned int dcn_bw_max(const unsigned int arg1, const unsigned int arg2) -{ - return arg1 > arg2 ? arg1 : arg2; -} - -static inline float dcn_bw_max2(const float arg1, const float arg2) -{ - return arg1 > arg2 ? arg1 : arg2; -} - -static inline float dcn_bw_max3(float v1, float v2, float v3) -{ - return v3 > dcn_bw_max2(v1, v2) ? v3 : dcn_bw_max2(v1, v2); -} - -static inline float dcn_bw_max5(float v1, float v2, float v3, float v4, float v5) -{ - return dcn_bw_max3(v1, v2, v3) > dcn_bw_max2(v4, v5) ? dcn_bw_max3(v1, v2, v3) : dcn_bw_max2(v4, v5); -} - +float dcn_bw_mod(const float arg1, const float arg2); +float dcn_bw_min2(const float arg1, const float arg2); +unsigned int dcn_bw_max(const unsigned int arg1, const unsigned int arg2); +float dcn_bw_max2(const float arg1, const float arg2); float dcn_bw_floor2(const float arg, const float significance); float dcn_bw_ceil2(const float arg, const float significance); +float dcn_bw_max3(float v1, float v2, float v3); +float dcn_bw_max5(float v1, float v2, float v3, float v4, float v5); float dcn_bw_pow(float a, float exp); float dcn_bw_log(float a, float b); From 6d04ee9dc10149db842d41de66eca201c9d91b60 Mon Sep 17 00:00:00 2001 From: Dmytro Laktyushkin Date: Wed, 23 Aug 2017 16:43:17 -0400 Subject: [PATCH 057/155] drm/amd/display: Restructuring and cleaning up DML Signed-off-by: Dmytro Laktyushkin Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../drm/amd/display/dc/calcs/dcn_calc_math.c | 16 + .../gpu/drm/amd/display/dc/calcs/dcn_calcs.c | 103 +- drivers/gpu/drm/amd/display/dc/dc.h | 1 - .../drm/amd/display/dc/dcn10/dcn10_resource.c | 5 +- drivers/gpu/drm/amd/display/dc/dml/Makefile | 8 +- .../gpu/drm/amd/display/dc/dml/dc_features.h | 2 + .../amd/display/dc/dml/display_mode_enums.h | 52 +- .../drm/amd/display/dc/dml/display_mode_lib.c | 7 +- .../drm/amd/display/dc/dml/display_mode_lib.h | 8 +- .../amd/display/dc/dml/display_mode_structs.h | 898 +++-- .../amd/display/dc/dml/display_mode_support.c | 2326 ------------ .../amd/display/dc/dml/display_mode_support.h | 199 - .../drm/amd/display/dc/dml/display_mode_vba.c | 3263 +++++++++++++++++ .../drm/amd/display/dc/dml/display_mode_vba.h | 410 +++ .../amd/display/dc/dml/display_pipe_clocks.c | 377 +- .../amd/display/dc/dml/display_pipe_clocks.h | 8 +- .../amd/display/dc/dml/display_rq_dlg_calc.c | 2457 +++++-------- .../amd/display/dc/dml/display_rq_dlg_calc.h | 151 +- .../display/dc/dml/display_rq_dlg_helpers.c | 482 +-- .../display/dc/dml/display_rq_dlg_helpers.h | 41 +- .../amd/display/dc/dml/display_watermark.c | 1281 ------- .../amd/display/dc/dml/display_watermark.h | 98 - .../display/dc/dml/dml1_display_rq_dlg_calc.c | 1903 ++++++++++ .../display/dc/dml/dml1_display_rq_dlg_calc.h | 67 + .../drm/amd/display/dc/dml/dml_common_defs.c | 12 +- .../drm/amd/display/dc/dml/dml_common_defs.h | 8 +- .../drm/amd/display/dc/dml/soc_bounding_box.c | 48 +- .../drm/amd/display/dc/dml/soc_bounding_box.h | 9 +- 28 files changed, 7658 insertions(+), 6582 deletions(-) delete mode 100644 drivers/gpu/drm/amd/display/dc/dml/display_mode_support.c delete mode 100644 drivers/gpu/drm/amd/display/dc/dml/display_mode_support.h create mode 100644 drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c create mode 100644 drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h delete mode 100644 drivers/gpu/drm/amd/display/dc/dml/display_watermark.c delete mode 100644 drivers/gpu/drm/amd/display/dc/dml/display_watermark.h create mode 100644 drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c create mode 100644 drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.h diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_math.c b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_math.c index a18474437990a..b6abe0f3bb152 100644 --- a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_math.c +++ b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_math.c @@ -27,20 +27,36 @@ float dcn_bw_mod(const float arg1, const float arg2) { + if (arg1 != arg1) + return arg2; + if (arg2 != arg2) + return arg1; return arg1 - arg1 * ((int) (arg1 / arg2)); } float dcn_bw_min2(const float arg1, const float arg2) { + if (arg1 != arg1) + return arg2; + if (arg2 != arg2) + return arg1; return arg1 < arg2 ? arg1 : arg2; } unsigned int dcn_bw_max(const unsigned int arg1, const unsigned int arg2) { + if (arg1 != arg1) + return arg2; + if (arg2 != arg2) + return arg1; return arg1 > arg2 ? arg1 : arg2; } float dcn_bw_max2(const float arg1, const float arg2) { + if (arg1 != arg1) + return arg2; + if (arg2 != arg2) + return arg1; return arg1 > arg2 ? arg1 : arg2; } diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c index 6318f9f69c928..fd1db8dc2f352 100644 --- a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c +++ b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c @@ -386,10 +386,6 @@ static void pipe_ctx_to_e2e_pipe_params ( - pipe->stream->timing.v_addressable - pipe->stream->timing.v_border_bottom - pipe->stream->timing.v_border_top; - - input->dest.vsync_plus_back_porch = pipe->stream->timing.v_total - - pipe->stream->timing.v_addressable - - pipe->stream->timing.v_front_porch; input->dest.pixel_rate_mhz = pipe->stream->timing.pix_clk_khz/1000.0; input->dest.vstartup_start = pipe->pipe_dlg_param.vstartup_start; input->dest.vupdate_offset = pipe->pipe_dlg_param.vupdate_offset; @@ -459,9 +455,9 @@ static void dcn_bw_calc_rq_dlg_ttu( /*todo: soc->sr_enter_plus_exit_time??*/ dlg_sys_param.t_srx_delay_us = dc->dcn_ip->dcfclk_cstate_latency / v->dcf_clk_deep_sleep; - dml_rq_dlg_get_rq_params(dml, &rq_param, input.pipe.src); - extract_rq_regs(dml, rq_regs, rq_param); - dml_rq_dlg_get_dlg_params( + dml1_rq_dlg_get_rq_params(dml, &rq_param, input.pipe.src); + dml1_extract_rq_regs(dml, rq_regs, rq_param); + dml1_rq_dlg_get_dlg_params( dml, dlg_regs, ttu_regs, @@ -474,96 +470,6 @@ static void dcn_bw_calc_rq_dlg_ttu( pipe->plane_state->flip_immediate); } -static void dcn_dml_wm_override( - const struct dcn_bw_internal_vars *v, - struct display_mode_lib *dml, - struct dc_state *context, - const struct resource_pool *pool) -{ - int i, in_idx, active_count; - - struct _vcs_dpi_display_e2e_pipe_params_st *input = kzalloc(pool->pipe_count * sizeof(struct _vcs_dpi_display_e2e_pipe_params_st), - GFP_KERNEL); - struct wm { - double urgent; - struct _vcs_dpi_cstate_pstate_watermarks_st cpstate; - double pte_meta_urgent; - } a; - - - for (i = 0, in_idx = 0; i < pool->pipe_count; i++) { - struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; - - if (!pipe->stream || !pipe->plane_state) - continue; - - input[in_idx].clks_cfg.dcfclk_mhz = v->dcfclk; - input[in_idx].clks_cfg.dispclk_mhz = v->dispclk; - input[in_idx].clks_cfg.dppclk_mhz = v->dppclk; - input[in_idx].clks_cfg.refclk_mhz = pool->ref_clock_inKhz / 1000; - input[in_idx].clks_cfg.socclk_mhz = v->socclk; - input[in_idx].clks_cfg.voltage = v->voltage_level; - input[in_idx].dout.output_format = (v->output_format[in_idx] == dcn_bw_420) ? dm_420 : dm_444; - input[in_idx].dout.output_type = (v->output[in_idx] == dcn_bw_hdmi) ? dm_hdmi : dm_dp; - //input[in_idx].dout.output_standard; - switch (v->output_deep_color[in_idx]) { - case dcn_bw_encoder_12bpc: - input[in_idx].dout.output_bpc = dm_out_12; - break; - case dcn_bw_encoder_10bpc: - input[in_idx].dout.output_bpc = dm_out_10; - break; - case dcn_bw_encoder_8bpc: - default: - input[in_idx].dout.output_bpc = dm_out_8; - break; - } - pipe_ctx_to_e2e_pipe_params(pipe, &input[in_idx].pipe); - dml_rq_dlg_get_rq_reg( - dml, - &pipe->rq_regs, - input[in_idx].pipe.src); - in_idx++; - } - active_count = in_idx; - - a.urgent = dml_wm_urgent_e2e(dml, input, active_count); - a.cpstate = dml_wm_cstate_pstate_e2e(dml, input, active_count); - a.pte_meta_urgent = dml_wm_pte_meta_urgent(dml, a.urgent); - - context->bw.dcn.watermarks.a.cstate_pstate.cstate_exit_ns = - a.cpstate.cstate_exit_us * 1000; - context->bw.dcn.watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns = - a.cpstate.cstate_enter_plus_exit_us * 1000; - context->bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns = - a.cpstate.pstate_change_us * 1000; - context->bw.dcn.watermarks.a.pte_meta_urgent_ns = a.pte_meta_urgent * 1000; - context->bw.dcn.watermarks.a.urgent_ns = a.urgent * 1000; - context->bw.dcn.watermarks.b = context->bw.dcn.watermarks.a; - context->bw.dcn.watermarks.c = context->bw.dcn.watermarks.a; - context->bw.dcn.watermarks.d = context->bw.dcn.watermarks.a; - - - for (i = 0, in_idx = 0; i < pool->pipe_count; i++) { - struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; - - if (!pipe->stream || !pipe->plane_state) - continue; - - dml_rq_dlg_get_dlg_reg(dml, - &pipe->dlg_regs, - &pipe->ttu_regs, - input, active_count, - in_idx, - true, - true, - v->pte_enable == dcn_bw_yes, - pipe->plane_state->flip_immediate); - in_idx++; - } - kfree(input); -} - static void split_stream_across_pipes( struct resource_context *res_ctx, const struct resource_pool *pool, @@ -1163,9 +1069,6 @@ bool dcn_validate_bandwidth( input_idx++; } - if (dc->debug.use_dml_wm) - dcn_dml_wm_override(v, (struct display_mode_lib *) - &dc->dml, context, pool); } if (v->voltage_level == 0) { diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index d624554efbc7c..bf83459456a80 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -200,7 +200,6 @@ struct dc_debug { bool disable_hubp_power_gate; bool disable_pplib_wm_range; enum wm_report_mode pplib_wm_report_mode; - bool use_dml_wm; unsigned int min_disp_clk_khz; int sr_exit_time_dpm0_ns; int sr_enter_plus_exit_time_dpm0_ns; diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c index 5d618e68a744d..3000ddab23578 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c @@ -425,8 +425,6 @@ static const struct dc_debug debug_defaults_drv = { .disable_pplib_clock_request = true, .disable_pplib_wm_range = false, .pplib_wm_report_mode = WM_REPORT_DEFAULT, - .use_dml_wm = false, - .pipe_split_policy = MPC_SPLIT_AVOID_MULT_DISP, .disable_dcc = DCC_ENABLE, .voltage_align_fclk = true, @@ -439,8 +437,7 @@ static const struct dc_debug debug_defaults_diags = { .clock_trace = true, .disable_stutter = true, .disable_pplib_clock_request = true, - .disable_pplib_wm_range = true, - .use_dml_wm = false, + .disable_pplib_wm_range = true }; static void dcn10_dpp_destroy(struct transform **xfm) diff --git a/drivers/gpu/drm/amd/display/dc/dml/Makefile b/drivers/gpu/drm/amd/display/dc/dml/Makefile index 9d7791d00e973..c6d9d9530d755 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/Makefile +++ b/drivers/gpu/drm/amd/display/dc/dml/Makefile @@ -3,19 +3,19 @@ # It provides the general basic services required by other DAL # subcomponents. +CFLAGS_display_mode_vba.o := -mhard-float -msse -mpreferred-stack-boundary=4 CFLAGS_display_mode_lib.o := -mhard-float -msse -mpreferred-stack-boundary=4 CFLAGS_display_pipe_clocks.o := -mhard-float -msse -mpreferred-stack-boundary=4 CFLAGS_display_rq_dlg_calc.o := -mhard-float -msse -mpreferred-stack-boundary=4 +CFLAGS_dml1_display_rq_dlg_calc.o := -mhard-float -msse -mpreferred-stack-boundary=4 CFLAGS_display_rq_dlg_helpers.o := -mhard-float -msse -mpreferred-stack-boundary=4 -CFLAGS_display_watermark.o := -mhard-float -msse -mpreferred-stack-boundary=4 CFLAGS_soc_bounding_box.o := -mhard-float -msse -mpreferred-stack-boundary=4 CFLAGS_dml_common_defs.o := -mhard-float -msse -mpreferred-stack-boundary=4 -CFLAGS_display_mode_support.o := -mhard-float -msse -mpreferred-stack-boundary=4 DML = display_mode_lib.o display_pipe_clocks.o display_rq_dlg_calc.o \ - display_rq_dlg_helpers.o display_watermark.o \ - soc_bounding_box.o dml_common_defs.o display_mode_support.o + display_rq_dlg_helpers.o dml1_display_rq_dlg_calc.o \ + soc_bounding_box.o dml_common_defs.o display_mode_vba.o AMD_DAL_DML = $(addprefix $(AMDDALPATH)/dc/dml/,$(DML)) diff --git a/drivers/gpu/drm/amd/display/dc/dml/dc_features.h b/drivers/gpu/drm/amd/display/dc/dml/dc_features.h index 745c04cb764a7..ea4cde952f4fe 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dc_features.h +++ b/drivers/gpu/drm/amd/display/dc/dml/dc_features.h @@ -25,9 +25,11 @@ #ifndef __DC_FEATURES_H__ #define __DC_FEATURES_H__ +// local features #define DC__PRESENT 1 #define DC__PRESENT__1 1 #define DC__NUM_DPP 4 +#define DC__VOLTAGE_STATES 7 #define DC__NUM_DPP__4 1 #define DC__NUM_DPP__0_PRESENT 1 #define DC__NUM_DPP__1_PRESENT 1 diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_enums.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_enums.h index 143a3d418de01..eebaeb1fb61cf 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_enums.h +++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_enums.h @@ -24,14 +24,12 @@ */ #ifndef __DISPLAY_MODE_ENUMS_H__ #define __DISPLAY_MODE_ENUMS_H__ + enum output_encoder_class { - dm_dp = 0, - dm_hdmi = 1, - dm_wb = 2 + dm_dp = 0, dm_hdmi = 1, dm_wb = 2 }; enum output_format_class { - dm_444 = 0, - dm_420 = 1 + dm_444 = 0, dm_420 = 1, dm_n422, dm_s422 }; enum source_format_class { dm_444_16 = 0, @@ -40,18 +38,14 @@ enum source_format_class { dm_420_8 = 3, dm_420_10 = 4, dm_422_8 = 5, - dm_422_10 = 6 + dm_422_10 = 6, + dm_444_8 = 7 }; enum output_bpc_class { - dm_out_6 = 0, - dm_out_8 = 1, - dm_out_10 = 2, - dm_out_12 = 3, - dm_out_16 = 4 + dm_out_6 = 0, dm_out_8 = 1, dm_out_10 = 2, dm_out_12 = 3, dm_out_16 = 4 }; enum scan_direction_class { - dm_horz = 0, - dm_vert = 1 + dm_horz = 0, dm_vert = 1 }; enum dm_swizzle_mode { dm_sw_linear = 0, @@ -84,28 +78,30 @@ enum dm_swizzle_mode { dm_sw_SPARE_14 = 27, dm_sw_SPARE_15 = 28, dm_sw_var_s_x = 29, - dm_sw_var_d_x = 30 + dm_sw_var_d_x = 30, + dm_sw_64kb_r_x }; enum lb_depth { - dm_lb_10 = 30, - dm_lb_8 = 24, - dm_lb_6 = 18, - dm_lb_12 = 36 + dm_lb_10 = 0, dm_lb_8 = 1, dm_lb_6 = 2, dm_lb_12 = 3, dm_lb_16 }; enum voltage_state { - dm_vmin = 0, - dm_vmid = 1, - dm_vnom = 2, - dm_vmax = 3, - dm_vmax_exceeded = 4 + dm_vmin = 0, dm_vmid = 1, dm_vnom = 2, dm_vmax = 3 }; enum source_macro_tile_size { - dm_4k_tile = 0, - dm_64k_tile = 1, - dm_256k_tile = 2 + dm_4k_tile = 0, dm_64k_tile = 1, dm_256k_tile = 2 }; enum cursor_bpp { - dm_cur_2bit = 0, - dm_cur_32bit = 1 + dm_cur_2bit = 0, dm_cur_32bit = 1, dm_cur_64bit = 2 }; +enum clock_change_support { + dm_dram_clock_change_uninitialized = 0, + dm_dram_clock_change_vactive, + dm_dram_clock_change_vblank, + dm_dram_clock_change_unsupported +}; + +enum output_standard { + dm_std_uninitialized = 0, dm_std_cvtr2, dm_std_cvt +}; + #endif diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.c b/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.c index c02c5522613bc..09d232806de7c 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.c +++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.c @@ -24,6 +24,7 @@ */ #include "display_mode_lib.h" +#include "dc_features.h" static void set_soc_bounding_box(struct _vcs_dpi_soc_bounding_box_st *soc, enum dml_project project) { @@ -128,11 +129,7 @@ static void set_ip_params(struct _vcs_dpi_ip_params_st *ip, enum dml_project pro static void set_mode_evaluation(struct _vcs_dpi_mode_evaluation_st *me, enum dml_project project) { - if (project == DML_PROJECT_RAVEN1) { - me->voltage_override = dm_vmin; - } else { - BREAK_TO_DEBUGGER(); /* Invalid Project Specified */ - } + me->voltage_override = dm_vmin; } void dml_init_instance(struct display_mode_lib *lib, enum dml_project project) diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.h index e2e311138358b..57f49d29c6b9d 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.h +++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.h @@ -25,12 +25,13 @@ #ifndef __DISPLAY_MODE_LIB_H__ #define __DISPLAY_MODE_LIB_H__ + #include "dml_common_defs.h" #include "soc_bounding_box.h" -#include "display_watermark.h" +#include "display_mode_vba.h" #include "display_pipe_clocks.h" #include "display_rq_dlg_calc.h" -#include "display_mode_support.h" +#include "dml1_display_rq_dlg_calc.h" enum dml_project { DML_PROJECT_UNDEFINED, @@ -42,8 +43,7 @@ struct display_mode_lib { struct _vcs_dpi_soc_bounding_box_st soc; struct _vcs_dpi_mode_evaluation_st me; enum dml_project project; - struct dml_ms_internal_vars vars; - struct _vcs_dpi_wm_calc_pipe_params_st wm_param[DC__NUM_PIPES__MAX]; + struct vba_vars_st vba; struct dal_logger *logger; }; diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h index e589a5eadb6ae..e5b7f7042e0bc 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h +++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h @@ -25,405 +25,531 @@ #ifndef __DISPLAY_MODE_STRUCTS_H__ #define __DISPLAY_MODE_STRUCTS_H__ +typedef struct _vcs_dpi_voltage_scaling_st voltage_scaling_st; +typedef struct _vcs_dpi_soc_bounding_box_st soc_bounding_box_st; +typedef struct _vcs_dpi_mode_evaluation_st mode_evaluation_st; +typedef struct _vcs_dpi_ip_params_st ip_params_st; +typedef struct _vcs_dpi_display_pipe_source_params_st display_pipe_source_params_st; +typedef struct _vcs_dpi_display_output_params_st display_output_params_st; +typedef struct _vcs_dpi_display_bandwidth_st display_bandwidth_st; +typedef struct _vcs_dpi_scaler_ratio_depth_st scaler_ratio_depth_st; +typedef struct _vcs_dpi_scaler_taps_st scaler_taps_st; +typedef struct _vcs_dpi_display_pipe_dest_params_st display_pipe_dest_params_st; +typedef struct _vcs_dpi_display_pipe_params_st display_pipe_params_st; +typedef struct _vcs_dpi_display_clocks_and_cfg_st display_clocks_and_cfg_st; +typedef struct _vcs_dpi_display_e2e_pipe_params_st display_e2e_pipe_params_st; +typedef struct _vcs_dpi_dchub_buffer_sizing_st dchub_buffer_sizing_st; +typedef struct _vcs_dpi_watermarks_perf_st watermarks_perf_st; +typedef struct _vcs_dpi_cstate_pstate_watermarks_st cstate_pstate_watermarks_st; +typedef struct _vcs_dpi_wm_calc_pipe_params_st wm_calc_pipe_params_st; +typedef struct _vcs_dpi_vratio_pre_st vratio_pre_st; +typedef struct _vcs_dpi_display_data_rq_misc_params_st display_data_rq_misc_params_st; +typedef struct _vcs_dpi_display_data_rq_sizing_params_st display_data_rq_sizing_params_st; +typedef struct _vcs_dpi_display_data_rq_dlg_params_st display_data_rq_dlg_params_st; +typedef struct _vcs_dpi_display_cur_rq_dlg_params_st display_cur_rq_dlg_params_st; +typedef struct _vcs_dpi_display_rq_dlg_params_st display_rq_dlg_params_st; +typedef struct _vcs_dpi_display_rq_sizing_params_st display_rq_sizing_params_st; +typedef struct _vcs_dpi_display_rq_misc_params_st display_rq_misc_params_st; +typedef struct _vcs_dpi_display_rq_params_st display_rq_params_st; +typedef struct _vcs_dpi_display_dlg_regs_st display_dlg_regs_st; +typedef struct _vcs_dpi_display_ttu_regs_st display_ttu_regs_st; +typedef struct _vcs_dpi_display_data_rq_regs_st display_data_rq_regs_st; +typedef struct _vcs_dpi_display_rq_regs_st display_rq_regs_st; +typedef struct _vcs_dpi_display_dlg_sys_params_st display_dlg_sys_params_st; +typedef struct _vcs_dpi_display_dlg_prefetch_param_st display_dlg_prefetch_param_st; +typedef struct _vcs_dpi_display_pipe_clock_st display_pipe_clock_st; +typedef struct _vcs_dpi_display_arb_params_st display_arb_params_st; + +struct _vcs_dpi_mode_evaluation_st { + int voltage_override; +}; + struct _vcs_dpi_voltage_scaling_st { + int state; double dcfclk_mhz; + double socclk_mhz; + double dram_speed_mhz; + double fabricclk_mhz; double dispclk_mhz; - double dppclk_mhz; double dram_bw_per_chan_gbps; double phyclk_mhz; - double socclk_mhz; + double dppclk_mhz; }; -struct _vcs_dpi_soc_bounding_box_st { - double sr_exit_time_us; - double sr_enter_plus_exit_time_us; - double urgent_latency_us; - double writeback_latency_us; - double ideal_dram_bw_after_urgent_percent; - unsigned int max_request_size_bytes; - struct _vcs_dpi_voltage_scaling_st vmin; - struct _vcs_dpi_voltage_scaling_st vmid; - struct _vcs_dpi_voltage_scaling_st vnom; - struct _vcs_dpi_voltage_scaling_st vmax; - double downspread_percent; - double dram_page_open_time_ns; - double dram_rw_turnaround_time_ns; - double dram_return_buffer_per_channel_bytes; - unsigned int round_trip_ping_latency_dcfclk_cycles; - unsigned int urgent_out_of_order_return_per_channel_bytes; - unsigned int channel_interleave_bytes; - unsigned int num_banks; - unsigned int num_chans; - unsigned int vmm_page_size_bytes; - double dram_clock_change_latency_us; - double writeback_dram_clock_change_latency_us; - unsigned int return_bus_width_bytes; -}; - -struct _vcs_dpi_ip_params_st { - unsigned int rob_buffer_size_kbytes; - unsigned int det_buffer_size_kbytes; - unsigned int dpte_buffer_size_in_pte_reqs; - unsigned int dpp_output_buffer_pixels; - unsigned int opp_output_buffer_lines; - unsigned int pixel_chunk_size_kbytes; - unsigned char pte_enable; - unsigned int pte_chunk_size_kbytes; - unsigned int meta_chunk_size_kbytes; - unsigned int writeback_chunk_size_kbytes; - unsigned int line_buffer_size_bits; - unsigned int max_line_buffer_lines; +struct _vcs_dpi_soc_bounding_box_st { + double sr_exit_time_us; + double sr_enter_plus_exit_time_us; + double urgent_latency_us; + double writeback_latency_us; + double ideal_dram_bw_after_urgent_percent; + unsigned int max_request_size_bytes; + struct _vcs_dpi_voltage_scaling_st vmin; + struct _vcs_dpi_voltage_scaling_st vmid; + struct _vcs_dpi_voltage_scaling_st vnom; + struct _vcs_dpi_voltage_scaling_st vmax; + double downspread_percent; + double dram_page_open_time_ns; + double dram_rw_turnaround_time_ns; + double dram_return_buffer_per_channel_bytes; + double dram_channel_width_bytes; + double fabric_datapath_to_dcn_data_return_bytes; + double dcn_downspread_percent; + double dispclk_dppclk_vco_speed_mhz; + unsigned int round_trip_ping_latency_dcfclk_cycles; + unsigned int urgent_out_of_order_return_per_channel_bytes; + unsigned int channel_interleave_bytes; + unsigned int num_banks; + unsigned int num_chans; + unsigned int vmm_page_size_bytes; + double dram_clock_change_latency_us; + double writeback_dram_clock_change_latency_us; + unsigned int return_bus_width_bytes; + double xfc_bus_transport_time_us; + double xfc_xbuf_latency_tolerance_us; + struct _vcs_dpi_voltage_scaling_st clock_limits[7]; +}; + +struct _vcs_dpi_ip_params_st { + unsigned int max_inter_dcn_tile_repeaters; + unsigned int num_dsc; + unsigned int odm_capable; + unsigned int rob_buffer_size_kbytes; + unsigned int det_buffer_size_kbytes; + unsigned int dpte_buffer_size_in_pte_reqs; + unsigned int pde_proc_buffer_size_64k_reqs; + unsigned int dpp_output_buffer_pixels; + unsigned int opp_output_buffer_lines; + unsigned int pixel_chunk_size_kbytes; + unsigned char pte_enable; + unsigned int pte_chunk_size_kbytes; + unsigned int meta_chunk_size_kbytes; + unsigned int writeback_chunk_size_kbytes; + unsigned int line_buffer_size_bits; + unsigned int max_line_buffer_lines; + unsigned int writeback_luma_buffer_size_kbytes; + unsigned int writeback_chroma_buffer_size_kbytes; + unsigned int writeback_chroma_line_buffer_width_pixels; + unsigned int max_page_table_levels; + unsigned int max_num_dpp; + unsigned int max_num_wb; + unsigned int max_dchub_pscl_bw_pix_per_clk; + unsigned int max_pscl_lb_bw_pix_per_clk; + unsigned int max_lb_vscl_bw_pix_per_clk; + unsigned int max_vscl_hscl_bw_pix_per_clk; + double max_hscl_ratio; + double max_vscl_ratio; + unsigned int hscl_mults; + unsigned int vscl_mults; + unsigned int max_hscl_taps; + unsigned int max_vscl_taps; + unsigned int xfc_supported; + unsigned int ptoi_supported; + unsigned int xfc_fill_constant_bytes; + double dispclk_ramp_margin_percent; + double xfc_fill_bw_overhead_percent; + double underscan_factor; + unsigned int min_vblank_lines; + unsigned int dppclk_delay_subtotal; + unsigned int dispclk_delay_subtotal; + unsigned int dcfclk_cstate_latency; + unsigned int dppclk_delay_scl; + unsigned int dppclk_delay_scl_lb_only; + unsigned int dppclk_delay_cnvc_formatter; + unsigned int dppclk_delay_cnvc_cursor; + unsigned int is_line_buffer_bpp_fixed; + unsigned int line_buffer_fixed_bpp; + unsigned int dcc_supported; + unsigned int IsLineBufferBppFixed; unsigned int LineBufferFixedBpp; - unsigned int writeback_luma_buffer_size_kbytes; - unsigned int writeback_chroma_buffer_size_kbytes; - unsigned int max_num_dpp; - unsigned int max_num_wb; - unsigned int max_dchub_pscl_bw_pix_per_clk; - unsigned int max_pscl_lb_bw_pix_per_clk; - unsigned int max_lb_vscl_bw_pix_per_clk; - unsigned int max_vscl_hscl_bw_pix_per_clk; - double max_hscl_ratio; - double max_vscl_ratio; - unsigned int hscl_mults; - unsigned int vscl_mults; - unsigned int max_hscl_taps; - unsigned int max_vscl_taps; - double dispclk_ramp_margin_percent; - double underscan_factor; - unsigned int min_vblank_lines; - unsigned int dppclk_delay_subtotal; - unsigned int dispclk_delay_subtotal; - unsigned int dcfclk_cstate_latency; - unsigned int max_inter_dcn_tile_repeaters; unsigned int can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one; unsigned int bug_forcing_LC_req_same_size_fixed; }; -struct _vcs_dpi_display_pipe_source_params_st { - int source_format; - unsigned char dcc; - unsigned int dcc_rate; - unsigned char vm; - int source_scan; - int sw_mode; - int macro_tile_size; - unsigned char is_display_sw; - unsigned int viewport_width; - unsigned int viewport_height; - unsigned int viewport_width_c; - unsigned int viewport_height_c; - unsigned int data_pitch; - unsigned int data_pitch_c; - unsigned int meta_pitch; - unsigned int meta_pitch_c; - unsigned int cur0_src_width; - int cur0_bpp; - unsigned char is_hsplit; - unsigned int hsplit_grp; -}; - -struct _vcs_dpi_display_output_params_st { - int output_bpc; - int output_type; - int output_format; - int output_standard; -}; - -struct _vcs_dpi_display_bandwidth_st { - double total_bw_consumed_gbps; - double guaranteed_urgent_return_bw_gbps; -}; - -struct _vcs_dpi_scaler_ratio_depth_st { - double hscl_ratio; - double vscl_ratio; - double hscl_ratio_c; - double vscl_ratio_c; - double vinit; - double vinit_c; - double vinit_bot; - double vinit_bot_c; - int lb_depth; -}; - -struct _vcs_dpi_scaler_taps_st { - unsigned int htaps; - unsigned int vtaps; - unsigned int htaps_c; - unsigned int vtaps_c; -}; - -struct _vcs_dpi_display_pipe_dest_params_st { - unsigned int recout_width; - unsigned int recout_height; - unsigned int full_recout_width; - unsigned int full_recout_height; - unsigned int hblank_start; - unsigned int hblank_end; - unsigned int vblank_start; - unsigned int vblank_end; - unsigned int htotal; - unsigned int vtotal; - unsigned int vactive; - unsigned int vstartup_start; - unsigned int vupdate_offset; - unsigned int vupdate_width; - unsigned int vready_offset; - unsigned int vsync_plus_back_porch; - unsigned char interlaced; - unsigned char underscan; - double pixel_rate_mhz; - unsigned char syncronized_vblank_all_planes; -}; - -struct _vcs_dpi_display_pipe_params_st { - struct _vcs_dpi_display_pipe_source_params_st src; - struct _vcs_dpi_display_pipe_dest_params_st dest; - struct _vcs_dpi_scaler_ratio_depth_st scale_ratio_depth; - struct _vcs_dpi_scaler_taps_st scale_taps; -}; - -struct _vcs_dpi_display_clocks_and_cfg_st { - int voltage; - double dppclk_mhz; - double refclk_mhz; - double dispclk_mhz; - double dcfclk_mhz; - double socclk_mhz; -}; - -struct _vcs_dpi_display_e2e_pipe_params_st { - struct _vcs_dpi_display_pipe_params_st pipe; - struct _vcs_dpi_display_output_params_st dout; - struct _vcs_dpi_display_clocks_and_cfg_st clks_cfg; -}; - -struct _vcs_dpi_dchub_buffer_sizing_st { - unsigned int swath_width_y; - unsigned int swath_height_y; - unsigned int swath_height_c; - unsigned int detail_buffer_size_y; -}; - -struct _vcs_dpi_watermarks_perf_st { - double stutter_eff_in_active_region_percent; - double urgent_latency_supported_us; - double non_urgent_latency_supported_us; - double dram_clock_change_margin_us; - double dram_access_eff_percent; -}; - -struct _vcs_dpi_cstate_pstate_watermarks_st { - double cstate_exit_us; - double cstate_enter_plus_exit_us; - double pstate_change_us; -}; - -struct _vcs_dpi_wm_calc_pipe_params_st { - unsigned int num_dpp; - int voltage; - int output_type; - double dcfclk_mhz; - double socclk_mhz; - double dppclk_mhz; - double pixclk_mhz; - unsigned char interlace_en; - unsigned char pte_enable; - unsigned char dcc_enable; - double dcc_rate; - double bytes_per_pixel_c; - double bytes_per_pixel_y; - unsigned int swath_width_y; - unsigned int swath_height_y; - unsigned int swath_height_c; - unsigned int det_buffer_size_y; - double h_ratio; - double v_ratio; - unsigned int h_taps; - unsigned int h_total; - unsigned int v_total; - unsigned int v_active; - unsigned int e2e_index; - double display_pipe_line_delivery_time; - double read_bw; - unsigned int lines_in_det_y; - unsigned int lines_in_det_y_rounded_down_to_swath; - double full_det_buffering_time; - double dcfclk_deepsleep_mhz_per_plane; -}; - -struct _vcs_dpi_vratio_pre_st { - double vratio_pre_l; - double vratio_pre_c; -}; - -struct _vcs_dpi_display_data_rq_misc_params_st { - unsigned int full_swath_bytes; - unsigned int stored_swath_bytes; - unsigned int blk256_height; - unsigned int blk256_width; - unsigned int req_height; - unsigned int req_width; -}; - -struct _vcs_dpi_display_data_rq_sizing_params_st { - unsigned int chunk_bytes; - unsigned int min_chunk_bytes; - unsigned int meta_chunk_bytes; - unsigned int min_meta_chunk_bytes; - unsigned int mpte_group_bytes; - unsigned int dpte_group_bytes; -}; - -struct _vcs_dpi_display_data_rq_dlg_params_st { - unsigned int swath_width_ub; - unsigned int swath_height; - unsigned int req_per_swath_ub; - unsigned int meta_pte_bytes_per_frame_ub; - unsigned int dpte_req_per_row_ub; - unsigned int dpte_groups_per_row_ub; - unsigned int dpte_row_height; - unsigned int dpte_bytes_per_row_ub; - unsigned int meta_chunks_per_row_ub; - unsigned int meta_req_per_row_ub; - unsigned int meta_row_height; - unsigned int meta_bytes_per_row_ub; -}; - -struct _vcs_dpi_display_cur_rq_dlg_params_st { - unsigned char enable; - unsigned int swath_height; - unsigned int req_per_line; -}; - -struct _vcs_dpi_display_rq_dlg_params_st { - struct _vcs_dpi_display_data_rq_dlg_params_st rq_l; - struct _vcs_dpi_display_data_rq_dlg_params_st rq_c; - struct _vcs_dpi_display_cur_rq_dlg_params_st rq_cur0; -}; - -struct _vcs_dpi_display_rq_sizing_params_st { - struct _vcs_dpi_display_data_rq_sizing_params_st rq_l; - struct _vcs_dpi_display_data_rq_sizing_params_st rq_c; -}; - -struct _vcs_dpi_display_rq_misc_params_st { - struct _vcs_dpi_display_data_rq_misc_params_st rq_l; - struct _vcs_dpi_display_data_rq_misc_params_st rq_c; -}; - -struct _vcs_dpi_display_rq_params_st { - unsigned char yuv420; - unsigned char yuv420_10bpc; - struct _vcs_dpi_display_rq_misc_params_st misc; - struct _vcs_dpi_display_rq_sizing_params_st sizing; - struct _vcs_dpi_display_rq_dlg_params_st dlg; -}; - -struct _vcs_dpi_display_dlg_regs_st { - unsigned int refcyc_h_blank_end; - unsigned int dlg_vblank_end; - unsigned int min_dst_y_next_start; - unsigned int refcyc_per_htotal; - unsigned int refcyc_x_after_scaler; - unsigned int dst_y_after_scaler; - unsigned int dst_y_prefetch; - unsigned int dst_y_per_vm_vblank; - unsigned int dst_y_per_row_vblank; - unsigned int ref_freq_to_pix_freq; - unsigned int vratio_prefetch; - unsigned int vratio_prefetch_c; - unsigned int refcyc_per_pte_group_vblank_l; - unsigned int refcyc_per_pte_group_vblank_c; - unsigned int refcyc_per_meta_chunk_vblank_l; - unsigned int refcyc_per_meta_chunk_vblank_c; - unsigned int dst_y_per_pte_row_nom_l; - unsigned int dst_y_per_pte_row_nom_c; - unsigned int refcyc_per_pte_group_nom_l; - unsigned int refcyc_per_pte_group_nom_c; - unsigned int dst_y_per_meta_row_nom_l; - unsigned int dst_y_per_meta_row_nom_c; - unsigned int refcyc_per_meta_chunk_nom_l; - unsigned int refcyc_per_meta_chunk_nom_c; - unsigned int refcyc_per_line_delivery_pre_l; - unsigned int refcyc_per_line_delivery_pre_c; - unsigned int refcyc_per_line_delivery_l; - unsigned int refcyc_per_line_delivery_c; - unsigned int chunk_hdl_adjust_cur0; -}; - -struct _vcs_dpi_display_ttu_regs_st { - unsigned int qos_level_low_wm; - unsigned int qos_level_high_wm; - unsigned int min_ttu_vblank; - unsigned int qos_level_flip; - unsigned int refcyc_per_req_delivery_l; - unsigned int refcyc_per_req_delivery_c; - unsigned int refcyc_per_req_delivery_cur0; - unsigned int refcyc_per_req_delivery_pre_l; - unsigned int refcyc_per_req_delivery_pre_c; - unsigned int refcyc_per_req_delivery_pre_cur0; - unsigned int qos_level_fixed_l; - unsigned int qos_level_fixed_c; - unsigned int qos_level_fixed_cur0; - unsigned int qos_ramp_disable_l; - unsigned int qos_ramp_disable_c; - unsigned int qos_ramp_disable_cur0; -}; - -struct _vcs_dpi_display_data_rq_regs_st { - unsigned int chunk_size; - unsigned int min_chunk_size; - unsigned int meta_chunk_size; - unsigned int min_meta_chunk_size; - unsigned int dpte_group_size; - unsigned int mpte_group_size; - unsigned int swath_height; - unsigned int pte_row_height_linear; -}; - -struct _vcs_dpi_display_rq_regs_st { - struct _vcs_dpi_display_data_rq_regs_st rq_regs_l; - struct _vcs_dpi_display_data_rq_regs_st rq_regs_c; - unsigned int drq_expansion_mode; - unsigned int prq_expansion_mode; - unsigned int mrq_expansion_mode; - unsigned int crq_expansion_mode; - unsigned int plane1_base_address; -}; - -struct _vcs_dpi_display_dlg_sys_params_st { - double t_mclk_wm_us; - double t_urg_wm_us; - double t_sr_wm_us; - double t_extra_us; - double t_srx_delay_us; - double deepsleep_dcfclk_mhz; - double total_flip_bw; - unsigned int total_flip_bytes; -}; - -struct _vcs_dpi_display_dlg_prefetch_param_st { - double prefetch_bw; - unsigned int flip_bytes; -}; - -struct _vcs_dpi_display_pipe_clock_st { - double dcfclk_mhz; - double dispclk_mhz; - double dppclk_mhz[4]; - unsigned char dppclk_div[4]; -}; - -struct _vcs_dpi_display_arb_params_st { - int max_req_outstanding; - int min_req_outstanding; - int sat_level_us; -}; - -struct _vcs_dpi_mode_evaluation_st { - int voltage_override; +struct _vcs_dpi_display_xfc_params_st { + double xfc_tslv_vready_offset_us; + double xfc_tslv_vupdate_width_us; + double xfc_tslv_vupdate_offset_us; + int xfc_slv_chunk_size_bytes; +}; + +struct _vcs_dpi_display_pipe_source_params_st { + int source_format; + unsigned char dcc; + unsigned int dcc_override; + unsigned int dcc_rate; + unsigned char dcc_use_global; + unsigned char vm; + unsigned char vm_levels_force_en; + unsigned int vm_levels_force; + int source_scan; + int sw_mode; + int macro_tile_size; + unsigned char is_display_sw; + unsigned int viewport_width; + unsigned int viewport_height; + unsigned int viewport_y_y; + unsigned int viewport_y_c; + unsigned int viewport_width_c; + unsigned int viewport_height_c; + unsigned int data_pitch; + unsigned int data_pitch_c; + unsigned int meta_pitch; + unsigned int meta_pitch_c; + unsigned int cur0_src_width; + int cur0_bpp; + unsigned int cur1_src_width; + int cur1_bpp; + int num_cursors; + unsigned char is_hsplit; + unsigned char dynamic_metadata_enable; + unsigned int dynamic_metadata_lines_before_active; + unsigned int dynamic_metadata_xmit_bytes; + unsigned int hsplit_grp; + unsigned char xfc_enable; + unsigned char xfc_slave; + struct _vcs_dpi_display_xfc_params_st xfc_params; +}; +struct writeback_st { + int wb_src_height; + int wb_dst_width; + int wb_dst_height; + int wb_pixel_format; + int wb_htaps_luma; + int wb_vtaps_luma; + int wb_htaps_chroma; + int wb_vtaps_chroma; + int wb_hratio; + int wb_vratio; +}; + +struct _vcs_dpi_display_output_params_st { + int output_bpp; + int dsc_enable; + int wb_enable; + int output_bpc; + int output_type; + int output_format; + int output_standard; + int dsc_slices; + struct writeback_st wb; +}; + +struct _vcs_dpi_display_bandwidth_st { + double total_bw_consumed_gbps; + double guaranteed_urgent_return_bw_gbps; +}; + +struct _vcs_dpi_scaler_ratio_depth_st { + double hscl_ratio; + double vscl_ratio; + double hscl_ratio_c; + double vscl_ratio_c; + double vinit; + double vinit_c; + double vinit_bot; + double vinit_bot_c; + int lb_depth; + int scl_enable; +}; + +struct _vcs_dpi_scaler_taps_st { + unsigned int htaps; + unsigned int vtaps; + unsigned int htaps_c; + unsigned int vtaps_c; +}; + +struct _vcs_dpi_display_pipe_dest_params_st { + unsigned int recout_width; + unsigned int recout_height; + unsigned int full_recout_width; + unsigned int full_recout_height; + unsigned int hblank_start; + unsigned int hblank_end; + unsigned int vblank_start; + unsigned int vblank_end; + unsigned int htotal; + unsigned int vtotal; + unsigned int vactive; + unsigned int hactive; + unsigned int vstartup_start; + unsigned int vupdate_offset; + unsigned int vupdate_width; + unsigned int vready_offset; + unsigned char interlaced; + unsigned char underscan; + double pixel_rate_mhz; + unsigned char synchronized_vblank_all_planes; + unsigned char otg_inst; + unsigned char odm_split_cnt; + unsigned char odm_combine; +}; + +struct _vcs_dpi_display_pipe_params_st { + display_pipe_source_params_st src; + display_pipe_dest_params_st dest; + scaler_ratio_depth_st scale_ratio_depth; + scaler_taps_st scale_taps; +}; + +struct _vcs_dpi_display_clocks_and_cfg_st { + int voltage; + double dppclk_mhz; + double refclk_mhz; + double dispclk_mhz; + double dcfclk_mhz; + double socclk_mhz; +}; + +struct _vcs_dpi_display_e2e_pipe_params_st { + display_pipe_params_st pipe; + display_output_params_st dout; + display_clocks_and_cfg_st clks_cfg; +}; + +struct _vcs_dpi_dchub_buffer_sizing_st { + unsigned int swath_width_y; + unsigned int swath_height_y; + unsigned int swath_height_c; + unsigned int detail_buffer_size_y; +}; + +struct _vcs_dpi_watermarks_perf_st { + double stutter_eff_in_active_region_percent; + double urgent_latency_supported_us; + double non_urgent_latency_supported_us; + double dram_clock_change_margin_us; + double dram_access_eff_percent; +}; + +struct _vcs_dpi_cstate_pstate_watermarks_st { + double cstate_exit_us; + double cstate_enter_plus_exit_us; + double pstate_change_us; +}; + +struct _vcs_dpi_wm_calc_pipe_params_st { + unsigned int num_dpp; + int voltage; + int output_type; + double dcfclk_mhz; + double socclk_mhz; + double dppclk_mhz; + double pixclk_mhz; + unsigned char interlace_en; + unsigned char pte_enable; + unsigned char dcc_enable; + double dcc_rate; + double bytes_per_pixel_c; + double bytes_per_pixel_y; + unsigned int swath_width_y; + unsigned int swath_height_y; + unsigned int swath_height_c; + unsigned int det_buffer_size_y; + double h_ratio; + double v_ratio; + unsigned int h_taps; + unsigned int h_total; + unsigned int v_total; + unsigned int v_active; + unsigned int e2e_index; + double display_pipe_line_delivery_time; + double read_bw; + unsigned int lines_in_det_y; + unsigned int lines_in_det_y_rounded_down_to_swath; + double full_det_buffering_time; + double dcfclk_deepsleep_mhz_per_plane; +}; + +struct _vcs_dpi_vratio_pre_st { + double vratio_pre_l; + double vratio_pre_c; +}; + +struct _vcs_dpi_display_data_rq_misc_params_st { + unsigned int full_swath_bytes; + unsigned int stored_swath_bytes; + unsigned int blk256_height; + unsigned int blk256_width; + unsigned int req_height; + unsigned int req_width; +}; + +struct _vcs_dpi_display_data_rq_sizing_params_st { + unsigned int chunk_bytes; + unsigned int min_chunk_bytes; + unsigned int meta_chunk_bytes; + unsigned int min_meta_chunk_bytes; + unsigned int mpte_group_bytes; + unsigned int dpte_group_bytes; +}; + +struct _vcs_dpi_display_data_rq_dlg_params_st { + unsigned int swath_width_ub; + unsigned int swath_height; + unsigned int req_per_swath_ub; + unsigned int meta_pte_bytes_per_frame_ub; + unsigned int dpte_req_per_row_ub; + unsigned int dpte_groups_per_row_ub; + unsigned int dpte_row_height; + unsigned int dpte_bytes_per_row_ub; + unsigned int meta_chunks_per_row_ub; + unsigned int meta_req_per_row_ub; + unsigned int meta_row_height; + unsigned int meta_bytes_per_row_ub; +}; + +struct _vcs_dpi_display_cur_rq_dlg_params_st { + unsigned char enable; + unsigned int swath_height; + unsigned int req_per_line; +}; + +struct _vcs_dpi_display_rq_dlg_params_st { + display_data_rq_dlg_params_st rq_l; + display_data_rq_dlg_params_st rq_c; + display_cur_rq_dlg_params_st rq_cur0; +}; + +struct _vcs_dpi_display_rq_sizing_params_st { + display_data_rq_sizing_params_st rq_l; + display_data_rq_sizing_params_st rq_c; +}; + +struct _vcs_dpi_display_rq_misc_params_st { + display_data_rq_misc_params_st rq_l; + display_data_rq_misc_params_st rq_c; +}; + +struct _vcs_dpi_display_rq_params_st { + unsigned char yuv420; + unsigned char yuv420_10bpc; + display_rq_misc_params_st misc; + display_rq_sizing_params_st sizing; + display_rq_dlg_params_st dlg; +}; + +struct _vcs_dpi_display_dlg_regs_st { + unsigned int refcyc_h_blank_end; + unsigned int dlg_vblank_end; + unsigned int min_dst_y_next_start; + unsigned int refcyc_per_htotal; + unsigned int refcyc_x_after_scaler; + unsigned int dst_y_after_scaler; + unsigned int dst_y_prefetch; + unsigned int dst_y_per_vm_vblank; + unsigned int dst_y_per_row_vblank; + unsigned int dst_y_per_vm_flip; + unsigned int dst_y_per_row_flip; + unsigned int ref_freq_to_pix_freq; + unsigned int vratio_prefetch; + unsigned int vratio_prefetch_c; + unsigned int refcyc_per_pte_group_vblank_l; + unsigned int refcyc_per_pte_group_vblank_c; + unsigned int refcyc_per_meta_chunk_vblank_l; + unsigned int refcyc_per_meta_chunk_vblank_c; + unsigned int refcyc_per_pte_group_flip_l; + unsigned int refcyc_per_pte_group_flip_c; + unsigned int refcyc_per_meta_chunk_flip_l; + unsigned int refcyc_per_meta_chunk_flip_c; + unsigned int dst_y_per_pte_row_nom_l; + unsigned int dst_y_per_pte_row_nom_c; + unsigned int refcyc_per_pte_group_nom_l; + unsigned int refcyc_per_pte_group_nom_c; + unsigned int dst_y_per_meta_row_nom_l; + unsigned int dst_y_per_meta_row_nom_c; + unsigned int refcyc_per_meta_chunk_nom_l; + unsigned int refcyc_per_meta_chunk_nom_c; + unsigned int refcyc_per_line_delivery_pre_l; + unsigned int refcyc_per_line_delivery_pre_c; + unsigned int refcyc_per_line_delivery_l; + unsigned int refcyc_per_line_delivery_c; + unsigned int chunk_hdl_adjust_cur0; + unsigned int chunk_hdl_adjust_cur1; + unsigned int vready_after_vcount0; + unsigned int dst_y_offset_cur0; + unsigned int dst_y_offset_cur1; + unsigned int xfc_reg_transfer_delay; + unsigned int xfc_reg_precharge_delay; + unsigned int xfc_reg_remote_surface_flip_latency; + unsigned int xfc_reg_prefetch_margin; + unsigned int dst_y_delta_drq_limit; +}; + +struct _vcs_dpi_display_ttu_regs_st { + unsigned int qos_level_low_wm; + unsigned int qos_level_high_wm; + unsigned int min_ttu_vblank; + unsigned int qos_level_flip; + unsigned int refcyc_per_req_delivery_l; + unsigned int refcyc_per_req_delivery_c; + unsigned int refcyc_per_req_delivery_cur0; + unsigned int refcyc_per_req_delivery_cur1; + unsigned int refcyc_per_req_delivery_pre_l; + unsigned int refcyc_per_req_delivery_pre_c; + unsigned int refcyc_per_req_delivery_pre_cur0; + unsigned int refcyc_per_req_delivery_pre_cur1; + unsigned int qos_level_fixed_l; + unsigned int qos_level_fixed_c; + unsigned int qos_level_fixed_cur0; + unsigned int qos_level_fixed_cur1; + unsigned int qos_ramp_disable_l; + unsigned int qos_ramp_disable_c; + unsigned int qos_ramp_disable_cur0; + unsigned int qos_ramp_disable_cur1; +}; + +struct _vcs_dpi_display_data_rq_regs_st { + unsigned int chunk_size; + unsigned int min_chunk_size; + unsigned int meta_chunk_size; + unsigned int min_meta_chunk_size; + unsigned int dpte_group_size; + unsigned int mpte_group_size; + unsigned int swath_height; + unsigned int pte_row_height_linear; +}; + +struct _vcs_dpi_display_rq_regs_st { + display_data_rq_regs_st rq_regs_l; + display_data_rq_regs_st rq_regs_c; + unsigned int drq_expansion_mode; + unsigned int prq_expansion_mode; + unsigned int mrq_expansion_mode; + unsigned int crq_expansion_mode; + unsigned int plane1_base_address; +}; + +struct _vcs_dpi_display_dlg_sys_params_st { + double t_mclk_wm_us; + double t_urg_wm_us; + double t_sr_wm_us; + double t_extra_us; + double mem_trip_us; + double t_srx_delay_us; + double deepsleep_dcfclk_mhz; + double total_flip_bw; + unsigned int total_flip_bytes; +}; + +struct _vcs_dpi_display_dlg_prefetch_param_st { + double prefetch_bw; + unsigned int flip_bytes; +}; + +struct _vcs_dpi_display_pipe_clock_st { + double dcfclk_mhz; + double dispclk_mhz; + double socclk_mhz; + double dscclk_mhz[6]; + double dppclk_mhz[6]; +}; + +struct _vcs_dpi_display_arb_params_st { + int max_req_outstanding; + int min_req_outstanding; + int sat_level_us; }; #endif /*__DISPLAY_MODE_STRUCTS_H__*/ diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_support.c b/drivers/gpu/drm/amd/display/dc/dml/display_mode_support.c deleted file mode 100644 index 3b4ee74527f50..0000000000000 --- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_support.c +++ /dev/null @@ -1,2326 +0,0 @@ -/* - * Copyright 2017 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: AMD - * - */ - -#include "display_mode_support.h" -#include "display_mode_lib.h" - -int dml_ms_check( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_display_e2e_pipe_params_st *e2e, - int num_pipes) -{ - struct _vcs_dpi_ip_params_st *ip; - struct _vcs_dpi_soc_bounding_box_st *soc; - struct _vcs_dpi_mode_evaluation_st *me; - struct dml_ms_internal_vars *v; - int num_planes, i, j, ij, k, ijk; - - ip = &(mode_lib->ip); - soc = &(mode_lib->soc); - me = &(mode_lib->me); - v = &(mode_lib->vars); - num_planes = dml_wm_e2e_to_wm(mode_lib, e2e, num_pipes, v->planes); - - //instantiating variables to zero - v->MacroTileBlockWidthC = 0; - v->SwathWidthGranularityC = 0; - - v->DCFCLKPerState[5] = 0; - v->DCFCLKPerState[4] = 0; - v->DCFCLKPerState[3] = 0; - v->DCFCLKPerState[2] = 0; - v->DCFCLKPerState[1] = 0; - v->DCFCLKPerState[0] = 0; - - if (soc->vmin.dcfclk_mhz > 0) { - v->DCFCLKPerState[5] = soc->vmin.dcfclk_mhz; - v->DCFCLKPerState[4] = soc->vmin.dcfclk_mhz; - v->DCFCLKPerState[3] = soc->vmin.dcfclk_mhz; - v->DCFCLKPerState[2] = soc->vmin.dcfclk_mhz; - v->DCFCLKPerState[1] = soc->vmin.dcfclk_mhz; - v->DCFCLKPerState[0] = soc->vmin.dcfclk_mhz; - } - - if (soc->vmid.dcfclk_mhz > 0) { - v->DCFCLKPerState[5] = soc->vmid.dcfclk_mhz; - v->DCFCLKPerState[4] = soc->vmid.dcfclk_mhz; - v->DCFCLKPerState[3] = soc->vmid.dcfclk_mhz; - v->DCFCLKPerState[2] = soc->vmid.dcfclk_mhz; - v->DCFCLKPerState[1] = soc->vmid.dcfclk_mhz; - } - - if (soc->vnom.dcfclk_mhz > 0) { - v->DCFCLKPerState[5] = soc->vnom.dcfclk_mhz; - v->DCFCLKPerState[4] = soc->vnom.dcfclk_mhz; - v->DCFCLKPerState[3] = soc->vnom.dcfclk_mhz; - v->DCFCLKPerState[2] = soc->vnom.dcfclk_mhz; - } - - if (soc->vmax.dcfclk_mhz > 0) { - v->DCFCLKPerState[5] = soc->vmax.dcfclk_mhz; - v->DCFCLKPerState[4] = soc->vmax.dcfclk_mhz; - v->DCFCLKPerState[3] = soc->vmax.dcfclk_mhz; - } - - v->FabricAndDRAMBandwidthPerState[5] = 0; - v->FabricAndDRAMBandwidthPerState[4] = 0; - v->FabricAndDRAMBandwidthPerState[3] = 0; - v->FabricAndDRAMBandwidthPerState[2] = 0; - v->FabricAndDRAMBandwidthPerState[1] = 0; - v->FabricAndDRAMBandwidthPerState[0] = 0; - - if (soc->vmin.dram_bw_per_chan_gbps > 0) { - v->FabricAndDRAMBandwidthPerState[5] = soc->vmin.dram_bw_per_chan_gbps; - v->FabricAndDRAMBandwidthPerState[4] = soc->vmin.dram_bw_per_chan_gbps; - v->FabricAndDRAMBandwidthPerState[3] = soc->vmin.dram_bw_per_chan_gbps; - v->FabricAndDRAMBandwidthPerState[2] = soc->vmin.dram_bw_per_chan_gbps; - v->FabricAndDRAMBandwidthPerState[1] = soc->vmin.dram_bw_per_chan_gbps; - v->FabricAndDRAMBandwidthPerState[0] = soc->vmin.dram_bw_per_chan_gbps; - } - - if (soc->vmid.dram_bw_per_chan_gbps > 0) { - v->FabricAndDRAMBandwidthPerState[5] = soc->vmid.dram_bw_per_chan_gbps; - v->FabricAndDRAMBandwidthPerState[4] = soc->vmid.dram_bw_per_chan_gbps; - v->FabricAndDRAMBandwidthPerState[3] = soc->vmid.dram_bw_per_chan_gbps; - v->FabricAndDRAMBandwidthPerState[2] = soc->vmid.dram_bw_per_chan_gbps; - v->FabricAndDRAMBandwidthPerState[1] = soc->vmid.dram_bw_per_chan_gbps; - } - - if (soc->vnom.dram_bw_per_chan_gbps > 0) { - v->FabricAndDRAMBandwidthPerState[5] = soc->vnom.dram_bw_per_chan_gbps; - v->FabricAndDRAMBandwidthPerState[4] = soc->vnom.dram_bw_per_chan_gbps; - v->FabricAndDRAMBandwidthPerState[3] = soc->vnom.dram_bw_per_chan_gbps; - v->FabricAndDRAMBandwidthPerState[2] = soc->vnom.dram_bw_per_chan_gbps; - } - - if (soc->vmax.dram_bw_per_chan_gbps > 0) { - v->FabricAndDRAMBandwidthPerState[5] = soc->vmax.dram_bw_per_chan_gbps; - v->FabricAndDRAMBandwidthPerState[4] = soc->vmax.dram_bw_per_chan_gbps; - v->FabricAndDRAMBandwidthPerState[3] = soc->vmax.dram_bw_per_chan_gbps; - } - - v->PHYCLKPerState[5] = 0; - v->PHYCLKPerState[4] = 0; - v->PHYCLKPerState[3] = 0; - v->PHYCLKPerState[2] = 0; - v->PHYCLKPerState[1] = 0; - v->PHYCLKPerState[0] = 0; - - if (soc->vmin.phyclk_mhz > 0) { - v->PHYCLKPerState[5] = soc->vmin.phyclk_mhz; - v->PHYCLKPerState[4] = soc->vmin.phyclk_mhz; - v->PHYCLKPerState[3] = soc->vmin.phyclk_mhz; - v->PHYCLKPerState[2] = soc->vmin.phyclk_mhz; - v->PHYCLKPerState[1] = soc->vmin.phyclk_mhz; - v->PHYCLKPerState[0] = soc->vmin.phyclk_mhz; - } - - if (soc->vmid.phyclk_mhz > 0) { - v->PHYCLKPerState[5] = soc->vmid.phyclk_mhz; - v->PHYCLKPerState[4] = soc->vmid.phyclk_mhz; - v->PHYCLKPerState[3] = soc->vmid.phyclk_mhz; - v->PHYCLKPerState[2] = soc->vmid.phyclk_mhz; - v->PHYCLKPerState[1] = soc->vmid.phyclk_mhz; - } - - if (soc->vnom.phyclk_mhz > 0) { - v->PHYCLKPerState[5] = soc->vnom.phyclk_mhz; - v->PHYCLKPerState[4] = soc->vnom.phyclk_mhz; - v->PHYCLKPerState[3] = soc->vnom.phyclk_mhz; - v->PHYCLKPerState[2] = soc->vnom.phyclk_mhz; - } - - if (soc->vmax.phyclk_mhz > 0) { - v->PHYCLKPerState[5] = soc->vmax.phyclk_mhz; - v->PHYCLKPerState[4] = soc->vmax.phyclk_mhz; - v->PHYCLKPerState[3] = soc->vmax.phyclk_mhz; - } - - v->MaxDispclk[5] = 0; - v->MaxDispclk[4] = 0; - v->MaxDispclk[3] = 0; - v->MaxDispclk[2] = 0; - v->MaxDispclk[1] = 0; - v->MaxDispclk[0] = 0; - - if (soc->vmin.dispclk_mhz > 0) { - v->MaxDispclk[5] = soc->vmin.dispclk_mhz; - v->MaxDispclk[4] = soc->vmin.dispclk_mhz; - v->MaxDispclk[3] = soc->vmin.dispclk_mhz; - v->MaxDispclk[2] = soc->vmin.dispclk_mhz; - v->MaxDispclk[1] = soc->vmin.dispclk_mhz; - v->MaxDispclk[0] = soc->vmin.dispclk_mhz; - } - - if (soc->vmid.dispclk_mhz > 0) { - v->MaxDispclk[5] = soc->vmid.dispclk_mhz; - v->MaxDispclk[4] = soc->vmid.dispclk_mhz; - v->MaxDispclk[3] = soc->vmid.dispclk_mhz; - v->MaxDispclk[2] = soc->vmid.dispclk_mhz; - v->MaxDispclk[1] = soc->vmid.dispclk_mhz; - } - - if (soc->vnom.dispclk_mhz > 0) { - v->MaxDispclk[5] = soc->vnom.dispclk_mhz; - v->MaxDispclk[4] = soc->vnom.dispclk_mhz; - v->MaxDispclk[3] = soc->vnom.dispclk_mhz; - v->MaxDispclk[2] = soc->vnom.dispclk_mhz; - } - - if (soc->vmax.dispclk_mhz > 0) { - v->MaxDispclk[5] = soc->vmax.dispclk_mhz; - v->MaxDispclk[4] = soc->vmax.dispclk_mhz; - v->MaxDispclk[3] = soc->vmax.dispclk_mhz; - } - - v->MaxDppclk[5] = 0; - v->MaxDppclk[4] = 0; - v->MaxDppclk[3] = 0; - v->MaxDppclk[2] = 0; - v->MaxDppclk[1] = 0; - v->MaxDppclk[0] = 0; - - if (soc->vmin.dppclk_mhz > 0) { - v->MaxDppclk[5] = soc->vmin.dppclk_mhz; - v->MaxDppclk[4] = soc->vmin.dppclk_mhz; - v->MaxDppclk[3] = soc->vmin.dppclk_mhz; - v->MaxDppclk[2] = soc->vmin.dppclk_mhz; - v->MaxDppclk[1] = soc->vmin.dppclk_mhz; - v->MaxDppclk[0] = soc->vmin.dppclk_mhz; - } - - if (soc->vmid.dppclk_mhz > 0) { - v->MaxDppclk[5] = soc->vmid.dppclk_mhz; - v->MaxDppclk[4] = soc->vmid.dppclk_mhz; - v->MaxDppclk[3] = soc->vmid.dppclk_mhz; - v->MaxDppclk[2] = soc->vmid.dppclk_mhz; - v->MaxDppclk[1] = soc->vmid.dppclk_mhz; - } - - if (soc->vnom.dppclk_mhz > 0) { - v->MaxDppclk[5] = soc->vnom.dppclk_mhz; - v->MaxDppclk[4] = soc->vnom.dppclk_mhz; - v->MaxDppclk[3] = soc->vnom.dppclk_mhz; - v->MaxDppclk[2] = soc->vnom.dppclk_mhz; - } - - if (soc->vmax.dppclk_mhz > 0) { - v->MaxDppclk[5] = soc->vmax.dppclk_mhz; - v->MaxDppclk[4] = soc->vmax.dppclk_mhz; - v->MaxDppclk[3] = soc->vmax.dppclk_mhz; - } - - if (me->voltage_override == dm_vmax) { - v->VoltageOverrideLevel = NumberOfStates - 1; - } else if (me->voltage_override == dm_vnom) { - v->VoltageOverrideLevel = NumberOfStates - 2; - } else if (me->voltage_override == dm_vmid) { - v->VoltageOverrideLevel = NumberOfStates - 3; - } else { - v->VoltageOverrideLevel = 0; - } - - // Scale Ratio Support Check - - v->ScaleRatioSupport = 1; - - for (k = 0; k < num_planes; k++) { - struct _vcs_dpi_scaler_ratio_depth_st scale_ratio_depth = - e2e[v->planes[k].e2e_index].pipe.scale_ratio_depth; - struct _vcs_dpi_scaler_taps_st scale_taps = - e2e[v->planes[k].e2e_index].pipe.scale_taps; - struct _vcs_dpi_display_pipe_source_params_st src = - e2e[v->planes[k].e2e_index].pipe.src; - - if (scale_ratio_depth.hscl_ratio > ip->max_hscl_ratio - || scale_ratio_depth.vscl_ratio > ip->max_vscl_ratio - || scale_ratio_depth.hscl_ratio > scale_taps.htaps - || scale_ratio_depth.vscl_ratio > scale_taps.vtaps - || (src.source_format != dm_444_64 && src.source_format != dm_444_32 - && src.source_format != dm_444_16 - && ((scale_ratio_depth.hscl_ratio / 2 - > scale_taps.htaps_c) - || (scale_ratio_depth.vscl_ratio / 2 - > scale_taps.vtaps_c)))) - - { - v->ScaleRatioSupport = 0; - } - } - - // Source Format, Pixel Format and Scan Support Check - - v->SourceFormatPixelAndScanSupport = 1; - - for (k = 0; k < num_planes; k++) { - struct _vcs_dpi_display_pipe_source_params_st src = - e2e[v->planes[k].e2e_index].pipe.src; - - if ((src.sw_mode == dm_sw_linear && src.source_scan != dm_horz) - || ((src.sw_mode == dm_sw_4kb_d || src.sw_mode == dm_sw_4kb_d_x - || src.sw_mode == dm_sw_64kb_d - || src.sw_mode == dm_sw_64kb_d_t - || src.sw_mode == dm_sw_64kb_d_x - || src.sw_mode == dm_sw_var_d - || src.sw_mode == dm_sw_var_d_x) - && (src.source_format != dm_444_64))) { - v->SourceFormatPixelAndScanSupport = 0; - } - } - - // Bandwidth Support Check - - for (k = 0; k < num_planes; k++) { - struct _vcs_dpi_display_pipe_source_params_st src = - e2e[v->planes[k].e2e_index].pipe.src; - - if (src.source_scan == dm_horz) { - v->SwathWidthYSingleDPP[k] = src.viewport_width; - } else { - v->SwathWidthYSingleDPP[k] = src.viewport_height; - } - - if (src.source_format == dm_444_64) { - v->BytePerPixelInDETY[k] = 8; - v->BytePerPixelInDETC[k] = 0; - } else if (src.source_format == dm_444_32) { - v->BytePerPixelInDETY[k] = 4; - v->BytePerPixelInDETC[k] = 0; - } else if (src.source_format == dm_444_16) { - v->BytePerPixelInDETY[k] = 2; - v->BytePerPixelInDETC[k] = 0; - } else if (src.source_format == dm_420_8) { - v->BytePerPixelInDETY[k] = 1; - v->BytePerPixelInDETC[k] = 2; - } else { - v->BytePerPixelInDETY[k] = 4.00 / 3.00; - v->BytePerPixelInDETC[k] = 8.00 / 3.00; - } - } - - v->TotalReadBandwidthConsumedGBytePerSecond = 0; - - for (k = 0; k < num_planes; k++) { - struct _vcs_dpi_display_pipe_source_params_st src = - e2e[v->planes[k].e2e_index].pipe.src; - struct _vcs_dpi_display_pipe_dest_params_st dest = - e2e[v->planes[k].e2e_index].pipe.dest; - struct _vcs_dpi_scaler_ratio_depth_st scale_ratio_depth = - e2e[v->planes[k].e2e_index].pipe.scale_ratio_depth; - - v->ReadBandwidth[k] = - v->SwathWidthYSingleDPP[k] - * (dml_ceil_ex(v->BytePerPixelInDETY[k], 1) - * scale_ratio_depth.vscl_ratio - + (dml_ceil_ex( - v->BytePerPixelInDETC[k], - 2) / 2) - * (scale_ratio_depth.vscl_ratio - / 2)) - / (dest.htotal / dest.pixel_rate_mhz); - - if (src.dcc == 1) { - v->ReadBandwidth[k] = v->ReadBandwidth[k] * (1 + 1 / 256); - } - - if (ip->pte_enable == 1 && src.source_scan != dm_horz - && (src.sw_mode == dm_sw_4kb_s || src.sw_mode == dm_sw_4kb_s_x - || src.sw_mode == dm_sw_4kb_d - || src.sw_mode == dm_sw_4kb_d_x)) { - v->ReadBandwidth[k] = v->ReadBandwidth[k] * (1 + 1 / 64); - } else if (ip->pte_enable == 1 && src.source_scan == dm_horz - && (src.source_format == dm_444_64 || src.source_format == dm_444_32) - && (src.sw_mode == dm_sw_64kb_s || src.sw_mode == dm_sw_64kb_s_t - || src.sw_mode == dm_sw_64kb_s_x - || src.sw_mode == dm_sw_64kb_d - || src.sw_mode == dm_sw_64kb_d_t - || src.sw_mode == dm_sw_64kb_d_x)) { - v->ReadBandwidth[k] = v->ReadBandwidth[k] * (1 + 1 / 256); - } else if (ip->pte_enable == 1) { - v->ReadBandwidth[k] = v->ReadBandwidth[k] * (1 + 1 / 512); - } - - v->TotalReadBandwidthConsumedGBytePerSecond = - v->TotalReadBandwidthConsumedGBytePerSecond - + v->ReadBandwidth[k] / 1000; - } - - v->TotalWriteBandwidthConsumedGBytePerSecond = 0; - - for (k = 0; k < num_planes; k++) { - struct _vcs_dpi_display_pipe_dest_params_st dest = - e2e[v->planes[k].e2e_index].pipe.dest; - struct _vcs_dpi_display_output_params_st dout = e2e[v->planes[k].e2e_index].dout; - - if (dout.output_type == dm_wb && dout.output_format == dm_444) { - v->WriteBandwidth[k] = dest.recout_width - / (dest.htotal / dest.pixel_rate_mhz) * 4; - } else if (dout.output_type == dm_wb) { - v->WriteBandwidth[k] = dest.recout_width - / (dest.htotal / dest.pixel_rate_mhz) * 1.5; - } else { - v->WriteBandwidth[k] = 0; - } - - v->TotalWriteBandwidthConsumedGBytePerSecond = - v->TotalWriteBandwidthConsumedGBytePerSecond - + v->WriteBandwidth[k] / 1000; - } - - v->TotalBandwidthConsumedGBytePerSecond = v->TotalReadBandwidthConsumedGBytePerSecond - + v->TotalWriteBandwidthConsumedGBytePerSecond; - - v->DCCEnabledInAnyPlane = 0; - - for (k = 0; k < num_planes; k++) { - struct _vcs_dpi_display_pipe_source_params_st src = - e2e[v->planes[k].e2e_index].pipe.src; - - if (src.dcc == 1) { - v->DCCEnabledInAnyPlane = 1; - } - } - - for (i = 0; i < NumberOfStatesPlusTwo; i++) { - v->ReturnBWToDCNPerState = dml_min( - soc->return_bus_width_bytes * v->DCFCLKPerState[i], - v->FabricAndDRAMBandwidthPerState[i] * 1000 - * soc->ideal_dram_bw_after_urgent_percent / 100); - - v->ReturnBWPerState[i] = v->ReturnBWToDCNPerState; - - if (v->DCCEnabledInAnyPlane == 1 - && v->ReturnBWToDCNPerState - > (v->DCFCLKPerState[i] - * soc->return_bus_width_bytes / 4)) { - v->ReturnBWPerState[i] = - dml_min( - v->ReturnBWPerState[i], - v->ReturnBWToDCNPerState * 4 - * (1 - - soc->urgent_latency_us - / ((ip->rob_buffer_size_kbytes - - ip->pixel_chunk_size_kbytes) - * 1024 - / (v->ReturnBWToDCNPerState - - v->DCFCLKPerState[i] - * soc->return_bus_width_bytes - / 4) - + soc->urgent_latency_us))); - } - - v->CriticalPoint = 2 * soc->return_bus_width_bytes * v->DCFCLKPerState[i] - * soc->urgent_latency_us - / (v->ReturnBWToDCNPerState * soc->urgent_latency_us - + (ip->rob_buffer_size_kbytes - - ip->pixel_chunk_size_kbytes) - * 1024); - - if (v->DCCEnabledInAnyPlane == 1 && v->CriticalPoint > 1 && v->CriticalPoint < 4) { - v->ReturnBWPerState[i] = - dml_min( - v->ReturnBWPerState[i], - 4 * v->ReturnBWToDCNPerState - * (ip->rob_buffer_size_kbytes - - ip->pixel_chunk_size_kbytes) - * 1024 - * soc->return_bus_width_bytes - * v->DCFCLKPerState[i] - * soc->urgent_latency_us - / dml_pow( - (v->ReturnBWToDCNPerState - * soc->urgent_latency_us - + (ip->rob_buffer_size_kbytes - - ip->pixel_chunk_size_kbytes) - * 1024), - 2)); - } - - v->ReturnBWToDCNPerState = dml_min( - soc->return_bus_width_bytes * v->DCFCLKPerState[i], - v->FabricAndDRAMBandwidthPerState[i] * 1000); - - if (v->DCCEnabledInAnyPlane == 1 - && v->ReturnBWToDCNPerState - > (v->DCFCLKPerState[i] - * soc->return_bus_width_bytes / 4)) { - v->ReturnBWPerState[i] = - dml_min( - v->ReturnBWPerState[i], - v->ReturnBWToDCNPerState * 4 - * (1 - - soc->urgent_latency_us - / ((ip->rob_buffer_size_kbytes - - ip->pixel_chunk_size_kbytes) - * 1024 - / (v->ReturnBWToDCNPerState - - v->DCFCLKPerState[i] - * soc->return_bus_width_bytes - / 4) - + soc->urgent_latency_us))); - } - - v->CriticalPoint = 2 * soc->return_bus_width_bytes * v->DCFCLKPerState[i] - * soc->urgent_latency_us - / (v->ReturnBWToDCNPerState * soc->urgent_latency_us - + (ip->rob_buffer_size_kbytes - - ip->pixel_chunk_size_kbytes) - * 1024); - - if (v->DCCEnabledInAnyPlane == 1 && v->CriticalPoint > 1 && v->CriticalPoint < 4) { - v->ReturnBWPerState[i] = - dml_min( - v->ReturnBWPerState[i], - 4 * v->ReturnBWToDCNPerState - * (ip->rob_buffer_size_kbytes - - ip->pixel_chunk_size_kbytes) - * 1024 - * soc->return_bus_width_bytes - * v->DCFCLKPerState[i] - * soc->urgent_latency_us - / dml_pow( - (v->ReturnBWToDCNPerState - * soc->urgent_latency_us - + (ip->rob_buffer_size_kbytes - - ip->pixel_chunk_size_kbytes) - * 1024), - 2)); - } - } - - for (i = 0; i < NumberOfStatesPlusTwo; i++) { - if ((v->TotalReadBandwidthConsumedGBytePerSecond * 1000 <= v->ReturnBWPerState[i]) - && (v->TotalBandwidthConsumedGBytePerSecond * 1000 - <= v->FabricAndDRAMBandwidthPerState[i] * 1000 - * soc->ideal_dram_bw_after_urgent_percent - / 100)) { - v->BandwidthSupport[i] = 1; - } else { - v->BandwidthSupport[i] = 0; - } - } - - // Writeback Latency support check - - v->WritebackLatencySupport = 1; - - for (k = 0; k < num_planes; k++) { - struct _vcs_dpi_display_pipe_dest_params_st dest = - e2e[v->planes[k].e2e_index].pipe.dest; - struct _vcs_dpi_display_output_params_st dout = e2e[v->planes[k].e2e_index].dout; - - if (dout.output_type == dm_wb && dout.output_format == dm_444 - && (dest.recout_width / (dest.htotal / dest.pixel_rate_mhz) * 4) - > ((ip->writeback_luma_buffer_size_kbytes - + ip->writeback_chroma_buffer_size_kbytes) - * 1024 / soc->writeback_latency_us)) { - v->WritebackLatencySupport = 0; - } else if (dout.output_type == dm_wb - && (dest.recout_width / (dest.htotal / dest.pixel_rate_mhz)) - > (dml_min( - ip->writeback_luma_buffer_size_kbytes, - 2 - * ip->writeback_chroma_buffer_size_kbytes) - * 1024 / soc->writeback_latency_us)) { - v->WritebackLatencySupport = 0; - } - } - - // Re-ordering Buffer Support Check - - for (i = 0; i < NumberOfStatesPlusTwo; i++) { - v->UrgentRoundTripAndOutOfOrderLatencyPerState[i] = - (soc->round_trip_ping_latency_dcfclk_cycles + 32) - / v->DCFCLKPerState[i] - + soc->urgent_out_of_order_return_per_channel_bytes - * soc->num_chans - / v->ReturnBWPerState[i]; - - if ((ip->rob_buffer_size_kbytes - ip->pixel_chunk_size_kbytes) * 1024 - / v->ReturnBWPerState[i] - > v->UrgentRoundTripAndOutOfOrderLatencyPerState[i]) { - v->ROBSupport[i] = 1; - } else { - v->ROBSupport[i] = 0; - } - } - - // Display IO Support Check - - for (k = 0; k < num_planes; k++) { - struct _vcs_dpi_display_pipe_dest_params_st dest = - e2e[v->planes[k].e2e_index].pipe.dest; - struct _vcs_dpi_display_output_params_st dout = e2e[v->planes[k].e2e_index].dout; - - if (dout.output_format == dm_420) { - v->RequiredOutputBW = dest.pixel_rate_mhz * 3 / 2; - } else { - v->RequiredOutputBW = dest.pixel_rate_mhz * 3; - } - - if (dout.output_type == dm_hdmi) { - v->RequiredPHYCLK[k] = v->RequiredOutputBW / 3; - } else if (dout.output_type == dm_dp) { - v->RequiredPHYCLK[k] = v->RequiredOutputBW / 4; - } else { - v->RequiredPHYCLK[k] = 0; - } - } - - for (i = 0; i < NumberOfStatesPlusTwo; i++) { - v->DIOSupport[i] = 1; - - for (k = 0; k < num_planes; k++) { - struct _vcs_dpi_display_output_params_st dout = - e2e[v->planes[k].e2e_index].dout; - - if ((v->RequiredPHYCLK[k] > v->PHYCLKPerState[i]) - || (dout.output_type == dm_hdmi - && v->RequiredPHYCLK[k] > 600)) { - v->DIOSupport[i] = 0; - } - } - } - - // Total Available Writeback Support Check - - v->TotalNumberOfActiveWriteback = 0; - - for (k = 0; k < num_planes; k++) { - struct _vcs_dpi_display_output_params_st dout = e2e[v->planes[k].e2e_index].dout; - - if (dout.output_type == dm_wb) { - v->TotalNumberOfActiveWriteback = v->TotalNumberOfActiveWriteback + 1; - } - } - - if (v->TotalNumberOfActiveWriteback <= ip->max_num_wb) { - v->TotalAvailableWritebackSupport = 1; - } else { - v->TotalAvailableWritebackSupport = 0; - } - - // Maximum DISPCLK/DPPCLK Support check - - for (k = 0; k < num_planes; k++) { - struct _vcs_dpi_display_pipe_dest_params_st dest = - e2e[v->planes[k].e2e_index].pipe.dest; - struct _vcs_dpi_scaler_ratio_depth_st scale_ratio_depth = - e2e[v->planes[k].e2e_index].pipe.scale_ratio_depth; - struct _vcs_dpi_scaler_taps_st scale_taps = - e2e[v->planes[k].e2e_index].pipe.scale_taps; - - if (scale_ratio_depth.hscl_ratio > 1) { - v->PSCL_FACTOR[k] = dml_min( - ip->max_dchub_pscl_bw_pix_per_clk, - ip->max_pscl_lb_bw_pix_per_clk - * scale_ratio_depth.hscl_ratio - / dml_ceil_ex(scale_taps.htaps / 6, 1)); - } else { - v->PSCL_FACTOR[k] = dml_min( - ip->max_dchub_pscl_bw_pix_per_clk, - ip->max_pscl_lb_bw_pix_per_clk); - } - - if (v->BytePerPixelInDETC[k] == 0) { - v->PSCL_FACTOR_CHROMA[k] = 0; - v->MinDPPCLKUsingSingleDPP[k] = - dest.pixel_rate_mhz - * dml_max( - scale_taps.vtaps / 6 - * dml_min( - 1, - scale_ratio_depth.hscl_ratio), - dml_max( - scale_ratio_depth.hscl_ratio - * scale_ratio_depth.vscl_ratio - / v->PSCL_FACTOR[k], - 1)); - - } else { - if (scale_ratio_depth.hscl_ratio / 2 > 1) { - v->PSCL_FACTOR_CHROMA[k] = dml_min( - ip->max_dchub_pscl_bw_pix_per_clk, - ip->max_pscl_lb_bw_pix_per_clk - * scale_ratio_depth.hscl_ratio / 2 - / dml_ceil_ex( - scale_taps.htaps_c - / 6, - 1)); - } else { - v->PSCL_FACTOR_CHROMA[k] = dml_min( - ip->max_dchub_pscl_bw_pix_per_clk, - ip->max_pscl_lb_bw_pix_per_clk); - } - v->MinDPPCLKUsingSingleDPP[k] = - dest.pixel_rate_mhz - * dml_max( - dml_max( - scale_taps.vtaps - / 6 - * dml_min( - 1, - scale_ratio_depth.hscl_ratio), - scale_ratio_depth.hscl_ratio - * scale_ratio_depth.vscl_ratio - / v->PSCL_FACTOR[k]), - dml_max( - dml_max( - scale_taps.vtaps_c - / 6 - * dml_min( - 1, - scale_ratio_depth.hscl_ratio - / 2), - scale_ratio_depth.hscl_ratio - * scale_ratio_depth.vscl_ratio - / 4 - / v->PSCL_FACTOR_CHROMA[k]), - 1)); - - } - } - - for (k = 0; k < num_planes; k++) { - struct _vcs_dpi_display_pipe_source_params_st src = - e2e[v->planes[k].e2e_index].pipe.src; - struct _vcs_dpi_scaler_ratio_depth_st scale_ratio_depth = - e2e[v->planes[k].e2e_index].pipe.scale_ratio_depth; - struct _vcs_dpi_scaler_taps_st scale_taps = - e2e[v->planes[k].e2e_index].pipe.scale_taps; - - if (src.source_format == dm_444_64 || src.source_format == dm_444_32 - || src.source_format == dm_444_16) { - if (src.sw_mode == dm_sw_linear) { - v->Read256BlockHeightY[k] = 1; - } else if (src.source_format == dm_444_64) { - v->Read256BlockHeightY[k] = 4; - } else { - v->Read256BlockHeightY[k] = 8; - } - - v->Read256BlockWidthY[k] = 256 / dml_ceil_ex(v->BytePerPixelInDETY[k], 1) - / v->Read256BlockHeightY[k]; - v->Read256BlockHeightC[k] = 0; - v->Read256BlockWidthC[k] = 0; - } else { - if (src.sw_mode == dm_sw_linear) { - v->Read256BlockHeightY[k] = 1; - v->Read256BlockHeightC[k] = 1; - } else if (src.source_format == dm_420_8) { - v->Read256BlockHeightY[k] = 16; - v->Read256BlockHeightC[k] = 8; - } else { - v->Read256BlockHeightY[k] = 8; - v->Read256BlockHeightC[k] = 8; - } - - v->Read256BlockWidthY[k] = 256 / dml_ceil_ex(v->BytePerPixelInDETY[k], 1) - / v->Read256BlockHeightY[k]; - v->Read256BlockWidthC[k] = 256 / dml_ceil_ex(v->BytePerPixelInDETC[k], 2) - / v->Read256BlockHeightC[k]; - } - - if (src.source_scan == dm_horz) { - v->MaxSwathHeightY[k] = v->Read256BlockHeightY[k]; - v->MaxSwathHeightC[k] = v->Read256BlockHeightC[k]; - } else { - v->MaxSwathHeightY[k] = v->Read256BlockWidthY[k]; - v->MaxSwathHeightC[k] = v->Read256BlockWidthC[k]; - } - - if (src.source_format == dm_444_64 || src.source_format == dm_444_32 - || src.source_format == dm_444_16) { - if (src.sw_mode == dm_sw_linear - || (src.source_format == dm_444_64 - && (src.sw_mode == dm_sw_4kb_s - || src.sw_mode - == dm_sw_4kb_s_x - || src.sw_mode - == dm_sw_64kb_s - || src.sw_mode - == dm_sw_64kb_s_t - || src.sw_mode - == dm_sw_64kb_s_x - || src.sw_mode - == dm_sw_var_s - || src.sw_mode - == dm_sw_var_s_x) - && src.source_scan == dm_horz)) { - v->MinSwathHeightY[k] = v->MaxSwathHeightY[k]; - } else { - v->MinSwathHeightY[k] = v->MaxSwathHeightY[k] / 2; - } - v->MinSwathHeightC[k] = v->MaxSwathHeightC[k]; - } else { - if (src.sw_mode == dm_sw_linear) { - v->MinSwathHeightY[k] = v->MaxSwathHeightY[k]; - v->MinSwathHeightC[k] = v->MaxSwathHeightC[k]; - } else if (src.source_format == dm_420_8 && src.source_scan == dm_horz) { - v->MinSwathHeightY[k] = v->MaxSwathHeightY[k] / 2; - if (ip->bug_forcing_LC_req_same_size_fixed == 1) { - v->MinSwathHeightC[k] = v->MaxSwathHeightC[k]; - } else { - v->MinSwathHeightC[k] = v->MaxSwathHeightC[k] / 2; - } - } else if (src.source_format == dm_420_10 && src.source_scan == dm_horz) { - v->MinSwathHeightC[k] = v->MaxSwathHeightC[k] / 2; - if (ip->bug_forcing_LC_req_same_size_fixed == 1) { - v->MinSwathHeightY[k] = v->MaxSwathHeightY[k]; - } else { - v->MinSwathHeightY[k] = v->MaxSwathHeightY[k] / 2; - } - } else { - v->MinSwathHeightY[k] = v->MaxSwathHeightY[k]; - v->MinSwathHeightC[k] = v->MaxSwathHeightC[k]; - } - } - - if (src.sw_mode == dm_sw_linear) { - v->MaximumSwathWidth = 8192; - } else { - v->MaximumSwathWidth = 5120; - } - - v->NumberOfDPPRequiredForDETSize = - dml_ceil_ex( - v->SwathWidthYSingleDPP[k] - / dml_min( - v->MaximumSwathWidth, - ip->det_buffer_size_kbytes - * 1024 - / 2 - / (v->BytePerPixelInDETY[k] - * v->MinSwathHeightY[k] - + v->BytePerPixelInDETC[k] - / 2 - * v->MinSwathHeightC[k])), - 1); - - if (v->BytePerPixelInDETC[k] == 0) { - v->NumberOfDPPRequiredForLBSize = - dml_ceil_ex( - (scale_taps.vtaps - + dml_max( - dml_ceil_ex( - scale_ratio_depth.vscl_ratio, - 1) - - 2, - 0)) - * v->SwathWidthYSingleDPP[k] - / dml_max( - scale_ratio_depth.hscl_ratio, - 1) - * scale_ratio_depth.lb_depth - / ip->line_buffer_size_bits, - 1); - } else { - v->NumberOfDPPRequiredForLBSize = - dml_max( - dml_ceil_ex( - (scale_taps.vtaps - + dml_max( - dml_ceil_ex( - scale_ratio_depth.vscl_ratio, - 1) - - 2, - 0)) - * v->SwathWidthYSingleDPP[k] - / dml_max( - scale_ratio_depth.hscl_ratio, - 1) - * scale_ratio_depth.lb_depth - / ip->line_buffer_size_bits, - 1), - dml_ceil_ex( - (scale_taps.vtaps_c - + dml_max( - dml_ceil_ex( - scale_ratio_depth.vscl_ratio - / 2, - 1) - - 2, - 0)) - * v->SwathWidthYSingleDPP[k] - / 2 - / dml_max( - scale_ratio_depth.hscl_ratio - / 2, - 1) - * scale_ratio_depth.lb_depth - / ip->line_buffer_size_bits, - 1)); - } - - v->NumberOfDPPRequiredForDETAndLBSize[k] = dml_max( - v->NumberOfDPPRequiredForDETSize, - v->NumberOfDPPRequiredForLBSize); - - } - - for (i = 0; i < NumberOfStatesPlusTwo; i++) { - for (j = 0; j < 2; j++) { - v->TotalNumberOfActiveDPP[j * NumberOfStatesPlusTwo + i] = 0; - v->RequiredDISPCLK[j * NumberOfStatesPlusTwo + i] = 0; - v->DISPCLK_DPPCLK_Support[j * NumberOfStatesPlusTwo + i] = 1; - - for (k = 0; k < num_planes; k++) { - struct _vcs_dpi_display_pipe_dest_params_st dest = - e2e[v->planes[k].e2e_index].pipe.dest; - ijk = k * 2 * NumberOfStatesPlusTwo + j * NumberOfStatesPlusTwo + i; - - v->MinDispclkUsingSingleDPP = dml_max( - dest.pixel_rate_mhz, - v->MinDPPCLKUsingSingleDPP[k] * (j + 1)) - * (1 + soc->downspread_percent / 100); - v->MinDispclkUsingDualDPP = dml_max( - dest.pixel_rate_mhz, - v->MinDPPCLKUsingSingleDPP[k] / 2 * (j + 1)) - * (1 + soc->downspread_percent / 100); - - if (i < NumberOfStates) { - v->MinDispclkUsingSingleDPP = - v->MinDispclkUsingSingleDPP - * (1 - + ip->dispclk_ramp_margin_percent - / 100); - v->MinDispclkUsingDualDPP = - v->MinDispclkUsingDualDPP - * (1 - + ip->dispclk_ramp_margin_percent - / 100); - } - - if (v->MinDispclkUsingSingleDPP - <= dml_min( - v->MaxDispclk[i], - (j + 1) * v->MaxDppclk[i]) - && v->NumberOfDPPRequiredForDETAndLBSize[k] <= 1) { - v->NoOfDPP[ijk] = 1; - v->RequiredDISPCLK[j * NumberOfStatesPlusTwo + i] = dml_max( - v->RequiredDISPCLK[j * NumberOfStatesPlusTwo - + i], - v->MinDispclkUsingSingleDPP); - } else if (v->MinDispclkUsingDualDPP - <= dml_min( - v->MaxDispclk[i], - (j + 1) * v->MaxDppclk[i])) { - v->NoOfDPP[ijk] = 2; - v->RequiredDISPCLK[j * NumberOfStatesPlusTwo + i] = dml_max( - v->RequiredDISPCLK[j * NumberOfStatesPlusTwo - + i], - v->MinDispclkUsingDualDPP); - } else { - v->NoOfDPP[ijk] = 2; - v->RequiredDISPCLK[j * NumberOfStatesPlusTwo + i] = dml_max( - v->RequiredDISPCLK[j * NumberOfStatesPlusTwo - + i], - v->MinDispclkUsingDualDPP); - v->DISPCLK_DPPCLK_Support[j * NumberOfStatesPlusTwo + i] = - 0; - } - - v->TotalNumberOfActiveDPP[j * NumberOfStatesPlusTwo + i] = - v->TotalNumberOfActiveDPP[j * NumberOfStatesPlusTwo - + i] + v->NoOfDPP[ijk]; - } - - if (v->TotalNumberOfActiveDPP[j * NumberOfStatesPlusTwo + i] - > ip->max_num_dpp) { - v->TotalNumberOfActiveDPP[j * NumberOfStatesPlusTwo + i] = 0; - v->RequiredDISPCLK[j * NumberOfStatesPlusTwo + i] = 0; - v->DISPCLK_DPPCLK_Support[j * NumberOfStatesPlusTwo + i] = 1; - - for (k = 0; k < num_planes; k++) { - struct _vcs_dpi_display_pipe_dest_params_st dest = - e2e[v->planes[k].e2e_index].pipe.dest; - ijk = k * 2 * NumberOfStatesPlusTwo - + j * NumberOfStatesPlusTwo + i; - - v->MinDispclkUsingSingleDPP = dml_max( - dest.pixel_rate_mhz, - v->MinDPPCLKUsingSingleDPP[k] * (j + 1)) - * (1 + soc->downspread_percent / 100); - v->MinDispclkUsingDualDPP = dml_max( - dest.pixel_rate_mhz, - v->MinDPPCLKUsingSingleDPP[k] / 2 * (j + 1)) - * (1 + soc->downspread_percent / 100); - - if (i < NumberOfStates) { - v->MinDispclkUsingSingleDPP = - v->MinDispclkUsingSingleDPP - * (1 - + ip->dispclk_ramp_margin_percent - / 100); - v->MinDispclkUsingDualDPP = - v->MinDispclkUsingDualDPP - * (1 - + ip->dispclk_ramp_margin_percent - / 100); - } - - if (v->NumberOfDPPRequiredForDETAndLBSize[k] <= 1) { - v->NoOfDPP[ijk] = 1; - v->RequiredDISPCLK[j * NumberOfStatesPlusTwo + i] = - dml_max( - v->RequiredDISPCLK[j - * NumberOfStatesPlusTwo - + i], - v->MinDispclkUsingSingleDPP); - if (v->MinDispclkUsingSingleDPP - > dml_min( - v->MaxDispclk[i], - (j + 1) - * v->MaxDppclk[i])) { - v->DISPCLK_DPPCLK_Support[j - * NumberOfStatesPlusTwo + i] = - 0; - } - } else { - v->NoOfDPP[ijk] = 2; - v->RequiredDISPCLK[j * NumberOfStatesPlusTwo + i] = - dml_max( - v->RequiredDISPCLK[j - * NumberOfStatesPlusTwo - + i], - v->MinDispclkUsingDualDPP); - if (v->MinDispclkUsingDualDPP - > dml_min( - v->MaxDispclk[i], - (j + 1) - * v->MaxDppclk[i])) { - v->DISPCLK_DPPCLK_Support[j - * NumberOfStatesPlusTwo + i] = - 0; - } - } - v->TotalNumberOfActiveDPP[j * NumberOfStatesPlusTwo + i] = - v->TotalNumberOfActiveDPP[j - * NumberOfStatesPlusTwo + i] - + v->NoOfDPP[ijk]; - } - } - } - } - - // Viewport Size Check - - v->ViewportSizeSupport = 1; - - for (k = 0; k < num_planes; k++) { - if (v->NumberOfDPPRequiredForDETAndLBSize[k] > 2) { - v->ViewportSizeSupport = 0; - } - } - - // Total Available Pipes Support Check - - for (i = 0; i < NumberOfStatesPlusTwo; i++) { - for (j = 0; j < 2; j++) { - if (v->TotalNumberOfActiveDPP[j * NumberOfStatesPlusTwo + i] - <= ip->max_num_dpp) { - v->TotalAvailablePipesSupport[j * NumberOfStatesPlusTwo + i] = 1; - } else { - v->TotalAvailablePipesSupport[j * NumberOfStatesPlusTwo + i] = 0; - } - } - } - - // Urgent Latency Support Check - - for (j = 0; j < 2; j++) { - for (i = 0; i < NumberOfStatesPlusTwo; i++) { - ij = j * NumberOfStatesPlusTwo + i; - for (k = 0; k < num_planes; k++) { - struct _vcs_dpi_display_pipe_source_params_st src = - e2e[v->planes[k].e2e_index].pipe.src; - struct _vcs_dpi_display_pipe_dest_params_st dest = - e2e[v->planes[k].e2e_index].pipe.dest; - struct _vcs_dpi_scaler_ratio_depth_st scale_ratio_depth = - e2e[v->planes[k].e2e_index].pipe.scale_ratio_depth; - struct _vcs_dpi_scaler_taps_st scale_taps = - e2e[v->planes[k].e2e_index].pipe.scale_taps; - ijk = k * 2 * NumberOfStatesPlusTwo + j * NumberOfStatesPlusTwo + i; - - v->SwathWidthYPerState[ijk] = v->SwathWidthYSingleDPP[k] - / v->NoOfDPP[ijk]; - - v->SwathWidthGranularityY = 256 - / dml_ceil_ex(v->BytePerPixelInDETY[k], 1) - / v->MaxSwathHeightY[k]; - v->RoundedUpMaxSwathSizeBytesY = (dml_ceil_ex( - v->SwathWidthYPerState[ijk] - 1, - v->SwathWidthGranularityY) - + v->SwathWidthGranularityY) - * v->BytePerPixelInDETY[k] * v->MaxSwathHeightY[k]; - if (src.source_format == dm_420_10) { - v->RoundedUpMaxSwathSizeBytesY = dml_ceil_ex( - v->RoundedUpMaxSwathSizeBytesY, - 256) + 256; - } - if (v->MaxSwathHeightC[k] > 0) { - v->SwathWidthGranularityC = 256 - / dml_ceil_ex(v->BytePerPixelInDETC[k], 2) - / v->MaxSwathHeightC[k]; - } - v->RoundedUpMaxSwathSizeBytesC = (dml_ceil_ex( - v->SwathWidthYPerState[ijk] / 2 - 1, - v->SwathWidthGranularityC) - + v->SwathWidthGranularityC) - * v->BytePerPixelInDETC[k] * v->MaxSwathHeightC[k]; - if (src.source_format == dm_420_10) { - v->RoundedUpMaxSwathSizeBytesC = dml_ceil_ex( - v->RoundedUpMaxSwathSizeBytesC, - 256) + 256; - } - - if (v->RoundedUpMaxSwathSizeBytesY + v->RoundedUpMaxSwathSizeBytesC - <= ip->det_buffer_size_kbytes * 1024 / 2) { - v->SwathHeightYPerState[ijk] = v->MaxSwathHeightY[k]; - v->SwathHeightCPerState[ijk] = v->MaxSwathHeightC[k]; - } else { - v->SwathHeightYPerState[ijk] = v->MinSwathHeightY[k]; - v->SwathHeightCPerState[ijk] = v->MinSwathHeightC[k]; - } - - if (v->BytePerPixelInDETC[k] == 0) { - v->LinesInDETLuma = ip->det_buffer_size_kbytes * 1024 - / v->BytePerPixelInDETY[k] - / v->SwathWidthYPerState[ijk]; - - v->LinesInDETChroma = 0; - } else if (v->SwathHeightYPerState[ijk] - <= v->SwathHeightCPerState[ijk]) { - v->LinesInDETLuma = ip->det_buffer_size_kbytes * 1024 / 2 - / v->BytePerPixelInDETY[k] - / v->SwathWidthYPerState[ijk]; - v->LinesInDETChroma = ip->det_buffer_size_kbytes * 1024 / 2 - / v->BytePerPixelInDETC[k] - / (v->SwathWidthYPerState[ijk] / 2); - } else { - v->LinesInDETLuma = ip->det_buffer_size_kbytes * 1024 * 2 - / 3 / v->BytePerPixelInDETY[k] - / v->SwathWidthYPerState[ijk]; - v->LinesInDETChroma = ip->det_buffer_size_kbytes * 1024 / 3 - / v->BytePerPixelInDETY[k] - / (v->SwathWidthYPerState[ijk] / 2); - } - - v->EffectiveLBLatencyHidingSourceLinesLuma = - dml_min( - ip->max_line_buffer_lines, - dml_floor_ex( - ip->line_buffer_size_bits - / scale_ratio_depth.lb_depth - / (v->SwathWidthYPerState[ijk] - / dml_max( - scale_ratio_depth.hscl_ratio, - 1)), - 1)) - - (scale_taps.vtaps - 1); - - v->EffectiveLBLatencyHidingSourceLinesChroma = - dml_min( - ip->max_line_buffer_lines, - dml_floor_ex( - ip->line_buffer_size_bits - / scale_ratio_depth.lb_depth - / (v->SwathWidthYPerState[ijk] - / 2 - / dml_max( - scale_ratio_depth.hscl_ratio - / 2, - 1)), - 1)) - - (scale_taps.vtaps_c - 1); - - v->EffectiveDETLBLinesLuma = - dml_floor_ex( - v->LinesInDETLuma - + dml_min( - v->LinesInDETLuma - * v->RequiredDISPCLK[ij] - * v->BytePerPixelInDETY[k] - * v->PSCL_FACTOR[k] - / v->ReturnBWPerState[i], - v->EffectiveLBLatencyHidingSourceLinesLuma), - v->SwathHeightYPerState[ijk]); - - v->EffectiveDETLBLinesChroma = - dml_floor_ex( - v->LinesInDETChroma - + dml_min( - v->LinesInDETChroma - * v->RequiredDISPCLK[ij] - * v->BytePerPixelInDETC[k] - * v->PSCL_FACTOR_CHROMA[k] - / v->ReturnBWPerState[i], - v->EffectiveLBLatencyHidingSourceLinesChroma), - v->SwathHeightCPerState[ijk]); - - if (v->BytePerPixelInDETC[k] == 0) { - v->UrgentLatencySupportUsPerState[ijk] = - v->EffectiveDETLBLinesLuma - * (dest.htotal - / dest.pixel_rate_mhz) - / scale_ratio_depth.vscl_ratio - - v->EffectiveDETLBLinesLuma - * v->SwathWidthYPerState[ijk] - * dml_ceil_ex( - v->BytePerPixelInDETY[k], - 1) - / (v->ReturnBWPerState[i] - / v->NoOfDPP[ijk]); - } else { - v->UrgentLatencySupportUsPerState[ijk] = - dml_min( - v->EffectiveDETLBLinesLuma - * (dest.htotal - / dest.pixel_rate_mhz) - / scale_ratio_depth.vscl_ratio - - v->EffectiveDETLBLinesLuma - * v->SwathWidthYPerState[ijk] - * dml_ceil_ex( - v->BytePerPixelInDETY[k], - 1) - / (v->ReturnBWPerState[i] - / v->NoOfDPP[ijk]), - v->EffectiveDETLBLinesChroma - * (dest.htotal - / dest.pixel_rate_mhz) - / (scale_ratio_depth.vscl_ratio - / 2) - - v->EffectiveDETLBLinesChroma - * v->SwathWidthYPerState[ijk] - / 2 - * dml_ceil_ex( - v->BytePerPixelInDETC[k], - 2) - / (v->ReturnBWPerState[i] - / v->NoOfDPP[ijk])); - } - - } - } - } - - for (i = 0; i < NumberOfStatesPlusTwo; i++) { - for (j = 0; j < 2; j++) { - ij = j * NumberOfStatesPlusTwo + i; - - v->UrgentLatencySupport[ij] = 1; - for (k = 0; k < num_planes; k++) { - ijk = k * 2 * NumberOfStatesPlusTwo + j * NumberOfStatesPlusTwo + i; - - if (v->UrgentLatencySupportUsPerState[ijk] - < soc->urgent_latency_us / 1) { - v->UrgentLatencySupport[ij] = 0; - } - } - } - } - - // Prefetch Check - - for (i = 0; i < NumberOfStatesPlusTwo; i++) { - for (j = 0; j < 2; j++) { - ij = j * NumberOfStatesPlusTwo + i; - - v->TotalNumberOfDCCActiveDPP[ij] = 0; - for (k = 0; k < num_planes; k++) { - struct _vcs_dpi_display_pipe_source_params_st src = - e2e[v->planes[k].e2e_index].pipe.src; - ijk = k * 2 * NumberOfStatesPlusTwo + j * NumberOfStatesPlusTwo + i; - - if (src.dcc == 1) { - v->TotalNumberOfDCCActiveDPP[ij] = - v->TotalNumberOfDCCActiveDPP[ij] - + v->NoOfDPP[ijk]; - } - } - } - } - - for (i = 0; i < NumberOfStatesPlusTwo; i++) { - for (j = 0; j < 2; j++) { - ij = j * NumberOfStatesPlusTwo + i; - - v->ProjectedDCFCLKDeepSleep = 8; - - for (k = 0; k < num_planes; k++) { - struct _vcs_dpi_display_pipe_dest_params_st dest = - e2e[v->planes[k].e2e_index].pipe.dest; - struct _vcs_dpi_scaler_ratio_depth_st scale_ratio_depth = - e2e[v->planes[k].e2e_index].pipe.scale_ratio_depth; - ijk = k * 2 * NumberOfStatesPlusTwo + j * NumberOfStatesPlusTwo + i; - - v->ProjectedDCFCLKDeepSleep = dml_max( - v->ProjectedDCFCLKDeepSleep, - dest.pixel_rate_mhz / 16); - if (v->BytePerPixelInDETC[k] == 0) { - if (scale_ratio_depth.vscl_ratio <= 1) { - v->ProjectedDCFCLKDeepSleep = - dml_max( - v->ProjectedDCFCLKDeepSleep, - 1.1 - * dml_ceil_ex( - v->BytePerPixelInDETY[k], - 1) - / 64 - * scale_ratio_depth.hscl_ratio - * dest.pixel_rate_mhz - / v->NoOfDPP[ijk]); - } else { - v->ProjectedDCFCLKDeepSleep = - dml_max( - v->ProjectedDCFCLKDeepSleep, - 1.1 - * dml_ceil_ex( - v->BytePerPixelInDETY[k], - 1) - / 64 - * v->PSCL_FACTOR[k] - * v->RequiredDISPCLK[ij] - / (1 - + j)); - } - - } else { - if (scale_ratio_depth.vscl_ratio <= 1) { - v->ProjectedDCFCLKDeepSleep = - dml_max( - v->ProjectedDCFCLKDeepSleep, - 1.1 - * dml_ceil_ex( - v->BytePerPixelInDETY[k], - 1) - / 32 - * scale_ratio_depth.hscl_ratio - * dest.pixel_rate_mhz - / v->NoOfDPP[ijk]); - } else { - v->ProjectedDCFCLKDeepSleep = - dml_max( - v->ProjectedDCFCLKDeepSleep, - 1.1 - * dml_ceil_ex( - v->BytePerPixelInDETY[k], - 1) - / 32 - * v->PSCL_FACTOR[k] - * v->RequiredDISPCLK[ij] - / (1 - + j)); - } - if ((scale_ratio_depth.vscl_ratio / 2) <= 1) { - v->ProjectedDCFCLKDeepSleep = - dml_max( - v->ProjectedDCFCLKDeepSleep, - 1.1 - * dml_ceil_ex( - v->BytePerPixelInDETC[k], - 2) - / 32 - * scale_ratio_depth.hscl_ratio - / 2 - * dest.pixel_rate_mhz - / v->NoOfDPP[ijk]); - } else { - v->ProjectedDCFCLKDeepSleep = - dml_max( - v->ProjectedDCFCLKDeepSleep, - 1.1 - * dml_ceil_ex( - v->BytePerPixelInDETC[k], - 2) - / 32 - * v->PSCL_FACTOR_CHROMA[k] - * v->RequiredDISPCLK[ij] - / (1 - + j)); - } - - } - } - - for (k = 0; k < num_planes; k++) { - struct _vcs_dpi_display_pipe_source_params_st src = - e2e[v->planes[k].e2e_index].pipe.src; - struct _vcs_dpi_display_pipe_dest_params_st dest = - e2e[v->planes[k].e2e_index].pipe.dest; - struct _vcs_dpi_scaler_ratio_depth_st scale_ratio_depth = - e2e[v->planes[k].e2e_index].pipe.scale_ratio_depth; - struct _vcs_dpi_scaler_taps_st scale_taps = - e2e[v->planes[k].e2e_index].pipe.scale_taps; - struct _vcs_dpi_display_output_params_st dout = - e2e[v->planes[k].e2e_index].dout; - ijk = k * 2 * NumberOfStatesPlusTwo + j * NumberOfStatesPlusTwo + i; - - if (src.dcc == 1) { - v->MetaReqHeightY = 8 * v->Read256BlockHeightY[k]; - v->MetaReqWidthY = 64 * 256 - / dml_ceil_ex(v->BytePerPixelInDETY[k], 1) - / v->MetaReqHeightY; - v->MetaSurfaceWidthY = dml_ceil_ex( - src.viewport_width / v->NoOfDPP[ijk] - 1, - v->MetaReqWidthY) + v->MetaReqWidthY; - v->MetaSurfaceHeightY = dml_ceil_ex( - src.viewport_height - 1, - v->MetaReqHeightY) + v->MetaReqHeightY; - if (ip->pte_enable == 1) { - v->MetaPteBytesPerFrameY = - (dml_ceil_ex( - (v->MetaSurfaceWidthY - * v->MetaSurfaceHeightY - * dml_ceil_ex( - v->BytePerPixelInDETY[k], - 1) - / 256.0 - - 4096) - / 8 - / 4096, - 1) + 1) * 64; - } else { - v->MetaPteBytesPerFrameY = 0; - } - if (src.source_scan == dm_horz) { - v->MetaRowBytesY = - v->MetaSurfaceWidthY - * v->MetaReqHeightY - * dml_ceil_ex( - v->BytePerPixelInDETY[k], - 1) - / 256; - } else { - v->MetaRowBytesY = - v->MetaSurfaceHeightY - * v->MetaReqWidthY - * dml_ceil_ex( - v->BytePerPixelInDETY[k], - 1) - / 256; - } - } else { - v->MetaPteBytesPerFrameY = 0; - v->MetaRowBytesY = 0; - } - - if (ip->pte_enable == 1) { - if (src.sw_mode == dm_sw_linear) { - v->MacroTileBlockSizeBytesY = 256; - v->MacroTileBlockHeightY = 1; - } else if (src.sw_mode == dm_sw_4kb_s - || src.sw_mode == dm_sw_4kb_s_x - || src.sw_mode == dm_sw_4kb_d - || src.sw_mode == dm_sw_4kb_d_x) { - v->MacroTileBlockSizeBytesY = 4096; - v->MacroTileBlockHeightY = 4 - * v->Read256BlockHeightY[k]; - } else if (src.sw_mode == dm_sw_64kb_s - || src.sw_mode == dm_sw_64kb_s_t - || src.sw_mode == dm_sw_64kb_s_x - || src.sw_mode == dm_sw_64kb_d - || src.sw_mode == dm_sw_64kb_d_t - || src.sw_mode == dm_sw_64kb_d_x) { - v->MacroTileBlockSizeBytesY = 64 * 1024; - v->MacroTileBlockHeightY = 16 - * v->Read256BlockHeightY[k]; - } else { - v->MacroTileBlockSizeBytesY = 256 * 1024; - v->MacroTileBlockHeightY = 32 - * v->Read256BlockHeightY[k]; - } - if (v->MacroTileBlockSizeBytesY <= 65536) { - v->DataPTEReqHeightY = v->MacroTileBlockHeightY; - } else { - v->DataPTEReqHeightY = 16 - * v->Read256BlockHeightY[k]; - } - v->DataPTEReqWidthY = 4096 - / dml_ceil_ex(v->BytePerPixelInDETY[k], 1) - / v->DataPTEReqHeightY * 8; - if (src.sw_mode == dm_sw_linear) { - v->DPTEBytesPerRowY = - 64 - * (dml_ceil_ex( - (src.viewport_width - / v->NoOfDPP[ijk] - * dml_min( - 128, - dml_pow( - 2, - dml_floor_ex( - dml_log( - ip->dpte_buffer_size_in_pte_reqs - * v->DataPTEReqWidthY - / (src.viewport_width - / v->NoOfDPP[ijk]), - 2), - 1))) - - 1) - / v->DataPTEReqWidthY, - 1) - + 1); - } else if (src.source_scan == dm_horz) { - v->DPTEBytesPerRowY = - 64 - * (dml_ceil_ex( - (src.viewport_width - / v->NoOfDPP[ijk] - - 1) - / v->DataPTEReqWidthY, - 1) - + 1); - } else { - v->DPTEBytesPerRowY = - 64 - * (dml_ceil_ex( - (src.viewport_height - - 1) - / v->DataPTEReqHeightY, - 1) - + 1); - } - } else { - v->DPTEBytesPerRowY = 0; - } - - if (src.source_format != dm_444_64 && src.source_format != dm_444_32 - && src.source_format != dm_444_16) { - if (src.dcc == 1) { - v->MetaReqHeightC = 8 * v->Read256BlockHeightC[k]; - v->MetaReqWidthC = - 64 * 256 - / dml_ceil_ex( - v->BytePerPixelInDETC[k], - 2) - / v->MetaReqHeightC; - v->MetaSurfaceWidthC = dml_ceil_ex( - src.viewport_width / v->NoOfDPP[ijk] - / 2 - 1, - v->MetaReqWidthC) - + v->MetaReqWidthC; - v->MetaSurfaceHeightC = dml_ceil_ex( - src.viewport_height / 2 - 1, - v->MetaReqHeightC) - + v->MetaReqHeightC; - if (ip->pte_enable == 1) { - v->MetaPteBytesPerFrameC = - (dml_ceil_ex( - (v->MetaSurfaceWidthC - * v->MetaSurfaceHeightC - * dml_ceil_ex( - v->BytePerPixelInDETC[k], - 2) - / 256.0 - - 4096) - / 8 - / 4096, - 1) + 1) - * 64; - } else { - v->MetaPteBytesPerFrameC = 0; - } - if (src.source_scan == dm_horz) { - v->MetaRowBytesC = - v->MetaSurfaceWidthC - * v->MetaReqHeightC - * dml_ceil_ex( - v->BytePerPixelInDETC[k], - 2) - / 256; - } else { - v->MetaRowBytesC = - v->MetaSurfaceHeightC - * v->MetaReqWidthC - * dml_ceil_ex( - v->BytePerPixelInDETC[k], - 2) - / 256; - } - } else { - v->MetaPteBytesPerFrameC = 0; - v->MetaRowBytesC = 0; - } - - if (ip->pte_enable == 1) { - if (src.sw_mode == dm_sw_linear) { - v->MacroTileBlockSizeBytesC = 256; - v->MacroTileBlockHeightC = 1; - } else if (src.sw_mode == dm_sw_4kb_s - || src.sw_mode == dm_sw_4kb_s_x - || src.sw_mode == dm_sw_4kb_d - || src.sw_mode == dm_sw_4kb_d_x) { - v->MacroTileBlockSizeBytesC = 4096; - v->MacroTileBlockHeightC = 4 - * v->Read256BlockHeightC[k]; - } else if (src.sw_mode == dm_sw_64kb_s - || src.sw_mode == dm_sw_64kb_s_t - || src.sw_mode == dm_sw_64kb_s_x - || src.sw_mode == dm_sw_64kb_d - || src.sw_mode == dm_sw_64kb_d_t - || src.sw_mode == dm_sw_64kb_d_x) { - v->MacroTileBlockSizeBytesC = 64 * 1024; - v->MacroTileBlockHeightC = 16 - * v->Read256BlockHeightC[k]; - } else { - v->MacroTileBlockSizeBytesC = 256 * 1024; - v->MacroTileBlockHeightC = 32 - * v->Read256BlockHeightC[k]; - } - v->MacroTileBlockWidthC = - v->MacroTileBlockSizeBytesC - / dml_ceil_ex( - v->BytePerPixelInDETC[k], - 2) - / v->MacroTileBlockHeightC; - if (v->MacroTileBlockSizeBytesC <= 65536) { - v->DataPTEReqHeightC = - v->MacroTileBlockHeightC; - } else { - v->DataPTEReqHeightC = 16 - * v->Read256BlockHeightC[k]; - } - v->DataPTEReqWidthC = - 4096 - / dml_ceil_ex( - v->BytePerPixelInDETC[k], - 2) - / v->DataPTEReqHeightC - * 8; - if (src.sw_mode == dm_sw_linear) { - v->DPTEBytesPerRowC = - 64 - * (dml_ceil_ex( - (src.viewport_width - / v->NoOfDPP[ijk] - / 2 - * dml_min( - 128, - dml_pow( - 2, - dml_floor_ex( - dml_log( - ip->dpte_buffer_size_in_pte_reqs - * v->DataPTEReqWidthC - / (src.viewport_width - / v->NoOfDPP[ijk] - / 2), - 2), - 1))) - - 1) - / v->DataPTEReqWidthC, - 1) - + 1); - } else if (src.source_scan == dm_horz) { - v->DPTEBytesPerRowC = - 64 - * (dml_ceil_ex( - (src.viewport_width - / v->NoOfDPP[ijk] - / 2 - - 1) - / v->DataPTEReqWidthC, - 1) - + 1); - } else { - v->DPTEBytesPerRowC = - 64 - * (dml_ceil_ex( - (src.viewport_height - / 2 - - 1) - / v->DataPTEReqHeightC, - 1) - + 1); - } - } else { - v->DPTEBytesPerRowC = 0; - } - } else { - v->DPTEBytesPerRowC = 0; - v->MetaPteBytesPerFrameC = 0; - v->MetaRowBytesC = 0; - } - - v->DPTEBytesPerRow[k] = v->DPTEBytesPerRowY + v->DPTEBytesPerRowC; - v->MetaPTEBytesPerFrame[k] = v->MetaPteBytesPerFrameY - + v->MetaPteBytesPerFrameC; - v->MetaRowBytes[k] = v->MetaRowBytesY + v->MetaRowBytesC; - - v->VInitY = (scale_ratio_depth.vscl_ratio + scale_taps.vtaps + 1 - + dest.interlaced * 0.5 - * scale_ratio_depth.vscl_ratio) - / 2.0; - v->PrefillY[k] = dml_floor_ex(v->VInitY, 1); - v->MaxNumSwY[k] = dml_ceil_ex( - (v->PrefillY[k] - 1.0) - / v->SwathHeightYPerState[ijk], - 1) + 1.0; - - if (v->PrefillY[k] > 1) { - v->MaxPartialSwY = ((int) (v->PrefillY[k] - 2)) - % ((int) v->SwathHeightYPerState[ijk]); - } else { - v->MaxPartialSwY = ((int) (v->PrefillY[k] - + v->SwathHeightYPerState[ijk] - 2)) - % ((int) v->SwathHeightYPerState[ijk]); - } - v->MaxPartialSwY = dml_max(1, v->MaxPartialSwY); - - v->PrefetchLinesY[k] = v->MaxNumSwY[k] - * v->SwathHeightYPerState[ijk] + v->MaxPartialSwY; - - if (src.source_format != dm_444_64 && src.source_format != dm_444_32 - && src.source_format != dm_444_16) { - v->VInitC = - (scale_ratio_depth.vscl_ratio / 2 - + scale_taps.vtaps + 1 - + dest.interlaced * 0.5 - * scale_ratio_depth.vscl_ratio - / 2) / 2.0; - v->PrefillC[k] = dml_floor_ex(v->VInitC, 1); - v->MaxNumSwC[k] = - dml_ceil_ex( - (v->PrefillC[k] - 1.0) - / v->SwathHeightCPerState[ijk], - 1) + 1.0; - if (v->PrefillC[k] > 1) { - v->MaxPartialSwC = - ((int) (v->PrefillC[k] - 2)) - % ((int) v->SwathHeightCPerState[ijk]); - } else { - v->MaxPartialSwC = - ((int) (v->PrefillC[k] - + v->SwathHeightCPerState[ijk] - - 2)) - % ((int) v->SwathHeightCPerState[ijk]); - } - v->MaxPartialSwC = dml_max(1, v->MaxPartialSwC); - - v->PrefetchLinesC[k] = v->MaxNumSwC[k] - * v->SwathHeightCPerState[ijk] - + v->MaxPartialSwC; - } else { - v->PrefetchLinesC[k] = 0; - } - - v->dst_x_after_scaler = 90 * dest.pixel_rate_mhz - / (v->RequiredDISPCLK[ij] / (j + 1)) - + 42 * dest.pixel_rate_mhz / v->RequiredDISPCLK[ij]; - if (v->NoOfDPP[ijk] > 1) { - v->dst_x_after_scaler = v->dst_x_after_scaler - + dest.recout_width / 2.0; - } - - if (dout.output_format == dm_420) { - v->dst_y_after_scaler = 1; - } else { - v->dst_y_after_scaler = 0; - } - - v->TimeCalc = 24 / v->ProjectedDCFCLKDeepSleep; - - v->VUpdateOffset = dml_ceil_ex(dest.htotal / 4, 1); - v->TotalRepeaterDelay = ip->max_inter_dcn_tile_repeaters - * (2 / (v->RequiredDISPCLK[ij] / (j + 1)) - + 3 / v->RequiredDISPCLK[ij]); - v->VUpdateWidth = (14 / v->ProjectedDCFCLKDeepSleep - + 12 / (v->RequiredDISPCLK[ij] / (j + 1)) - + v->TotalRepeaterDelay) * dest.pixel_rate_mhz; - v->VReadyOffset = - dml_max( - 150 - / (v->RequiredDISPCLK[ij] - / (j - + 1)), - v->TotalRepeaterDelay - + 20 - / v->ProjectedDCFCLKDeepSleep - + 10 - / (v->RequiredDISPCLK[ij] - / (j - + 1))) - * dest.pixel_rate_mhz; - - v->TimeSetup = - (v->VUpdateOffset + v->VUpdateWidth - + v->VReadyOffset) - / dest.pixel_rate_mhz; - - v->ExtraLatency = - v->UrgentRoundTripAndOutOfOrderLatencyPerState[i] - + (v->TotalNumberOfActiveDPP[ij] - * ip->pixel_chunk_size_kbytes - + v->TotalNumberOfDCCActiveDPP[ij] - * ip->meta_chunk_size_kbytes) - * 1024 - / v->ReturnBWPerState[i]; - - if (ip->pte_enable == 1) { - v->ExtraLatency = v->ExtraLatency - + v->TotalNumberOfActiveDPP[ij] - * ip->pte_chunk_size_kbytes - * 1024 - / v->ReturnBWPerState[i]; - } - - if (ip->can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one - == 1) { - v->MaximumVStartup = dest.vtotal - dest.vactive - 1; - } else { - v->MaximumVStartup = dest.vsync_plus_back_porch - 1; - } - - v->LineTimesForPrefetch[k] = - v->MaximumVStartup - - soc->urgent_latency_us - / (dest.htotal - / dest.pixel_rate_mhz) - - (v->TimeCalc + v->TimeSetup) - / (dest.htotal - / dest.pixel_rate_mhz) - - (v->dst_y_after_scaler - + v->dst_x_after_scaler - / dest.htotal); - - v->LineTimesForPrefetch[k] = dml_floor_ex( - 4.0 * (v->LineTimesForPrefetch[k] + 0.125), - 1) / 4; - - v->PrefetchBW[k] = - (v->MetaPTEBytesPerFrame[k] + 2 * v->MetaRowBytes[k] - + 2 * v->DPTEBytesPerRow[k] - + v->PrefetchLinesY[k] - * v->SwathWidthYPerState[ijk] - * dml_ceil_ex( - v->BytePerPixelInDETY[k], - 1) - + v->PrefetchLinesC[k] - * v->SwathWidthYPerState[ijk] - / 2 - * dml_ceil_ex( - v->BytePerPixelInDETC[k], - 2)) - / (v->LineTimesForPrefetch[k] - * dest.htotal - / dest.pixel_rate_mhz); - } - - v->BWAvailableForImmediateFlip = v->ReturnBWPerState[i]; - - for (k = 0; k < num_planes; k++) { - v->BWAvailableForImmediateFlip = v->BWAvailableForImmediateFlip - - dml_max(v->ReadBandwidth[k], v->PrefetchBW[k]); - } - - v->TotalImmediateFlipBytes = 0; - - for (k = 0; k < num_planes; k++) { - struct _vcs_dpi_display_pipe_source_params_st src = - e2e[v->planes[k].e2e_index].pipe.src; - - if (src.source_format != dm_420_8 - && src.source_format != dm_420_10) { - v->TotalImmediateFlipBytes = v->TotalImmediateFlipBytes - + v->MetaPTEBytesPerFrame[k] - + v->MetaRowBytes[k] - + v->DPTEBytesPerRow[k]; - } - } - - for (k = 0; k < num_planes; k++) { - struct _vcs_dpi_display_pipe_source_params_st src = - e2e[v->planes[k].e2e_index].pipe.src; - struct _vcs_dpi_display_pipe_dest_params_st dest = - e2e[v->planes[k].e2e_index].pipe.dest; - ijk = k * 2 * NumberOfStatesPlusTwo + j * NumberOfStatesPlusTwo + i; - - if (ip->pte_enable == 1 && src.dcc == 1) { - v->TimeForMetaPTEWithImmediateFlip = - dml_max( - v->MetaPTEBytesPerFrame[k] - / v->PrefetchBW[k], - dml_max( - v->MetaPTEBytesPerFrame[k] - * v->TotalImmediateFlipBytes - / (v->BWAvailableForImmediateFlip - * (v->MetaPTEBytesPerFrame[k] - + v->MetaRowBytes[k] - + v->DPTEBytesPerRow[k])), - dml_max( - v->ExtraLatency, - dml_max( - soc->urgent_latency_us, - dest.htotal - / dest.pixel_rate_mhz - / 4)))); - - v->TimeForMetaPTEWithoutImmediateFlip = - dml_max( - v->MetaPTEBytesPerFrame[k] - / v->PrefetchBW[k], - dml_max( - v->ExtraLatency, - dest.htotal - / dest.pixel_rate_mhz - / 4)); - } else { - v->TimeForMetaPTEWithImmediateFlip = dest.htotal - / dest.pixel_rate_mhz / 4; - v->TimeForMetaPTEWithoutImmediateFlip = dest.htotal - / dest.pixel_rate_mhz / 4; - } - - if (ip->pte_enable == 1 || src.dcc == 1) { - v->TimeForMetaAndDPTERowWithImmediateFlip = - dml_max( - (v->MetaRowBytes[k] - + v->DPTEBytesPerRow[k]) - / v->PrefetchBW[k], - dml_max( - (v->MetaRowBytes[k] - + v->DPTEBytesPerRow[k]) - * v->TotalImmediateFlipBytes - / (v->BWAvailableForImmediateFlip - * (v->MetaPTEBytesPerFrame[k] - + v->MetaRowBytes[k] - + v->DPTEBytesPerRow[k])), - dml_max( - dest.htotal - / dest.pixel_rate_mhz - - v->TimeForMetaPTEWithImmediateFlip, - dml_max( - v->ExtraLatency, - 2 - * soc->urgent_latency_us)))); - - v->TimeForMetaAndDPTERowWithoutImmediateFlip = - dml_max( - (v->MetaRowBytes[k] - + v->DPTEBytesPerRow[k]) - / v->PrefetchBW[k], - dml_max( - dest.htotal - / dest.pixel_rate_mhz - - v->TimeForMetaPTEWithoutImmediateFlip, - v->ExtraLatency)); - } else { - v->TimeForMetaAndDPTERowWithImmediateFlip = - dml_max( - dest.htotal - / dest.pixel_rate_mhz - - v->TimeForMetaPTEWithImmediateFlip, - v->ExtraLatency - - v->TimeForMetaPTEWithImmediateFlip); - v->TimeForMetaAndDPTERowWithoutImmediateFlip = - dml_max( - dest.htotal - / dest.pixel_rate_mhz - - v->TimeForMetaPTEWithoutImmediateFlip, - v->ExtraLatency - - v->TimeForMetaPTEWithoutImmediateFlip); - } - - v->LinesForMetaPTEWithImmediateFlip[k] = - dml_floor_ex( - 4.0 - * (v->TimeForMetaPTEWithImmediateFlip - / (dest.htotal - / dest.pixel_rate_mhz) - + 0.125), - 1) / 4.0; - - v->LinesForMetaPTEWithoutImmediateFlip[k] = - dml_floor_ex( - 4.0 - * (v->TimeForMetaPTEWithoutImmediateFlip - / (dest.htotal - / dest.pixel_rate_mhz) - + 0.125), - 1) / 4.0; - - v->LinesForMetaAndDPTERowWithImmediateFlip[k] = - dml_floor_ex( - 4.0 - * (v->TimeForMetaAndDPTERowWithImmediateFlip - / (dest.htotal - / dest.pixel_rate_mhz) - + 0.125), - 1) / 4.0; - - v->LinesForMetaAndDPTERowWithoutImmediateFlip[k] = - dml_floor_ex( - 4.0 - * (v->TimeForMetaAndDPTERowWithoutImmediateFlip - / (dest.htotal - / dest.pixel_rate_mhz) - + 0.125), - 1) / 4.0; - - v->LineTimesToRequestPrefetchPixelDataWithImmediateFlip = - v->LineTimesForPrefetch[k] - - v->LinesForMetaPTEWithImmediateFlip[k] - - v->LinesForMetaAndDPTERowWithImmediateFlip[k]; - - v->LineTimesToRequestPrefetchPixelDataWithoutImmediateFlip = - v->LineTimesForPrefetch[k] - - v->LinesForMetaPTEWithoutImmediateFlip[k] - - v->LinesForMetaAndDPTERowWithoutImmediateFlip[k]; - - if (v->LineTimesToRequestPrefetchPixelDataWithImmediateFlip > 0) { - v->VRatioPreYWithImmediateFlip[ijk] = - v->PrefetchLinesY[k] - / v->LineTimesToRequestPrefetchPixelDataWithImmediateFlip; - if (v->SwathHeightYPerState[ijk] > 4) { - if (v->LineTimesToRequestPrefetchPixelDataWithImmediateFlip - - (v->PrefillY[k] - 3.0) / 2.0 - > 0) { - v->VRatioPreYWithImmediateFlip[ijk] = - dml_max( - v->VRatioPreYWithImmediateFlip[ijk], - (v->MaxNumSwY[k] - * v->SwathHeightYPerState[ijk]) - / (v->LineTimesToRequestPrefetchPixelDataWithImmediateFlip - - (v->PrefillY[k] - - 3.0) - / 2.0)); - } else { - v->VRatioPreYWithImmediateFlip[ijk] = - 999999; - } - } - v->VRatioPreCWithImmediateFlip[ijk] = - v->PrefetchLinesC[k] - / v->LineTimesToRequestPrefetchPixelDataWithImmediateFlip; - if (v->SwathHeightCPerState[ijk] > 4) { - if (v->LineTimesToRequestPrefetchPixelDataWithImmediateFlip - - (v->PrefillC[k] - 3.0) / 2.0 - > 0) { - v->VRatioPreCWithImmediateFlip[ijk] = - dml_max( - v->VRatioPreCWithImmediateFlip[ijk], - (v->MaxNumSwC[k] - * v->SwathHeightCPerState[ijk]) - / (v->LineTimesToRequestPrefetchPixelDataWithImmediateFlip - - (v->PrefillC[k] - - 3.0) - / 2.0)); - } else { - v->VRatioPreCWithImmediateFlip[ijk] = - 999999; - } - } - - v->RequiredPrefetchPixelDataBWWithImmediateFlip[ijk] = - v->NoOfDPP[ijk] - * (v->PrefetchLinesY[k] - / v->LineTimesToRequestPrefetchPixelDataWithImmediateFlip - * dml_ceil_ex( - v->BytePerPixelInDETY[k], - 1) - + v->PrefetchLinesC[k] - / v->LineTimesToRequestPrefetchPixelDataWithImmediateFlip - * dml_ceil_ex( - v->BytePerPixelInDETC[k], - 2) - / 2) - * v->SwathWidthYPerState[ijk] - / (dest.htotal - / dest.pixel_rate_mhz); - } else { - v->VRatioPreYWithImmediateFlip[ijk] = 999999; - v->VRatioPreCWithImmediateFlip[ijk] = 999999; - v->RequiredPrefetchPixelDataBWWithImmediateFlip[ijk] = - 999999; - } - - if (v->LineTimesToRequestPrefetchPixelDataWithoutImmediateFlip - > 0) { - v->VRatioPreYWithoutImmediateFlip[ijk] = - v->PrefetchLinesY[k] - / v->LineTimesToRequestPrefetchPixelDataWithoutImmediateFlip; - if (v->SwathHeightYPerState[ijk] > 4) { - if (v->LineTimesToRequestPrefetchPixelDataWithoutImmediateFlip - - (v->PrefillY[k] - 3.0) / 2.0 - > 0) { - v->VRatioPreYWithoutImmediateFlip[ijk] = - dml_max( - v->VRatioPreYWithoutImmediateFlip[ijk], - (v->MaxNumSwY[k] - * v->SwathHeightYPerState[ijk]) - / (v->LineTimesToRequestPrefetchPixelDataWithoutImmediateFlip - - (v->PrefillY[k] - - 3.0) - / 2.0)); - } else { - v->VRatioPreYWithoutImmediateFlip[ijk] = - 999999; - } - } - v->VRatioPreCWithoutImmediateFlip[ijk] = - v->PrefetchLinesC[k] - / v->LineTimesToRequestPrefetchPixelDataWithoutImmediateFlip; - if (v->SwathHeightCPerState[ijk] > 4) { - if (v->LineTimesToRequestPrefetchPixelDataWithoutImmediateFlip - - (v->PrefillC[k] - 3.0) / 2.0 - > 0) { - v->VRatioPreCWithoutImmediateFlip[ijk] = - dml_max( - v->VRatioPreCWithoutImmediateFlip[ijk], - (v->MaxNumSwC[k] - * v->SwathHeightCPerState[ijk]) - / (v->LineTimesToRequestPrefetchPixelDataWithoutImmediateFlip - - (v->PrefillC[k] - - 3.0) - / 2.0)); - } else { - v->VRatioPreCWithoutImmediateFlip[ijk] = - 999999; - } - } - - v->RequiredPrefetchPixelDataBWWithoutImmediateFlip[ijk] = - v->NoOfDPP[ijk] - * (v->PrefetchLinesY[k] - / v->LineTimesToRequestPrefetchPixelDataWithoutImmediateFlip - * dml_ceil_ex( - v->BytePerPixelInDETY[k], - 1) - + v->PrefetchLinesC[k] - / v->LineTimesToRequestPrefetchPixelDataWithoutImmediateFlip - * dml_ceil_ex( - v->BytePerPixelInDETC[k], - 2) - / 2) - * v->SwathWidthYPerState[ijk] - / (dest.htotal - / dest.pixel_rate_mhz); - } else { - v->VRatioPreYWithoutImmediateFlip[ijk] = 999999; - v->VRatioPreCWithoutImmediateFlip[ijk] = 999999; - v->RequiredPrefetchPixelDataBWWithoutImmediateFlip[ijk] = - 999999; - } - } - - v->MaximumReadBandwidthWithPrefetchWithImmediateFlip = 0; - - for (k = 0; k < num_planes; k++) { - struct _vcs_dpi_display_pipe_source_params_st src = - e2e[v->planes[k].e2e_index].pipe.src; - struct _vcs_dpi_display_pipe_dest_params_st dest = - e2e[v->planes[k].e2e_index].pipe.dest; - ijk = k * 2 * NumberOfStatesPlusTwo + j * NumberOfStatesPlusTwo + i; - - if (src.source_format != dm_420_8 - && src.source_format != dm_420_10) { - v->MaximumReadBandwidthWithPrefetchWithImmediateFlip = - v->MaximumReadBandwidthWithPrefetchWithImmediateFlip - + dml_max( - v->ReadBandwidth[k], - v->RequiredPrefetchPixelDataBWWithImmediateFlip[ijk]) - + dml_max( - v->MetaPTEBytesPerFrame[k] - / (v->LinesForMetaPTEWithImmediateFlip[k] - * dest.htotal - / dest.pixel_rate_mhz), - (v->MetaRowBytes[k] - + v->DPTEBytesPerRow[k]) - / (v->LinesForMetaAndDPTERowWithImmediateFlip[k] - * dest.htotal - / dest.pixel_rate_mhz)); - } else { - v->MaximumReadBandwidthWithPrefetchWithImmediateFlip = - v->MaximumReadBandwidthWithPrefetchWithImmediateFlip - + dml_max( - v->ReadBandwidth[k], - v->RequiredPrefetchPixelDataBWWithoutImmediateFlip[ijk]); - } - } - - v->MaximumReadBandwidthWithPrefetchWithoutImmediateFlip = 0; - - for (k = 0; k < num_planes; k++) { - ijk = k * 2 * NumberOfStatesPlusTwo + j * NumberOfStatesPlusTwo + i; - - v->MaximumReadBandwidthWithPrefetchWithoutImmediateFlip = - v->MaximumReadBandwidthWithPrefetchWithoutImmediateFlip - + dml_max( - v->ReadBandwidth[k], - v->RequiredPrefetchPixelDataBWWithoutImmediateFlip[ijk]); - } - - v->PrefetchSupportedWithImmediateFlip[ij] = 1; - if (v->MaximumReadBandwidthWithPrefetchWithImmediateFlip - > v->ReturnBWPerState[i]) { - v->PrefetchSupportedWithImmediateFlip[ij] = 0; - } - for (k = 0; k < num_planes; k++) { - if (v->LineTimesForPrefetch[k] < 2 - || v->LinesForMetaPTEWithImmediateFlip[k] >= 8 - || v->LinesForMetaAndDPTERowWithImmediateFlip[k] - >= 16) { - v->PrefetchSupportedWithImmediateFlip[ij] = 0; - } - } - - v->PrefetchSupportedWithoutImmediateFlip[ij] = 1; - if (v->MaximumReadBandwidthWithPrefetchWithoutImmediateFlip - > v->ReturnBWPerState[i]) { - v->PrefetchSupportedWithoutImmediateFlip[ij] = 0; - } - for (k = 0; k < num_planes; k++) { - if (v->LineTimesForPrefetch[k] < 2 - || v->LinesForMetaPTEWithoutImmediateFlip[k] >= 8 - || v->LinesForMetaAndDPTERowWithoutImmediateFlip[k] - >= 16) { - v->PrefetchSupportedWithoutImmediateFlip[ij] = 0; - } - } - } - } - - for (i = 0; i < NumberOfStatesPlusTwo; i++) { - for (j = 0; j < 2; j++) { - ij = j * NumberOfStatesPlusTwo + i; - - v->VRatioInPrefetchSupportedWithImmediateFlip[ij] = 1; - for (k = 0; k < num_planes; k++) { - struct _vcs_dpi_display_pipe_source_params_st src = - e2e[v->planes[k].e2e_index].pipe.src; - ijk = k * 2 * NumberOfStatesPlusTwo + j * NumberOfStatesPlusTwo + i; - - if (((src.source_format != dm_420_8 - && src.source_format != dm_420_10) - && (v->VRatioPreYWithImmediateFlip[ijk] > 4 - || v->VRatioPreCWithImmediateFlip[ijk] - > 4)) - || ((src.source_format == dm_420_8 - || src.source_format == dm_420_10) - && (v->VRatioPreYWithoutImmediateFlip[ijk] - > 4 - || v->VRatioPreCWithoutImmediateFlip[ijk] - > 4))) { - v->VRatioInPrefetchSupportedWithImmediateFlip[ij] = 0; - } - } - v->VRatioInPrefetchSupportedWithoutImmediateFlip[ij] = 1; - for (k = 0; k < num_planes; k++) { - ijk = k * 2 * NumberOfStatesPlusTwo + j * NumberOfStatesPlusTwo + i; - - if (v->VRatioPreYWithoutImmediateFlip[ijk] > 4 - || v->VRatioPreCWithoutImmediateFlip[ijk] > 4) { - v->VRatioInPrefetchSupportedWithoutImmediateFlip[ij] = 0; - } - } - } - } - - // Mode Support, Voltage State and SOC Configuration - - for (i = (NumberOfStatesPlusTwo - 1); i >= 0; i--) // use int type here - { - for (j = 0; j < 2; j++) { - ij = j * NumberOfStatesPlusTwo + i; - - if (v->ScaleRatioSupport == 1 && v->SourceFormatPixelAndScanSupport == 1 - && v->ViewportSizeSupport == 1 - && v->BandwidthSupport[i] == 1 && v->DIOSupport[i] == 1 - && v->UrgentLatencySupport[ij] == 1 && v->ROBSupport[i] == 1 - && v->DISPCLK_DPPCLK_Support[ij] == 1 - && v->TotalAvailablePipesSupport[ij] == 1 - && v->TotalAvailableWritebackSupport == 1 - && v->WritebackLatencySupport == 1) { - if (v->PrefetchSupportedWithImmediateFlip[ij] == 1 - && v->VRatioInPrefetchSupportedWithImmediateFlip[ij] - == 1) { - v->ModeSupportWithImmediateFlip[ij] = 1; - } else { - v->ModeSupportWithImmediateFlip[ij] = 0; - } - if (v->PrefetchSupportedWithoutImmediateFlip[ij] == 1 - && v->VRatioInPrefetchSupportedWithoutImmediateFlip[ij] - == 1) { - v->ModeSupportWithoutImmediateFlip[ij] = 1; - } else { - v->ModeSupportWithoutImmediateFlip[ij] = 0; - } - } else { - v->ModeSupportWithImmediateFlip[ij] = 0; - v->ModeSupportWithoutImmediateFlip[ij] = 0; - } - } - } - - for (i = (NumberOfStatesPlusTwo - 1); i >= 0; i--) // use int type here - { - if ((i == (NumberOfStatesPlusTwo - 1) - || v->ModeSupportWithImmediateFlip[1 * NumberOfStatesPlusTwo + i] - == 1 - || v->ModeSupportWithImmediateFlip[0 * NumberOfStatesPlusTwo + i] - == 1) && i >= v->VoltageOverrideLevel) { - v->VoltageLevelWithImmediateFlip = i; - } - } - - for (i = (NumberOfStatesPlusTwo - 1); i >= 0; i--) // use int type here - { - if ((i == (NumberOfStatesPlusTwo - 1) - || v->ModeSupportWithoutImmediateFlip[1 * NumberOfStatesPlusTwo + i] - == 1 - || v->ModeSupportWithoutImmediateFlip[0 * NumberOfStatesPlusTwo + i] - == 1) && i >= v->VoltageOverrideLevel) { - v->VoltageLevelWithoutImmediateFlip = i; - } - } - - if (v->VoltageLevelWithImmediateFlip == (NumberOfStatesPlusTwo - 1)) { - v->ImmediateFlipSupported = 0; - v->VoltageLevel = v->VoltageLevelWithoutImmediateFlip; - } else { - v->ImmediateFlipSupported = 1; - v->VoltageLevel = v->VoltageLevelWithImmediateFlip; - } - - v->DCFCLK = v->DCFCLKPerState[(int) v->VoltageLevel]; - v->FabricAndDRAMBandwidth = v->FabricAndDRAMBandwidthPerState[(int) v->VoltageLevel]; - - for (j = 0; j < 2; j++) { - v->RequiredDISPCLKPerRatio[j] = v->RequiredDISPCLK[j * NumberOfStatesPlusTwo - + (int) v->VoltageLevel]; - for (k = 0; k < num_planes; k++) { - v->DPPPerPlanePerRatio[k * 2 + j] = v->NoOfDPP[k * 2 * NumberOfStatesPlusTwo - + j * NumberOfStatesPlusTwo + (int) v->VoltageLevel]; - } - v->DISPCLK_DPPCLK_SupportPerRatio[j] = v->DISPCLK_DPPCLK_Support[j - * NumberOfStatesPlusTwo + (int) v->VoltageLevel]; - } - - ASSERT(v->ImmediateFlipSupported || v->MacroTileBlockWidthC || v->DCFCLK || v->FabricAndDRAMBandwidth); - - return (v->VoltageLevel); -} - diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_support.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_support.h deleted file mode 100644 index ead4942f998c2..0000000000000 --- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_support.h +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright 2017 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: AMD - * - */ -#ifndef __DISPLAY_MODE_SUPPORT_H__ -#define __DISPLAY_MODE_SUPPORT_H__ - -#include "dml_common_defs.h" - -struct display_mode_lib; - -#define NumberOfStates 4 -#define NumberOfStatesPlusTwo (NumberOfStates+2) - -struct dml_ms_internal_vars { - double ScaleRatioSupport; - double SourceFormatPixelAndScanSupport; - double TotalReadBandwidthConsumedGBytePerSecond; - double TotalWriteBandwidthConsumedGBytePerSecond; - double TotalBandwidthConsumedGBytePerSecond; - double DCCEnabledInAnyPlane; - double ReturnBWToDCNPerState; - double CriticalPoint; - double WritebackLatencySupport; - double RequiredOutputBW; - double TotalNumberOfActiveWriteback; - double TotalAvailableWritebackSupport; - double MaximumSwathWidth; - double NumberOfDPPRequiredForDETSize; - double NumberOfDPPRequiredForLBSize; - double MinDispclkUsingSingleDPP; - double MinDispclkUsingDualDPP; - double ViewportSizeSupport; - double SwathWidthGranularityY; - double RoundedUpMaxSwathSizeBytesY; - double SwathWidthGranularityC; - double RoundedUpMaxSwathSizeBytesC; - double LinesInDETLuma; - double LinesInDETChroma; - double EffectiveLBLatencyHidingSourceLinesLuma; - double EffectiveLBLatencyHidingSourceLinesChroma; - double EffectiveDETLBLinesLuma; - double EffectiveDETLBLinesChroma; - double ProjectedDCFCLKDeepSleep; - double MetaReqHeightY; - double MetaReqWidthY; - double MetaSurfaceWidthY; - double MetaSurfaceHeightY; - double MetaPteBytesPerFrameY; - double MetaRowBytesY; - double MacroTileBlockSizeBytesY; - double MacroTileBlockHeightY; - double DataPTEReqHeightY; - double DataPTEReqWidthY; - double DPTEBytesPerRowY; - double MetaReqHeightC; - double MetaReqWidthC; - double MetaSurfaceWidthC; - double MetaSurfaceHeightC; - double MetaPteBytesPerFrameC; - double MetaRowBytesC; - double MacroTileBlockSizeBytesC; - double MacroTileBlockHeightC; - double MacroTileBlockWidthC; - double DataPTEReqHeightC; - double DataPTEReqWidthC; - double DPTEBytesPerRowC; - double VInitY; - double MaxPartialSwY; - double VInitC; - double MaxPartialSwC; - double dst_x_after_scaler; - double dst_y_after_scaler; - double TimeCalc; - double VUpdateOffset; - double TotalRepeaterDelay; - double VUpdateWidth; - double VReadyOffset; - double TimeSetup; - double ExtraLatency; - double MaximumVStartup; - double BWAvailableForImmediateFlip; - double TotalImmediateFlipBytes; - double TimeForMetaPTEWithImmediateFlip; - double TimeForMetaPTEWithoutImmediateFlip; - double TimeForMetaAndDPTERowWithImmediateFlip; - double TimeForMetaAndDPTERowWithoutImmediateFlip; - double LineTimesToRequestPrefetchPixelDataWithImmediateFlip; - double LineTimesToRequestPrefetchPixelDataWithoutImmediateFlip; - double MaximumReadBandwidthWithPrefetchWithImmediateFlip; - double MaximumReadBandwidthWithPrefetchWithoutImmediateFlip; - double VoltageOverrideLevel; - double VoltageLevelWithImmediateFlip; - double VoltageLevelWithoutImmediateFlip; - double ImmediateFlipSupported; - double VoltageLevel; - double DCFCLK; - double FabricAndDRAMBandwidth; - double SwathWidthYSingleDPP[DC__NUM_PIPES__MAX]; - double BytePerPixelInDETY[DC__NUM_PIPES__MAX]; - double BytePerPixelInDETC[DC__NUM_PIPES__MAX]; - double ReadBandwidth[DC__NUM_PIPES__MAX]; - double WriteBandwidth[DC__NUM_PIPES__MAX]; - double DCFCLKPerState[NumberOfStatesPlusTwo]; - double FabricAndDRAMBandwidthPerState[NumberOfStatesPlusTwo]; - double ReturnBWPerState[NumberOfStatesPlusTwo]; - double BandwidthSupport[NumberOfStatesPlusTwo]; - double UrgentRoundTripAndOutOfOrderLatencyPerState[NumberOfStatesPlusTwo]; - double ROBSupport[NumberOfStatesPlusTwo]; - double RequiredPHYCLK[DC__NUM_PIPES__MAX]; - double DIOSupport[NumberOfStatesPlusTwo]; - double PHYCLKPerState[NumberOfStatesPlusTwo]; - double PSCL_FACTOR[DC__NUM_PIPES__MAX]; - double PSCL_FACTOR_CHROMA[DC__NUM_PIPES__MAX]; - double MinDPPCLKUsingSingleDPP[DC__NUM_PIPES__MAX]; - double Read256BlockHeightY[DC__NUM_PIPES__MAX]; - double Read256BlockWidthY[DC__NUM_PIPES__MAX]; - double Read256BlockHeightC[DC__NUM_PIPES__MAX]; - double Read256BlockWidthC[DC__NUM_PIPES__MAX]; - double MaxSwathHeightY[DC__NUM_PIPES__MAX]; - double MaxSwathHeightC[DC__NUM_PIPES__MAX]; - double MinSwathHeightY[DC__NUM_PIPES__MAX]; - double MinSwathHeightC[DC__NUM_PIPES__MAX]; - double NumberOfDPPRequiredForDETAndLBSize[DC__NUM_PIPES__MAX]; - double TotalNumberOfActiveDPP[NumberOfStatesPlusTwo * 2]; - double RequiredDISPCLK[NumberOfStatesPlusTwo * 2]; - double DISPCLK_DPPCLK_Support[NumberOfStatesPlusTwo * 2]; - double MaxDispclk[NumberOfStatesPlusTwo]; - double MaxDppclk[NumberOfStatesPlusTwo]; - double NoOfDPP[NumberOfStatesPlusTwo * 2 * DC__NUM_PIPES__MAX]; - double TotalAvailablePipesSupport[NumberOfStatesPlusTwo * 2]; - double SwathWidthYPerState[NumberOfStatesPlusTwo * 2 * DC__NUM_PIPES__MAX]; - double SwathHeightYPerState[NumberOfStatesPlusTwo * 2 * DC__NUM_PIPES__MAX]; - double SwathHeightCPerState[NumberOfStatesPlusTwo * 2 * DC__NUM_PIPES__MAX]; - double DETBufferSizeYPerState[NumberOfStatesPlusTwo * 2 * DC__NUM_PIPES__MAX]; - double UrgentLatencySupportUsPerState[NumberOfStatesPlusTwo * 2 * DC__NUM_PIPES__MAX]; - double UrgentLatencySupport[NumberOfStatesPlusTwo * 2]; - double TotalNumberOfDCCActiveDPP[NumberOfStatesPlusTwo * 2]; - double DPTEBytesPerRow[DC__NUM_PIPES__MAX]; - double MetaPTEBytesPerFrame[DC__NUM_PIPES__MAX]; - double MetaRowBytes[DC__NUM_PIPES__MAX]; - double PrefillY[DC__NUM_PIPES__MAX]; - double MaxNumSwY[DC__NUM_PIPES__MAX]; - double PrefetchLinesY[DC__NUM_PIPES__MAX]; - double PrefillC[DC__NUM_PIPES__MAX]; - double MaxNumSwC[DC__NUM_PIPES__MAX]; - double PrefetchLinesC[DC__NUM_PIPES__MAX]; - double LineTimesForPrefetch[DC__NUM_PIPES__MAX]; - double PrefetchBW[DC__NUM_PIPES__MAX]; - double LinesForMetaPTEWithImmediateFlip[DC__NUM_PIPES__MAX]; - double LinesForMetaPTEWithoutImmediateFlip[DC__NUM_PIPES__MAX]; - double LinesForMetaAndDPTERowWithImmediateFlip[DC__NUM_PIPES__MAX]; - double LinesForMetaAndDPTERowWithoutImmediateFlip[DC__NUM_PIPES__MAX]; - double VRatioPreYWithImmediateFlip[NumberOfStatesPlusTwo * 2 * DC__NUM_PIPES__MAX]; - double VRatioPreCWithImmediateFlip[NumberOfStatesPlusTwo * 2 * DC__NUM_PIPES__MAX]; - double RequiredPrefetchPixelDataBWWithImmediateFlip[NumberOfStatesPlusTwo * 2 - * DC__NUM_PIPES__MAX]; - double VRatioPreYWithoutImmediateFlip[NumberOfStatesPlusTwo * 2 * DC__NUM_PIPES__MAX]; - double VRatioPreCWithoutImmediateFlip[NumberOfStatesPlusTwo * 2 * DC__NUM_PIPES__MAX]; - double RequiredPrefetchPixelDataBWWithoutImmediateFlip[NumberOfStatesPlusTwo * 2 - * DC__NUM_PIPES__MAX]; - double PrefetchSupportedWithImmediateFlip[NumberOfStatesPlusTwo * 2]; - double PrefetchSupportedWithoutImmediateFlip[NumberOfStatesPlusTwo * 2]; - double VRatioInPrefetchSupportedWithImmediateFlip[NumberOfStatesPlusTwo * 2]; - double VRatioInPrefetchSupportedWithoutImmediateFlip[NumberOfStatesPlusTwo * 2]; - double ModeSupportWithImmediateFlip[NumberOfStatesPlusTwo * 2]; - double ModeSupportWithoutImmediateFlip[NumberOfStatesPlusTwo * 2]; - double RequiredDISPCLKPerRatio[2]; - double DPPPerPlanePerRatio[2 * DC__NUM_PIPES__MAX]; - double DISPCLK_DPPCLK_SupportPerRatio[2]; - struct _vcs_dpi_wm_calc_pipe_params_st planes[DC__NUM_PIPES__MAX]; -}; - -int dml_ms_check( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_display_e2e_pipe_params_st *e2e, - int num_pipes); - -#endif diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c new file mode 100644 index 0000000000000..ada0eeed33011 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c @@ -0,0 +1,3263 @@ +#include "display_mode_lib.h" +#include "display_mode_vba.h" + +static const unsigned int NumberOfStates = DC__VOLTAGE_STATES; + +static void fetch_socbb_params(struct display_mode_lib *mode_lib); +static void fetch_ip_params(struct display_mode_lib *mode_lib); +static void fetch_pipe_params(struct display_mode_lib *mode_lib); +static void recalculate_params(struct display_mode_lib *mode_lib, + const display_e2e_pipe_params_st *pipes, + unsigned int num_pipes); +static void recalculate(struct display_mode_lib *mode_lib); +static double adjust_ReturnBW(struct display_mode_lib *mode_lib, double ReturnBW, bool DCCEnabledAnyPlane, double ReturnBandwidthToDCN); +static void ModeSupportAndSystemConfiguration(struct display_mode_lib *mode_lib); +static void DisplayPipeConfiguration(struct display_mode_lib *mode_lib); +static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation(struct display_mode_lib *mode_lib); +static unsigned int dscceComputeDelay(unsigned int bpc, + double bpp, + unsigned int sliceWidth, + unsigned int numSlices, + enum output_format_class pixelFormat); +static unsigned int dscComputeDelay(enum output_format_class pixelFormat); +// Super monster function with some 45 argument +static bool CalculatePrefetchSchedule(struct display_mode_lib *mode_lib, + double DPPCLK, + double DISPCLK, + double PixelClock, + double DCFClkDeepSleep, + unsigned int DSCDelay, + unsigned int DPPPerPlane, + bool ScalerEnabled, + unsigned int NumberOfCursors, + double DPPCLKDelaySubtotal, + double DPPCLKDelaySCL, + double DPPCLKDelaySCLLBOnly, + double DPPCLKDelayCNVCFormater, + double DPPCLKDelayCNVCCursor, + double DISPCLKDelaySubtotal, + unsigned int ScalerRecoutWidth, + enum output_format_class OutputFormat, + unsigned int VBlank, + unsigned int HTotal, + unsigned int MaxInterDCNTileRepeaters, + unsigned int VStartup, + unsigned int PageTableLevels, + bool VirtualMemoryEnable, + bool DynamicMetadataEnable, + unsigned int DynamicMetadataLinesBeforeActiveRequired, + unsigned int DynamicMetadataTransmittedBytes, + bool DCCEnable, + double UrgentLatency, + double UrgentExtraLatency, + double TCalc, + unsigned int PDEAndMetaPTEBytesFrame, + unsigned int MetaRowByte, + unsigned int PixelPTEBytesPerRow, + double PrefetchSourceLinesY, + unsigned int SwathWidthY, + double BytePerPixelDETY, + double VInitPreFillY, + unsigned int MaxNumSwathY, + double PrefetchSourceLinesC, + double BytePerPixelDETC, + double VInitPreFillC, + unsigned int MaxNumSwathC, + unsigned int SwathHeightY, + unsigned int SwathHeightC, + double TWait, + bool XFCEnabled, + double XFCRemoteSurfaceFlipDelay, + bool InterlaceEnable, + bool ProgressiveToInterlaceUnitInOPP, + double *DSTXAfterScaler, + double *DSTYAfterScaler, + double *DestinationLinesForPrefetch, + double *PrefetchBandwidth, + double *DestinationLinesToRequestVMInVBlank, + double *DestinationLinesToRequestRowInVBlank, + double *VRatioPrefetchY, + double *VRatioPrefetchC, + double *RequiredPrefetchPixDataBW, + unsigned int *VStartupRequiredWhenNotEnoughTimeForDynamicMetadata, + double *Tno_bw); +static double CeilToDFSGranularity(double Clock, double VCOSpeed); +static double FloorToDFSGranularity(double Clock, double VCOSpeed); +static double CalculatePrefetchSourceLines(struct display_mode_lib *mode_lib, + double VRatio, + double vtaps, + bool Interlace, + bool ProgressiveToInterlaceUnitInOPP, + unsigned int SwathHeight, + unsigned int ViewportYStart, + double *VInitPreFill, + unsigned int *MaxNumSwath); +static unsigned int CalculateVMAndRowBytes(struct display_mode_lib *mode_lib, + bool DCCEnable, + unsigned int BlockHeight256Bytes, + unsigned int BlockWidth256Bytes, + enum source_format_class SourcePixelFormat, + unsigned int SurfaceTiling, + unsigned int BytePerPixel, + enum scan_direction_class ScanDirection, + unsigned int ViewportWidth, + unsigned int ViewportHeight, + unsigned int SwathWidthY, + bool VirtualMemoryEnable, + unsigned int VMMPageSize, + unsigned int PTEBufferSizeInRequests, + unsigned int PDEProcessingBufIn64KBReqs, + unsigned int Pitch, + unsigned int DCCMetaPitch, + unsigned int *MacroTileWidth, + unsigned int *MetaRowByte, + unsigned int *PixelPTEBytesPerRow, + bool *PTEBufferSizeNotExceeded, + unsigned int *dpte_row_height, + unsigned int *meta_row_height); +static double CalculateTWait(unsigned int PrefetchMode, + double DRAMClockChangeLatency, + double UrgentLatency, + double SREnterPlusExitTime); +static double CalculateRemoteSurfaceFlipDelay(struct display_mode_lib *mode_lib, + double VRatio, + double SwathWidth, + double Bpp, + double LineTime, + double XFCTSlvVupdateOffset, + double XFCTSlvVupdateWidth, + double XFCTSlvVreadyOffset, + double XFCXBUFLatencyTolerance, + double XFCFillBWOverhead, + double XFCSlvChunkSize, + double XFCBusTransportTime, + double TCalc, + double TWait, + double *SrcActiveDrainRate, + double *TInitXFill, + double *TslvChk); +static double CalculateWriteBackDISPCLK(enum source_format_class WritebackPixelFormat, + double PixelClock, + double WritebackHRatio, + double WritebackVRatio, + unsigned int WritebackLumaHTaps, + unsigned int WritebackLumaVTaps, + unsigned int WritebackChromaHTaps, + unsigned int WritebackChromaVTaps, + double WritebackDestinationWidth, + unsigned int HTotal, + unsigned int WritebackChromaLineBufferWidth); +static void CalculateActiveRowBandwidth(bool VirtualMemoryEnable, + enum source_format_class SourcePixelFormat, + double VRatio, + bool DCCEnable, + double LineTime, + unsigned int MetaRowByteLuma, + unsigned int MetaRowByteChroma, + unsigned int meta_row_height_luma, + unsigned int meta_row_height_chroma, + unsigned int PixelPTEBytesPerRowLuma, + unsigned int PixelPTEBytesPerRowChroma, + unsigned int dpte_row_height_luma, + unsigned int dpte_row_height_chroma, + double *meta_row_bw, + double *dpte_row_bw, + double *qual_row_bw); +static void CalculateFlipSchedule(struct display_mode_lib *mode_lib, + double UrgentExtraLatency, + double UrgentLatency, + unsigned int MaxPageTableLevels, + bool VirtualMemoryEnable, + double BandwidthAvailableForImmediateFlip, + unsigned int TotImmediateFlipBytes, + enum source_format_class SourcePixelFormat, + unsigned int ImmediateFlipBytes, + double LineTime, + double Tno_bw, + double VRatio, + double PDEAndMetaPTEBytesFrame, + unsigned int MetaRowByte, + unsigned int PixelPTEBytesPerRow, + bool DCCEnable, + unsigned int dpte_row_height, + unsigned int meta_row_height, + double qual_row_bw, + double *DestinationLinesToRequestVMInImmediateFlip, + double *DestinationLinesToRequestRowInImmediateFlip, + double *final_flip_bw, + bool *ImmediateFlipSupportedForPipe); +static double CalculateWriteBackDelay(enum source_format_class WritebackPixelFormat, + double WritebackHRatio, + double WritebackVRatio, + unsigned int WritebackLumaHTaps, + unsigned int WritebackLumaVTaps, + unsigned int WritebackChromaHTaps, + unsigned int WritebackChromaVTaps, + unsigned int WritebackDestinationWidth); +static void PixelClockAdjustmentForProgressiveToInterlaceUnit(struct display_mode_lib *mode_lib); +static unsigned int CursorBppEnumToBits(enum cursor_bpp ebpp); + +void set_prefetch_mode(struct display_mode_lib *mode_lib, + bool cstate_en, + bool pstate_en, + bool ignore_viewport_pos, + bool immediate_flip_support) +{ + unsigned int prefetch_mode; + + if (cstate_en && pstate_en) + prefetch_mode = 0; + else if (cstate_en) + prefetch_mode = 1; + else + prefetch_mode = 2; + if (prefetch_mode != mode_lib->vba.PrefetchMode || ignore_viewport_pos != mode_lib->vba.IgnoreViewportPositioning + || immediate_flip_support != mode_lib->vba.ImmediateFlipSupport) { + DTRACE(" Prefetch mode has changed from %i to %i. Recalculating.", + prefetch_mode, + mode_lib->vba.PrefetchMode); + mode_lib->vba.PrefetchMode = prefetch_mode; + mode_lib->vba.IgnoreViewportPositioning = ignore_viewport_pos; + mode_lib->vba.ImmediateFlipSupport = immediate_flip_support; + recalculate(mode_lib); + } +} + +#define dml_get_attr_func(attr, var) double get_##attr(struct display_mode_lib *mode_lib, const display_e2e_pipe_params_st *pipes, unsigned int num_pipes) \ +{ \ + recalculate_params(mode_lib, pipes, num_pipes); \ + return var; \ +} + +dml_get_attr_func(clk_dcf_deepsleep, mode_lib->vba.DCFClkDeepSleep); +dml_get_attr_func(wm_urgent, mode_lib->vba.UrgentWatermark); +dml_get_attr_func(wm_memory_trip, mode_lib->vba.MemoryTripWatermark); +dml_get_attr_func(wm_writeback_urgent, mode_lib->vba.WritebackUrgentWatermark); +dml_get_attr_func(wm_stutter_exit, mode_lib->vba.StutterExitWatermark); +dml_get_attr_func(wm_stutter_enter_exit, mode_lib->vba.StutterEnterPlusExitWatermark); +dml_get_attr_func(wm_dram_clock_change, mode_lib->vba.DRAMClockChangeWatermark); +dml_get_attr_func(wm_writeback_dram_clock_change, mode_lib->vba.WritebackDRAMClockChangeWatermark); +dml_get_attr_func(wm_xfc_underflow, mode_lib->vba.UrgentWatermark); // xfc_underflow maps to urgent +dml_get_attr_func(stutter_efficiency, mode_lib->vba.StutterEfficiency); +dml_get_attr_func(stutter_efficiency_no_vblank, mode_lib->vba.StutterEfficiencyNotIncludingVBlank); +dml_get_attr_func(urgent_latency, mode_lib->vba.MinUrgentLatencySupportUs); +dml_get_attr_func(urgent_extra_latency, mode_lib->vba.UrgentExtraLatency); +dml_get_attr_func(nonurgent_latency, mode_lib->vba.NonUrgentLatencyTolerance); +dml_get_attr_func(dram_clock_change_latency, mode_lib->vba.MinActiveDRAMClockChangeLatencySupported); +dml_get_attr_func(dispclk_calculated, mode_lib->vba.DISPCLK_calculated); +dml_get_attr_func(total_data_read_bw, mode_lib->vba.TotalDataReadBandwidth); +dml_get_attr_func(return_bw, mode_lib->vba.ReturnBW); +dml_get_attr_func(tcalc, mode_lib->vba.TCalc); + +#define dml_get_pipe_attr_func(attr, var) double get_##attr(struct display_mode_lib *mode_lib, const display_e2e_pipe_params_st *pipes, unsigned int num_pipes, unsigned int which_pipe) \ +{\ + unsigned int which_plane; \ + recalculate_params(mode_lib, pipes, num_pipes); \ + which_plane = mode_lib->vba.pipe_plane[which_pipe]; \ + return var[which_plane]; \ +} + +dml_get_pipe_attr_func(dsc_delay, mode_lib->vba.DSCDelay); +dml_get_pipe_attr_func(dppclk_calculated, mode_lib->vba.DPPCLK_calculated); +dml_get_pipe_attr_func(dscclk_calculated, mode_lib->vba.DSCCLK_calculated); +dml_get_pipe_attr_func(min_ttu_vblank, mode_lib->vba.MinTTUVBlank); +dml_get_pipe_attr_func(vratio_prefetch_l, mode_lib->vba.VRatioPrefetchY); +dml_get_pipe_attr_func(vratio_prefetch_c, mode_lib->vba.VRatioPrefetchC); +dml_get_pipe_attr_func(dst_x_after_scaler, mode_lib->vba.DSTXAfterScaler); +dml_get_pipe_attr_func(dst_y_after_scaler, mode_lib->vba.DSTYAfterScaler); +dml_get_pipe_attr_func(dst_y_per_vm_vblank, mode_lib->vba.DestinationLinesToRequestVMInVBlank); +dml_get_pipe_attr_func(dst_y_per_row_vblank, mode_lib->vba.DestinationLinesToRequestRowInVBlank); +dml_get_pipe_attr_func(dst_y_prefetch, mode_lib->vba.DestinationLinesForPrefetch); +dml_get_pipe_attr_func(dst_y_per_vm_flip, mode_lib->vba.DestinationLinesToRequestVMInImmediateFlip); +dml_get_pipe_attr_func(dst_y_per_row_flip, mode_lib->vba.DestinationLinesToRequestRowInImmediateFlip); + +dml_get_pipe_attr_func(xfc_transfer_delay, mode_lib->vba.XFCTransferDelay); +dml_get_pipe_attr_func(xfc_precharge_delay, mode_lib->vba.XFCPrechargeDelay); +dml_get_pipe_attr_func(xfc_remote_surface_flip_latency, mode_lib->vba.XFCRemoteSurfaceFlipLatency); +dml_get_pipe_attr_func(xfc_prefetch_margin, mode_lib->vba.XFCPrefetchMargin); + +unsigned int get_vstartup_calculated(struct display_mode_lib *mode_lib, + const display_e2e_pipe_params_st *pipes, + unsigned int num_pipes, + unsigned int which_pipe) +{ + unsigned int which_plane; + + recalculate_params(mode_lib, pipes, num_pipes); + which_plane = mode_lib->vba.pipe_plane[which_pipe]; + return mode_lib->vba.VStartup[which_plane]; +} + +double get_total_immediate_flip_bytes(struct display_mode_lib *mode_lib, + const display_e2e_pipe_params_st *pipes, + unsigned int num_pipes) +{ + recalculate_params(mode_lib, pipes, num_pipes); + return mode_lib->vba.TotImmediateFlipBytes; +} + +double get_total_immediate_flip_bw(struct display_mode_lib *mode_lib, + const display_e2e_pipe_params_st *pipes, + unsigned int num_pipes) +{ + recalculate_params(mode_lib, pipes, num_pipes); + return mode_lib->vba.ImmediateFlipBW; +} + +double get_total_prefetch_bw(struct display_mode_lib *mode_lib, + const display_e2e_pipe_params_st *pipes, + unsigned int num_pipes) +{ + unsigned int k; + double total_prefetch_bw = 0.0; + + recalculate_params(mode_lib, pipes, num_pipes); + for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) + total_prefetch_bw += mode_lib->vba.PrefetchBandwidth[k]; + return total_prefetch_bw; +} + +static void fetch_socbb_params(struct display_mode_lib *mode_lib) +{ + soc_bounding_box_st *soc = &mode_lib->vba.soc; + unsigned int i; + + // SOC Bounding Box Parameters + mode_lib->vba.ReturnBusWidth = soc->return_bus_width_bytes; + mode_lib->vba.NumberOfChannels = soc->num_chans; + mode_lib->vba.PercentOfIdealDRAMAndFabricBWReceivedAfterUrgLatency = + soc->ideal_dram_bw_after_urgent_percent; // there's always that one bastard variable that's so long it throws everything out of alignment! + mode_lib->vba.UrgentLatency = soc->urgent_latency_us; + mode_lib->vba.RoundTripPingLatencyCycles = soc->round_trip_ping_latency_dcfclk_cycles; + mode_lib->vba.UrgentOutOfOrderReturnPerChannel = soc->urgent_out_of_order_return_per_channel_bytes; + mode_lib->vba.WritebackLatency = soc->writeback_latency_us; + mode_lib->vba.SRExitTime = soc->sr_exit_time_us; + mode_lib->vba.SREnterPlusExitTime = soc->sr_enter_plus_exit_time_us; + mode_lib->vba.DRAMClockChangeLatency = soc->dram_clock_change_latency_us; + mode_lib->vba.Downspreading = soc->downspread_percent; + mode_lib->vba.DRAMChannelWidth = soc->dram_channel_width_bytes; // new! + mode_lib->vba.FabricDatapathToDCNDataReturn = soc->fabric_datapath_to_dcn_data_return_bytes; // new! + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading = soc->dcn_downspread_percent; // new + mode_lib->vba.DISPCLKDPPCLKVCOSpeed = soc->dispclk_dppclk_vco_speed_mhz; // new + mode_lib->vba.VMMPageSize = soc->vmm_page_size_bytes; + // Set the voltage scaling clocks as the defaults. Most of these will + // be set to different values by the test + for (i = 0; i < DC__VOLTAGE_STATES; ++i) + if (soc->clock_limits[i].state == mode_lib->vba.VoltageLevel) + break; + + mode_lib->vba.DCFCLK = soc->clock_limits[i].dcfclk_mhz; + mode_lib->vba.SOCCLK = soc->clock_limits[i].socclk_mhz; + mode_lib->vba.DRAMSpeed = soc->clock_limits[i].dram_speed_mhz; + mode_lib->vba.FabricClock = soc->clock_limits[i].fabricclk_mhz; + + mode_lib->vba.XFCBusTransportTime = soc->xfc_bus_transport_time_us; + mode_lib->vba.XFCXBUFLatencyTolerance = soc->xfc_xbuf_latency_tolerance_us; +} + +static void fetch_ip_params(struct display_mode_lib *mode_lib) +{ + ip_params_st *ip = &mode_lib->vba.ip; + + // IP Parameters + mode_lib->vba.MaxDCHUBToPSCLThroughput = ip->max_dchub_pscl_bw_pix_per_clk; + mode_lib->vba.MaxPSCLToLBThroughput = ip->max_pscl_lb_bw_pix_per_clk; + mode_lib->vba.ROBBufferSizeInKByte = ip->rob_buffer_size_kbytes; + mode_lib->vba.DETBufferSizeInKByte = ip->det_buffer_size_kbytes; + mode_lib->vba.PixelChunkSizeInKByte = ip->pixel_chunk_size_kbytes; + mode_lib->vba.MetaChunkSize = ip->meta_chunk_size_kbytes; + mode_lib->vba.PTEChunkSize = ip->pte_chunk_size_kbytes; + mode_lib->vba.WritebackChunkSize = ip->writeback_chunk_size_kbytes; + mode_lib->vba.LineBufferSize = ip->line_buffer_size_bits; + mode_lib->vba.MaxLineBufferLines = ip->max_line_buffer_lines; + mode_lib->vba.PTEBufferSizeInRequests = ip->dpte_buffer_size_in_pte_reqs; + mode_lib->vba.DPPOutputBufferPixels = ip->dpp_output_buffer_pixels; + mode_lib->vba.OPPOutputBufferLines = ip->opp_output_buffer_lines; + mode_lib->vba.WritebackInterfaceLumaBufferSize = ip->writeback_luma_buffer_size_kbytes; + mode_lib->vba.WritebackInterfaceChromaBufferSize = ip->writeback_chroma_buffer_size_kbytes; + mode_lib->vba.WritebackChromaLineBufferWidth = ip->writeback_chroma_line_buffer_width_pixels; + mode_lib->vba.MaxPageTableLevels = ip->max_page_table_levels; + mode_lib->vba.MaxInterDCNTileRepeaters = ip->max_inter_dcn_tile_repeaters; + mode_lib->vba.NumberOfDSC = ip->num_dsc; + mode_lib->vba.ODMCapability = ip->odm_capable; + mode_lib->vba.DISPCLKRampingMargin = ip->dispclk_ramp_margin_percent; + + mode_lib->vba.XFCSupported = ip->xfc_supported; + mode_lib->vba.XFCFillBWOverhead = ip->xfc_fill_bw_overhead_percent; + mode_lib->vba.XFCFillConstant = ip->xfc_fill_constant_bytes; + mode_lib->vba.DPPCLKDelaySubtotal = ip->dppclk_delay_subtotal; + mode_lib->vba.DPPCLKDelaySCL = ip->dppclk_delay_scl; + mode_lib->vba.DPPCLKDelaySCLLBOnly = ip->dppclk_delay_scl_lb_only; + mode_lib->vba.DPPCLKDelayCNVCFormater = ip->dppclk_delay_cnvc_formatter; + mode_lib->vba.DPPCLKDelayCNVCCursor = ip->dppclk_delay_cnvc_cursor; + mode_lib->vba.DISPCLKDelaySubtotal = ip->dispclk_delay_subtotal; + + mode_lib->vba.ProgressiveToInterlaceUnitInOPP = ip->ptoi_supported; + + mode_lib->vba.PDEProcessingBufIn64KBReqs = ip->pde_proc_buffer_size_64k_reqs; +} + +static void fetch_pipe_params(struct display_mode_lib *mode_lib) +{ + display_e2e_pipe_params_st *pipes = mode_lib->vba.cache_pipes; + ip_params_st *ip = &mode_lib->vba.ip; + + unsigned int OTGInstPlane[DC__NUM_DPP]; + unsigned int j, k; + bool PlaneVisited[DC__NUM_DPP]; + bool visited[DC__NUM_PIPES__MAX]; + + // Convert Pipes to Planes + for (k = 0; k < mode_lib->vba.cache_num_pipes; ++k) + visited[k] = false; + + mode_lib->vba.NumberOfActivePlanes = 0; + for (j = 0; j < mode_lib->vba.cache_num_pipes; ++j) { + display_pipe_source_params_st *src = &pipes[j].pipe.src; + display_pipe_dest_params_st *dst = &pipes[j].pipe.dest; + scaler_ratio_depth_st *scl = &pipes[j].pipe.scale_ratio_depth; + scaler_taps_st *taps = &pipes[j].pipe.scale_taps; + display_output_params_st *dout = &pipes[j].dout; + display_clocks_and_cfg_st *clks = &pipes[j].clks_cfg; + + if (visited[j]) + continue; + visited[j] = true; + + mode_lib->vba.pipe_plane[j] = mode_lib->vba.NumberOfActivePlanes; + + mode_lib->vba.DPPPerPlane[mode_lib->vba.NumberOfActivePlanes] = 1; + mode_lib->vba.SourceScan[mode_lib->vba.NumberOfActivePlanes] = (enum scan_direction_class)(src->source_scan); + mode_lib->vba.ViewportWidth[mode_lib->vba.NumberOfActivePlanes] = src->viewport_width; + mode_lib->vba.ViewportHeight[mode_lib->vba.NumberOfActivePlanes] = src->viewport_height; + mode_lib->vba.ViewportYStartY[mode_lib->vba.NumberOfActivePlanes] = src->viewport_y_y; + mode_lib->vba.ViewportYStartC[mode_lib->vba.NumberOfActivePlanes] = src->viewport_y_c; + mode_lib->vba.PitchY[mode_lib->vba.NumberOfActivePlanes] = src->data_pitch; + mode_lib->vba.PitchC[mode_lib->vba.NumberOfActivePlanes] = src->data_pitch_c; + mode_lib->vba.DCCMetaPitchY[mode_lib->vba.NumberOfActivePlanes] = src->meta_pitch; + mode_lib->vba.HRatio[mode_lib->vba.NumberOfActivePlanes] = scl->hscl_ratio; + mode_lib->vba.VRatio[mode_lib->vba.NumberOfActivePlanes] = scl->vscl_ratio; + mode_lib->vba.ScalerEnabled[mode_lib->vba.NumberOfActivePlanes] = scl->scl_enable; + mode_lib->vba.Interlace[mode_lib->vba.NumberOfActivePlanes] = dst->interlaced; + if (mode_lib->vba.Interlace[mode_lib->vba.NumberOfActivePlanes]) + mode_lib->vba.VRatio[mode_lib->vba.NumberOfActivePlanes] *= 2.0; + mode_lib->vba.htaps[mode_lib->vba.NumberOfActivePlanes] = taps->htaps; + mode_lib->vba.vtaps[mode_lib->vba.NumberOfActivePlanes] = taps->vtaps; + mode_lib->vba.HTAPsChroma[mode_lib->vba.NumberOfActivePlanes] = taps->htaps_c; + mode_lib->vba.VTAPsChroma[mode_lib->vba.NumberOfActivePlanes] = taps->vtaps_c; + mode_lib->vba.HTotal[mode_lib->vba.NumberOfActivePlanes] = dst->htotal; + mode_lib->vba.VTotal[mode_lib->vba.NumberOfActivePlanes] = dst->vtotal; + mode_lib->vba.DCCEnable[mode_lib->vba.NumberOfActivePlanes] = + src->dcc_use_global ? ip->dcc_supported : src->dcc & ip->dcc_supported; + mode_lib->vba.DCCRate[mode_lib->vba.NumberOfActivePlanes] = src->dcc_rate; + mode_lib->vba.SourcePixelFormat[mode_lib->vba.NumberOfActivePlanes] = (enum source_format_class)(src->source_format); + mode_lib->vba.HActive[mode_lib->vba.NumberOfActivePlanes] = dst->hactive; + mode_lib->vba.VActive[mode_lib->vba.NumberOfActivePlanes] = dst->vactive; + mode_lib->vba.SurfaceTiling[mode_lib->vba.NumberOfActivePlanes] = (enum dm_swizzle_mode)(src->sw_mode); + mode_lib->vba.ScalerRecoutWidth[mode_lib->vba.NumberOfActivePlanes] = dst->recout_width; // TODO: or should this be full_recout_width???...maybe only when in hsplit mode? + mode_lib->vba.ODMCombineEnabled[mode_lib->vba.NumberOfActivePlanes] = dst->odm_combine; + mode_lib->vba.OutputFormat[mode_lib->vba.NumberOfActivePlanes] = (enum output_format_class)(dout->output_format); + mode_lib->vba.Output[mode_lib->vba.NumberOfActivePlanes] = (enum output_encoder_class)(dout->output_type); + mode_lib->vba.OutputBpp[mode_lib->vba.NumberOfActivePlanes] = dout->output_bpp; + mode_lib->vba.DSCEnabled[mode_lib->vba.NumberOfActivePlanes] = dout->dsc_enable; + mode_lib->vba.NumberOfDSCSlices[mode_lib->vba.NumberOfActivePlanes] = dout->dsc_slices; + mode_lib->vba.DSCInputBitPerComponent[mode_lib->vba.NumberOfActivePlanes] = + dout->output_bpc == 0 ? 12 : dout->output_bpc; + mode_lib->vba.WritebackEnable[mode_lib->vba.NumberOfActivePlanes] = dout->wb_enable; + mode_lib->vba.WritebackSourceHeight[mode_lib->vba.NumberOfActivePlanes] = dout->wb.wb_src_height; + mode_lib->vba.WritebackDestinationWidth[mode_lib->vba.NumberOfActivePlanes] = dout->wb.wb_dst_width; + mode_lib->vba.WritebackDestinationHeight[mode_lib->vba.NumberOfActivePlanes] = dout->wb.wb_dst_height; + mode_lib->vba.WritebackPixelFormat[mode_lib->vba.NumberOfActivePlanes] = (enum source_format_class)(dout->wb.wb_pixel_format); + mode_lib->vba.WritebackLumaHTaps[mode_lib->vba.NumberOfActivePlanes] = dout->wb.wb_htaps_luma; + mode_lib->vba.WritebackLumaVTaps[mode_lib->vba.NumberOfActivePlanes] = dout->wb.wb_vtaps_luma; + mode_lib->vba.WritebackChromaHTaps[mode_lib->vba.NumberOfActivePlanes] = dout->wb.wb_htaps_chroma; + mode_lib->vba.WritebackChromaVTaps[mode_lib->vba.NumberOfActivePlanes] = dout->wb.wb_vtaps_chroma; + mode_lib->vba.WritebackHRatio[mode_lib->vba.NumberOfActivePlanes] = dout->wb.wb_hratio; + mode_lib->vba.WritebackVRatio[mode_lib->vba.NumberOfActivePlanes] = dout->wb.wb_vratio; + + mode_lib->vba.DynamicMetadataEnable[mode_lib->vba.NumberOfActivePlanes] = src->dynamic_metadata_enable; + mode_lib->vba.DynamicMetadataLinesBeforeActiveRequired[mode_lib->vba.NumberOfActivePlanes] = + src->dynamic_metadata_lines_before_active; + mode_lib->vba.DynamicMetadataTransmittedBytes[mode_lib->vba.NumberOfActivePlanes] = + src->dynamic_metadata_xmit_bytes; + + mode_lib->vba.XFCEnabled[mode_lib->vba.NumberOfActivePlanes] = src->xfc_enable && ip->xfc_supported; + mode_lib->vba.XFCSlvChunkSize = src->xfc_params.xfc_slv_chunk_size_bytes; + mode_lib->vba.XFCTSlvVupdateOffset = src->xfc_params.xfc_tslv_vupdate_offset_us; + mode_lib->vba.XFCTSlvVupdateWidth = src->xfc_params.xfc_tslv_vupdate_width_us; + mode_lib->vba.XFCTSlvVreadyOffset = src->xfc_params.xfc_tslv_vready_offset_us; + mode_lib->vba.PixelClock[mode_lib->vba.NumberOfActivePlanes] = dst->pixel_rate_mhz; + mode_lib->vba.DPPCLK[mode_lib->vba.NumberOfActivePlanes] = clks->dppclk_mhz; + if (ip->is_line_buffer_bpp_fixed) + mode_lib->vba.LBBitPerPixel[mode_lib->vba.NumberOfActivePlanes] = ip->line_buffer_fixed_bpp; + else { + unsigned int lb_depth; + + switch (scl->lb_depth) { + case dm_lb_6: + lb_depth = 18; + break; + case dm_lb_8: + lb_depth = 24; + break; + case dm_lb_10: + lb_depth = 30; + break; + case dm_lb_12: + lb_depth = 36; + break; + case dm_lb_16: + lb_depth = 48; + break; + default: + lb_depth = 36; + } + mode_lib->vba.LBBitPerPixel[mode_lib->vba.NumberOfActivePlanes] = lb_depth; + } + mode_lib->vba.NumberOfCursors[mode_lib->vba.NumberOfActivePlanes] = 0; + // The DML spreadsheet assumes that the two cursors utilize the same amount of bandwidth. We'll + // calculate things a little more accurately + for (k = 0; k < DC__NUM_CURSOR; ++k) { + switch (k) { + case 0: + mode_lib->vba.CursorBPP[mode_lib->vba.NumberOfActivePlanes][0] = CursorBppEnumToBits((enum cursor_bpp)(src->cur0_bpp)); + mode_lib->vba.CursorWidth[mode_lib->vba.NumberOfActivePlanes][0] = src->cur0_src_width; + if (src->cur0_src_width > 0) + mode_lib->vba.NumberOfCursors[mode_lib->vba.NumberOfActivePlanes]++; + break; + case 1: + mode_lib->vba.CursorBPP[mode_lib->vba.NumberOfActivePlanes][1] = CursorBppEnumToBits((enum cursor_bpp)(src->cur1_bpp)); + mode_lib->vba.CursorWidth[mode_lib->vba.NumberOfActivePlanes][1] = src->cur1_src_width; + if (src->cur1_src_width > 0) + mode_lib->vba.NumberOfCursors[mode_lib->vba.NumberOfActivePlanes]++; + break; + default: + dml_print("ERROR: Number of cursors specified exceeds supported maximum\n"); + } + } + + OTGInstPlane[mode_lib->vba.NumberOfActivePlanes] = dst->otg_inst; + + if (dst->odm_combine && !src->is_hsplit) + dml_print("ERROR: ODM Combine is specified but is_hsplit has not be specified for pipe %i\n", + j); + + if (src->is_hsplit) { + for (k = j + 1; k < mode_lib->vba.cache_num_pipes; ++k) { + display_pipe_source_params_st *src_k = &pipes[k].pipe.src; + display_output_params_st *dout_k = &pipes[k].dout; + + if (src_k->is_hsplit && !visited[k] + && src->hsplit_grp == src_k->hsplit_grp) { + mode_lib->vba.pipe_plane[k] = mode_lib->vba.NumberOfActivePlanes; + mode_lib->vba.DPPPerPlane[mode_lib->vba.NumberOfActivePlanes]++; + if (mode_lib->vba.SourceScan[mode_lib->vba.NumberOfActivePlanes] == dm_horz) + mode_lib->vba.ViewportWidth[mode_lib->vba.NumberOfActivePlanes] += + src_k->viewport_width; + else + mode_lib->vba.ViewportHeight[mode_lib->vba.NumberOfActivePlanes] += + src_k->viewport_height; + + mode_lib->vba.NumberOfDSCSlices[mode_lib->vba.NumberOfActivePlanes] += + dout_k->dsc_slices; + visited[k] = true; + } + } + } + + mode_lib->vba.NumberOfActivePlanes++; + } + + // handle overlays through dml_ml->vba.BlendingAndTiming + // dml_ml->vba.BlendingAndTiming tells you which instance to look at to get timing, the so called 'master' + + for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) + PlaneVisited[j] = false; + + for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) { + for (k = j + 1; k < mode_lib->vba.NumberOfActivePlanes; ++k) { + if (!PlaneVisited[k] && OTGInstPlane[j] == OTGInstPlane[k]) { + // doesn't matter, so choose the smaller one + mode_lib->vba.BlendingAndTiming[j] = j; + PlaneVisited[j] = true; + mode_lib->vba.BlendingAndTiming[k] = j; + PlaneVisited[k] = true; + } + } + + if (!PlaneVisited[j]) { + mode_lib->vba.BlendingAndTiming[j] = j; + PlaneVisited[j] = true; + } + } + + // TODO: dml_ml->vba.ODMCombineEnabled => 2 * dml_ml->vba.DPPPerPlane...actually maybe not since all pipes are specified + // Do we want the dscclk to automatically be halved? Guess not since the value is specified + + mode_lib->vba.SynchronizedVBlank = pipes[0].pipe.dest.synchronized_vblank_all_planes; + for (k = 1; k < mode_lib->vba.cache_num_pipes; ++k) + ASSERT(mode_lib->vba.SynchronizedVBlank == pipes[k].pipe.dest.synchronized_vblank_all_planes); + + mode_lib->vba.VirtualMemoryEnable = 0; + mode_lib->vba.OverridePageTableLevels = 0; + + for (k = 0; k < mode_lib->vba.cache_num_pipes; ++k) { + mode_lib->vba.VirtualMemoryEnable |= pipes[k].pipe.src.vm; + mode_lib->vba.OverridePageTableLevels = + (pipes[k].pipe.src.vm_levels_force_en + && mode_lib->vba.OverridePageTableLevels + < pipes[k].pipe.src.vm_levels_force) ? + pipes[k].pipe.src.vm_levels_force : + mode_lib->vba.OverridePageTableLevels; + } + + if (mode_lib->vba.OverridePageTableLevels) + mode_lib->vba.MaxPageTableLevels = mode_lib->vba.OverridePageTableLevels; + + mode_lib->vba.VirtualMemoryEnable &= ip->pte_enable; + + mode_lib->vba.FabricAndDRAMBandwidth = dml_min(mode_lib->vba.DRAMSpeed * mode_lib->vba.NumberOfChannels * mode_lib->vba.DRAMChannelWidth, + mode_lib->vba.FabricClock * mode_lib->vba.FabricDatapathToDCNDataReturn) / 1000.0; + + // TODO: Must be consistent across all pipes + // DCCProgrammingAssumesScanDirectionUnknown = src.dcc_scan_dir_unknown; +} + +static void recalculate(struct display_mode_lib *mode_lib) +{ + ModeSupportAndSystemConfiguration(mode_lib); + PixelClockAdjustmentForProgressiveToInterlaceUnit(mode_lib); + DisplayPipeConfiguration(mode_lib); + DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation(mode_lib); +} + +// in wm mode we pull the parameters needed from the display_e2e_pipe_params_st structs +// rather than working them out as in recalculate_ms +static void recalculate_params(struct display_mode_lib *mode_lib, + const display_e2e_pipe_params_st *pipes, + unsigned int num_pipes) +{ + // This is only safe to use memcmp because there are non-POD types in struct display_mode_lib + if (memcmp(&mode_lib->soc, &mode_lib->vba.soc, sizeof(mode_lib->vba.soc)) != 0 + || memcmp(&mode_lib->ip, &mode_lib->vba.ip, sizeof(mode_lib->vba.ip)) != 0 + || memcmp(&mode_lib->me, &mode_lib->vba.me, sizeof(mode_lib->vba.me)) != 0 + || num_pipes != mode_lib->vba.cache_num_pipes + || memcmp(pipes, mode_lib->vba.cache_pipes, sizeof(display_e2e_pipe_params_st) * num_pipes) != 0) { + mode_lib->vba.soc = mode_lib->soc; + mode_lib->vba.ip = mode_lib->ip; + mode_lib->vba.me = mode_lib->me; + memcpy(mode_lib->vba.cache_pipes, pipes, sizeof(*pipes) * num_pipes); + mode_lib->vba.cache_num_pipes = num_pipes; + recalculate(mode_lib); + } +} + +static void ModeSupportAndSystemConfiguration(struct display_mode_lib *mode_lib) +{ + soc_bounding_box_st *soc = &mode_lib->vba.soc; + unsigned int i, k; + unsigned int total_pipes = 0; + + mode_lib->vba.VoltageLevel = mode_lib->vba.cache_pipes[0].clks_cfg.voltage; + for (i = 1; i < mode_lib->vba.cache_num_pipes; ++i) + ASSERT(mode_lib->vba.VoltageLevel == -1 || mode_lib->vba.VoltageLevel == mode_lib->vba.cache_pipes[i].clks_cfg.voltage); + + mode_lib->vba.DCFCLK = mode_lib->vba.cache_pipes[0].clks_cfg.dcfclk_mhz; + mode_lib->vba.SOCCLK = mode_lib->vba.cache_pipes[0].clks_cfg.socclk_mhz; + + if (mode_lib->vba.cache_pipes[0].clks_cfg.dispclk_mhz > 0.0) + mode_lib->vba.DISPCLK = mode_lib->vba.cache_pipes[0].clks_cfg.dispclk_mhz; + else + mode_lib->vba.DISPCLK = soc->clock_limits[mode_lib->vba.VoltageLevel].dispclk_mhz; + + fetch_socbb_params(mode_lib); + fetch_ip_params(mode_lib); + fetch_pipe_params(mode_lib); + + // Total Available Pipes Support Check + for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) + total_pipes += mode_lib->vba.DPPPerPlane[k]; + ASSERT(total_pipes <= DC__NUM_DPP); +} + +static double adjust_ReturnBW(struct display_mode_lib *mode_lib, double ReturnBW, bool DCCEnabledAnyPlane, double ReturnBandwidthToDCN) +{ + double CriticalCompression; + + if (DCCEnabledAnyPlane && ReturnBandwidthToDCN > mode_lib->vba.DCFCLK * mode_lib->vba.ReturnBusWidth / 4.0) + ReturnBW = + dml_min(ReturnBW, + ReturnBandwidthToDCN * 4 + * (1.0 + - mode_lib->vba.UrgentLatency + / ((mode_lib->vba.ROBBufferSizeInKByte + - mode_lib->vba.PixelChunkSizeInKByte) + * 1024 + / ReturnBandwidthToDCN + - mode_lib->vba.DCFCLK + * mode_lib->vba.ReturnBusWidth + / 4) + + mode_lib->vba.UrgentLatency)); + + CriticalCompression = 2.0 * mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLK * mode_lib->vba.UrgentLatency + / (ReturnBandwidthToDCN * mode_lib->vba.UrgentLatency + + (mode_lib->vba.ROBBufferSizeInKByte - mode_lib->vba.PixelChunkSizeInKByte) * 1024); + + if (DCCEnabledAnyPlane && CriticalCompression > 1.0 && CriticalCompression < 4.0) + ReturnBW = + dml_min(ReturnBW, + 4.0 * ReturnBandwidthToDCN + * (mode_lib->vba.ROBBufferSizeInKByte + - mode_lib->vba.PixelChunkSizeInKByte) + * 1024 * mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLK + * mode_lib->vba.UrgentLatency + / dml_pow((ReturnBandwidthToDCN + * mode_lib->vba.UrgentLatency + + (mode_lib->vba.ROBBufferSizeInKByte + - mode_lib->vba.PixelChunkSizeInKByte) + * 1024), + 2)); + + return ReturnBW; +} + +static unsigned int dscceComputeDelay(unsigned int bpc, + double bpp, + unsigned int sliceWidth, + unsigned int numSlices, + enum output_format_class pixelFormat) +{ + // valid bpc = source bits per component in the set of {8, 10, 12} + // valid bpp = increments of 1/16 of a bit + // min = 6/7/8 in N420/N422/444, respectively + // max = such that compression is 1:1 + //valid sliceWidth = number of pixels per slice line, must be less than or equal to 5184/numSlices (or 4096/numSlices in 420 mode) + //valid numSlices = number of slices in the horiziontal direction per DSC engine in the set of {1, 2, 3, 4} + //valid pixelFormat = pixel/color format in the set of {:N444_RGB, :S422, :N422, :N420} + + // fixed value + unsigned int rcModelSize = 8192; + + // N422/N420 operate at 2 pixels per clock + unsigned int pixelsPerClock, lstall, D, initalXmitDelay, w, s, ix, wx, p, l0, a, ax, l, Delay, + pixels; + + if (pixelFormat == dm_n422 || pixelFormat == dm_420) + pixelsPerClock = 2; + // #all other modes operate at 1 pixel per clock + else + pixelsPerClock = 1; + + //initial transmit delay as per PPS + initalXmitDelay = dml_round(rcModelSize / 2.0 / bpp / pixelsPerClock); + + //compute ssm delay + if (bpc == 8) + D = 81; + else if (bpc == 10) + D = 89; + else + D = 113; + + //divide by pixel per cycle to compute slice width as seen by DSC + w = sliceWidth / pixelsPerClock; + + //422 mode has an additional cycle of delay + if (pixelFormat == dm_s422) + s = 1; + else + s = 0; + + //main calculation for the dscce + ix = initalXmitDelay + 45; + wx = (w + 2) / 3; + p = 3 * wx - w; + l0 = ix / w; + a = ix + p * l0; + ax = (a + 2) / 3 + D + 6 + 1; + l = (ax + wx - 1) / wx; + if ((ix % w) == 0 && p != 0) + lstall = 1; + else + lstall = 0; + Delay = l * wx * (numSlices - 1) + ax + s + lstall + 22; + + //dsc processes 3 pixel containers per cycle and a container can contain 1 or 2 pixels + pixels = Delay * 3 * pixelsPerClock; + return pixels; +} + +static unsigned int dscComputeDelay(enum output_format_class pixelFormat) +{ + unsigned int Delay = 0; + + if (pixelFormat == dm_420) { + // sfr + Delay = Delay + 2; + // dsccif + Delay = Delay + 0; + // dscc - input deserializer + Delay = Delay + 3; + // dscc gets pixels every other cycle + Delay = Delay + 2; + // dscc - input cdc fifo + Delay = Delay + 12; + // dscc gets pixels every other cycle + Delay = Delay + 13; + // dscc - cdc uncertainty + Delay = Delay + 2; + // dscc - output cdc fifo + Delay = Delay + 7; + // dscc gets pixels every other cycle + Delay = Delay + 3; + // dscc - cdc uncertainty + Delay = Delay + 2; + // dscc - output serializer + Delay = Delay + 1; + // sft + Delay = Delay + 1; + } else if (pixelFormat == dm_n422) { + // sfr + Delay = Delay + 2; + // dsccif + Delay = Delay + 1; + // dscc - input deserializer + Delay = Delay + 5; + // dscc - input cdc fifo + Delay = Delay + 25; + // dscc - cdc uncertainty + Delay = Delay + 2; + // dscc - output cdc fifo + Delay = Delay + 10; + // dscc - cdc uncertainty + Delay = Delay + 2; + // dscc - output serializer + Delay = Delay + 1; + // sft + Delay = Delay + 1; + } else { + // sfr + Delay = Delay + 2; + // dsccif + Delay = Delay + 0; + // dscc - input deserializer + Delay = Delay + 3; + // dscc - input cdc fifo + Delay = Delay + 12; + // dscc - cdc uncertainty + Delay = Delay + 2; + // dscc - output cdc fifo + Delay = Delay + 7; + // dscc - output serializer + Delay = Delay + 1; + // dscc - cdc uncertainty + Delay = Delay + 2; + // sft + Delay = Delay + 1; + } + + return Delay; +} + +static bool CalculatePrefetchSchedule(struct display_mode_lib *mode_lib, + double DPPCLK, + double DISPCLK, + double PixelClock, + double DCFClkDeepSleep, + unsigned int DSCDelay, + unsigned int DPPPerPlane, + bool ScalerEnabled, + unsigned int NumberOfCursors, + double DPPCLKDelaySubtotal, + double DPPCLKDelaySCL, + double DPPCLKDelaySCLLBOnly, + double DPPCLKDelayCNVCFormater, + double DPPCLKDelayCNVCCursor, + double DISPCLKDelaySubtotal, + unsigned int ScalerRecoutWidth, + enum output_format_class OutputFormat, + unsigned int VBlank, + unsigned int HTotal, + unsigned int MaxInterDCNTileRepeaters, + unsigned int VStartup, + unsigned int PageTableLevels, + bool VirtualMemoryEnable, + bool DynamicMetadataEnable, + unsigned int DynamicMetadataLinesBeforeActiveRequired, + unsigned int DynamicMetadataTransmittedBytes, + bool DCCEnable, + double UrgentLatency, + double UrgentExtraLatency, + double TCalc, + unsigned int PDEAndMetaPTEBytesFrame, + unsigned int MetaRowByte, + unsigned int PixelPTEBytesPerRow, + double PrefetchSourceLinesY, + unsigned int SwathWidthY, + double BytePerPixelDETY, + double VInitPreFillY, + unsigned int MaxNumSwathY, + double PrefetchSourceLinesC, + double BytePerPixelDETC, + double VInitPreFillC, + unsigned int MaxNumSwathC, + unsigned int SwathHeightY, + unsigned int SwathHeightC, + double TWait, + bool XFCEnabled, + double XFCRemoteSurfaceFlipDelay, + bool InterlaceEnable, + bool ProgressiveToInterlaceUnitInOPP, + double *DSTXAfterScaler, + double *DSTYAfterScaler, + double *DestinationLinesForPrefetch, + double *PrefetchBandwidth, + double *DestinationLinesToRequestVMInVBlank, + double *DestinationLinesToRequestRowInVBlank, + double *VRatioPrefetchY, + double *VRatioPrefetchC, + double *RequiredPrefetchPixDataBW, + unsigned int *VStartupRequiredWhenNotEnoughTimeForDynamicMetadata, + double *Tno_bw) +{ + bool MyError = false; + unsigned int DPPCycles, DISPCLKCycles, VUpdateOffsetPix, VUpdateWidthPix, VReadyOffsetPix; + double DSTTotalPixelsAfterScaler, TotalRepeaterDelayTime; + double Tdm, LineTime, Tsetup; + double dst_y_prefetch_equ; + double Tsw_oto; + double prefetch_bw_oto; + double Tvm_oto; + double Tr0_oto; + double Tpre_oto; + double dst_y_prefetch_oto; + double TimeForFetchingMetaPTE = 0; + double TimeForFetchingRowInVBlank = 0; + double LinesToRequestPrefetchPixelData = 0; + + if (ScalerEnabled) + DPPCycles = DPPCLKDelaySubtotal + DPPCLKDelaySCL; + else + DPPCycles = DPPCLKDelaySubtotal + DPPCLKDelaySCLLBOnly; + + DPPCycles = DPPCycles + DPPCLKDelayCNVCFormater + NumberOfCursors * DPPCLKDelayCNVCCursor; + + DISPCLKCycles = DISPCLKDelaySubtotal; + + if (DPPCLK == 0.0 || DISPCLK == 0.0) + return true; + + *DSTXAfterScaler = DPPCycles * PixelClock / DPPCLK + DISPCLKCycles * PixelClock / DISPCLK + + DSCDelay; + + if (DPPPerPlane > 1) + *DSTXAfterScaler = *DSTXAfterScaler + ScalerRecoutWidth; + + if (OutputFormat == dm_420 || (InterlaceEnable && ProgressiveToInterlaceUnitInOPP)) + *DSTYAfterScaler = 1; + else + *DSTYAfterScaler = 0; + + DSTTotalPixelsAfterScaler = ((double)(*DSTYAfterScaler * HTotal)) + *DSTXAfterScaler; + *DSTYAfterScaler = dml_floor(DSTTotalPixelsAfterScaler / HTotal, 1); + *DSTXAfterScaler = DSTTotalPixelsAfterScaler - ((double)(*DSTYAfterScaler * HTotal)); + + VUpdateOffsetPix = dml_ceil(HTotal / 4.0, 1); + TotalRepeaterDelayTime = MaxInterDCNTileRepeaters * (2.0 / DPPCLK + 3.0 / DISPCLK); + VUpdateWidthPix = (14.0 / DCFClkDeepSleep + 12.0 / DPPCLK + TotalRepeaterDelayTime) + * PixelClock; + + VReadyOffsetPix = dml_max(150.0 / DPPCLK, + TotalRepeaterDelayTime + 20.0 / DCFClkDeepSleep + 10.0 / DPPCLK) + * PixelClock; + + Tsetup = (double)(VUpdateOffsetPix + VUpdateWidthPix + VReadyOffsetPix) / PixelClock; + + LineTime = (double)HTotal / PixelClock; + + if (DynamicMetadataEnable) { + double Tdmbf, Tdmec, Tdmsks; + + Tdm = dml_max(0.0, UrgentExtraLatency - TCalc); + Tdmbf = DynamicMetadataTransmittedBytes / 4.0 / DISPCLK; + Tdmec = LineTime; + if (DynamicMetadataLinesBeforeActiveRequired == 0) + Tdmsks = VBlank * LineTime / 2.0; + else + Tdmsks = DynamicMetadataLinesBeforeActiveRequired * LineTime; + if (InterlaceEnable && !ProgressiveToInterlaceUnitInOPP) + Tdmsks = Tdmsks / 2; + if (VStartup * LineTime + < Tsetup + TWait + UrgentExtraLatency + Tdmbf + Tdmec + Tdmsks) { + MyError = true; + *VStartupRequiredWhenNotEnoughTimeForDynamicMetadata = (Tsetup + TWait + + UrgentExtraLatency + Tdmbf + Tdmec + Tdmsks) / LineTime; + } else + *VStartupRequiredWhenNotEnoughTimeForDynamicMetadata = 0.0; + } else + Tdm = 0; + + if (VirtualMemoryEnable) { + if (PageTableLevels == 4) + *Tno_bw = UrgentExtraLatency + UrgentLatency; + else if (PageTableLevels == 3) + *Tno_bw = UrgentExtraLatency; + else + Tno_bw = 0; + } else if (DCCEnable) + *Tno_bw = LineTime; + else + *Tno_bw = LineTime / 4; + + dst_y_prefetch_equ = VStartup - dml_max(TCalc + TWait, XFCRemoteSurfaceFlipDelay) / LineTime + - (Tsetup + Tdm) / LineTime + - (*DSTYAfterScaler + *DSTXAfterScaler / HTotal); + + Tsw_oto = dml_max(PrefetchSourceLinesY, PrefetchSourceLinesC) * LineTime; + + prefetch_bw_oto = (MetaRowByte + PixelPTEBytesPerRow + + PrefetchSourceLinesY * SwathWidthY * dml_ceil(BytePerPixelDETY, 1) + + PrefetchSourceLinesC * SwathWidthY / 2 * dml_ceil(BytePerPixelDETC, 2)) + / Tsw_oto; + + if (VirtualMemoryEnable == true) { + Tvm_oto = + dml_max(*Tno_bw + PDEAndMetaPTEBytesFrame / prefetch_bw_oto, + dml_max(UrgentExtraLatency + + UrgentLatency + * (PageTableLevels + - 1), + LineTime / 4.0)); + } else + Tvm_oto = LineTime / 4.0; + + if ((VirtualMemoryEnable == true || DCCEnable == true)) { + Tr0_oto = dml_max((MetaRowByte + PixelPTEBytesPerRow) / prefetch_bw_oto, + dml_max(UrgentLatency, dml_max(LineTime - Tvm_oto, LineTime / 4))); + } else + Tr0_oto = LineTime - Tvm_oto; + + Tpre_oto = Tvm_oto + Tr0_oto + Tsw_oto; + + dst_y_prefetch_oto = Tpre_oto / LineTime; + + if (dst_y_prefetch_oto < dst_y_prefetch_equ) + *DestinationLinesForPrefetch = dst_y_prefetch_oto; + else + *DestinationLinesForPrefetch = dst_y_prefetch_equ; + + *DestinationLinesForPrefetch = dml_floor(4.0 * (*DestinationLinesForPrefetch + 0.125), 1) / 4; + + dml_print("DML: VStartup: %d\n", VStartup); + dml_print("DML: TCalc: %f\n", TCalc); + dml_print("DML: TWait: %f\n", TWait); + dml_print("DML: XFCRemoteSurfaceFlipDelay: %f\n", XFCRemoteSurfaceFlipDelay); + dml_print("DML: LineTime: %f\n", LineTime); + dml_print("DML: Tsetup: %f\n", Tsetup); + dml_print("DML: Tdm: %f\n", Tdm); + dml_print("DML: DSTYAfterScaler: %f\n", *DSTYAfterScaler); + dml_print("DML: DSTXAfterScaler: %f\n", *DSTXAfterScaler); + dml_print("DML: HTotal: %d\n", HTotal); + + *PrefetchBandwidth = 0; + *DestinationLinesToRequestVMInVBlank = 0; + *DestinationLinesToRequestRowInVBlank = 0; + *VRatioPrefetchY = 0; + *VRatioPrefetchC = 0; + *RequiredPrefetchPixDataBW = 0; + if (*DestinationLinesForPrefetch > 1) { + *PrefetchBandwidth = (PDEAndMetaPTEBytesFrame + 2 * MetaRowByte + + 2 * PixelPTEBytesPerRow + + PrefetchSourceLinesY * SwathWidthY * dml_ceil(BytePerPixelDETY, 1) + + PrefetchSourceLinesC * SwathWidthY / 2 + * dml_ceil(BytePerPixelDETC, 2)) + / (*DestinationLinesForPrefetch * LineTime - *Tno_bw); + if (VirtualMemoryEnable) { + TimeForFetchingMetaPTE = + dml_max(*Tno_bw + + (double)PDEAndMetaPTEBytesFrame + / *PrefetchBandwidth, + dml_max(UrgentExtraLatency + + UrgentLatency + * (PageTableLevels + - 1), + LineTime / 4)); + } else { + if (NumberOfCursors > 0 || XFCEnabled) + TimeForFetchingMetaPTE = LineTime / 4; + else + TimeForFetchingMetaPTE = 0.0; + } + + if ((VirtualMemoryEnable == true || DCCEnable == true)) { + TimeForFetchingRowInVBlank = + dml_max((MetaRowByte + PixelPTEBytesPerRow) + / *PrefetchBandwidth, + dml_max(UrgentLatency, + dml_max(LineTime + - TimeForFetchingMetaPTE, + LineTime + / 4.0))); + } else { + if (NumberOfCursors > 0 || XFCEnabled) + TimeForFetchingRowInVBlank = LineTime - TimeForFetchingMetaPTE; + else + TimeForFetchingRowInVBlank = 0.0; + } + + *DestinationLinesToRequestVMInVBlank = dml_floor(4.0 * (TimeForFetchingMetaPTE / LineTime + 0.125), + 1) / 4.0; + + *DestinationLinesToRequestRowInVBlank = dml_floor(4.0 * (TimeForFetchingRowInVBlank / LineTime + 0.125), + 1) / 4.0; + + LinesToRequestPrefetchPixelData = + *DestinationLinesForPrefetch + - ((NumberOfCursors > 0 || VirtualMemoryEnable + || DCCEnable) ? + (*DestinationLinesToRequestVMInVBlank + + *DestinationLinesToRequestRowInVBlank) : + 0.0); + + if (LinesToRequestPrefetchPixelData > 0) { + + *VRatioPrefetchY = (double)PrefetchSourceLinesY + / LinesToRequestPrefetchPixelData; + *VRatioPrefetchY = dml_max(*VRatioPrefetchY, 1.0); + if ((SwathHeightY > 4) && (VInitPreFillY > 3)) { + if (LinesToRequestPrefetchPixelData > (VInitPreFillY - 3.0) / 2.0) { + *VRatioPrefetchY = + dml_max((double)PrefetchSourceLinesY + / LinesToRequestPrefetchPixelData, + (double)MaxNumSwathY + * SwathHeightY + / (LinesToRequestPrefetchPixelData + - (VInitPreFillY + - 3.0) + / 2.0)); + *VRatioPrefetchY = dml_max(*VRatioPrefetchY, 1.0); + } else { + MyError = true; + *VRatioPrefetchY = 0; + } + } + + *VRatioPrefetchC = (double)PrefetchSourceLinesC + / LinesToRequestPrefetchPixelData; + *VRatioPrefetchC = dml_max(*VRatioPrefetchC, 1.0); + + if ((SwathHeightC > 4)) { + if (LinesToRequestPrefetchPixelData > (VInitPreFillC - 3.0) / 2.0) { + *VRatioPrefetchC = + dml_max(*VRatioPrefetchC, + (double)MaxNumSwathC + * SwathHeightC + / (LinesToRequestPrefetchPixelData + - (VInitPreFillC + - 3.0) + / 2.0)); + *VRatioPrefetchC = dml_max(*VRatioPrefetchC, 1.0); + } else { + MyError = true; + *VRatioPrefetchC = 0; + } + } + + *RequiredPrefetchPixDataBW = + DPPPerPlane + * ((double)PrefetchSourceLinesY + / LinesToRequestPrefetchPixelData + * dml_ceil(BytePerPixelDETY, + 1) + + (double)PrefetchSourceLinesC + / LinesToRequestPrefetchPixelData + * dml_ceil(BytePerPixelDETC, + 2) + / 2) + * SwathWidthY / LineTime; + } else { + MyError = true; + *VRatioPrefetchY = 0; + *VRatioPrefetchC = 0; + *RequiredPrefetchPixDataBW = 0; + } + + } else { + MyError = true; + } + + if (MyError) { + *PrefetchBandwidth = 0; + TimeForFetchingMetaPTE = 0; + TimeForFetchingRowInVBlank = 0; + *DestinationLinesToRequestVMInVBlank = 0; + *DestinationLinesToRequestRowInVBlank = 0; + *DestinationLinesForPrefetch = 0; + LinesToRequestPrefetchPixelData = 0; + *VRatioPrefetchY = 0; + *VRatioPrefetchC = 0; + *RequiredPrefetchPixDataBW = 0; + } + + return MyError; +} + +static double CeilToDFSGranularity(double Clock, double VCOSpeed) +{ + return VCOSpeed * 4 / dml_floor(VCOSpeed * 4 / Clock, 1); +} + +static double FloorToDFSGranularity(double Clock, double VCOSpeed) +{ + return VCOSpeed * 4 / dml_ceil(VCOSpeed * 4 / Clock, 1); +} + +static double CalculatePrefetchSourceLines(struct display_mode_lib *mode_lib, + double VRatio, + double vtaps, + bool Interlace, + bool ProgressiveToInterlaceUnitInOPP, + unsigned int SwathHeight, + unsigned int ViewportYStart, + double *VInitPreFill, + unsigned int *MaxNumSwath) +{ + unsigned int MaxPartialSwath; + + if (ProgressiveToInterlaceUnitInOPP) + *VInitPreFill = dml_floor((VRatio + vtaps + 1) / 2.0, 1); + else + *VInitPreFill = dml_floor((VRatio + vtaps + 1 + Interlace * 0.5 * VRatio) / 2.0, 1); + + if (!mode_lib->vba.IgnoreViewportPositioning) { + + *MaxNumSwath = dml_ceil((*VInitPreFill - 1.0) / SwathHeight, 1) + 1.0; + + if (*VInitPreFill > 1.0) + MaxPartialSwath = (unsigned int)(*VInitPreFill - 2) % SwathHeight; + else + MaxPartialSwath = (unsigned int)(*VInitPreFill + SwathHeight - 2) % SwathHeight; + MaxPartialSwath = dml_max(1U, MaxPartialSwath); + + } else { + + if (ViewportYStart != 0) + dml_print("WARNING DML: using viewport y position of 0 even though actual viewport y position is non-zero in prefetch source lines calculation\n"); + + *MaxNumSwath = dml_ceil(*VInitPreFill / SwathHeight, 1); + + if (*VInitPreFill > 1.0) + MaxPartialSwath = (unsigned int)(*VInitPreFill - 1) % SwathHeight; + else + MaxPartialSwath = (unsigned int)(*VInitPreFill + SwathHeight - 1) % SwathHeight; + } + + return *MaxNumSwath * SwathHeight + MaxPartialSwath; +} + +static unsigned int CalculateVMAndRowBytes(struct display_mode_lib *mode_lib, + bool DCCEnable, + unsigned int BlockHeight256Bytes, + unsigned int BlockWidth256Bytes, + enum source_format_class SourcePixelFormat, + unsigned int SurfaceTiling, + unsigned int BytePerPixel, + enum scan_direction_class ScanDirection, + unsigned int ViewportWidth, + unsigned int ViewportHeight, + unsigned int SwathWidth, + bool VirtualMemoryEnable, + unsigned int VMMPageSize, + unsigned int PTEBufferSizeInRequests, + unsigned int PDEProcessingBufIn64KBReqs, + unsigned int Pitch, + unsigned int DCCMetaPitch, + unsigned int *MacroTileWidth, + unsigned int *MetaRowByte, + unsigned int *PixelPTEBytesPerRow, + bool *PTEBufferSizeNotExceeded, + unsigned int *dpte_row_height, + unsigned int *meta_row_height) +{ + unsigned int MetaRequestHeight; + unsigned int MetaRequestWidth; + unsigned int MetaSurfWidth; + unsigned int MetaSurfHeight; + unsigned int MPDEBytesFrame; + unsigned int MetaPTEBytesFrame; + unsigned int DCCMetaSurfaceBytes; + + unsigned int MacroTileSizeBytes; + unsigned int MacroTileHeight; + unsigned int DPDE0BytesFrame; + unsigned int ExtraDPDEBytesFrame; + unsigned int PDEAndMetaPTEBytesFrame; + + if (DCCEnable == true) { + MetaRequestHeight = 8 * BlockHeight256Bytes; + MetaRequestWidth = 8 * BlockWidth256Bytes; + if (ScanDirection == dm_horz) { + *meta_row_height = MetaRequestHeight; + MetaSurfWidth = dml_ceil((double)SwathWidth - 1, MetaRequestWidth) + + MetaRequestWidth; + *MetaRowByte = MetaSurfWidth * MetaRequestHeight * BytePerPixel / 256.0; + } else { + *meta_row_height = MetaRequestWidth; + MetaSurfHeight = dml_ceil((double)SwathWidth - 1, MetaRequestHeight) + + MetaRequestHeight; + *MetaRowByte = MetaSurfHeight * MetaRequestWidth * BytePerPixel / 256.0; + } + if (ScanDirection == dm_horz) { + DCCMetaSurfaceBytes = DCCMetaPitch + * (dml_ceil(ViewportHeight - 1, 64 * BlockHeight256Bytes) + + 64 * BlockHeight256Bytes) * BytePerPixel + / 256; + } else { + DCCMetaSurfaceBytes = DCCMetaPitch + * (dml_ceil((double)ViewportHeight - 1, + 64 * BlockHeight256Bytes) + + 64 * BlockHeight256Bytes) * BytePerPixel + / 256; + } + if (VirtualMemoryEnable == true) { + MetaPTEBytesFrame = (dml_ceil((double)(DCCMetaSurfaceBytes - VMMPageSize) + / (8 * VMMPageSize), + 1) + 1) * 64; + MPDEBytesFrame = 128 * (mode_lib->vba.MaxPageTableLevels - 1); + } else { + MetaPTEBytesFrame = 0; + MPDEBytesFrame = 0; + } + } else { + MetaPTEBytesFrame = 0; + MPDEBytesFrame = 0; + *MetaRowByte = 0; + } + + if (SurfaceTiling == dm_sw_linear) { + MacroTileSizeBytes = 256; + MacroTileHeight = 1; + } else if (SurfaceTiling == dm_sw_4kb_s || SurfaceTiling == dm_sw_4kb_s_x + || SurfaceTiling == dm_sw_4kb_d || SurfaceTiling == dm_sw_4kb_d_x) { + MacroTileSizeBytes = 4096; + MacroTileHeight = 4 * BlockHeight256Bytes; + } else if (SurfaceTiling == dm_sw_64kb_s || SurfaceTiling == dm_sw_64kb_s_t + || SurfaceTiling == dm_sw_64kb_s_x || SurfaceTiling == dm_sw_64kb_d + || SurfaceTiling == dm_sw_64kb_d_t || SurfaceTiling == dm_sw_64kb_d_x + || SurfaceTiling == dm_sw_64kb_r_x) { + MacroTileSizeBytes = 65536; + MacroTileHeight = 16 * BlockHeight256Bytes; + } else { + MacroTileSizeBytes = 262144; + MacroTileHeight = 32 * BlockHeight256Bytes; + } + *MacroTileWidth = MacroTileSizeBytes / BytePerPixel / MacroTileHeight; + + if (VirtualMemoryEnable == true && mode_lib->vba.MaxPageTableLevels > 1) { + if (ScanDirection == dm_horz) { + DPDE0BytesFrame = + 64 + * (dml_ceil(((Pitch + * (dml_ceil(ViewportHeight + - 1, + MacroTileHeight) + + MacroTileHeight) + * BytePerPixel) + - MacroTileSizeBytes) + / (8 + * 2097152), + 1) + 1); + } else { + DPDE0BytesFrame = + 64 + * (dml_ceil(((Pitch + * (dml_ceil((double)SwathWidth + - 1, + MacroTileHeight) + + MacroTileHeight) + * BytePerPixel) + - MacroTileSizeBytes) + / (8 + * 2097152), + 1) + 1); + } + ExtraDPDEBytesFrame = 128 * (mode_lib->vba.MaxPageTableLevels - 2); + } else { + DPDE0BytesFrame = 0; + ExtraDPDEBytesFrame = 0; + } + + PDEAndMetaPTEBytesFrame = MetaPTEBytesFrame + MPDEBytesFrame + DPDE0BytesFrame + + ExtraDPDEBytesFrame; + + if (VirtualMemoryEnable == true) { + unsigned int PTERequestSize; + unsigned int PixelPTEReqHeight; + unsigned int PixelPTEReqWidth; + double FractionOfPTEReturnDrop; + unsigned int EffectivePDEProcessingBufIn64KBReqs; + + if (SurfaceTiling == dm_sw_linear) { + PixelPTEReqHeight = 1; + PixelPTEReqWidth = 8.0 * VMMPageSize / BytePerPixel; + PTERequestSize = 64; + FractionOfPTEReturnDrop = 0; + } else if (MacroTileSizeBytes == 4096) { + PixelPTEReqHeight = MacroTileHeight; + PixelPTEReqWidth = 8 * *MacroTileWidth; + PTERequestSize = 64; + if (ScanDirection == dm_horz) + FractionOfPTEReturnDrop = 0; + else + FractionOfPTEReturnDrop = 7 / 8; + } else if (VMMPageSize == 4096 && MacroTileSizeBytes > 4096) { + PixelPTEReqHeight = 16 * BlockHeight256Bytes; + PixelPTEReqWidth = 16 * BlockWidth256Bytes; + PTERequestSize = 128; + FractionOfPTEReturnDrop = 0; + } else { + PixelPTEReqHeight = MacroTileHeight; + PixelPTEReqWidth = 8 * *MacroTileWidth; + PTERequestSize = 64; + FractionOfPTEReturnDrop = 0; + } + + if (SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10) + EffectivePDEProcessingBufIn64KBReqs = PDEProcessingBufIn64KBReqs / 2; + else + EffectivePDEProcessingBufIn64KBReqs = PDEProcessingBufIn64KBReqs; + + if (SurfaceTiling == dm_sw_linear) { + *dpte_row_height = + dml_min(128, + 1 + << (unsigned int)dml_floor(dml_log2(dml_min((double)PTEBufferSizeInRequests + * PixelPTEReqWidth, + EffectivePDEProcessingBufIn64KBReqs + * 65536.0 + / BytePerPixel) + / Pitch), + 1)); + *PixelPTEBytesPerRow = PTERequestSize + * (dml_ceil((double)(Pitch * *dpte_row_height - 1) + / PixelPTEReqWidth, + 1) + 1); + } else if (ScanDirection == dm_horz) { + *dpte_row_height = PixelPTEReqHeight; + *PixelPTEBytesPerRow = PTERequestSize + * (dml_ceil(((double)SwathWidth - 1) / PixelPTEReqWidth, 1) + + 1); + } else { + *dpte_row_height = dml_min(PixelPTEReqWidth, *MacroTileWidth); + *PixelPTEBytesPerRow = PTERequestSize + * (dml_ceil(((double)SwathWidth - 1) + / PixelPTEReqHeight, + 1) + 1); + } + if (*PixelPTEBytesPerRow * (1 - FractionOfPTEReturnDrop) + <= 64 * PTEBufferSizeInRequests) { + *PTEBufferSizeNotExceeded = true; + } else { + *PTEBufferSizeNotExceeded = false; + } + } else { + *PixelPTEBytesPerRow = 0; + *PTEBufferSizeNotExceeded = true; + } + + return PDEAndMetaPTEBytesFrame; +} + +static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation(struct display_mode_lib *mode_lib) +{ + unsigned int j, k; + + mode_lib->vba.WritebackDISPCLK = 0.0; + mode_lib->vba.DISPCLKWithRamping = 0; + mode_lib->vba.DISPCLKWithoutRamping = 0; + mode_lib->vba.GlobalDPPCLK = 0.0; + + // dml_ml->vba.DISPCLK and dml_ml->vba.DPPCLK Calculation + // + for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { + if (mode_lib->vba.WritebackEnable[k]) { + mode_lib->vba.WritebackDISPCLK = dml_max(mode_lib->vba.WritebackDISPCLK, + CalculateWriteBackDISPCLK(mode_lib->vba.WritebackPixelFormat[k], + mode_lib->vba.PixelClock[k], + mode_lib->vba.WritebackHRatio[k], + mode_lib->vba.WritebackVRatio[k], + mode_lib->vba.WritebackLumaHTaps[k], + mode_lib->vba.WritebackLumaVTaps[k], + mode_lib->vba.WritebackChromaHTaps[k], + mode_lib->vba.WritebackChromaVTaps[k], + mode_lib->vba.WritebackDestinationWidth[k], + mode_lib->vba.HTotal[k], + mode_lib->vba.WritebackChromaLineBufferWidth)); + } + } + + for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { + if (mode_lib->vba.HRatio[k] > 1) { + mode_lib->vba.PSCL_THROUGHPUT_LUMA[k] = dml_min(mode_lib->vba.MaxDCHUBToPSCLThroughput, + mode_lib->vba.MaxPSCLToLBThroughput * mode_lib->vba.HRatio[k] + / dml_ceil(mode_lib->vba.htaps[k] / 6.0, 1)); + } else { + mode_lib->vba.PSCL_THROUGHPUT_LUMA[k] = dml_min(mode_lib->vba.MaxDCHUBToPSCLThroughput, + mode_lib->vba.MaxPSCLToLBThroughput); + } + + mode_lib->vba.DPPCLKUsingSingleDPPLuma = + mode_lib->vba.PixelClock[k] + * dml_max(mode_lib->vba.vtaps[k] / 6.0 + * dml_min(1.0, + mode_lib->vba.HRatio[k]), + dml_max(mode_lib->vba.HRatio[k] + * mode_lib->vba.VRatio[k] + / mode_lib->vba.PSCL_THROUGHPUT_LUMA[k], + 1.0)); + + if ((mode_lib->vba.htaps[k] > 6 || mode_lib->vba.vtaps[k] > 6) + && mode_lib->vba.DPPCLKUsingSingleDPPLuma < 2 * mode_lib->vba.PixelClock[k]) { + mode_lib->vba.DPPCLKUsingSingleDPPLuma = 2 * mode_lib->vba.PixelClock[k]; + } + + if ((mode_lib->vba.SourcePixelFormat[k] != dm_420_8 && mode_lib->vba.SourcePixelFormat[k] != dm_420_10)) { + mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k] = 0.0; + mode_lib->vba.DPPCLKUsingSingleDPP[k] = mode_lib->vba.DPPCLKUsingSingleDPPLuma; + } else { + if (mode_lib->vba.HRatio[k] > 1) { + mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k] = + dml_min(mode_lib->vba.MaxDCHUBToPSCLThroughput, + mode_lib->vba.MaxPSCLToLBThroughput * mode_lib->vba.HRatio[k] + / 2 + / dml_ceil(mode_lib->vba.HTAPsChroma[k] + / 6.0, + 1.0)); + } else { + mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k] = dml_min(mode_lib->vba.MaxDCHUBToPSCLThroughput, + mode_lib->vba.MaxPSCLToLBThroughput); + } + mode_lib->vba.DPPCLKUsingSingleDPPChroma = + mode_lib->vba.PixelClock[k] + * dml_max(mode_lib->vba.VTAPsChroma[k] / 6.0 + * dml_min(1.0, + mode_lib->vba.HRatio[k] + / 2), + dml_max(mode_lib->vba.HRatio[k] + * mode_lib->vba.VRatio[k] + / 4 + / mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k], + 1.0)); + + if ((mode_lib->vba.HTAPsChroma[k] > 6 || mode_lib->vba.VTAPsChroma[k] > 6) + && mode_lib->vba.DPPCLKUsingSingleDPPChroma < 2 * mode_lib->vba.PixelClock[k]) { + mode_lib->vba.DPPCLKUsingSingleDPPChroma = 2 * mode_lib->vba.PixelClock[k]; + } + + mode_lib->vba.DPPCLKUsingSingleDPP[k] = dml_max(mode_lib->vba.DPPCLKUsingSingleDPPLuma, + mode_lib->vba.DPPCLKUsingSingleDPPChroma); + } + } + + for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { + if (mode_lib->vba.BlendingAndTiming[k] != k) + continue; + if (mode_lib->vba.ODMCombineEnabled[k]) { + mode_lib->vba.DISPCLKWithRamping = + dml_max(mode_lib->vba.DISPCLKWithRamping, + mode_lib->vba.PixelClock[k] / 2 + * (1 + + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading + / 100) + * (1 + + mode_lib->vba.DISPCLKRampingMargin + / 100)); + mode_lib->vba.DISPCLKWithoutRamping = + dml_max(mode_lib->vba.DISPCLKWithoutRamping, + mode_lib->vba.PixelClock[k] / 2 + * (1 + + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading + / 100)); + } else if (!mode_lib->vba.ODMCombineEnabled[k]) { + mode_lib->vba.DISPCLKWithRamping = dml_max(mode_lib->vba.DISPCLKWithRamping, + mode_lib->vba.PixelClock[k] * (1 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100) + * (1 + mode_lib->vba.DISPCLKRampingMargin / 100)); + mode_lib->vba.DISPCLKWithoutRamping = + dml_max(mode_lib->vba.DISPCLKWithoutRamping, + mode_lib->vba.PixelClock[k] + * (1 + + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading + / 100)); + } + } + + mode_lib->vba.DISPCLKWithRamping = dml_max(mode_lib->vba.DISPCLKWithRamping, mode_lib->vba.WritebackDISPCLK); + mode_lib->vba.DISPCLKWithoutRamping = dml_max(mode_lib->vba.DISPCLKWithoutRamping, mode_lib->vba.WritebackDISPCLK); + + mode_lib->vba.MaxDispclk = mode_lib->vba.soc.clock_limits[NumberOfStates - 1].dispclk_mhz; + ASSERT(mode_lib->vba.DISPCLKDPPCLKVCOSpeed != 0); + mode_lib->vba.DISPCLKWithRampingRoundedToDFSGranularity = CeilToDFSGranularity( + mode_lib->vba.DISPCLKWithRamping, + mode_lib->vba.DISPCLKDPPCLKVCOSpeed); + mode_lib->vba.DISPCLKWithoutRampingRoundedToDFSGranularity = CeilToDFSGranularity( + mode_lib->vba.DISPCLKWithoutRamping, + mode_lib->vba.DISPCLKDPPCLKVCOSpeed); + mode_lib->vba.MaxDispclkRoundedToDFSGranularity = FloorToDFSGranularity( + mode_lib->vba.MaxDispclk, + mode_lib->vba.DISPCLKDPPCLKVCOSpeed); + if (mode_lib->vba.DISPCLKWithoutRampingRoundedToDFSGranularity + > mode_lib->vba.MaxDispclkRoundedToDFSGranularity) { + mode_lib->vba.DISPCLK_calculated = mode_lib->vba.DISPCLKWithoutRampingRoundedToDFSGranularity; + } else if (mode_lib->vba.DISPCLKWithRampingRoundedToDFSGranularity + > mode_lib->vba.MaxDispclkRoundedToDFSGranularity) { + mode_lib->vba.DISPCLK_calculated = mode_lib->vba.MaxDispclkRoundedToDFSGranularity; + } else { + mode_lib->vba.DISPCLK_calculated = mode_lib->vba.DISPCLKWithRampingRoundedToDFSGranularity; + } + DTRACE(" dispclk_mhz (calculated) = %f", mode_lib->vba.DISPCLK_calculated); + + for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { + mode_lib->vba.DPPCLK_calculated[k] = mode_lib->vba.DPPCLKUsingSingleDPP[k] / mode_lib->vba.DPPPerPlane[k] + * (1 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100); + mode_lib->vba.GlobalDPPCLK = dml_max(mode_lib->vba.GlobalDPPCLK, mode_lib->vba.DPPCLK_calculated[k]); + } + mode_lib->vba.GlobalDPPCLK = CeilToDFSGranularity(mode_lib->vba.GlobalDPPCLK, mode_lib->vba.DISPCLKDPPCLKVCOSpeed); + for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { + mode_lib->vba.DPPCLK_calculated[k] = mode_lib->vba.GlobalDPPCLK / 255 + * dml_ceil(mode_lib->vba.DPPCLK_calculated[k] * 255 / mode_lib->vba.GlobalDPPCLK, 1); + DTRACE(" dppclk_mhz[%i] (calculated) = %f", k, mode_lib->vba.DPPCLK_calculated[k]); + } + + // Urgent Watermark + mode_lib->vba.DCCEnabledAnyPlane = false; + for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) + if (mode_lib->vba.DCCEnable[k]) + mode_lib->vba.DCCEnabledAnyPlane = true; + + mode_lib->vba.ReturnBandwidthToDCN = dml_min(mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLK, mode_lib->vba.FabricAndDRAMBandwidth * 1000) + * mode_lib->vba.PercentOfIdealDRAMAndFabricBWReceivedAfterUrgLatency / 100; + + mode_lib->vba.ReturnBW = mode_lib->vba.ReturnBandwidthToDCN; + mode_lib->vba.ReturnBW = adjust_ReturnBW(mode_lib, mode_lib->vba.ReturnBW, mode_lib->vba.DCCEnabledAnyPlane, mode_lib->vba.ReturnBandwidthToDCN); + + // Let's do this calculation again?? + mode_lib->vba.ReturnBandwidthToDCN = dml_min(mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLK, mode_lib->vba.FabricAndDRAMBandwidth * 1000); + mode_lib->vba.ReturnBW = adjust_ReturnBW(mode_lib, mode_lib->vba.ReturnBW, mode_lib->vba.DCCEnabledAnyPlane, mode_lib->vba.ReturnBandwidthToDCN); + + DTRACE(" dcfclk_mhz = %f", mode_lib->vba.DCFCLK); + DTRACE(" return_bw_to_dcn = %f", mode_lib->vba.ReturnBandwidthToDCN); + DTRACE(" return_bus_bw = %f", mode_lib->vba.ReturnBW); + + for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { + bool MainPlaneDoesODMCombine = false; + + if (mode_lib->vba.SourceScan[k] == dm_horz) + mode_lib->vba.SwathWidthSingleDPPY[k] = mode_lib->vba.ViewportWidth[k]; + else + mode_lib->vba.SwathWidthSingleDPPY[k] = mode_lib->vba.ViewportHeight[k]; + + if (mode_lib->vba.ODMCombineEnabled[k] == true) + MainPlaneDoesODMCombine = true; + for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) + if (mode_lib->vba.BlendingAndTiming[k] == j && mode_lib->vba.ODMCombineEnabled[j] == true) + MainPlaneDoesODMCombine = true; + + if (MainPlaneDoesODMCombine == true) + mode_lib->vba.SwathWidthY[k] = dml_min((double)mode_lib->vba.SwathWidthSingleDPPY[k], + dml_round(mode_lib->vba.HActive[k] / 2.0 * mode_lib->vba.HRatio[k])); + else + mode_lib->vba.SwathWidthY[k] = mode_lib->vba.SwathWidthSingleDPPY[k] / mode_lib->vba.DPPPerPlane[k]; + } + + for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { + if (mode_lib->vba.SourcePixelFormat[k] == dm_444_64) { + mode_lib->vba.BytePerPixelDETY[k] = 8; + mode_lib->vba.BytePerPixelDETC[k] = 0; + } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_32) { + mode_lib->vba.BytePerPixelDETY[k] = 4; + mode_lib->vba.BytePerPixelDETC[k] = 0; + } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_16) { + mode_lib->vba.BytePerPixelDETY[k] = 2; + mode_lib->vba.BytePerPixelDETC[k] = 0; + } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_8) { + mode_lib->vba.BytePerPixelDETY[k] = 1; + mode_lib->vba.BytePerPixelDETC[k] = 0; + } else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8) { + mode_lib->vba.BytePerPixelDETY[k] = 1; + mode_lib->vba.BytePerPixelDETC[k] = 2; + } else { // dm_420_10 + mode_lib->vba.BytePerPixelDETY[k] = 4.0 / 3.0; + mode_lib->vba.BytePerPixelDETC[k] = 8.0 / 3.0; + } + } + + mode_lib->vba.TotalDataReadBandwidth = 0.0; + for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { + mode_lib->vba.ReadBandwidthPlaneLuma[k] = mode_lib->vba.SwathWidthSingleDPPY[k] + * dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1) / (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]) + * mode_lib->vba.VRatio[k]; + mode_lib->vba.ReadBandwidthPlaneChroma[k] = mode_lib->vba.SwathWidthSingleDPPY[k] / 2 + * dml_ceil(mode_lib->vba.BytePerPixelDETC[k], 2) / (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]) + * mode_lib->vba.VRatio[k] / 2; + DTRACE(" read_bw[%i] = %fBps", + k, + mode_lib->vba.ReadBandwidthPlaneLuma[k] + mode_lib->vba.ReadBandwidthPlaneChroma[k]); + mode_lib->vba.TotalDataReadBandwidth += mode_lib->vba.ReadBandwidthPlaneLuma[k] + + mode_lib->vba.ReadBandwidthPlaneChroma[k]; + } + + mode_lib->vba.TotalDCCActiveDPP = 0; + mode_lib->vba.TotalActiveDPP = 0; + for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { + mode_lib->vba.TotalActiveDPP = mode_lib->vba.TotalActiveDPP + mode_lib->vba.DPPPerPlane[k]; + if (mode_lib->vba.DCCEnable[k]) + mode_lib->vba.TotalDCCActiveDPP = mode_lib->vba.TotalDCCActiveDPP + mode_lib->vba.DPPPerPlane[k]; + } + + mode_lib->vba.UrgentRoundTripAndOutOfOrderLatency = (mode_lib->vba.RoundTripPingLatencyCycles + 32) / mode_lib->vba.DCFCLK + + mode_lib->vba.UrgentOutOfOrderReturnPerChannel * mode_lib->vba.NumberOfChannels / mode_lib->vba.ReturnBW; + + mode_lib->vba.LastPixelOfLineExtraWatermark = 0; + for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { + double DataFabricLineDeliveryTimeLuma, DataFabricLineDeliveryTimeChroma; + + if (mode_lib->vba.VRatio[k] <= 1.0) + mode_lib->vba.DisplayPipeLineDeliveryTimeLuma[k] = (double)mode_lib->vba.SwathWidthY[k] + * mode_lib->vba.DPPPerPlane[k] / mode_lib->vba.HRatio[k] / mode_lib->vba.PixelClock[k]; + else + mode_lib->vba.DisplayPipeLineDeliveryTimeLuma[k] = (double)mode_lib->vba.SwathWidthY[k] + / mode_lib->vba.PSCL_THROUGHPUT_LUMA[k] / mode_lib->vba.DPPCLK[k]; + + DataFabricLineDeliveryTimeLuma = + mode_lib->vba.SwathWidthSingleDPPY[k] * mode_lib->vba.SwathHeightY[k] + * dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1) + / (mode_lib->vba.ReturnBW * mode_lib->vba.ReadBandwidthPlaneLuma[k] + / mode_lib->vba.TotalDataReadBandwidth); + mode_lib->vba.LastPixelOfLineExtraWatermark = dml_max(mode_lib->vba.LastPixelOfLineExtraWatermark, + DataFabricLineDeliveryTimeLuma + - mode_lib->vba.DisplayPipeLineDeliveryTimeLuma[k]); + + if (mode_lib->vba.BytePerPixelDETC[k] == 0) + mode_lib->vba.DisplayPipeLineDeliveryTimeChroma[k] = 0.0; + else if (mode_lib->vba.VRatio[k] / 2.0 <= 1.0) + mode_lib->vba.DisplayPipeLineDeliveryTimeChroma[k] = mode_lib->vba.SwathWidthY[k] / 2.0 + * mode_lib->vba.DPPPerPlane[k] / (mode_lib->vba.HRatio[k] / 2.0) / mode_lib->vba.PixelClock[k]; + else + mode_lib->vba.DisplayPipeLineDeliveryTimeChroma[k] = mode_lib->vba.SwathWidthY[k] / 2.0 + / mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k] / mode_lib->vba.DPPCLK[k]; + + DataFabricLineDeliveryTimeChroma = mode_lib->vba.SwathWidthSingleDPPY[k] / 2.0 + * mode_lib->vba.SwathHeightC[k] * dml_ceil(mode_lib->vba.BytePerPixelDETC[k], 2) + / (mode_lib->vba.ReturnBW * mode_lib->vba.ReadBandwidthPlaneChroma[k] + / mode_lib->vba.TotalDataReadBandwidth); + mode_lib->vba.LastPixelOfLineExtraWatermark = dml_max(mode_lib->vba.LastPixelOfLineExtraWatermark, + DataFabricLineDeliveryTimeChroma + - mode_lib->vba.DisplayPipeLineDeliveryTimeChroma[k]); + } + + mode_lib->vba.UrgentExtraLatency = mode_lib->vba.UrgentRoundTripAndOutOfOrderLatency + + (mode_lib->vba.TotalActiveDPP * mode_lib->vba.PixelChunkSizeInKByte + + mode_lib->vba.TotalDCCActiveDPP * mode_lib->vba.MetaChunkSize) * 1024.0 + / mode_lib->vba.ReturnBW; + + if (mode_lib->vba.VirtualMemoryEnable) + mode_lib->vba.UrgentExtraLatency += mode_lib->vba.TotalActiveDPP * mode_lib->vba.PTEChunkSize * 1024.0 / mode_lib->vba.ReturnBW; + + mode_lib->vba.UrgentWatermark = mode_lib->vba.UrgentLatency + mode_lib->vba.LastPixelOfLineExtraWatermark + mode_lib->vba.UrgentExtraLatency; + + DTRACE(" urgent_extra_latency = %fus", mode_lib->vba.UrgentExtraLatency); + DTRACE(" wm_urgent = %fus", mode_lib->vba.UrgentWatermark); + + mode_lib->vba.MemoryTripWatermark = mode_lib->vba.UrgentLatency; + + mode_lib->vba.TotalActiveWriteback = 0; + for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { + if (mode_lib->vba.WritebackEnable[k]) + mode_lib->vba.TotalActiveWriteback = mode_lib->vba.TotalActiveWriteback + 1; + } + + if (mode_lib->vba.TotalActiveWriteback <= 1) + mode_lib->vba.WritebackUrgentWatermark = mode_lib->vba.WritebackLatency; + else + mode_lib->vba.WritebackUrgentWatermark = mode_lib->vba.WritebackLatency + + mode_lib->vba.WritebackChunkSize * 1024.0 / 32 / mode_lib->vba.SOCCLK; + + DTRACE(" wm_wb_urgent = %fus", mode_lib->vba.WritebackUrgentWatermark); + + // NB P-State/DRAM Clock Change Watermark + mode_lib->vba.DRAMClockChangeWatermark = mode_lib->vba.DRAMClockChangeLatency + mode_lib->vba.UrgentWatermark; + + DTRACE(" wm_pstate_change = %fus", mode_lib->vba.DRAMClockChangeWatermark); + + DTRACE(" calculating wb pstate watermark"); + DTRACE(" total wb outputs %d", mode_lib->vba.TotalActiveWriteback); + DTRACE(" socclk frequency %f Mhz", mode_lib->vba.SOCCLK); + + if (mode_lib->vba.TotalActiveWriteback <= 1) + mode_lib->vba.WritebackDRAMClockChangeWatermark = mode_lib->vba.DRAMClockChangeLatency + mode_lib->vba.WritebackLatency; + else + mode_lib->vba.WritebackDRAMClockChangeWatermark = mode_lib->vba.DRAMClockChangeLatency + mode_lib->vba.WritebackLatency + + mode_lib->vba.WritebackChunkSize * 1024.0 / 32 / mode_lib->vba.SOCCLK; + + DTRACE(" wm_wb_pstate %fus", mode_lib->vba.WritebackDRAMClockChangeWatermark); + + // Stutter Efficiency + for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { + mode_lib->vba.LinesInDETY[k] = mode_lib->vba.DETBufferSizeY[k] / mode_lib->vba.BytePerPixelDETY[k] + / mode_lib->vba.SwathWidthY[k]; + mode_lib->vba.LinesInDETYRoundedDownToSwath[k] = dml_floor(mode_lib->vba.LinesInDETY[k], + mode_lib->vba.SwathHeightY[k]); + mode_lib->vba.FullDETBufferingTimeY[k] = mode_lib->vba.LinesInDETYRoundedDownToSwath[k] + * (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]) / mode_lib->vba.VRatio[k]; + if (mode_lib->vba.BytePerPixelDETC[k] > 0) { + mode_lib->vba.LinesInDETC[k] = mode_lib->vba.DETBufferSizeC[k] / mode_lib->vba.BytePerPixelDETC[k] + / (mode_lib->vba.SwathWidthY[k] / 2); + mode_lib->vba.LinesInDETCRoundedDownToSwath[k] = dml_floor(mode_lib->vba.LinesInDETC[k], + mode_lib->vba.SwathHeightC[k]); + mode_lib->vba.FullDETBufferingTimeC[k] = mode_lib->vba.LinesInDETCRoundedDownToSwath[k] + * (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]) / (mode_lib->vba.VRatio[k] / 2); + } else { + mode_lib->vba.LinesInDETC[k] = 0; + mode_lib->vba.LinesInDETCRoundedDownToSwath[k] = 0; + mode_lib->vba.FullDETBufferingTimeC[k] = 999999; + } + } + + mode_lib->vba.MinFullDETBufferingTime = 999999.0; + for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { + if (mode_lib->vba.FullDETBufferingTimeY[k] < mode_lib->vba.MinFullDETBufferingTime) { + mode_lib->vba.MinFullDETBufferingTime = mode_lib->vba.FullDETBufferingTimeY[k]; + mode_lib->vba.FrameTimeForMinFullDETBufferingTime = (double)mode_lib->vba.VTotal[k] * mode_lib->vba.HTotal[k] + / mode_lib->vba.PixelClock[k]; + } + if (mode_lib->vba.FullDETBufferingTimeC[k] < mode_lib->vba.MinFullDETBufferingTime) { + mode_lib->vba.MinFullDETBufferingTime = mode_lib->vba.FullDETBufferingTimeC[k]; + mode_lib->vba.FrameTimeForMinFullDETBufferingTime = (double)mode_lib->vba.VTotal[k] * mode_lib->vba.HTotal[k] + / mode_lib->vba.PixelClock[k]; + } + } + + mode_lib->vba.AverageReadBandwidthGBytePerSecond = 0.0; + for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { + if (mode_lib->vba.DCCEnable[k]) { + mode_lib->vba.AverageReadBandwidthGBytePerSecond = + mode_lib->vba.AverageReadBandwidthGBytePerSecond + + mode_lib->vba.ReadBandwidthPlaneLuma[k] / mode_lib->vba.DCCRate[k] + / 1000 + + mode_lib->vba.ReadBandwidthPlaneChroma[k] + / mode_lib->vba.DCCRate[k] / 1000; + } else { + mode_lib->vba.AverageReadBandwidthGBytePerSecond = + mode_lib->vba.AverageReadBandwidthGBytePerSecond + + mode_lib->vba.ReadBandwidthPlaneLuma[k] / 1000 + + mode_lib->vba.ReadBandwidthPlaneChroma[k] / 1000; + } + if (mode_lib->vba.DCCEnable[k]) { + mode_lib->vba.AverageReadBandwidthGBytePerSecond = + mode_lib->vba.AverageReadBandwidthGBytePerSecond + + mode_lib->vba.ReadBandwidthPlaneLuma[k] / 1000 / 256 + + mode_lib->vba.ReadBandwidthPlaneChroma[k] / 1000 + / 256; + } + if (mode_lib->vba.VirtualMemoryEnable) { + mode_lib->vba.AverageReadBandwidthGBytePerSecond = + mode_lib->vba.AverageReadBandwidthGBytePerSecond + + mode_lib->vba.ReadBandwidthPlaneLuma[k] / 1000 / 512 + + mode_lib->vba.ReadBandwidthPlaneChroma[k] / 1000 + / 512; + } + } + + mode_lib->vba.PartOfBurstThatFitsInROB = dml_min(mode_lib->vba.MinFullDETBufferingTime * mode_lib->vba.TotalDataReadBandwidth, + mode_lib->vba.ROBBufferSizeInKByte * 1024 * mode_lib->vba.TotalDataReadBandwidth + / (mode_lib->vba.AverageReadBandwidthGBytePerSecond * 1000)); + mode_lib->vba.StutterBurstTime = mode_lib->vba.PartOfBurstThatFitsInROB + * (mode_lib->vba.AverageReadBandwidthGBytePerSecond * 1000) / mode_lib->vba.TotalDataReadBandwidth + / mode_lib->vba.ReturnBW + + (mode_lib->vba.MinFullDETBufferingTime * mode_lib->vba.TotalDataReadBandwidth + - mode_lib->vba.PartOfBurstThatFitsInROB) / (mode_lib->vba.DCFCLK * 64); + if (mode_lib->vba.TotalActiveWriteback == 0) { + mode_lib->vba.StutterEfficiencyNotIncludingVBlank = (1 + - (mode_lib->vba.SRExitTime + mode_lib->vba.StutterBurstTime) / mode_lib->vba.MinFullDETBufferingTime) + * 100; + } else { + mode_lib->vba.StutterEfficiencyNotIncludingVBlank = 0; + } + + mode_lib->vba.SmallestVBlank = 999999; + for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { + if (mode_lib->vba.SynchronizedVBlank || mode_lib->vba.NumberOfActivePlanes == 1) { + mode_lib->vba.VBlankTime = (double)(mode_lib->vba.VTotal[k] - mode_lib->vba.VActive[k]) * mode_lib->vba.HTotal[k] + / mode_lib->vba.PixelClock[k]; + } else { + mode_lib->vba.VBlankTime = 0; + } + mode_lib->vba.SmallestVBlank = dml_min(mode_lib->vba.SmallestVBlank, mode_lib->vba.VBlankTime); + } + + mode_lib->vba.StutterEfficiency = (mode_lib->vba.StutterEfficiencyNotIncludingVBlank / 100 + * (mode_lib->vba.FrameTimeForMinFullDETBufferingTime - mode_lib->vba.SmallestVBlank) + + mode_lib->vba.SmallestVBlank) / mode_lib->vba.FrameTimeForMinFullDETBufferingTime * 100; + + // dml_ml->vba.DCFCLK Deep Sleep + mode_lib->vba.DCFClkDeepSleep = 8.0; + + for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; k++) { + if (mode_lib->vba.BytePerPixelDETC[k] > 0) { + mode_lib->vba.DCFCLKDeepSleepPerPlane = dml_max(1.1 * mode_lib->vba.SwathWidthY[k] + * dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1) / 32 + / mode_lib->vba.DisplayPipeLineDeliveryTimeLuma[k], + 1.1 * mode_lib->vba.SwathWidthY[k] / 2.0 + * dml_ceil(mode_lib->vba.BytePerPixelDETC[k], 2) / 32 + / mode_lib->vba.DisplayPipeLineDeliveryTimeChroma[k]); + } else + mode_lib->vba.DCFCLKDeepSleepPerPlane = 1.1 * mode_lib->vba.SwathWidthY[k] + * dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1) / 64.0 + / mode_lib->vba.DisplayPipeLineDeliveryTimeLuma[k]; + mode_lib->vba.DCFCLKDeepSleepPerPlane = dml_max(mode_lib->vba.DCFCLKDeepSleepPerPlane, + mode_lib->vba.PixelClock[k] / 16.0); + mode_lib->vba.DCFClkDeepSleep = dml_max(mode_lib->vba.DCFClkDeepSleep, mode_lib->vba.DCFCLKDeepSleepPerPlane); + + DTRACE(" dcfclk_deepsleep_per_plane[%i] = %fMHz", k, mode_lib->vba.DCFCLKDeepSleepPerPlane); + } + + DTRACE(" dcfclk_deepsleep_mhz = %fMHz", mode_lib->vba.DCFClkDeepSleep); + + // Stutter Watermark + mode_lib->vba.StutterExitWatermark = mode_lib->vba.SRExitTime + mode_lib->vba.LastPixelOfLineExtraWatermark + mode_lib->vba.UrgentExtraLatency + + 10 / mode_lib->vba.DCFClkDeepSleep; + mode_lib->vba.StutterEnterPlusExitWatermark = mode_lib->vba.SREnterPlusExitTime + mode_lib->vba.LastPixelOfLineExtraWatermark + + mode_lib->vba.UrgentExtraLatency; + + DTRACE(" wm_cstate_exit = %fus", mode_lib->vba.StutterExitWatermark); + DTRACE(" wm_cstate_enter_exit = %fus", mode_lib->vba.StutterEnterPlusExitWatermark); + + // Urgent Latency Supported + for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { + mode_lib->vba.EffectiveDETPlusLBLinesLuma = + dml_floor(mode_lib->vba.LinesInDETY[k] + + dml_min(mode_lib->vba.LinesInDETY[k] + * mode_lib->vba.DPPCLK[k] + * mode_lib->vba.BytePerPixelDETY[k] + * mode_lib->vba.PSCL_THROUGHPUT_LUMA[k] + / (mode_lib->vba.ReturnBW + / mode_lib->vba.DPPPerPlane[k]), + (double)mode_lib->vba.EffectiveLBLatencyHidingSourceLinesLuma), + mode_lib->vba.SwathHeightY[k]); + + mode_lib->vba.UrgentLatencySupportUsLuma = mode_lib->vba.EffectiveDETPlusLBLinesLuma + * (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]) / mode_lib->vba.VRatio[k] + - mode_lib->vba.EffectiveDETPlusLBLinesLuma * mode_lib->vba.SwathWidthY[k] + * mode_lib->vba.BytePerPixelDETY[k] + / (mode_lib->vba.ReturnBW / mode_lib->vba.DPPPerPlane[k]); + + if (mode_lib->vba.BytePerPixelDETC[k] > 0) { + mode_lib->vba.EffectiveDETPlusLBLinesChroma = + dml_floor(mode_lib->vba.LinesInDETC[k] + + dml_min(mode_lib->vba.LinesInDETC[k] + * mode_lib->vba.DPPCLK[k] + * mode_lib->vba.BytePerPixelDETC[k] + * mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k] + / (mode_lib->vba.ReturnBW + / mode_lib->vba.DPPPerPlane[k]), + (double)mode_lib->vba.EffectiveLBLatencyHidingSourceLinesChroma), + mode_lib->vba.SwathHeightC[k]); + mode_lib->vba.UrgentLatencySupportUsChroma = mode_lib->vba.EffectiveDETPlusLBLinesChroma + * (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]) / (mode_lib->vba.VRatio[k] / 2) + - mode_lib->vba.EffectiveDETPlusLBLinesChroma + * (mode_lib->vba.SwathWidthY[k] / 2) + * mode_lib->vba.BytePerPixelDETC[k] + / (mode_lib->vba.ReturnBW / mode_lib->vba.DPPPerPlane[k]); + mode_lib->vba.UrgentLatencySupportUs[k] = dml_min(mode_lib->vba.UrgentLatencySupportUsLuma, + mode_lib->vba.UrgentLatencySupportUsChroma); + } else { + mode_lib->vba.UrgentLatencySupportUs[k] = mode_lib->vba.UrgentLatencySupportUsLuma; + } + } + + mode_lib->vba.MinUrgentLatencySupportUs = 999999; + for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { + mode_lib->vba.MinUrgentLatencySupportUs = dml_min(mode_lib->vba.MinUrgentLatencySupportUs, + mode_lib->vba.UrgentLatencySupportUs[k]); + } + + // Non-Urgent Latency Tolerance + mode_lib->vba.NonUrgentLatencyTolerance = mode_lib->vba.MinUrgentLatencySupportUs - mode_lib->vba.UrgentWatermark; + + // DSCCLK + for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { + if ((mode_lib->vba.BlendingAndTiming[k] != k) || !mode_lib->vba.DSCEnabled[k]) { + mode_lib->vba.DSCCLK_calculated[k] = 0.0; + } else { + if (mode_lib->vba.OutputFormat[k] == dm_420 || mode_lib->vba.OutputFormat[k] == dm_n422) + mode_lib->vba.DSCFormatFactor = 2; + else + mode_lib->vba.DSCFormatFactor = 1; + if (mode_lib->vba.ODMCombineEnabled[k]) + mode_lib->vba.DSCCLK_calculated[k] = mode_lib->vba.PixelClockBackEnd[k] / 6 + / mode_lib->vba.DSCFormatFactor + / (1 - mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100); + else + mode_lib->vba.DSCCLK_calculated[k] = mode_lib->vba.PixelClockBackEnd[k] / 3 + / mode_lib->vba.DSCFormatFactor + / (1 - mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100); + } + } + + // DSC Delay + // TODO + for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { + double bpp = mode_lib->vba.OutputBpp[k]; + unsigned int slices = mode_lib->vba.NumberOfDSCSlices[k]; + + if (mode_lib->vba.DSCEnabled[k] && bpp != 0) { + if (!mode_lib->vba.ODMCombineEnabled[k]) { + mode_lib->vba.DSCDelay[k] = + dscceComputeDelay(mode_lib->vba.DSCInputBitPerComponent[k], + bpp, + dml_ceil((double)mode_lib->vba.HActive[k] + / mode_lib->vba.NumberOfDSCSlices[k], + 1), + slices, + mode_lib->vba.OutputFormat[k]) + + dscComputeDelay(mode_lib->vba.OutputFormat[k]); + } else { + mode_lib->vba.DSCDelay[k] = + 2 + * (dscceComputeDelay(mode_lib->vba.DSCInputBitPerComponent[k], + bpp, + dml_ceil((double)mode_lib->vba.HActive[k] + / mode_lib->vba.NumberOfDSCSlices[k], + 1), + slices / 2.0, + mode_lib->vba.OutputFormat[k]) + + dscComputeDelay(mode_lib->vba.OutputFormat[k])); + } + mode_lib->vba.DSCDelay[k] = mode_lib->vba.DSCDelay[k] * mode_lib->vba.PixelClock[k] / mode_lib->vba.PixelClockBackEnd[k]; + } else { + mode_lib->vba.DSCDelay[k] = 0; + } + } + + for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) + for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) // NumberOfPlanes + if (j != k && mode_lib->vba.BlendingAndTiming[k] == j && mode_lib->vba.DSCEnabled[j]) + mode_lib->vba.DSCDelay[k] = mode_lib->vba.DSCDelay[j]; + + // Prefetch + for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { + unsigned int PDEAndMetaPTEBytesFrameY; + unsigned int PixelPTEBytesPerRowY; + unsigned int MetaRowByteY; + unsigned int MetaRowByteC; + unsigned int PDEAndMetaPTEBytesFrameC; + unsigned int PixelPTEBytesPerRowC; + + Calculate256BBlockSizes(mode_lib->vba.SourcePixelFormat[k], + mode_lib->vba.SurfaceTiling[k], + dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1), + dml_ceil(mode_lib->vba.BytePerPixelDETC[k], 2), + &mode_lib->vba.BlockHeight256BytesY[k], + &mode_lib->vba.BlockHeight256BytesC[k], + &mode_lib->vba.BlockWidth256BytesY[k], + &mode_lib->vba.BlockWidth256BytesC[k]); + PDEAndMetaPTEBytesFrameY = CalculateVMAndRowBytes(mode_lib, + mode_lib->vba.DCCEnable[k], + mode_lib->vba.BlockHeight256BytesY[k], + mode_lib->vba.BlockWidth256BytesY[k], + mode_lib->vba.SourcePixelFormat[k], + mode_lib->vba.SurfaceTiling[k], + dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1), + mode_lib->vba.SourceScan[k], + mode_lib->vba.ViewportWidth[k], + mode_lib->vba.ViewportHeight[k], + mode_lib->vba.SwathWidthY[k], + mode_lib->vba.VirtualMemoryEnable, + mode_lib->vba.VMMPageSize, + mode_lib->vba.PTEBufferSizeInRequests, + mode_lib->vba.PDEProcessingBufIn64KBReqs, + mode_lib->vba.PitchY[k], + mode_lib->vba.DCCMetaPitchY[k], + &mode_lib->vba.MacroTileWidthY, + &MetaRowByteY, + &PixelPTEBytesPerRowY, + &mode_lib->vba.PTEBufferSizeNotExceeded, + &mode_lib->vba.dpte_row_height[k], + &mode_lib->vba.meta_row_height[k]); + mode_lib->vba.PrefetchSourceLinesY[k] = CalculatePrefetchSourceLines(mode_lib, + mode_lib->vba.VRatio[k], + mode_lib->vba.vtaps[k], + mode_lib->vba.Interlace[k], + mode_lib->vba.ProgressiveToInterlaceUnitInOPP, + mode_lib->vba.SwathHeightY[k], + mode_lib->vba.ViewportYStartY[k], + &mode_lib->vba.VInitPreFillY[k], + &mode_lib->vba.MaxNumSwathY[k]); + + if ((mode_lib->vba.SourcePixelFormat[k] != dm_444_64 && mode_lib->vba.SourcePixelFormat[k] != dm_444_32 + && mode_lib->vba.SourcePixelFormat[k] != dm_444_16 + && mode_lib->vba.SourcePixelFormat[k] != dm_444_8)) { + PDEAndMetaPTEBytesFrameC = CalculateVMAndRowBytes(mode_lib, + mode_lib->vba.DCCEnable[k], + mode_lib->vba.BlockHeight256BytesC[k], + mode_lib->vba.BlockWidth256BytesC[k], + mode_lib->vba.SourcePixelFormat[k], + mode_lib->vba.SurfaceTiling[k], + dml_ceil(mode_lib->vba.BytePerPixelDETC[k], 2), + mode_lib->vba.SourceScan[k], + mode_lib->vba.ViewportWidth[k] / 2, + mode_lib->vba.ViewportHeight[k] / 2, + mode_lib->vba.SwathWidthY[k] / 2, + mode_lib->vba.VirtualMemoryEnable, + mode_lib->vba.VMMPageSize, + mode_lib->vba.PTEBufferSizeInRequests, + mode_lib->vba.PDEProcessingBufIn64KBReqs, + mode_lib->vba.PitchC[k], + 0, + &mode_lib->vba.MacroTileWidthC, + &MetaRowByteC, + &PixelPTEBytesPerRowC, + &mode_lib->vba.PTEBufferSizeNotExceeded, + &mode_lib->vba.dpte_row_height_chroma[k], + &mode_lib->vba.meta_row_height_chroma[k]); + mode_lib->vba.PrefetchSourceLinesC[k] = CalculatePrefetchSourceLines(mode_lib, + mode_lib->vba.VRatio[k] / 2, + mode_lib->vba.VTAPsChroma[k], + mode_lib->vba.Interlace[k], + mode_lib->vba.ProgressiveToInterlaceUnitInOPP, + mode_lib->vba.SwathHeightC[k], + mode_lib->vba.ViewportYStartC[k], + &mode_lib->vba.VInitPreFillC[k], + &mode_lib->vba.MaxNumSwathC[k]); + } else { + PixelPTEBytesPerRowC = 0; + PDEAndMetaPTEBytesFrameC = 0; + MetaRowByteC = 0; + mode_lib->vba.MaxNumSwathC[k] = 0; + mode_lib->vba.PrefetchSourceLinesC[k] = 0; + } + + mode_lib->vba.PixelPTEBytesPerRow[k] = PixelPTEBytesPerRowY + PixelPTEBytesPerRowC; + mode_lib->vba.PDEAndMetaPTEBytesFrame[k] = PDEAndMetaPTEBytesFrameY + PDEAndMetaPTEBytesFrameC; + mode_lib->vba.MetaRowByte[k] = MetaRowByteY + MetaRowByteC; + + CalculateActiveRowBandwidth(mode_lib->vba.VirtualMemoryEnable, + mode_lib->vba.SourcePixelFormat[k], + mode_lib->vba.VRatio[k], + mode_lib->vba.DCCEnable[k], + mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k], + MetaRowByteY, + MetaRowByteC, + mode_lib->vba.meta_row_height[k], + mode_lib->vba.meta_row_height_chroma[k], + PixelPTEBytesPerRowY, + PixelPTEBytesPerRowC, + mode_lib->vba.dpte_row_height[k], + mode_lib->vba.dpte_row_height_chroma[k], + &mode_lib->vba.meta_row_bw[k], + &mode_lib->vba.dpte_row_bw[k], + &mode_lib->vba.qual_row_bw[k]); + } + + mode_lib->vba.TCalc = 24.0 / mode_lib->vba.DCFClkDeepSleep; + + for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { + if (mode_lib->vba.BlendingAndTiming[k] == k) { + if (mode_lib->vba.WritebackEnable[k] == true) { + mode_lib->vba.WritebackDelay[k] = mode_lib->vba.WritebackLatency + + CalculateWriteBackDelay(mode_lib->vba.WritebackPixelFormat[k], + mode_lib->vba.WritebackHRatio[k], + mode_lib->vba.WritebackVRatio[k], + mode_lib->vba.WritebackLumaHTaps[k], + mode_lib->vba.WritebackLumaVTaps[k], + mode_lib->vba.WritebackChromaHTaps[k], + mode_lib->vba.WritebackChromaVTaps[k], + mode_lib->vba.WritebackDestinationWidth[k]) + / mode_lib->vba.DISPCLK; + } else + mode_lib->vba.WritebackDelay[k] = 0; + for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) { + if (mode_lib->vba.BlendingAndTiming[j] == k && mode_lib->vba.WritebackEnable[j] == true) { + mode_lib->vba.WritebackDelay[k] = + dml_max(mode_lib->vba.WritebackDelay[k], + mode_lib->vba.WritebackLatency + + CalculateWriteBackDelay(mode_lib->vba.WritebackPixelFormat[j], + mode_lib->vba.WritebackHRatio[j], + mode_lib->vba.WritebackVRatio[j], + mode_lib->vba.WritebackLumaHTaps[j], + mode_lib->vba.WritebackLumaVTaps[j], + mode_lib->vba.WritebackChromaHTaps[j], + mode_lib->vba.WritebackChromaVTaps[j], + mode_lib->vba.WritebackDestinationWidth[j]) + / mode_lib->vba.DISPCLK); + } + } + } + } + + for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) + for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) + if (mode_lib->vba.BlendingAndTiming[k] == j) + mode_lib->vba.WritebackDelay[k] = mode_lib->vba.WritebackDelay[j]; + + mode_lib->vba.VStartupLines = 13; + for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { + mode_lib->vba.MaxVStartupLines[k] = + mode_lib->vba.VTotal[k] - mode_lib->vba.VActive[k] + - dml_max(1.0, + dml_ceil(mode_lib->vba.WritebackDelay[k] + / (mode_lib->vba.HTotal[k] + / mode_lib->vba.PixelClock[k]), + 1)); + } + + for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) + mode_lib->vba.MaximumMaxVStartupLines = dml_max(mode_lib->vba.MaximumMaxVStartupLines, mode_lib->vba.MaxVStartupLines[k]); + + for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { + mode_lib->vba.cursor_bw[k] = 0.0; + for (j = 0; j < mode_lib->vba.NumberOfCursors[k]; ++j) + mode_lib->vba.cursor_bw[k] += mode_lib->vba.CursorWidth[k][j] * mode_lib->vba.CursorBPP[k][j] / 8.0 + / (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]) * mode_lib->vba.VRatio[k]; + } + + do { + double MaxTotalRDBandwidth = 0; + bool DestinationLineTimesForPrefetchLessThan2 = false; + bool VRatioPrefetchMoreThan4 = false; + bool prefetch_vm_bw_valid = true; + bool prefetch_row_bw_valid = true; + double TWait = CalculateTWait(mode_lib->vba.PrefetchMode, + mode_lib->vba.DRAMClockChangeLatency, + mode_lib->vba.UrgentLatency, + mode_lib->vba.SREnterPlusExitTime); + + for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { + if (mode_lib->vba.XFCEnabled[k] == true) { + mode_lib->vba.XFCRemoteSurfaceFlipDelay = CalculateRemoteSurfaceFlipDelay(mode_lib, + mode_lib->vba.VRatio[k], + mode_lib->vba.SwathWidthY[k], + dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1), + mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k], + mode_lib->vba.XFCTSlvVupdateOffset, + mode_lib->vba.XFCTSlvVupdateWidth, + mode_lib->vba.XFCTSlvVreadyOffset, + mode_lib->vba.XFCXBUFLatencyTolerance, + mode_lib->vba.XFCFillBWOverhead, + mode_lib->vba.XFCSlvChunkSize, + mode_lib->vba.XFCBusTransportTime, + mode_lib->vba.TCalc, + TWait, + &mode_lib->vba.SrcActiveDrainRate, + &mode_lib->vba.TInitXFill, + &mode_lib->vba.TslvChk); + } else { + mode_lib->vba.XFCRemoteSurfaceFlipDelay = 0; + } + mode_lib->vba.ErrorResult[k] = CalculatePrefetchSchedule(mode_lib, + mode_lib->vba.DPPCLK[k], + mode_lib->vba.DISPCLK, + mode_lib->vba.PixelClock[k], + mode_lib->vba.DCFClkDeepSleep, + mode_lib->vba.DSCDelay[k], + mode_lib->vba.DPPPerPlane[k], + mode_lib->vba.ScalerEnabled[k], + mode_lib->vba.NumberOfCursors[k], + mode_lib->vba.DPPCLKDelaySubtotal, + mode_lib->vba.DPPCLKDelaySCL, + mode_lib->vba.DPPCLKDelaySCLLBOnly, + mode_lib->vba.DPPCLKDelayCNVCFormater, + mode_lib->vba.DPPCLKDelayCNVCCursor, + mode_lib->vba.DISPCLKDelaySubtotal, + (unsigned int)(mode_lib->vba.SwathWidthY[k] / mode_lib->vba.HRatio[k]), + mode_lib->vba.OutputFormat[k], + mode_lib->vba.VTotal[k] - mode_lib->vba.VActive[k], + mode_lib->vba.HTotal[k], + mode_lib->vba.MaxInterDCNTileRepeaters, + dml_min(mode_lib->vba.VStartupLines, mode_lib->vba.MaxVStartupLines[k]), + mode_lib->vba.MaxPageTableLevels, + mode_lib->vba.VirtualMemoryEnable, + mode_lib->vba.DynamicMetadataEnable[k], + mode_lib->vba.DynamicMetadataLinesBeforeActiveRequired[k], + mode_lib->vba.DynamicMetadataTransmittedBytes[k], + mode_lib->vba.DCCEnable[k], + mode_lib->vba.UrgentLatency, + mode_lib->vba.UrgentExtraLatency, + mode_lib->vba.TCalc, + mode_lib->vba.PDEAndMetaPTEBytesFrame[k], + mode_lib->vba.MetaRowByte[k], + mode_lib->vba.PixelPTEBytesPerRow[k], + mode_lib->vba.PrefetchSourceLinesY[k], + mode_lib->vba.SwathWidthY[k], + mode_lib->vba.BytePerPixelDETY[k], + mode_lib->vba.VInitPreFillY[k], + mode_lib->vba.MaxNumSwathY[k], + mode_lib->vba.PrefetchSourceLinesC[k], + mode_lib->vba.BytePerPixelDETC[k], + mode_lib->vba.VInitPreFillC[k], + mode_lib->vba.MaxNumSwathC[k], + mode_lib->vba.SwathHeightY[k], + mode_lib->vba.SwathHeightC[k], + TWait, + mode_lib->vba.XFCEnabled[k], + mode_lib->vba.XFCRemoteSurfaceFlipDelay, + mode_lib->vba.Interlace[k], + mode_lib->vba.ProgressiveToInterlaceUnitInOPP, + &mode_lib->vba.DSTXAfterScaler[k], + &mode_lib->vba.DSTYAfterScaler[k], + &mode_lib->vba.DestinationLinesForPrefetch[k], + &mode_lib->vba.PrefetchBandwidth[k], + &mode_lib->vba.DestinationLinesToRequestVMInVBlank[k], + &mode_lib->vba.DestinationLinesToRequestRowInVBlank[k], + &mode_lib->vba.VRatioPrefetchY[k], + &mode_lib->vba.VRatioPrefetchC[k], + &mode_lib->vba.RequiredPrefetchPixDataBW[k], + &mode_lib->vba.VStartupRequiredWhenNotEnoughTimeForDynamicMetadata, + &mode_lib->vba.Tno_bw[k]); + if (mode_lib->vba.BlendingAndTiming[k] == k) { + mode_lib->vba.VStartup[k] = dml_min(mode_lib->vba.VStartupLines, mode_lib->vba.MaxVStartupLines[k]); + if (mode_lib->vba.VStartupRequiredWhenNotEnoughTimeForDynamicMetadata != 0) { + mode_lib->vba.VStartup[k] = + mode_lib->vba.VStartupRequiredWhenNotEnoughTimeForDynamicMetadata; + } + } else { + mode_lib->vba.VStartup[k] = dml_min(mode_lib->vba.VStartupLines, + mode_lib->vba.MaxVStartupLines[mode_lib->vba.BlendingAndTiming[k]]); + } + } + + for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { + + if (mode_lib->vba.PDEAndMetaPTEBytesFrame[k] == 0) + mode_lib->vba.prefetch_vm_bw[k] = 0; + else if (mode_lib->vba.DestinationLinesToRequestVMInVBlank[k] > 0) { + mode_lib->vba.prefetch_vm_bw[k] = (double)mode_lib->vba.PDEAndMetaPTEBytesFrame[k] + / (mode_lib->vba.DestinationLinesToRequestVMInVBlank[k] + * mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]); + } else { + mode_lib->vba.prefetch_vm_bw[k] = 0; + prefetch_vm_bw_valid = false; + } + if (mode_lib->vba.MetaRowByte[k] + mode_lib->vba.PixelPTEBytesPerRow[k] == 0) + mode_lib->vba.prefetch_row_bw[k] = 0; + else if (mode_lib->vba.DestinationLinesToRequestRowInVBlank[k] > 0) { + mode_lib->vba.prefetch_row_bw[k] = (double)(mode_lib->vba.MetaRowByte[k] + + mode_lib->vba.PixelPTEBytesPerRow[k]) + / (mode_lib->vba.DestinationLinesToRequestRowInVBlank[k] + * mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]); + } else { + mode_lib->vba.prefetch_row_bw[k] = 0; + prefetch_row_bw_valid = false; + } + + MaxTotalRDBandwidth = + MaxTotalRDBandwidth + mode_lib->vba.cursor_bw[k] + + dml_max(mode_lib->vba.prefetch_vm_bw[k], + dml_max(mode_lib->vba.prefetch_row_bw[k], + dml_max(mode_lib->vba.ReadBandwidthPlaneLuma[k] + + mode_lib->vba.ReadBandwidthPlaneChroma[k], + mode_lib->vba.RequiredPrefetchPixDataBW[k]) + + mode_lib->vba.meta_row_bw[k] + + mode_lib->vba.dpte_row_bw[k])); + + if (mode_lib->vba.DestinationLinesForPrefetch[k] < 2) + DestinationLineTimesForPrefetchLessThan2 = true; + if (mode_lib->vba.VRatioPrefetchY[k] > 4 || mode_lib->vba.VRatioPrefetchC[k] > 4) + VRatioPrefetchMoreThan4 = true; + } + + if (MaxTotalRDBandwidth <= mode_lib->vba.ReturnBW && prefetch_vm_bw_valid && prefetch_row_bw_valid + && !VRatioPrefetchMoreThan4 + && !DestinationLineTimesForPrefetchLessThan2) + mode_lib->vba.PrefetchModeSupported = true; + else { + mode_lib->vba.PrefetchModeSupported = false; + dml_print("DML: CalculatePrefetchSchedule ***failed***. Bandwidth violation. Results are NOT valid\n"); + } + + if (mode_lib->vba.PrefetchModeSupported == true) { + double final_flip_bw[DC__NUM_PIPES__MAX]; + unsigned int ImmediateFlipBytes[DC__NUM_PIPES__MAX]; + double total_dcn_read_bw_with_flip = 0; + + mode_lib->vba.BandwidthAvailableForImmediateFlip = mode_lib->vba.ReturnBW; + for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { + mode_lib->vba.BandwidthAvailableForImmediateFlip = + mode_lib->vba.BandwidthAvailableForImmediateFlip - mode_lib->vba.cursor_bw[k] + - dml_max(mode_lib->vba.ReadBandwidthPlaneLuma[k] + + mode_lib->vba.ReadBandwidthPlaneChroma[k] + + mode_lib->vba.qual_row_bw[k], + mode_lib->vba.PrefetchBandwidth[k]); + } + + for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { + ImmediateFlipBytes[k] = 0; + if ((mode_lib->vba.SourcePixelFormat[k] != dm_420_8 + && mode_lib->vba.SourcePixelFormat[k] != dm_420_10)) { + ImmediateFlipBytes[k] = mode_lib->vba.PDEAndMetaPTEBytesFrame[k] + + mode_lib->vba.MetaRowByte[k] + + mode_lib->vba.PixelPTEBytesPerRow[k]; + } + } + mode_lib->vba.TotImmediateFlipBytes = 0; + for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { + if ((mode_lib->vba.SourcePixelFormat[k] != dm_420_8 + && mode_lib->vba.SourcePixelFormat[k] != dm_420_10)) { + mode_lib->vba.TotImmediateFlipBytes = mode_lib->vba.TotImmediateFlipBytes + + ImmediateFlipBytes[k]; + } + } + for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { + CalculateFlipSchedule(mode_lib, + mode_lib->vba.UrgentExtraLatency, + mode_lib->vba.UrgentLatency, + mode_lib->vba.MaxPageTableLevels, + mode_lib->vba.VirtualMemoryEnable, + mode_lib->vba.BandwidthAvailableForImmediateFlip, + mode_lib->vba.TotImmediateFlipBytes, + mode_lib->vba.SourcePixelFormat[k], + ImmediateFlipBytes[k], + mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k], + mode_lib->vba.VRatio[k], + mode_lib->vba.Tno_bw[k], + mode_lib->vba.PDEAndMetaPTEBytesFrame[k], + mode_lib->vba.MetaRowByte[k], + mode_lib->vba.PixelPTEBytesPerRow[k], + mode_lib->vba.DCCEnable[k], + mode_lib->vba.dpte_row_height[k], + mode_lib->vba.meta_row_height[k], + mode_lib->vba.qual_row_bw[k], + &mode_lib->vba.DestinationLinesToRequestVMInImmediateFlip[k], + &mode_lib->vba.DestinationLinesToRequestRowInImmediateFlip[k], + &final_flip_bw[k], + &mode_lib->vba.ImmediateFlipSupportedForPipe[k]); + } + for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { + total_dcn_read_bw_with_flip = + total_dcn_read_bw_with_flip + mode_lib->vba.cursor_bw[k] + + dml_max(mode_lib->vba.prefetch_vm_bw[k], + dml_max(mode_lib->vba.prefetch_row_bw[k], + final_flip_bw[k] + + dml_max(mode_lib->vba.ReadBandwidthPlaneLuma[k] + + mode_lib->vba.ReadBandwidthPlaneChroma[k], + mode_lib->vba.RequiredPrefetchPixDataBW[k]))); + } + mode_lib->vba.ImmediateFlipSupported = true; + if (total_dcn_read_bw_with_flip > mode_lib->vba.ReturnBW) { + mode_lib->vba.ImmediateFlipSupported = false; + } + for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { + if (mode_lib->vba.ImmediateFlipSupportedForPipe[k] == false) { + mode_lib->vba.ImmediateFlipSupported = false; + } + } + } else { + mode_lib->vba.ImmediateFlipSupported = false; + } + + for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { + if (mode_lib->vba.ErrorResult[k]) { + mode_lib->vba.PrefetchModeSupported = false; + dml_print("DML: CalculatePrefetchSchedule ***failed***. Prefetch schedule violation. Results are NOT valid\n"); + } + } + + mode_lib->vba.VStartupLines = mode_lib->vba.VStartupLines + 1; + } while (!((mode_lib->vba.PrefetchModeSupported + && (!mode_lib->vba.ImmediateFlipSupport || mode_lib->vba.ImmediateFlipSupported)) + || mode_lib->vba.MaximumMaxVStartupLines < mode_lib->vba.VStartupLines)); + + //Display Pipeline Delivery Time in Prefetch + for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { + if (mode_lib->vba.VRatioPrefetchY[k] <= 1) { + mode_lib->vba.DisplayPipeLineDeliveryTimeLumaPrefetch[k] = mode_lib->vba.SwathWidthY[k] + * mode_lib->vba.DPPPerPlane[k] / mode_lib->vba.HRatio[k] / mode_lib->vba.PixelClock[k]; + } else { + mode_lib->vba.DisplayPipeLineDeliveryTimeLumaPrefetch[k] = mode_lib->vba.SwathWidthY[k] + / mode_lib->vba.PSCL_THROUGHPUT_LUMA[k] / mode_lib->vba.DPPCLK[k]; + } + if (mode_lib->vba.BytePerPixelDETC[k] == 0) { + mode_lib->vba.DisplayPipeLineDeliveryTimeChromaPrefetch[k] = 0; + } else { + if (mode_lib->vba.VRatioPrefetchC[k] <= 1) { + mode_lib->vba.DisplayPipeLineDeliveryTimeChromaPrefetch[k] = + mode_lib->vba.SwathWidthY[k] * mode_lib->vba.DPPPerPlane[k] / mode_lib->vba.HRatio[k] + / mode_lib->vba.PixelClock[k]; + } else { + mode_lib->vba.DisplayPipeLineDeliveryTimeChromaPrefetch[k] = + mode_lib->vba.SwathWidthY[k] / mode_lib->vba.PSCL_THROUGHPUT_LUMA[k] + / mode_lib->vba.DPPCLK[k]; + } + } + } + + // Min TTUVBlank + for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { + if (mode_lib->vba.PrefetchMode == 0) { + mode_lib->vba.AllowDRAMClockChangeDuringVBlank[k] = true; + mode_lib->vba.AllowDRAMSelfRefreshDuringVBlank[k] = true; + mode_lib->vba.MinTTUVBlank[k] = dml_max(mode_lib->vba.DRAMClockChangeWatermark, + dml_max(mode_lib->vba.StutterEnterPlusExitWatermark, mode_lib->vba.UrgentWatermark)); + } else if (mode_lib->vba.PrefetchMode == 1) { + mode_lib->vba.AllowDRAMClockChangeDuringVBlank[k] = false; + mode_lib->vba.AllowDRAMSelfRefreshDuringVBlank[k] = true; + mode_lib->vba.MinTTUVBlank[k] = dml_max(mode_lib->vba.StutterEnterPlusExitWatermark, mode_lib->vba.UrgentWatermark); + } else { + mode_lib->vba.AllowDRAMClockChangeDuringVBlank[k] = false; + mode_lib->vba.AllowDRAMSelfRefreshDuringVBlank[k] = false; + mode_lib->vba.MinTTUVBlank[k] = mode_lib->vba.UrgentWatermark; + } + if (!mode_lib->vba.DynamicMetadataEnable[k]) + mode_lib->vba.MinTTUVBlank[k] = mode_lib->vba.TCalc + mode_lib->vba.MinTTUVBlank[k]; + } + + // DCC Configuration + mode_lib->vba.ActiveDPPs = 0; + // NB P-State/DRAM Clock Change Support + for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { + mode_lib->vba.ActiveDPPs = mode_lib->vba.ActiveDPPs + mode_lib->vba.DPPPerPlane[k]; + } + + for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { + double EffectiveLBLatencyHidingY; + double EffectiveLBLatencyHidingC; + double DPPOutputBufferLinesY; + double DPPOutputBufferLinesC; + double DPPOPPBufferingY; + double MaxDETBufferingTimeY; + double ActiveDRAMClockChangeLatencyMarginY; + + mode_lib->vba.LBLatencyHidingSourceLinesY = + dml_min(mode_lib->vba.MaxLineBufferLines, + (unsigned int)dml_floor((double)mode_lib->vba.LineBufferSize + / mode_lib->vba.LBBitPerPixel[k] + / (mode_lib->vba.SwathWidthY[k] + / dml_max(mode_lib->vba.HRatio[k], + 1.0)), + 1)) - (mode_lib->vba.vtaps[k] - 1); + + mode_lib->vba.LBLatencyHidingSourceLinesC = + dml_min(mode_lib->vba.MaxLineBufferLines, + (unsigned int)dml_floor((double)mode_lib->vba.LineBufferSize + / mode_lib->vba.LBBitPerPixel[k] + / (mode_lib->vba.SwathWidthY[k] + / 2.0 + / dml_max(mode_lib->vba.HRatio[k] + / 2, + 1.0)), + 1)) - (mode_lib->vba.VTAPsChroma[k] - 1); + + EffectiveLBLatencyHidingY = mode_lib->vba.LBLatencyHidingSourceLinesY / mode_lib->vba.VRatio[k] + * (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]); + + EffectiveLBLatencyHidingC = mode_lib->vba.LBLatencyHidingSourceLinesC / (mode_lib->vba.VRatio[k] / 2) + * (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]); + + if (mode_lib->vba.SwathWidthY[k] > 2 * mode_lib->vba.DPPOutputBufferPixels) { + DPPOutputBufferLinesY = mode_lib->vba.DPPOutputBufferPixels / mode_lib->vba.SwathWidthY[k]; + } else if (mode_lib->vba.SwathWidthY[k] > mode_lib->vba.DPPOutputBufferPixels) { + DPPOutputBufferLinesY = 0.5; + } else { + DPPOutputBufferLinesY = 1; + } + + if (mode_lib->vba.SwathWidthY[k] / 2 > 2 * mode_lib->vba.DPPOutputBufferPixels) { + DPPOutputBufferLinesC = mode_lib->vba.DPPOutputBufferPixels / (mode_lib->vba.SwathWidthY[k] / 2); + } else if (mode_lib->vba.SwathWidthY[k] / 2 > mode_lib->vba.DPPOutputBufferPixels) { + DPPOutputBufferLinesC = 0.5; + } else { + DPPOutputBufferLinesC = 1; + } + + DPPOPPBufferingY = (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]) + * (DPPOutputBufferLinesY + mode_lib->vba.OPPOutputBufferLines); + MaxDETBufferingTimeY = mode_lib->vba.FullDETBufferingTimeY[k] + + (mode_lib->vba.LinesInDETY[k] - mode_lib->vba.LinesInDETYRoundedDownToSwath[k]) + / mode_lib->vba.SwathHeightY[k] * (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]); + + ActiveDRAMClockChangeLatencyMarginY = DPPOPPBufferingY + EffectiveLBLatencyHidingY + + MaxDETBufferingTimeY - mode_lib->vba.DRAMClockChangeWatermark; + + if (mode_lib->vba.ActiveDPPs > 1) { + ActiveDRAMClockChangeLatencyMarginY = ActiveDRAMClockChangeLatencyMarginY + - (1 - 1 / (mode_lib->vba.ActiveDPPs - 1)) * mode_lib->vba.SwathHeightY[k] + * (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]); + } + + if (mode_lib->vba.BytePerPixelDETC[k] > 0) { + double DPPOPPBufferingC = (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]) + * (DPPOutputBufferLinesC + mode_lib->vba.OPPOutputBufferLines); + double MaxDETBufferingTimeC = + mode_lib->vba.FullDETBufferingTimeC[k] + + (mode_lib->vba.LinesInDETC[k] + - mode_lib->vba.LinesInDETCRoundedDownToSwath[k]) + / mode_lib->vba.SwathHeightC[k] + * (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]); + double ActiveDRAMClockChangeLatencyMarginC = DPPOPPBufferingC + + EffectiveLBLatencyHidingC + MaxDETBufferingTimeC + - mode_lib->vba.DRAMClockChangeWatermark; + + if (mode_lib->vba.ActiveDPPs > 1) { + ActiveDRAMClockChangeLatencyMarginC = + ActiveDRAMClockChangeLatencyMarginC + - (1 - 1 / (mode_lib->vba.ActiveDPPs - 1)) + * mode_lib->vba.SwathHeightC[k] + * (mode_lib->vba.HTotal[k] + / mode_lib->vba.PixelClock[k]); + } + mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k] = dml_min(ActiveDRAMClockChangeLatencyMarginY, + ActiveDRAMClockChangeLatencyMarginC); + } else { + mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k] = + ActiveDRAMClockChangeLatencyMarginY; + } + + if (mode_lib->vba.WritebackEnable[k]) { + double WritebackDRAMClockChangeLatencyMargin; + + if (mode_lib->vba.WritebackPixelFormat[k] == dm_444_32) { + WritebackDRAMClockChangeLatencyMargin = + (double)(mode_lib->vba.WritebackInterfaceLumaBufferSize + + mode_lib->vba.WritebackInterfaceChromaBufferSize) + / (mode_lib->vba.WritebackDestinationWidth[k] + * mode_lib->vba.WritebackDestinationHeight[k] + / (mode_lib->vba.WritebackSourceHeight[k] + * mode_lib->vba.HTotal[k] + / mode_lib->vba.PixelClock[k]) + * 4) + - mode_lib->vba.WritebackDRAMClockChangeWatermark; + } else if (mode_lib->vba.WritebackPixelFormat[k] == dm_420_10) { + WritebackDRAMClockChangeLatencyMargin = dml_min((double)mode_lib->vba.WritebackInterfaceLumaBufferSize * 8.0 + / 10, + 2.0 * mode_lib->vba.WritebackInterfaceChromaBufferSize * 8 / 10) + / (mode_lib->vba.WritebackDestinationWidth[k] + * mode_lib->vba.WritebackDestinationHeight[k] + / (mode_lib->vba.WritebackSourceHeight[k] + * mode_lib->vba.HTotal[k] + / mode_lib->vba.PixelClock[k])) + - mode_lib->vba.WritebackDRAMClockChangeWatermark; + } else { + WritebackDRAMClockChangeLatencyMargin = dml_min((double)mode_lib->vba.WritebackInterfaceLumaBufferSize, + 2.0 * mode_lib->vba.WritebackInterfaceChromaBufferSize) + / (mode_lib->vba.WritebackDestinationWidth[k] + * mode_lib->vba.WritebackDestinationHeight[k] + / (mode_lib->vba.WritebackSourceHeight[k] + * mode_lib->vba.HTotal[k] + / mode_lib->vba.PixelClock[k])) + - mode_lib->vba.WritebackDRAMClockChangeWatermark; + } + mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k] = dml_min(mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k], + WritebackDRAMClockChangeLatencyMargin); + } + } + + mode_lib->vba.MinActiveDRAMClockChangeMargin = 999999; + for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { + if (mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k] + < mode_lib->vba.MinActiveDRAMClockChangeMargin) { + mode_lib->vba.MinActiveDRAMClockChangeMargin = + mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k]; + } + } + + mode_lib->vba.MinActiveDRAMClockChangeLatencySupported = mode_lib->vba.MinActiveDRAMClockChangeMargin + + mode_lib->vba.DRAMClockChangeLatency; + + if (mode_lib->vba.MinActiveDRAMClockChangeMargin > 0) { + mode_lib->vba.DRAMClockChangeSupport = dm_dram_clock_change_vactive; + } else { + if (mode_lib->vba.SynchronizedVBlank || mode_lib->vba.NumberOfActivePlanes == 1) { + mode_lib->vba.DRAMClockChangeSupport = dm_dram_clock_change_vblank; + for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { + if (!mode_lib->vba.AllowDRAMClockChangeDuringVBlank[k]) { + mode_lib->vba.DRAMClockChangeSupport = dm_dram_clock_change_unsupported; + } + } + } else { + mode_lib->vba.DRAMClockChangeSupport = dm_dram_clock_change_unsupported; + } + } + + //XFC Parameters: + for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { + if (mode_lib->vba.XFCEnabled[k] == true) { + double TWait; + + mode_lib->vba.XFCSlaveVUpdateOffset[k] = mode_lib->vba.XFCTSlvVupdateOffset; + mode_lib->vba.XFCSlaveVupdateWidth[k] = mode_lib->vba.XFCTSlvVupdateWidth; + mode_lib->vba.XFCSlaveVReadyOffset[k] = mode_lib->vba.XFCTSlvVreadyOffset; + TWait = CalculateTWait(mode_lib->vba.PrefetchMode, + mode_lib->vba.DRAMClockChangeLatency, + mode_lib->vba.UrgentLatency, + mode_lib->vba.SREnterPlusExitTime); + mode_lib->vba.XFCRemoteSurfaceFlipDelay = CalculateRemoteSurfaceFlipDelay(mode_lib, + mode_lib->vba.VRatio[k], + mode_lib->vba.SwathWidthY[k], + dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1), + mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k], + mode_lib->vba.XFCTSlvVupdateOffset, + mode_lib->vba.XFCTSlvVupdateWidth, + mode_lib->vba.XFCTSlvVreadyOffset, + mode_lib->vba.XFCXBUFLatencyTolerance, + mode_lib->vba.XFCFillBWOverhead, + mode_lib->vba.XFCSlvChunkSize, + mode_lib->vba.XFCBusTransportTime, + mode_lib->vba.TCalc, + TWait, + &mode_lib->vba.SrcActiveDrainRate, + &mode_lib->vba.TInitXFill, + &mode_lib->vba.TslvChk); + mode_lib->vba.XFCRemoteSurfaceFlipLatency[k] = dml_floor(mode_lib->vba.XFCRemoteSurfaceFlipDelay / (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]), + 1); + mode_lib->vba.XFCTransferDelay[k] = dml_ceil(mode_lib->vba.XFCBusTransportTime / (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]), + 1); + mode_lib->vba.XFCPrechargeDelay[k] = dml_ceil((mode_lib->vba.XFCBusTransportTime + mode_lib->vba.TInitXFill + mode_lib->vba.TslvChk) + / (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]), + 1); + mode_lib->vba.InitFillLevel = mode_lib->vba.XFCXBUFLatencyTolerance * mode_lib->vba.SrcActiveDrainRate; + mode_lib->vba.FinalFillMargin = (mode_lib->vba.DestinationLinesToRequestVMInVBlank[k] + + mode_lib->vba.DestinationLinesToRequestRowInVBlank[k]) * mode_lib->vba.HTotal[k] + / mode_lib->vba.PixelClock[k] * mode_lib->vba.SrcActiveDrainRate + mode_lib->vba.XFCFillConstant; + mode_lib->vba.FinalFillLevel = mode_lib->vba.XFCRemoteSurfaceFlipDelay * mode_lib->vba.SrcActiveDrainRate + + mode_lib->vba.FinalFillMargin; + mode_lib->vba.RemainingFillLevel = dml_max(0.0, + mode_lib->vba.FinalFillLevel - mode_lib->vba.InitFillLevel); + mode_lib->vba.TFinalxFill = mode_lib->vba.RemainingFillLevel + / (mode_lib->vba.SrcActiveDrainRate * mode_lib->vba.XFCFillBWOverhead / 100); + mode_lib->vba.XFCPrefetchMargin[k] = mode_lib->vba.XFCRemoteSurfaceFlipDelay + mode_lib->vba.TFinalxFill + + (mode_lib->vba.DestinationLinesToRequestVMInVBlank[k] + + mode_lib->vba.DestinationLinesToRequestRowInVBlank[k]) + * mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]; + } else { + mode_lib->vba.XFCSlaveVUpdateOffset[k] = 0; + mode_lib->vba.XFCSlaveVupdateWidth[k] = 0; + mode_lib->vba.XFCSlaveVReadyOffset[k] = 0; + mode_lib->vba.XFCRemoteSurfaceFlipLatency[k] = 0; + mode_lib->vba.XFCPrechargeDelay[k] = 0; + mode_lib->vba.XFCTransferDelay[k] = 0; + mode_lib->vba.XFCPrefetchMargin[k] = 0; + } + } +} + +static void DisplayPipeConfiguration(struct display_mode_lib *mode_lib) +{ + double BytePerPixDETY; + double BytePerPixDETC; + double Read256BytesBlockHeightY; + double Read256BytesBlockHeightC; + double Read256BytesBlockWidthY; + double Read256BytesBlockWidthC; + double MaximumSwathHeightY; + double MaximumSwathHeightC; + double MinimumSwathHeightY; + double MinimumSwathHeightC; + double SwathWidth; + double SwathWidthGranularityY; + double SwathWidthGranularityC; + double RoundedUpMaxSwathSizeBytesY; + double RoundedUpMaxSwathSizeBytesC; + unsigned int j, k; + + for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { + bool MainPlaneDoesODMCombine = false; + + if (mode_lib->vba.SourcePixelFormat[k] == dm_444_64) { + BytePerPixDETY = 8; + BytePerPixDETC = 0; + } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_32) { + BytePerPixDETY = 4; + BytePerPixDETC = 0; + } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_16) { + BytePerPixDETY = 2; + BytePerPixDETC = 0; + } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_8) { + BytePerPixDETY = 1; + BytePerPixDETC = 0; + } else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8) { + BytePerPixDETY = 1; + BytePerPixDETC = 2; + } else { + BytePerPixDETY = 4.0 / 3.0; + BytePerPixDETC = 8.0 / 3.0; + } + + if ((mode_lib->vba.SourcePixelFormat[k] == dm_444_64 || mode_lib->vba.SourcePixelFormat[k] == dm_444_32 + || mode_lib->vba.SourcePixelFormat[k] == dm_444_16 + || mode_lib->vba.SourcePixelFormat[k] == dm_444_8)) { + if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear) { + Read256BytesBlockHeightY = 1; + } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_64) { + Read256BytesBlockHeightY = 4; + } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_32 + || mode_lib->vba.SourcePixelFormat[k] == dm_444_16) { + Read256BytesBlockHeightY = 8; + } else { + Read256BytesBlockHeightY = 16; + } + Read256BytesBlockWidthY = 256 / dml_ceil(BytePerPixDETY, 1) + / Read256BytesBlockHeightY; + Read256BytesBlockHeightC = 0; + Read256BytesBlockWidthC = 0; + } else { + if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear) { + Read256BytesBlockHeightY = 1; + Read256BytesBlockHeightC = 1; + } else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8) { + Read256BytesBlockHeightY = 16; + Read256BytesBlockHeightC = 8; + } else { + Read256BytesBlockHeightY = 8; + Read256BytesBlockHeightC = 8; + } + Read256BytesBlockWidthY = 256 / dml_ceil(BytePerPixDETY, 1) + / Read256BytesBlockHeightY; + Read256BytesBlockWidthC = 256 / dml_ceil(BytePerPixDETC, 2) + / Read256BytesBlockHeightC; + } + + if (mode_lib->vba.SourceScan[k] == dm_horz) { + MaximumSwathHeightY = Read256BytesBlockHeightY; + MaximumSwathHeightC = Read256BytesBlockHeightC; + } else { + MaximumSwathHeightY = Read256BytesBlockWidthY; + MaximumSwathHeightC = Read256BytesBlockWidthC; + } + + if ((mode_lib->vba.SourcePixelFormat[k] == dm_444_64 || mode_lib->vba.SourcePixelFormat[k] == dm_444_32 + || mode_lib->vba.SourcePixelFormat[k] == dm_444_16 + || mode_lib->vba.SourcePixelFormat[k] == dm_444_8)) { + if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear + || (mode_lib->vba.SourcePixelFormat[k] == dm_444_64 + && (mode_lib->vba.SurfaceTiling[k] == dm_sw_4kb_s + || mode_lib->vba.SurfaceTiling[k] + == dm_sw_4kb_s_x + || mode_lib->vba.SurfaceTiling[k] + == dm_sw_64kb_s + || mode_lib->vba.SurfaceTiling[k] + == dm_sw_64kb_s_t + || mode_lib->vba.SurfaceTiling[k] + == dm_sw_64kb_s_x + || mode_lib->vba.SurfaceTiling[k] + == dm_sw_var_s + || mode_lib->vba.SurfaceTiling[k] + == dm_sw_var_s_x) + && mode_lib->vba.SourceScan[k] == dm_horz)) { + MinimumSwathHeightY = MaximumSwathHeightY; + } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_8 && mode_lib->vba.SourceScan[k] != dm_horz) { + MinimumSwathHeightY = MaximumSwathHeightY; + } else { + MinimumSwathHeightY = MaximumSwathHeightY / 2.0; + } + MinimumSwathHeightC = MaximumSwathHeightC; + } else { + if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear) { + MinimumSwathHeightY = MaximumSwathHeightY; + MinimumSwathHeightC = MaximumSwathHeightC; + } else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8 && mode_lib->vba.SourceScan[k] == dm_horz) { + MinimumSwathHeightY = MaximumSwathHeightY / 2.0; + MinimumSwathHeightC = MaximumSwathHeightC; + } else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10 && mode_lib->vba.SourceScan[k] == dm_horz) { + MinimumSwathHeightC = MaximumSwathHeightC / 2.0; + MinimumSwathHeightY = MaximumSwathHeightY; + } else { + MinimumSwathHeightY = MaximumSwathHeightY; + MinimumSwathHeightC = MaximumSwathHeightC; + } + } + + if (mode_lib->vba.SourceScan[k] == dm_horz) { + SwathWidth = mode_lib->vba.ViewportWidth[k]; + } else { + SwathWidth = mode_lib->vba.ViewportHeight[k]; + } + + if (mode_lib->vba.ODMCombineEnabled[k] == true) { + MainPlaneDoesODMCombine = true; + } + for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) { + if (mode_lib->vba.BlendingAndTiming[k] == j && mode_lib->vba.ODMCombineEnabled[j] == true) { + MainPlaneDoesODMCombine = true; + } + } + + if (MainPlaneDoesODMCombine == true) { + SwathWidth = dml_min(SwathWidth, mode_lib->vba.HActive[k] / 2.0 * mode_lib->vba.HRatio[k]); + } else { + SwathWidth = SwathWidth / mode_lib->vba.DPPPerPlane[k]; + } + + SwathWidthGranularityY = 256 / dml_ceil(BytePerPixDETY, 1) / MaximumSwathHeightY; + RoundedUpMaxSwathSizeBytesY = (dml_ceil((double)(SwathWidth - 1), + SwathWidthGranularityY) + SwathWidthGranularityY) * BytePerPixDETY + * MaximumSwathHeightY; + if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10) { + RoundedUpMaxSwathSizeBytesY = dml_ceil(RoundedUpMaxSwathSizeBytesY, 256) + + 256; + } + if (MaximumSwathHeightC > 0) { + SwathWidthGranularityC = 256.0 / dml_ceil(BytePerPixDETC, 2) + / MaximumSwathHeightC; + RoundedUpMaxSwathSizeBytesC = (dml_ceil((double)(SwathWidth / 2.0 - 1), + SwathWidthGranularityC) + SwathWidthGranularityC) + * BytePerPixDETC * MaximumSwathHeightC; + if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10) { + RoundedUpMaxSwathSizeBytesC = dml_ceil(RoundedUpMaxSwathSizeBytesC, + 256) + 256; + } + } else + RoundedUpMaxSwathSizeBytesC = 0.0; + + if (RoundedUpMaxSwathSizeBytesY + RoundedUpMaxSwathSizeBytesC + <= mode_lib->vba.DETBufferSizeInKByte * 1024.0 / 2.0) { + mode_lib->vba.SwathHeightY[k] = MaximumSwathHeightY; + mode_lib->vba.SwathHeightC[k] = MaximumSwathHeightC; + } else { + mode_lib->vba.SwathHeightY[k] = MinimumSwathHeightY; + mode_lib->vba.SwathHeightC[k] = MinimumSwathHeightC; + } + + if (mode_lib->vba.SwathHeightC[k] == 0) { + mode_lib->vba.DETBufferSizeY[k] = mode_lib->vba.DETBufferSizeInKByte * 1024; + mode_lib->vba.DETBufferSizeC[k] = 0; + } else if (mode_lib->vba.SwathHeightY[k] <= mode_lib->vba.SwathHeightC[k]) { + mode_lib->vba.DETBufferSizeY[k] = mode_lib->vba.DETBufferSizeInKByte * 1024.0 / 2; + mode_lib->vba.DETBufferSizeC[k] = mode_lib->vba.DETBufferSizeInKByte * 1024.0 / 2; + } else { + mode_lib->vba.DETBufferSizeY[k] = mode_lib->vba.DETBufferSizeInKByte * 1024.0 * 2 / 3; + mode_lib->vba.DETBufferSizeC[k] = mode_lib->vba.DETBufferSizeInKByte * 1024.0 / 3; + } + } +} + +bool Calculate256BBlockSizes(enum source_format_class SourcePixelFormat, + enum dm_swizzle_mode SurfaceTiling, + unsigned int BytePerPixelY, + unsigned int BytePerPixelC, + unsigned int *BlockHeight256BytesY, + unsigned int *BlockHeight256BytesC, + unsigned int *BlockWidth256BytesY, + unsigned int *BlockWidth256BytesC) +{ + if ((SourcePixelFormat == dm_444_64 || SourcePixelFormat == dm_444_32 + || SourcePixelFormat == dm_444_16 || SourcePixelFormat == dm_444_16 + || SourcePixelFormat == dm_444_8)) { + if (SurfaceTiling == dm_sw_linear) { + *BlockHeight256BytesY = 1; + } else if (SourcePixelFormat == dm_444_64) { + *BlockHeight256BytesY = 4; + } else if (SourcePixelFormat == dm_444_8) { + *BlockHeight256BytesY = 16; + } else { + *BlockHeight256BytesY = 8; + } + *BlockWidth256BytesY = 256 / BytePerPixelY / *BlockHeight256BytesY; + *BlockHeight256BytesC = 0; + *BlockWidth256BytesC = 0; + } else { + if (SurfaceTiling == dm_sw_linear) { + *BlockHeight256BytesY = 1; + *BlockHeight256BytesC = 1; + } else if (SourcePixelFormat == dm_420_8) { + *BlockHeight256BytesY = 16; + *BlockHeight256BytesC = 8; + } else { + *BlockHeight256BytesY = 8; + *BlockHeight256BytesC = 8; + } + *BlockWidth256BytesY = 256 / BytePerPixelY / *BlockHeight256BytesY; + *BlockWidth256BytesC = 256 / BytePerPixelC / *BlockHeight256BytesC; + } + return true; +} + +static double CalculateTWait(unsigned int PrefetchMode, + double DRAMClockChangeLatency, + double UrgentLatency, + double SREnterPlusExitTime) +{ + if (PrefetchMode == 0) { + return dml_max(DRAMClockChangeLatency + UrgentLatency, + dml_max(SREnterPlusExitTime, UrgentLatency)); + } else if (PrefetchMode == 1) { + return dml_max(SREnterPlusExitTime, UrgentLatency); + } else { + return UrgentLatency; + } +} + +static double CalculateRemoteSurfaceFlipDelay(struct display_mode_lib *mode_lib, + double VRatio, + double SwathWidth, + double Bpp, + double LineTime, + double XFCTSlvVupdateOffset, + double XFCTSlvVupdateWidth, + double XFCTSlvVreadyOffset, + double XFCXBUFLatencyTolerance, + double XFCFillBWOverhead, + double XFCSlvChunkSize, + double XFCBusTransportTime, + double TCalc, + double TWait, + double *SrcActiveDrainRate, + double *TInitXFill, + double *TslvChk) +{ + double TSlvSetup, AvgfillRate, result; + + *SrcActiveDrainRate = VRatio * SwathWidth * Bpp / LineTime; + TSlvSetup = XFCTSlvVupdateOffset + XFCTSlvVupdateWidth + XFCTSlvVreadyOffset; + *TInitXFill = XFCXBUFLatencyTolerance / (1 + XFCFillBWOverhead / 100); + AvgfillRate = *SrcActiveDrainRate * (1 + XFCFillBWOverhead / 100); + *TslvChk = XFCSlvChunkSize / AvgfillRate; + dml_print("DML::CalculateRemoteSurfaceFlipDelay: SrcActiveDrainRate: %f\n", + *SrcActiveDrainRate); + dml_print("DML::CalculateRemoteSurfaceFlipDelay: TSlvSetup: %f\n", TSlvSetup); + dml_print("DML::CalculateRemoteSurfaceFlipDelay: TInitXFill: %f\n", *TInitXFill); + dml_print("DML::CalculateRemoteSurfaceFlipDelay: AvgfillRate: %f\n", AvgfillRate); + dml_print("DML::CalculateRemoteSurfaceFlipDelay: TslvChk: %f\n", *TslvChk); + result = 2 * XFCBusTransportTime + TSlvSetup + TCalc + TWait + *TslvChk + *TInitXFill; // TODO: This doesn't seem to match programming guide + dml_print("DML::CalculateRemoteSurfaceFlipDelay: RemoteSurfaceFlipDelay: %f\n", result); + return result; +} + +static double CalculateWriteBackDISPCLK(enum source_format_class WritebackPixelFormat, + double PixelClock, + double WritebackHRatio, + double WritebackVRatio, + unsigned int WritebackLumaHTaps, + unsigned int WritebackLumaVTaps, + unsigned int WritebackChromaHTaps, + unsigned int WritebackChromaVTaps, + double WritebackDestinationWidth, + unsigned int HTotal, + unsigned int WritebackChromaLineBufferWidth) +{ + double CalculateWriteBackDISPCLK = 1.01 * PixelClock + * dml_max( + dml_ceil(WritebackLumaHTaps / 4.0, 1) / WritebackHRatio, + dml_max( + (WritebackLumaVTaps * dml_ceil(1.0 / WritebackVRatio, 1) + * dml_ceil(WritebackDestinationWidth / 4.0, 1) + + dml_ceil(WritebackDestinationWidth / 4.0, 1)) / (double)HTotal + + dml_ceil(1.0 / WritebackVRatio, 1) * (dml_ceil(WritebackLumaVTaps / 4.0, 1) + 4.0) + / (double)HTotal, + dml_ceil(1.0 / WritebackVRatio, 1) * WritebackDestinationWidth / (double)HTotal)); + if (WritebackPixelFormat != dm_444_32) { + CalculateWriteBackDISPCLK = dml_max( + CalculateWriteBackDISPCLK, + 1.01 * PixelClock + * dml_max( + dml_ceil(WritebackChromaHTaps / 2.0, 1) / (2 * WritebackHRatio), + dml_max( + (WritebackChromaVTaps * dml_ceil(1 / (2 * WritebackVRatio), 1) + * dml_ceil(WritebackDestinationWidth / 2.0 / 2.0, 1) + + dml_ceil(WritebackDestinationWidth / 2.0 / WritebackChromaLineBufferWidth, 1)) + / HTotal + + dml_ceil(1 / (2 * WritebackVRatio), 1) + * (dml_ceil(WritebackChromaVTaps / 4.0, 1) + 4) / HTotal, + dml_ceil(1.0 / (2 * WritebackVRatio), 1) * WritebackDestinationWidth / 2.0 + / HTotal))); + } + return CalculateWriteBackDISPCLK; +} + +static double CalculateWriteBackDelay( +enum source_format_class WritebackPixelFormat, + double WritebackHRatio, + double WritebackVRatio, + unsigned int WritebackLumaHTaps, + unsigned int WritebackLumaVTaps, + unsigned int WritebackChromaHTaps, + unsigned int WritebackChromaVTaps, + unsigned int WritebackDestinationWidth) +{ + double CalculateWriteBackDelay = dml_max( + dml_ceil(WritebackLumaHTaps / 4.0, 1) / WritebackHRatio, + WritebackLumaVTaps * dml_ceil(1.0 / WritebackVRatio, 1) + * dml_ceil(WritebackDestinationWidth / 4.0, 1) + + dml_ceil(1.0 / WritebackVRatio, 1) * (dml_ceil(WritebackLumaVTaps / 4.0, 1) + 4)); + + if (WritebackPixelFormat != dm_444_32) { + CalculateWriteBackDelay = dml_max( + CalculateWriteBackDelay, + dml_max( + dml_ceil(WritebackChromaHTaps / 2.0, 1) / (2 * WritebackHRatio), + WritebackChromaVTaps * dml_ceil(1 / (2 * WritebackVRatio), 1) + * dml_ceil(WritebackDestinationWidth / 2.0 / 2.0, 1) + + dml_ceil(1 / (2 * WritebackVRatio), 1) + * (dml_ceil(WritebackChromaVTaps / 4.0, 1) + 4))); + } + return CalculateWriteBackDelay; +} + +static void CalculateActiveRowBandwidth(bool VirtualMemoryEnable, + enum source_format_class SourcePixelFormat, + double VRatio, + bool DCCEnable, + double LineTime, + unsigned int MetaRowByteLuma, + unsigned int MetaRowByteChroma, + unsigned int meta_row_height_luma, + unsigned int meta_row_height_chroma, + unsigned int PixelPTEBytesPerRowLuma, + unsigned int PixelPTEBytesPerRowChroma, + unsigned int dpte_row_height_luma, + unsigned int dpte_row_height_chroma, + double *meta_row_bw, + double *dpte_row_bw, + double *qual_row_bw) +{ + if (DCCEnable != true) { + *meta_row_bw = 0; + } else if (SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10) { + *meta_row_bw = VRatio * MetaRowByteLuma / (meta_row_height_luma * LineTime) + + VRatio / 2 * MetaRowByteChroma + / (meta_row_height_chroma * LineTime); + } else { + *meta_row_bw = VRatio * MetaRowByteLuma / (meta_row_height_luma * LineTime); + } + + if (VirtualMemoryEnable != true) { + *dpte_row_bw = 0; + } else if (SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10) { + *dpte_row_bw = VRatio * PixelPTEBytesPerRowLuma / (dpte_row_height_luma * LineTime) + + VRatio / 2 * PixelPTEBytesPerRowChroma + / (dpte_row_height_chroma * LineTime); + } else { + *dpte_row_bw = VRatio * PixelPTEBytesPerRowLuma / (dpte_row_height_luma * LineTime); + } + + if ((SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10)) { + *qual_row_bw = *meta_row_bw + *dpte_row_bw; + } else { + *qual_row_bw = 0; + } +} + +static void CalculateFlipSchedule(struct display_mode_lib *mode_lib, + double UrgentExtraLatency, + double UrgentLatency, + unsigned int MaxPageTableLevels, + bool VirtualMemoryEnable, + double BandwidthAvailableForImmediateFlip, + unsigned int TotImmediateFlipBytes, + enum source_format_class SourcePixelFormat, + unsigned int ImmediateFlipBytes, + double LineTime, + double Tno_bw, + double VRatio, + double PDEAndMetaPTEBytesFrame, + unsigned int MetaRowByte, + unsigned int PixelPTEBytesPerRow, + bool DCCEnable, + unsigned int dpte_row_height, + unsigned int meta_row_height, + double qual_row_bw, + double *DestinationLinesToRequestVMInImmediateFlip, + double *DestinationLinesToRequestRowInImmediateFlip, + double *final_flip_bw, + bool *ImmediateFlipSupportedForPipe) +{ + double min_row_time = 0.0; + + if (SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10) { + *DestinationLinesToRequestVMInImmediateFlip = 0.0; + *DestinationLinesToRequestRowInImmediateFlip = 0.0; + *final_flip_bw = qual_row_bw; + *ImmediateFlipSupportedForPipe = true; + } else { + double TimeForFetchingMetaPTEImmediateFlip; + double TimeForFetchingRowInVBlankImmediateFlip; + + if (VirtualMemoryEnable == true) { + mode_lib->vba.ImmediateFlipBW = BandwidthAvailableForImmediateFlip * ImmediateFlipBytes + / TotImmediateFlipBytes; + TimeForFetchingMetaPTEImmediateFlip = + dml_max(Tno_bw + + PDEAndMetaPTEBytesFrame + / mode_lib->vba.ImmediateFlipBW, + dml_max(UrgentExtraLatency + + UrgentLatency + * (MaxPageTableLevels + - 1), + LineTime / 4.0)); + } else { + TimeForFetchingMetaPTEImmediateFlip = 0; + } + + *DestinationLinesToRequestVMInImmediateFlip = dml_floor(4.0 * (TimeForFetchingMetaPTEImmediateFlip / LineTime + 0.125), + 1) / 4.0; + + if ((VirtualMemoryEnable == true || DCCEnable == true)) { + mode_lib->vba.ImmediateFlipBW = BandwidthAvailableForImmediateFlip * ImmediateFlipBytes + / TotImmediateFlipBytes; + TimeForFetchingRowInVBlankImmediateFlip = dml_max((MetaRowByte + PixelPTEBytesPerRow) / mode_lib->vba.ImmediateFlipBW, + dml_max(UrgentLatency, LineTime / 4.0)); + } else { + TimeForFetchingRowInVBlankImmediateFlip = 0; + } + + *DestinationLinesToRequestRowInImmediateFlip = dml_floor(4.0 * (TimeForFetchingRowInVBlankImmediateFlip / LineTime + 0.125), + 1) / 4.0; + + if (VirtualMemoryEnable == true) { + *final_flip_bw = + dml_max(PDEAndMetaPTEBytesFrame + / (*DestinationLinesToRequestVMInImmediateFlip + * LineTime), + (MetaRowByte + PixelPTEBytesPerRow) + / (TimeForFetchingRowInVBlankImmediateFlip + * LineTime)); + } else if (MetaRowByte + PixelPTEBytesPerRow > 0) { + *final_flip_bw = (MetaRowByte + PixelPTEBytesPerRow) + / (TimeForFetchingRowInVBlankImmediateFlip * LineTime); + } else { + *final_flip_bw = 0; + } + + if (VirtualMemoryEnable && !DCCEnable) + min_row_time = dpte_row_height * LineTime / VRatio; + else if (!VirtualMemoryEnable && DCCEnable) + min_row_time = meta_row_height * LineTime / VRatio; + else + min_row_time = dml_min(dpte_row_height, meta_row_height) * LineTime + / VRatio; + + if (*DestinationLinesToRequestVMInImmediateFlip >= 8 + || *DestinationLinesToRequestRowInImmediateFlip >= 16 + || TimeForFetchingMetaPTEImmediateFlip + + 2 * TimeForFetchingRowInVBlankImmediateFlip > min_row_time) + *ImmediateFlipSupportedForPipe = false; + else + *ImmediateFlipSupportedForPipe = true; + } +} + +static void PixelClockAdjustmentForProgressiveToInterlaceUnit(struct display_mode_lib *mode_lib) +{ + unsigned int k; + + //Progressive To dml_ml->vba.Interlace Unit Effect + for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { + mode_lib->vba.PixelClockBackEnd[k] = mode_lib->vba.PixelClock[k]; + if (mode_lib->vba.Interlace[k] == 1 && mode_lib->vba.ProgressiveToInterlaceUnitInOPP == true) { + mode_lib->vba.PixelClock[k] = 2 * mode_lib->vba.PixelClock[k]; + } + } +} + +static unsigned int CursorBppEnumToBits(enum cursor_bpp ebpp) +{ + switch (ebpp) { + case dm_cur_2bit: + return 2; + case dm_cur_32bit: + return 32; + case dm_cur_64bit: + return 64; + default: + return 0; + } +} diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h new file mode 100644 index 0000000000000..a24fe9a0383db --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h @@ -0,0 +1,410 @@ +/* + * display_mode_vba.h + * + * Created on: Aug 18, 2017 + * Author: dlaktyus + */ + +#ifndef __DML2_DISPLAY_MODE_VBA_H__ +#define __DML2_DISPLAY_MODE_VBA_H__ + +#include "dml_common_defs.h" + +struct display_mode_lib; + +void set_prefetch_mode(struct display_mode_lib *mode_lib, + bool cstate_en, + bool pstate_en, + bool ignore_viewport_pos, + bool immediate_flip_support); + +#define dml_get_attr_decl(attr) double get_##attr(struct display_mode_lib *mode_lib, const display_e2e_pipe_params_st *pipes, unsigned int num_pipes) + +dml_get_attr_decl(clk_dcf_deepsleep); +dml_get_attr_decl(wm_urgent); +dml_get_attr_decl(wm_memory_trip); +dml_get_attr_decl(wm_writeback_urgent); +dml_get_attr_decl(wm_stutter_exit); +dml_get_attr_decl(wm_stutter_enter_exit); +dml_get_attr_decl(wm_dram_clock_change); +dml_get_attr_decl(wm_writeback_dram_clock_change); +dml_get_attr_decl(wm_xfc_underflow); +dml_get_attr_decl(stutter_efficiency_no_vblank); +dml_get_attr_decl(stutter_efficiency); +dml_get_attr_decl(urgent_latency); +dml_get_attr_decl(urgent_extra_latency); +dml_get_attr_decl(nonurgent_latency); +dml_get_attr_decl(dram_clock_change_latency); +dml_get_attr_decl(dispclk_calculated); +dml_get_attr_decl(total_data_read_bw); +dml_get_attr_decl(return_bw); +dml_get_attr_decl(tcalc); + +#define dml_get_pipe_attr_decl(attr) double get_##attr(struct display_mode_lib *mode_lib, const display_e2e_pipe_params_st *pipes, unsigned int num_pipes, unsigned int which_pipe) + +dml_get_pipe_attr_decl(dsc_delay); +dml_get_pipe_attr_decl(dppclk_calculated); +dml_get_pipe_attr_decl(dscclk_calculated); +dml_get_pipe_attr_decl(min_ttu_vblank); +dml_get_pipe_attr_decl(vratio_prefetch_l); +dml_get_pipe_attr_decl(vratio_prefetch_c); +dml_get_pipe_attr_decl(dst_x_after_scaler); +dml_get_pipe_attr_decl(dst_y_after_scaler); +dml_get_pipe_attr_decl(dst_y_per_vm_vblank); +dml_get_pipe_attr_decl(dst_y_per_row_vblank); +dml_get_pipe_attr_decl(dst_y_prefetch); +dml_get_pipe_attr_decl(dst_y_per_vm_flip); +dml_get_pipe_attr_decl(dst_y_per_row_flip); +dml_get_pipe_attr_decl(xfc_transfer_delay); +dml_get_pipe_attr_decl(xfc_precharge_delay); +dml_get_pipe_attr_decl(xfc_remote_surface_flip_latency); +dml_get_pipe_attr_decl(xfc_prefetch_margin); + +unsigned int get_vstartup_calculated( + struct display_mode_lib *mode_lib, + const display_e2e_pipe_params_st *pipes, + unsigned int num_pipes, + unsigned int which_pipe); + +double get_total_immediate_flip_bytes( + struct display_mode_lib *mode_lib, + const display_e2e_pipe_params_st *pipes, + unsigned int num_pipes); +double get_total_immediate_flip_bw( + struct display_mode_lib *mode_lib, + const display_e2e_pipe_params_st *pipes, + unsigned int num_pipes); +double get_total_prefetch_bw( + struct display_mode_lib *mode_lib, + const display_e2e_pipe_params_st *pipes, + unsigned int num_pipes); + +bool Calculate256BBlockSizes( + enum source_format_class SourcePixelFormat, + enum dm_swizzle_mode SurfaceTiling, + unsigned int BytePerPixelY, + unsigned int BytePerPixelC, + unsigned int *BlockHeight256BytesY, + unsigned int *BlockHeight256BytesC, + unsigned int *BlockWidth256BytesY, + unsigned int *BlockWidth256BytesC); + + +struct vba_vars_st { + ip_params_st ip; + soc_bounding_box_st soc; + mode_evaluation_st me; + + unsigned int MaximumMaxVStartupLines; + double cursor_bw[DC__NUM_PIPES__MAX]; + double meta_row_bw[DC__NUM_PIPES__MAX]; + double dpte_row_bw[DC__NUM_PIPES__MAX]; + double qual_row_bw[DC__NUM_PIPES__MAX]; + double WritebackDISPCLK; + double PSCL_THROUGHPUT_LUMA[DC__NUM_PIPES__MAX]; + double PSCL_THROUGHPUT_CHROMA[DC__NUM_PIPES__MAX]; + double DPPCLKUsingSingleDPPLuma; + double DPPCLKUsingSingleDPPChroma; + double DPPCLKUsingSingleDPP[DC__NUM_PIPES__MAX]; + double DISPCLKWithRamping; + double DISPCLKWithoutRamping; + double GlobalDPPCLK; + double MaxDispclk; + double DISPCLKWithRampingRoundedToDFSGranularity; + double DISPCLKWithoutRampingRoundedToDFSGranularity; + double MaxDispclkRoundedToDFSGranularity; + bool DCCEnabledAnyPlane; + double ReturnBandwidthToDCN; + unsigned int SwathWidthY[DC__NUM_PIPES__MAX]; + unsigned int SwathWidthSingleDPPY[DC__NUM_PIPES__MAX]; + double BytePerPixelDETY[DC__NUM_PIPES__MAX]; + double BytePerPixelDETC[DC__NUM_PIPES__MAX]; + double ReadBandwidthPlaneLuma[DC__NUM_PIPES__MAX]; + double ReadBandwidthPlaneChroma[DC__NUM_PIPES__MAX]; + unsigned int TotalActiveDPP; + unsigned int TotalDCCActiveDPP; + double UrgentRoundTripAndOutOfOrderLatency; + double DisplayPipeLineDeliveryTimeLuma[DC__NUM_PIPES__MAX]; // WM + double DisplayPipeLineDeliveryTimeChroma[DC__NUM_PIPES__MAX]; // WM + double LinesInDETY[DC__NUM_PIPES__MAX]; // WM + double LinesInDETC[DC__NUM_PIPES__MAX]; // WM + unsigned int LinesInDETYRoundedDownToSwath[DC__NUM_PIPES__MAX]; // WM + unsigned int LinesInDETCRoundedDownToSwath[DC__NUM_PIPES__MAX]; // WM + double FullDETBufferingTimeY[DC__NUM_PIPES__MAX]; // WM + double FullDETBufferingTimeC[DC__NUM_PIPES__MAX]; // WM + double MinFullDETBufferingTime; + double FrameTimeForMinFullDETBufferingTime; + double AverageReadBandwidthGBytePerSecond; + double PartOfBurstThatFitsInROB; + double StutterBurstTime; + //unsigned int NextPrefetchMode; + double VBlankTime; + double SmallestVBlank; + double DCFCLKDeepSleepPerPlane; + double EffectiveDETPlusLBLinesLuma; + double EffectiveDETPlusLBLinesChroma; + double UrgentLatencySupportUsLuma; + double UrgentLatencySupportUsChroma; + double UrgentLatencySupportUs[DC__NUM_PIPES__MAX]; + unsigned int DSCFormatFactor; + unsigned int BlockHeight256BytesY[DC__NUM_PIPES__MAX]; + unsigned int BlockHeight256BytesC[DC__NUM_PIPES__MAX]; + unsigned int BlockWidth256BytesY[DC__NUM_PIPES__MAX]; + unsigned int BlockWidth256BytesC[DC__NUM_PIPES__MAX]; + double VInitPreFillY[DC__NUM_PIPES__MAX]; + double VInitPreFillC[DC__NUM_PIPES__MAX]; + unsigned int MaxNumSwathY[DC__NUM_PIPES__MAX]; + unsigned int MaxNumSwathC[DC__NUM_PIPES__MAX]; + double PrefetchSourceLinesY[DC__NUM_PIPES__MAX]; + double PrefetchSourceLinesC[DC__NUM_PIPES__MAX]; + double PixelPTEBytesPerRow[DC__NUM_PIPES__MAX]; + double MetaRowByte[DC__NUM_PIPES__MAX]; + bool PTEBufferSizeNotExceeded; // not used + unsigned int dpte_row_height[DC__NUM_PIPES__MAX]; + unsigned int dpte_row_height_chroma[DC__NUM_PIPES__MAX]; + unsigned int meta_row_height[DC__NUM_PIPES__MAX]; + unsigned int meta_row_height_chroma[DC__NUM_PIPES__MAX]; + + unsigned int MacroTileWidthY; + unsigned int MacroTileWidthC; + unsigned int MaxVStartupLines[DC__NUM_PIPES__MAX]; + double WritebackDelay[DC__NUM_PIPES__MAX]; + bool PrefetchModeSupported; + bool AllowDRAMClockChangeDuringVBlank[DC__NUM_PIPES__MAX]; + bool AllowDRAMSelfRefreshDuringVBlank[DC__NUM_PIPES__MAX]; + double RequiredPrefetchPixDataBW[DC__NUM_PIPES__MAX]; + double XFCRemoteSurfaceFlipDelay; + double TInitXFill; + double TslvChk; + double SrcActiveDrainRate; + double Tno_bw[DC__NUM_PIPES__MAX]; + bool ImmediateFlipSupported; + + double prefetch_vm_bw[DC__NUM_PIPES__MAX]; + double prefetch_row_bw[DC__NUM_PIPES__MAX]; + bool ImmediateFlipSupportedForPipe[DC__NUM_PIPES__MAX]; + unsigned int VStartupLines; + double DisplayPipeLineDeliveryTimeLumaPrefetch[DC__NUM_PIPES__MAX]; + double DisplayPipeLineDeliveryTimeChromaPrefetch[DC__NUM_PIPES__MAX]; + unsigned int ActiveDPPs; + unsigned int LBLatencyHidingSourceLinesY; + unsigned int LBLatencyHidingSourceLinesC; + double ActiveDRAMClockChangeLatencyMargin[DC__NUM_PIPES__MAX]; + double MinActiveDRAMClockChangeMargin; + double XFCSlaveVUpdateOffset[DC__NUM_PIPES__MAX]; + double XFCSlaveVupdateWidth[DC__NUM_PIPES__MAX]; + double XFCSlaveVReadyOffset[DC__NUM_PIPES__MAX]; + double InitFillLevel; + double FinalFillMargin; + double FinalFillLevel; + double RemainingFillLevel; + double TFinalxFill; + + + // + // SOC Bounding Box Parameters + // + double SRExitTime; + double SREnterPlusExitTime; + double UrgentLatency; + double WritebackLatency; + double PercentOfIdealDRAMAndFabricBWReceivedAfterUrgLatency; + double NumberOfChannels; + double DRAMChannelWidth; + double FabricDatapathToDCNDataReturn; + double ReturnBusWidth; + double Downspreading; + double DISPCLKDPPCLKDSCCLKDownSpreading; + double DISPCLKDPPCLKVCOSpeed; + double RoundTripPingLatencyCycles; + double UrgentOutOfOrderReturnPerChannel; + unsigned int VMMPageSize; + double DRAMClockChangeLatency; + double XFCBusTransportTime; + double XFCXBUFLatencyTolerance; + + // + // IP Parameters + // + unsigned int ROBBufferSizeInKByte; + double DETBufferSizeInKByte; + unsigned int DPPOutputBufferPixels; + unsigned int OPPOutputBufferLines; + unsigned int PixelChunkSizeInKByte; + double ReturnBW; + bool VirtualMemoryEnable; + unsigned int MaxPageTableLevels; + unsigned int OverridePageTableLevels; + unsigned int PTEChunkSize; + unsigned int MetaChunkSize; + unsigned int WritebackChunkSize; + bool ODMCapability; + unsigned int NumberOfDSC; + unsigned int LineBufferSize; + unsigned int MaxLineBufferLines; + unsigned int WritebackInterfaceLumaBufferSize; + unsigned int WritebackInterfaceChromaBufferSize; + unsigned int WritebackChromaLineBufferWidth; + double MaxDCHUBToPSCLThroughput; + double MaxPSCLToLBThroughput; + unsigned int PTEBufferSizeInRequests; + double DISPCLKRampingMargin; + unsigned int MaxInterDCNTileRepeaters; + bool XFCSupported; + double XFCSlvChunkSize; + double XFCFillBWOverhead; + double XFCFillConstant; + double XFCTSlvVupdateOffset; + double XFCTSlvVupdateWidth; + double XFCTSlvVreadyOffset; + double DPPCLKDelaySubtotal; + double DPPCLKDelaySCL; + double DPPCLKDelaySCLLBOnly; + double DPPCLKDelayCNVCFormater; + double DPPCLKDelayCNVCCursor; + double DISPCLKDelaySubtotal; + bool ProgressiveToInterlaceUnitInOPP; + unsigned int PDEProcessingBufIn64KBReqs; + + // Pipe/Plane Parameters + int VoltageLevel; + double FabricAndDRAMBandwidth; + double FabricClock; + double DRAMSpeed; + double DISPCLK; + double SOCCLK; + double DCFCLK; + + unsigned int NumberOfActivePlanes; + unsigned int ViewportWidth[DC__NUM_DPP]; + unsigned int ViewportHeight[DC__NUM_DPP]; + unsigned int ViewportYStartY[DC__NUM_DPP]; + unsigned int ViewportYStartC[DC__NUM_DPP]; + unsigned int PitchY[DC__NUM_DPP]; + unsigned int PitchC[DC__NUM_DPP]; + double HRatio[DC__NUM_DPP]; + double VRatio[DC__NUM_DPP]; + unsigned int htaps[DC__NUM_DPP]; + unsigned int vtaps[DC__NUM_DPP]; + unsigned int HTAPsChroma[DC__NUM_DPP]; + unsigned int VTAPsChroma[DC__NUM_DPP]; + unsigned int HTotal[DC__NUM_DPP]; + unsigned int VTotal[DC__NUM_DPP]; + unsigned int DPPPerPlane[DC__NUM_DPP]; + double PixelClock[DC__NUM_DPP]; + double PixelClockBackEnd[DC__NUM_DPP]; + double DPPCLK[DC__NUM_DPP]; + bool DCCEnable[DC__NUM_DPP]; + unsigned int DCCMetaPitchY[DC__NUM_DPP]; + enum scan_direction_class SourceScan[DC__NUM_DPP]; + enum source_format_class SourcePixelFormat[DC__NUM_DPP]; + bool WritebackEnable[DC__NUM_DPP]; + double WritebackDestinationWidth[DC__NUM_DPP]; + double WritebackDestinationHeight[DC__NUM_DPP]; + double WritebackSourceHeight[DC__NUM_DPP]; + enum source_format_class WritebackPixelFormat[DC__NUM_DPP]; + unsigned int WritebackLumaHTaps[DC__NUM_DPP]; + unsigned int WritebackLumaVTaps[DC__NUM_DPP]; + unsigned int WritebackChromaHTaps[DC__NUM_DPP]; + unsigned int WritebackChromaVTaps[DC__NUM_DPP]; + double WritebackHRatio[DC__NUM_DPP]; + double WritebackVRatio[DC__NUM_DPP]; + unsigned int HActive[DC__NUM_DPP]; + unsigned int VActive[DC__NUM_DPP]; + bool Interlace[DC__NUM_DPP]; + enum dm_swizzle_mode SurfaceTiling[DC__NUM_DPP]; + unsigned int ScalerRecoutWidth[DC__NUM_DPP]; + bool DynamicMetadataEnable[DC__NUM_DPP]; + unsigned int DynamicMetadataLinesBeforeActiveRequired[DC__NUM_DPP]; + unsigned int DynamicMetadataTransmittedBytes[DC__NUM_DPP]; + double DCCRate[DC__NUM_DPP]; + bool ODMCombineEnabled[DC__NUM_DPP]; + double OutputBpp[DC__NUM_DPP]; + unsigned int NumberOfDSCSlices[DC__NUM_DPP]; + bool DSCEnabled[DC__NUM_DPP]; + unsigned int DSCDelay[DC__NUM_DPP]; + unsigned int DSCInputBitPerComponent[DC__NUM_DPP]; + enum output_format_class OutputFormat[DC__NUM_DPP]; + enum output_encoder_class Output[DC__NUM_DPP]; + unsigned int BlendingAndTiming[DC__NUM_DPP]; + bool SynchronizedVBlank; + unsigned int NumberOfCursors[DC__NUM_DPP]; + unsigned int CursorWidth[DC__NUM_DPP][DC__NUM_CURSOR]; + unsigned int CursorBPP[DC__NUM_DPP][DC__NUM_CURSOR]; + bool XFCEnabled[DC__NUM_DPP]; + bool ScalerEnabled[DC__NUM_DPP]; + + // Intermediates/Informational + bool ImmediateFlipSupport; + unsigned int SwathHeightY[DC__NUM_DPP]; + unsigned int SwathHeightC[DC__NUM_DPP]; + unsigned int DETBufferSizeY[DC__NUM_DPP]; + unsigned int DETBufferSizeC[DC__NUM_DPP]; + unsigned int LBBitPerPixel[DC__NUM_DPP]; + double LastPixelOfLineExtraWatermark; + double TotalDataReadBandwidth; + unsigned int TotalActiveWriteback; + unsigned int EffectiveLBLatencyHidingSourceLinesLuma; + unsigned int EffectiveLBLatencyHidingSourceLinesChroma; + double BandwidthAvailableForImmediateFlip; + unsigned int PrefetchMode; + bool IgnoreViewportPositioning; + double PrefetchBandwidth[DC__NUM_DPP]; + bool ErrorResult[DC__NUM_DPP]; + double PDEAndMetaPTEBytesFrame[DC__NUM_DPP]; + + // + // Calculated dml_ml->vba.Outputs + // + double DCFClkDeepSleep; + double UrgentWatermark; + double UrgentExtraLatency; + double MemoryTripWatermark; + double WritebackUrgentWatermark; + double StutterExitWatermark; + double StutterEnterPlusExitWatermark; + double DRAMClockChangeWatermark; + double WritebackDRAMClockChangeWatermark; + double StutterEfficiency; + double StutterEfficiencyNotIncludingVBlank; + double MinUrgentLatencySupportUs; + double NonUrgentLatencyTolerance; + double MinActiveDRAMClockChangeLatencySupported; + enum clock_change_support DRAMClockChangeSupport; + + // These are the clocks calcuated by the library but they are not actually + // used explicitly. They are fetched by tests and then possibly used. The + // ultimate values to use are the ones specified by the parameters to DML + double DISPCLK_calculated; + double DSCCLK_calculated[DC__NUM_DPP]; + double DPPCLK_calculated[DC__NUM_DPP]; + + unsigned int VStartup[DC__NUM_DPP]; + unsigned int VStartupRequiredWhenNotEnoughTimeForDynamicMetadata; + + double ImmediateFlipBW; + unsigned int TotImmediateFlipBytes; + double TCalc; + double MinTTUVBlank[DC__NUM_DPP]; + double VRatioPrefetchY[DC__NUM_DPP]; + double VRatioPrefetchC[DC__NUM_DPP]; + double DSTXAfterScaler[DC__NUM_DPP]; + double DSTYAfterScaler[DC__NUM_DPP]; + + double DestinationLinesToRequestVMInVBlank[DC__NUM_DPP]; + double DestinationLinesToRequestRowInVBlank[DC__NUM_DPP]; + double DestinationLinesForPrefetch[DC__NUM_DPP]; + double DestinationLinesToRequestRowInImmediateFlip[DC__NUM_DPP]; + double DestinationLinesToRequestVMInImmediateFlip[DC__NUM_DPP]; + + double XFCTransferDelay[DC__NUM_DPP]; + double XFCPrechargeDelay[DC__NUM_DPP]; + double XFCRemoteSurfaceFlipLatency[DC__NUM_DPP]; + double XFCPrefetchMargin[DC__NUM_DPP]; + + display_e2e_pipe_params_st cache_pipes[DC__NUM_DPP]; + unsigned int cache_num_pipes; + unsigned int pipe_plane[DC__NUM_PIPES__MAX]; +}; + +#endif /* _DML2_DISPLAY_MODE_VBA_H_ */ diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_pipe_clocks.c b/drivers/gpu/drm/amd/display/dc/dml/display_pipe_clocks.c index 2e4dc57cafa09..30c379d951569 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_pipe_clocks.c +++ b/drivers/gpu/drm/amd/display/dc/dml/display_pipe_clocks.c @@ -27,340 +27,79 @@ #include "display_mode_lib.h" #include "soc_bounding_box.h" -static enum voltage_state power_state( +display_pipe_clock_st dml_clks_get_pipe_clocks( struct display_mode_lib *mode_lib, - double dispclk, - double dppclk) -{ - enum voltage_state state1; - enum voltage_state state2; - - if (dispclk <= mode_lib->soc.vmin.dispclk_mhz) - state1 = dm_vmin; - else if (dispclk <= mode_lib->soc.vnom.dispclk_mhz) - state1 = dm_vnom; - else if (dispclk <= mode_lib->soc.vmax.dispclk_mhz) - state1 = dm_vmax; - else - state1 = dm_vmax_exceeded; - - if (dppclk <= mode_lib->soc.vmin.dppclk_mhz) - state2 = dm_vmin; - else if (dppclk <= mode_lib->soc.vnom.dppclk_mhz) - state2 = dm_vnom; - else if (dppclk <= mode_lib->soc.vmax.dppclk_mhz) - state2 = dm_vmax; - else - state2 = dm_vmax_exceeded; - - if (state1 > state2) - return state1; - else - return state2; -} - -static unsigned int dpp_in_grp( - struct _vcs_dpi_display_e2e_pipe_params_st *e2e, - unsigned int num_pipes, - unsigned int hsplit_grp) -{ - unsigned int num_dpp = 0; - unsigned int i; - - for (i = 0; i < num_pipes; i++) { - if (e2e[i].pipe.src.is_hsplit) { - if (e2e[i].pipe.src.hsplit_grp == hsplit_grp) { - num_dpp++; - } - } - } - - if (0 == num_dpp) - num_dpp = 1; - - return num_dpp; -} - -static void calculate_pipe_clk_requirement( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_display_e2e_pipe_params_st *e2e, - unsigned int num_dpp_in_grp, - double *dppclk, - double *dispclk, - bool *dppdiv) -{ - double pscl_throughput = 0.0; - double max_hratio = e2e->pipe.scale_ratio_depth.hscl_ratio; - double max_vratio = e2e->pipe.scale_ratio_depth.vscl_ratio; - double max_htaps = e2e->pipe.scale_taps.htaps; - double max_vtaps = e2e->pipe.scale_taps.vtaps; - double dpp_clock_divider = (double) num_dpp_in_grp; - double dispclk_dppclk_ratio; - double dispclk_ramp_margin_percent; - - if (max_hratio > 1.0) { - double pscl_to_lb = ((double) mode_lib->ip.max_pscl_lb_bw_pix_per_clk * max_hratio) - / dml_ceil(max_htaps / 6.0); - pscl_throughput = dml_min( - pscl_to_lb, - (double) mode_lib->ip.max_dchub_pscl_bw_pix_per_clk); - } else { - pscl_throughput = dml_min( - (double) mode_lib->ip.max_pscl_lb_bw_pix_per_clk, - (double) mode_lib->ip.max_dchub_pscl_bw_pix_per_clk); - } - - DTRACE("pscl_throughput: %f pix per clk", pscl_throughput); - DTRACE("vtaps: %f hratio: %f vratio: %f", max_vtaps, max_hratio, max_vratio); - *dppclk = dml_max( - max_vtaps / 6.0 * dml_min(1.0, max_hratio), - max_hratio * max_vratio / pscl_throughput); - DTRACE("pixel rate multiplier: %f", *dppclk); - *dppclk = dml_max(*dppclk, 1.0); - DTRACE("pixel rate multiplier clamped: %f", *dppclk); - *dppclk = *dppclk * e2e->pipe.dest.pixel_rate_mhz; - - *dppclk = *dppclk / dpp_clock_divider; - DTRACE("dppclk after split: %f", *dppclk); - - if (dpp_clock_divider > 1.0 && (*dppclk < e2e->pipe.dest.pixel_rate_mhz)) { - dispclk_dppclk_ratio = 2.0; - *dppdiv = true; - } else { - dispclk_dppclk_ratio = 1.0; - *dppdiv = false; - } - - dispclk_ramp_margin_percent = mode_lib->ip.dispclk_ramp_margin_percent; - - /* Comment this out because of Gabes possible bug in spreadsheet, - * just to make other cases evident during debug - * - *if(e2e->clks_cfg.voltage == dm_vmax) - * dispclk_ramp_margin_percent = 0.0; - */ - - /* account for ramping margin and downspread */ - *dispclk = dml_max(*dppclk * dispclk_dppclk_ratio, e2e->pipe.dest.pixel_rate_mhz) - * (1.0 + (double) mode_lib->soc.downspread_percent / 100.0) - * (1.0 + (double) dispclk_ramp_margin_percent / 100.0); - - return; -} - -bool dml_clks_pipe_clock_requirement_fit_power_constraint( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_display_e2e_pipe_params_st *e2e, - unsigned int num_dpp_in_grp) -{ - double dppclk = 0; - double dispclk = 0; - bool dppdiv = 0; - - calculate_pipe_clk_requirement(mode_lib, e2e, num_dpp_in_grp, &dppclk, &dispclk, &dppdiv); - - if (power_state(mode_lib, dispclk, dppclk) > e2e->clks_cfg.voltage) { - return false; - } - - return true; -} - -static void get_plane_clks( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_display_e2e_pipe_params_st *e2e, - unsigned int num_pipes, - double *dppclks, - double *dispclks, - bool *dppdiv) -{ - /* it is assumed that the scale ratios passed into the e2e pipe params have already been calculated - * for any split pipe configurations, where extra pixels inthe overlap region do not contribute to - * the scale ratio. This means that we can simply calculate the dppclk for each dpp independently - * and we would expect the same result on any split pipes, which would be handled - */ - unsigned int i; - - for (i = 0; i < num_pipes; i++) { - double num_dpp_in_grp; - double dispclk_ramp_margin_percent; - double dispclk_margined; - - if (e2e[i].pipe.src.is_hsplit) - num_dpp_in_grp = (double) dpp_in_grp( - e2e, - num_pipes, - e2e[i].pipe.src.hsplit_grp); - else - num_dpp_in_grp = 1; - - calculate_pipe_clk_requirement( - mode_lib, - &e2e[i], - num_dpp_in_grp, - &dppclks[i], - &dispclks[i], - &dppdiv[i]); - - dispclk_ramp_margin_percent = mode_lib->ip.dispclk_ramp_margin_percent; - - dispclk_margined = e2e[i].pipe.dest.pixel_rate_mhz - * (1.0 + (double) mode_lib->soc.downspread_percent / 100.0) - * (1.0 + (double) dispclk_ramp_margin_percent / 100.0); - - DTRACE("p%d: requested power state: %d", i, (int) e2e[0].clks_cfg.voltage); - - if (power_state(mode_lib, dispclks[i], dppclks[i]) - > power_state(mode_lib, dispclk_margined, dispclk_margined) - && dispclk_margined > dppclks[i]) { - if (power_state(mode_lib, dispclks[i], dppclks[i]) - > e2e[0].clks_cfg.voltage) { - dispclks[i] = dispclk_margined; - dppclks[i] = dispclk_margined; - dppdiv[i] = false; - } - } - - DTRACE("p%d: dispclk: %f", i, dispclks[i]); - } -} - -static void get_dcfclk( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_display_e2e_pipe_params_st *e2e, - unsigned int num_pipes, - double *dcfclk_mhz) -{ - double bytes_per_pixel_det_y[DC__NUM_PIPES__MAX]; - double bytes_per_pixel_det_c[DC__NUM_PIPES__MAX]; - double swath_width_y[DC__NUM_PIPES__MAX]; - unsigned int i; - double total_read_bandwidth_gbps = 0.0; - - for (i = 0; i < num_pipes; i++) { - if (e2e[i].pipe.src.source_scan == dm_horz) { - swath_width_y[i] = e2e[i].pipe.src.viewport_width * 1.0; - } else { - swath_width_y[i] = e2e[i].pipe.src.viewport_height * 1.0; - } - - switch (e2e[i].pipe.src.source_format) { - case dm_444_64: - bytes_per_pixel_det_y[i] = 8.0; - bytes_per_pixel_det_c[i] = 0.0; - break; - case dm_444_32: - bytes_per_pixel_det_y[i] = 4.0; - bytes_per_pixel_det_c[i] = 0.0; - break; - case dm_444_16: - bytes_per_pixel_det_y[i] = 2.0; - bytes_per_pixel_det_c[i] = 0.0; - break; - case dm_422_8: - bytes_per_pixel_det_y[i] = 2.0; - bytes_per_pixel_det_c[i] = 0.0; - break; - case dm_422_10: - bytes_per_pixel_det_y[i] = 4.0; - bytes_per_pixel_det_c[i] = 0.0; - break; - case dm_420_8: - bytes_per_pixel_det_y[i] = 1.0; - bytes_per_pixel_det_c[i] = 2.0; - break; - case dm_420_10: - bytes_per_pixel_det_y[i] = 4.0 / 3.0; - bytes_per_pixel_det_c[i] = 8.0 / 3.0; - break; - default: - BREAK_TO_DEBUGGER(); /* invalid src_format in get_dcfclk */ - } - } - - for (i = 0; i < num_pipes; i++) { - double read_bandwidth_plane_mbps = 0.0; - read_bandwidth_plane_mbps = (double) swath_width_y[i] - * ((double) bytes_per_pixel_det_y[i] - + (double) bytes_per_pixel_det_c[i] / 2.0) - / ((double) e2e[i].pipe.dest.htotal - / (double) e2e[i].pipe.dest.pixel_rate_mhz) - * e2e[i].pipe.scale_ratio_depth.vscl_ratio; - - if (e2e[i].pipe.src.dcc) { - read_bandwidth_plane_mbps += (read_bandwidth_plane_mbps / 1000.0 / 256.0); - } - - if (e2e[i].pipe.src.vm) { - read_bandwidth_plane_mbps += (read_bandwidth_plane_mbps / 1000.0 / 512.0); - } - - total_read_bandwidth_gbps = total_read_bandwidth_gbps - + read_bandwidth_plane_mbps / 1000.0; - } - - DTRACE("total bandwidth = %f gbps", total_read_bandwidth_gbps); - - (*dcfclk_mhz) = (total_read_bandwidth_gbps * 1000.0) / mode_lib->soc.return_bus_width_bytes; - - DTRACE( - "minimum theoretical dcfclk without stutter and full utilization = %f MHz", - (*dcfclk_mhz)); - -} - -struct _vcs_dpi_display_pipe_clock_st dml_clks_get_pipe_clocks( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_display_e2e_pipe_params_st *e2e, + display_e2e_pipe_params_st *e2e, unsigned int num_pipes) { - struct _vcs_dpi_display_pipe_clock_st clocks; - double max_dispclk = 0.0; - double dcfclk; - double dispclks[DC__NUM_PIPES__MAX]; - double dppclks[DC__NUM_PIPES__MAX]; - bool dppdiv[DC__NUM_PIPES__MAX]; - unsigned int i; + display_pipe_clock_st clocks; + bool visited[DC__NUM_PIPES__MAX]; + double max_dispclk = 25.0; //the min dispclk is 25MHz, so keep the min dispclk caculated larger thant 25MHz + double dcfclk, socclk; + unsigned int i, j, k; + unsigned int dsc_inst = 0; DTRACE("Calculating pipe clocks..."); - /* this is the theoretical minimum, have to adjust based on valid values for soc */ - get_dcfclk(mode_lib, e2e, num_pipes, &dcfclk); - - /* if(dcfclk > soc.vnom.dcfclk_mhz) - * dcfclk = soc.vmax.dcfclk_mhz; - * else if(dcfclk > soc.vmin.dcfclk_mhz) - * dcfclk = soc.vnom.dcfclk_mhz; - * else - * dcfclk = soc.vmin.dcfclk_mhz; - */ - dcfclk = dml_socbb_voltage_scaling( &mode_lib->soc, (enum voltage_state) e2e[0].clks_cfg.voltage).dcfclk_mhz; + socclk = dml_socbb_voltage_scaling( + &mode_lib->soc, + (enum voltage_state) e2e[0].clks_cfg.voltage).socclk_mhz; clocks.dcfclk_mhz = dcfclk; + clocks.socclk_mhz = socclk; - get_plane_clks(mode_lib, e2e, num_pipes, dppclks, dispclks, dppdiv); - - for (i = 0; i < num_pipes; i++) { - max_dispclk = dml_max(max_dispclk, dispclks[i]); - } - + max_dispclk = dml_max(max_dispclk, get_dispclk_calculated(mode_lib, e2e, num_pipes)); clocks.dispclk_mhz = max_dispclk; - DTRACE("dispclk: %f Mhz", clocks.dispclk_mhz); - DTRACE("dcfclk: %f Mhz", clocks.dcfclk_mhz); + DTRACE(" dispclk: %f Mhz", clocks.dispclk_mhz); + DTRACE(" dcfclk: %f Mhz", clocks.dcfclk_mhz); + DTRACE(" socclk: %f Mhz", clocks.socclk_mhz); - for (i = 0; i < num_pipes; i++) { - if (dppclks[i] * 2 < max_dispclk) - dppdiv[i] = 1; + for (k = 0; k < num_pipes; ++k) + visited[k] = false; - if (dppdiv[i]) - clocks.dppclk_div[i] = 1; - else - clocks.dppclk_div[i] = 0; + for (i = 0; i < num_pipes; i++) { + clocks.dppclk_mhz[i] = get_dppclk_calculated(mode_lib, e2e, num_pipes, i); + DTRACE(" dppclk%d: %f Mhz", i, clocks.dppclk_mhz[i]); + + if (e2e[i].pipe.src.is_hsplit && !visited[i]) { + unsigned int grp = e2e[i].pipe.src.hsplit_grp; + + for (j = i; j < num_pipes; j++) { + if (e2e[j].pipe.src.hsplit_grp == grp && e2e[j].pipe.src.is_hsplit + && !visited[j]) { + clocks.dscclk_mhz[j] = get_dscclk_calculated( + mode_lib, + e2e, + num_pipes, + dsc_inst); + DTRACE(" dscclk%d: %f Mhz", j, clocks.dscclk_mhz[j]); + visited[j] = true; + } + } + dsc_inst++; + } - clocks.dppclk_mhz[i] = max_dispclk / ((dppdiv[i]) ? 2.0 : 1.0); - DTRACE("dppclk%d: %f Mhz", i, clocks.dppclk_mhz[i]); + if (!visited[i]) { + unsigned int otg_inst = e2e[i].pipe.dest.otg_inst; + + for (j = i; j < num_pipes; j++) { + // assign dscclk to all planes with this otg, except if they're doing odm combine, or mpc combine + // which is handled by the conditions above, the odm_combine is not required, but it helps make sense of this code + if (e2e[j].pipe.dest.otg_inst == otg_inst + && !e2e[j].pipe.dest.odm_combine && !visited[j]) { + clocks.dscclk_mhz[j] = get_dscclk_calculated( + mode_lib, + e2e, + num_pipes, + dsc_inst); + DTRACE(" dscclk%d: %f Mhz", j, clocks.dscclk_mhz[j]); + visited[j] = true; + } + } + dsc_inst++; + } } return clocks; diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_pipe_clocks.h b/drivers/gpu/drm/amd/display/dc/dml/display_pipe_clocks.h index aed5f33bb04f6..a712dc3ecf4bc 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_pipe_clocks.h +++ b/drivers/gpu/drm/amd/display/dc/dml/display_pipe_clocks.h @@ -29,13 +29,9 @@ struct display_mode_lib; -struct _vcs_dpi_display_pipe_clock_st dml_clks_get_pipe_clocks( +display_pipe_clock_st dml_clks_get_pipe_clocks( struct display_mode_lib *mode_lib, - struct _vcs_dpi_display_e2e_pipe_params_st *e2e, + display_e2e_pipe_params_st *e2e, unsigned int num_pipes); -bool dml_clks_pipe_clock_requirement_fit_power_constraint( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_display_e2e_pipe_params_st *e2e, - unsigned int num_dpp_in_grp); #endif diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_calc.c b/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_calc.c index 9fccbbffe1295..657b7386021d7 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_calc.c +++ b/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_calc.c @@ -22,8 +22,22 @@ * Authors: AMD * */ -#include "display_rq_dlg_calc.h" + #include "display_mode_lib.h" +#include "display_mode_vba.h" +#include "display_rq_dlg_calc.h" + +static void calculate_ttu_cursor(struct display_mode_lib *mode_lib, + double *refcyc_per_req_delivery_pre_cur, + double *refcyc_per_req_delivery_cur, + double refclk_freq_in_mhz, + double ref_freq_to_pix_freq, + double hscale_pixel_rate_l, + double hscl_ratio, + double vratio_pre_l, + double vratio_l, + unsigned int cur_width, + enum cursor_bpp cur_bpp); static unsigned int get_bytes_per_element(enum source_format_class source_format, bool is_chroma) { @@ -48,6 +62,8 @@ static unsigned int get_bytes_per_element(enum source_format_class source_format ret_val = 4; else ret_val = 2; + } else if (source_format == dm_444_8) { + ret_val = 1; } return ret_val; } @@ -62,123 +78,43 @@ static bool is_dual_plane(enum source_format_class source_format) return ret_val; } -static void get_blk256_size( - unsigned int *blk256_width, - unsigned int *blk256_height, - unsigned int bytes_per_element) -{ - if (bytes_per_element == 1) { - *blk256_width = 16; - *blk256_height = 16; - } else if (bytes_per_element == 2) { - *blk256_width = 16; - *blk256_height = 8; - } else if (bytes_per_element == 4) { - *blk256_width = 8; - *blk256_height = 8; - } else if (bytes_per_element == 8) { - *blk256_width = 8; - *blk256_height = 4; - } -} - -static double get_refcyc_per_delivery( - struct display_mode_lib *mode_lib, +static double get_refcyc_per_delivery(struct display_mode_lib *mode_lib, double refclk_freq_in_mhz, double pclk_freq_in_mhz, - int unsigned recout_width, + bool odm_combine, + unsigned int recout_width, + unsigned int hactive, double vratio, double hscale_pixel_rate, - int unsigned delivery_width, - int unsigned req_per_swath_ub) + unsigned int delivery_width, + unsigned int req_per_swath_ub) { double refcyc_per_delivery = 0.0; + if (vratio <= 1.0) { - refcyc_per_delivery = (double) refclk_freq_in_mhz * (double) recout_width - / pclk_freq_in_mhz / (double) req_per_swath_ub; + if (odm_combine) + refcyc_per_delivery = (double) refclk_freq_in_mhz + * dml_min((double) recout_width, (double) hactive / 2.0) + / pclk_freq_in_mhz / (double) req_per_swath_ub; + else + refcyc_per_delivery = (double) refclk_freq_in_mhz * (double) recout_width + / pclk_freq_in_mhz / (double) req_per_swath_ub; } else { refcyc_per_delivery = (double) refclk_freq_in_mhz * (double) delivery_width / (double) hscale_pixel_rate / (double) req_per_swath_ub; } - DTRACE("DLG: %s: refclk_freq_in_mhz = %3.2f", __func__, refclk_freq_in_mhz); - DTRACE("DLG: %s: pclk_freq_in_mhz = %3.2f", __func__, pclk_freq_in_mhz); - DTRACE("DLG: %s: recout_width = %d", __func__, recout_width); - DTRACE("DLG: %s: vratio = %3.2f", __func__, vratio); - DTRACE("DLG: %s: req_per_swath_ub = %d", __func__, req_per_swath_ub); - DTRACE("DLG: %s: refcyc_per_delivery= %3.2f", __func__, refcyc_per_delivery); + dml_print("DML_DLG: %s: refclk_freq_in_mhz = %3.2f\n", __func__, refclk_freq_in_mhz); + dml_print("DML_DLG: %s: pclk_freq_in_mhz = %3.2f\n", __func__, pclk_freq_in_mhz); + dml_print("DML_DLG: %s: recout_width = %d\n", __func__, recout_width); + dml_print("DML_DLG: %s: vratio = %3.2f\n", __func__, vratio); + dml_print("DML_DLG: %s: req_per_swath_ub = %d\n", __func__, req_per_swath_ub); + dml_print("DML_DLG: %s: refcyc_per_delivery= %3.2f\n", __func__, refcyc_per_delivery); return refcyc_per_delivery; } -static double get_vratio_pre( - struct display_mode_lib *mode_lib, - unsigned int max_num_sw, - unsigned int max_partial_sw, - unsigned int swath_height, - double vinit, - double l_sw) -{ - double prefill = dml_floor(vinit); - double vratio_pre = 1.0; - - vratio_pre = (max_num_sw * swath_height + max_partial_sw) / l_sw; - - if (swath_height > 4) { - double tmp0 = (max_num_sw * swath_height) / (l_sw - (prefill - 3.0) / 2.0); - if (tmp0 > vratio_pre) - vratio_pre = tmp0; - } - - DTRACE("DLG: %s: max_num_sw = %0d", __func__, max_num_sw); - DTRACE("DLG: %s: max_partial_sw = %0d", __func__, max_partial_sw); - DTRACE("DLG: %s: swath_height = %0d", __func__, swath_height); - DTRACE("DLG: %s: vinit = %3.2f", __func__, vinit); - DTRACE("DLG: %s: vratio_pre = %3.2f", __func__, vratio_pre); - - if (vratio_pre < 1.0) { - DTRACE("WARNING_DLG: %s: vratio_pre=%3.2f < 1.0, set to 1.0", __func__, vratio_pre); - vratio_pre = 1.0; - } - - if (vratio_pre > 4.0) { - DTRACE( - "WARNING_DLG: %s: vratio_pre=%3.2f > 4.0 (max scaling ratio). set to 4.0", - __func__, - vratio_pre); - vratio_pre = 4.0; - } - - return vratio_pre; -} - -static void get_swath_need( - struct display_mode_lib *mode_lib, - unsigned int *max_num_sw, - unsigned int *max_partial_sw, - unsigned int swath_height, - double vinit) -{ - double prefill = dml_floor(vinit); - unsigned int max_partial_sw_int; - - DTRACE("DLG: %s: swath_height = %0d", __func__, swath_height); - DTRACE("DLG: %s: vinit = %3.2f", __func__, vinit); - - ASSERT(prefill > 0.0 && prefill <= 8.0); - - *max_num_sw = (int unsigned) (dml_ceil((prefill - 1.0) / (double) swath_height) + 1.0); /* prefill has to be >= 1 */ - max_partial_sw_int = - (prefill == 1) ? - (swath_height - 1) : - ((int unsigned) (prefill - 2.0) % swath_height); - *max_partial_sw = (max_partial_sw_int < 1) ? 1 : max_partial_sw_int; /* ensure minimum of 1 is used */ - - DTRACE("DLG: %s: max_num_sw = %0d", __func__, *max_num_sw); - DTRACE("DLG: %s: max_partial_sw = %0d", __func__, *max_partial_sw); -} - static unsigned int get_blk_size_bytes(const enum source_macro_tile_size tile_size) { if (tile_size == dm_256k_tile) @@ -189,12 +125,11 @@ static unsigned int get_blk_size_bytes(const enum source_macro_tile_size tile_si return (4 * 1024); } -static void extract_rq_sizing_regs( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_display_data_rq_regs_st *rq_regs, - const struct _vcs_dpi_display_data_rq_sizing_params_st rq_sizing) +static void extract_rq_sizing_regs(struct display_mode_lib *mode_lib, + display_data_rq_regs_st *rq_regs, + const display_data_rq_sizing_params_st rq_sizing) { - DTRACE("DLG: %s: rq_sizing param", __func__); + dml_print("DML_DLG: %s: rq_sizing param\n", __func__); print__data_rq_sizing_params_st(mode_lib, rq_sizing); rq_regs->chunk_size = dml_log2(rq_sizing.chunk_bytes) - 10; @@ -214,25 +149,30 @@ static void extract_rq_sizing_regs( rq_regs->mpte_group_size = dml_log2(rq_sizing.mpte_group_bytes) - 6; } -void extract_rq_regs( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_display_rq_regs_st *rq_regs, - const struct _vcs_dpi_display_rq_params_st rq_param) +static void extract_rq_regs(struct display_mode_lib *mode_lib, + display_rq_regs_st *rq_regs, + const display_rq_params_st rq_param) { unsigned int detile_buf_size_in_bytes = mode_lib->ip.det_buffer_size_kbytes * 1024; unsigned int detile_buf_plane1_addr = 0; extract_rq_sizing_regs(mode_lib, &(rq_regs->rq_regs_l), rq_param.sizing.rq_l); - if (rq_param.yuv420) + + rq_regs->rq_regs_l.pte_row_height_linear = dml_floor(dml_log2(rq_param.dlg.rq_l.dpte_row_height), + 1) - 3; + + if (rq_param.yuv420) { extract_rq_sizing_regs(mode_lib, &(rq_regs->rq_regs_c), rq_param.sizing.rq_c); + rq_regs->rq_regs_c.pte_row_height_linear = dml_floor(dml_log2(rq_param.dlg.rq_c.dpte_row_height), + 1) - 3; + } rq_regs->rq_regs_l.swath_height = dml_log2(rq_param.dlg.rq_l.swath_height); rq_regs->rq_regs_c.swath_height = dml_log2(rq_param.dlg.rq_c.swath_height); - /* FIXME: take the max between luma, chroma chunk size? - * okay for now, as we are setting chunk_bytes to 8kb anyways - */ - if (rq_param.sizing.rq_l.chunk_bytes >= 32 * 1024) { /*32kb */ + // FIXME: take the max between luma, chroma chunk size? + // okay for now, as we are setting chunk_bytes to 8kb anyways + if (rq_param.sizing.rq_l.chunk_bytes >= 32 * 1024) { //32kb rq_regs->drq_expansion_mode = 0; } else { rq_regs->drq_expansion_mode = 2; @@ -244,21 +184,19 @@ void extract_rq_regs( if (rq_param.yuv420) { if ((double) rq_param.misc.rq_l.stored_swath_bytes / (double) rq_param.misc.rq_c.stored_swath_bytes <= 1.5) { - detile_buf_plane1_addr = (detile_buf_size_in_bytes / 2.0 / 64.0); /* half to chroma */ + detile_buf_plane1_addr = (detile_buf_size_in_bytes / 2.0 / 64.0); // half to chroma } else { - detile_buf_plane1_addr = dml_round_to_multiple( - (unsigned int) ((2.0 * detile_buf_size_in_bytes) / 3.0), + detile_buf_plane1_addr = dml_round_to_multiple((unsigned int) ((2.0 * detile_buf_size_in_bytes) / 3.0), 256, - 0) / 64.0; /* 2/3 to chroma */ + 0) / 64.0; // 2/3 to chroma } } rq_regs->plane1_base_address = detile_buf_plane1_addr; } -static void handle_det_buf_split( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_display_rq_params_st *rq_param, - const struct _vcs_dpi_display_pipe_source_params_st pipe_src_param) +static void handle_det_buf_split(struct display_mode_lib *mode_lib, + display_rq_params_st *rq_param, + const display_pipe_source_params_st pipe_src_param) { unsigned int total_swath_bytes = 0; unsigned int swath_bytes_l = 0; @@ -277,12 +215,10 @@ static void handle_det_buf_split( full_swath_bytes_packed_c = rq_param->misc.rq_c.full_swath_bytes; if (rq_param->yuv420_10bpc) { - full_swath_bytes_packed_l = dml_round_to_multiple( - rq_param->misc.rq_l.full_swath_bytes * 2 / 3, + full_swath_bytes_packed_l = dml_round_to_multiple(rq_param->misc.rq_l.full_swath_bytes * 2 / 3, 256, 1) + 256; - full_swath_bytes_packed_c = dml_round_to_multiple( - rq_param->misc.rq_c.full_swath_bytes * 2 / 3, + full_swath_bytes_packed_c = dml_round_to_multiple(rq_param->misc.rq_c.full_swath_bytes * 2 / 3, 256, 1) + 256; } @@ -290,29 +226,19 @@ static void handle_det_buf_split( if (rq_param->yuv420) { total_swath_bytes = 2 * full_swath_bytes_packed_l + 2 * full_swath_bytes_packed_c; - if (total_swath_bytes <= detile_buf_size_in_bytes) { /*full 256b request */ + if (total_swath_bytes <= detile_buf_size_in_bytes) { //full 256b request req128_l = 0; req128_c = 0; swath_bytes_l = full_swath_bytes_packed_l; swath_bytes_c = full_swath_bytes_packed_c; - } else { /*128b request (for luma only for yuv420 8bpc) */ + } else { //128b request (for luma only for yuv420 8bpc) req128_l = 1; req128_c = 0; swath_bytes_l = full_swath_bytes_packed_l / 2; swath_bytes_c = full_swath_bytes_packed_c; } - - /* Bug workaround, luma and chroma req size needs to be the same. (see: DEGVIDCN10-137) - * TODO: Remove after rtl fix - */ - if (req128_l == 1) { - req128_c = 1; - DTRACE("DLG: %s: bug workaround DEGVIDCN10-137", __func__); - } - - /* Note: assumption, the config that pass in will fit into - * the detiled buffer. - */ + // Note: assumption, the config that pass in will fit into + // the detiled buffer. } else { total_swath_bytes = 2 * full_swath_bytes_packed_l; @@ -340,207 +266,47 @@ static void handle_det_buf_split( rq_param->dlg.rq_l.swath_height = 1 << log2_swath_height_l; rq_param->dlg.rq_c.swath_height = 1 << log2_swath_height_c; - DTRACE("DLG: %s: req128_l = %0d", __func__, req128_l); - DTRACE("DLG: %s: req128_c = %0d", __func__, req128_c); - DTRACE("DLG: %s: full_swath_bytes_packed_l = %0d", __func__, full_swath_bytes_packed_l); - DTRACE("DLG: %s: full_swath_bytes_packed_c = %0d", __func__, full_swath_bytes_packed_c); + dml_print("DML_DLG: %s: req128_l = %0d\n", __func__, req128_l); + dml_print("DML_DLG: %s: req128_c = %0d\n", __func__, req128_c); + dml_print("DML_DLG: %s: full_swath_bytes_packed_l = %0d\n", + __func__, + full_swath_bytes_packed_l); + dml_print("DML_DLG: %s: full_swath_bytes_packed_c = %0d\n", + __func__, + full_swath_bytes_packed_c); } -/* Need refactor. */ -void dml_rq_dlg_get_row_heights( - struct display_mode_lib *mode_lib, - unsigned int *o_dpte_row_height, - unsigned int *o_meta_row_height, +static void get_meta_and_pte_attr(struct display_mode_lib *mode_lib, + display_data_rq_dlg_params_st *rq_dlg_param, + display_data_rq_misc_params_st *rq_misc_param, + display_data_rq_sizing_params_st *rq_sizing_param, unsigned int vp_width, + unsigned int vp_height, unsigned int data_pitch, - int source_format, - int tiling, - int macro_tile_size, - int source_scan, - int is_chroma) + unsigned int meta_pitch, + unsigned int source_format, + unsigned int tiling, + unsigned int macro_tile_size, + unsigned int source_scan, + unsigned int is_chroma) { bool surf_linear = (tiling == dm_sw_linear); bool surf_vert = (source_scan == dm_vert); - unsigned int bytes_per_element = get_bytes_per_element( - (enum source_format_class) source_format, - is_chroma); - unsigned int log2_bytes_per_element = dml_log2(bytes_per_element); + unsigned int bytes_per_element; + unsigned int bytes_per_element_y = get_bytes_per_element((enum source_format_class)(source_format), + false); + unsigned int bytes_per_element_c = get_bytes_per_element((enum source_format_class)(source_format), + true); + unsigned int blk256_width = 0; unsigned int blk256_height = 0; - unsigned int log2_blk256_height; - unsigned int blk_bytes; - unsigned int log2_blk_bytes; - unsigned int log2_blk_height; - unsigned int log2_blk_width; - unsigned int log2_meta_req_bytes; - unsigned int log2_meta_req_height; - unsigned int log2_meta_req_width; - unsigned int log2_meta_row_height; - unsigned int log2_vmpg_bytes; - unsigned int dpte_buf_in_pte_reqs; - unsigned int log2_vmpg_height; - unsigned int log2_vmpg_width; - unsigned int log2_dpte_req_height_ptes; - unsigned int log2_dpte_req_width_ptes; - unsigned int log2_dpte_req_height; - unsigned int log2_dpte_req_width; - unsigned int log2_dpte_row_height_linear; - unsigned int log2_dpte_row_height; - unsigned int dpte_req_width; - - if (surf_linear) { - blk256_width = 256; - blk256_height = 1; - } else { - get_blk256_size(&blk256_width, &blk256_height, bytes_per_element); - } - - log2_blk256_height = dml_log2((double) blk256_height); - blk_bytes = surf_linear ? - 256 : get_blk_size_bytes((enum source_macro_tile_size) macro_tile_size); - log2_blk_bytes = dml_log2((double) blk_bytes); - log2_blk_height = 0; - log2_blk_width = 0; - - /* remember log rule - * "+" in log is multiply - * "-" in log is divide - * "/2" is like square root - * blk is vertical biased - */ - if (tiling != dm_sw_linear) - log2_blk_height = log2_blk256_height - + dml_ceil((double) (log2_blk_bytes - 8) / 2.0); - else - log2_blk_height = 0; /* blk height of 1 */ - - log2_blk_width = log2_blk_bytes - log2_bytes_per_element - log2_blk_height; - - /* ------- */ - /* meta */ - /* ------- */ - log2_meta_req_bytes = 6; /* meta request is 64b and is 8x8byte meta element */ - - /* each 64b meta request for dcn is 8x8 meta elements and - * a meta element covers one 256b block of the the data surface. - */ - log2_meta_req_height = log2_blk256_height + 3; /* meta req is 8x8 */ - log2_meta_req_width = log2_meta_req_bytes + 8 - log2_bytes_per_element - - log2_meta_req_height; - log2_meta_row_height = 0; - - /* the dimensions of a meta row are meta_row_width x meta_row_height in elements. - * calculate upper bound of the meta_row_width - */ - if (!surf_vert) - log2_meta_row_height = log2_meta_req_height; - else - log2_meta_row_height = log2_meta_req_width; - - *o_meta_row_height = 1 << log2_meta_row_height; - - /* ------ */ - /* dpte */ - /* ------ */ - log2_vmpg_bytes = dml_log2(mode_lib->soc.vmm_page_size_bytes); - dpte_buf_in_pte_reqs = mode_lib->ip.dpte_buffer_size_in_pte_reqs; - - log2_vmpg_height = 0; - log2_vmpg_width = 0; - log2_dpte_req_height_ptes = 0; - log2_dpte_req_width_ptes = 0; - log2_dpte_req_height = 0; - log2_dpte_req_width = 0; - log2_dpte_row_height_linear = 0; - log2_dpte_row_height = 0; - dpte_req_width = 0; /* 64b dpte req width in data element */ - - if (surf_linear) { - log2_vmpg_height = 0; /* one line high */ - } else { - log2_vmpg_height = (log2_vmpg_bytes - 8) / 2 + log2_blk256_height; - } - log2_vmpg_width = log2_vmpg_bytes - log2_bytes_per_element - log2_vmpg_height; - - /* only 3 possible shapes for dpte request in dimensions of ptes: 8x1, 4x2, 2x4. */ - if (log2_blk_bytes <= log2_vmpg_bytes) - log2_dpte_req_height_ptes = 0; - else if (log2_blk_height - log2_vmpg_height >= 2) - log2_dpte_req_height_ptes = 2; - else - log2_dpte_req_height_ptes = log2_blk_height - log2_vmpg_height; - log2_dpte_req_width_ptes = 3 - log2_dpte_req_height_ptes; - - ASSERT((log2_dpte_req_width_ptes == 3 && log2_dpte_req_height_ptes == 0) || /* 8x1 */ - (log2_dpte_req_width_ptes == 2 && log2_dpte_req_height_ptes == 1) || /* 4x2 */ - (log2_dpte_req_width_ptes == 1 && log2_dpte_req_height_ptes == 2)); /* 2x4 */ - - /* the dpte request dimensions in data elements is dpte_req_width x dpte_req_height - * log2_wmpg_width is how much 1 pte represent, now trying to calculate how much 64b pte req represent - */ - log2_dpte_req_height = log2_vmpg_height + log2_dpte_req_height_ptes; - log2_dpte_req_width = log2_vmpg_width + log2_dpte_req_width_ptes; - dpte_req_width = 1 << log2_dpte_req_width; - - /* calculate pitch dpte row buffer can hold - * round the result down to a power of two. - */ - if (surf_linear) { - log2_dpte_row_height_linear = dml_floor( - dml_log2(dpte_buf_in_pte_reqs * dpte_req_width / data_pitch)); - - ASSERT(log2_dpte_row_height_linear >= 3); - - if (log2_dpte_row_height_linear > 7) - log2_dpte_row_height_linear = 7; - - log2_dpte_row_height = log2_dpte_row_height_linear; - } else { - /* the upper bound of the dpte_row_width without dependency on viewport position follows. */ - if (!surf_vert) { - log2_dpte_row_height = log2_dpte_req_height; - } else { - log2_dpte_row_height = - (log2_blk_width < log2_dpte_req_width) ? - log2_blk_width : log2_dpte_req_width; - } - } - - /* From programming guide: - * There is a special case of saving only half of ptes returned due to buffer space limits. - * this case applies to 4 and 8bpe in horizontal access of a vp_width greater than 2560+16 - * when the pte request is 2x4 ptes (which happens when vmpg_bytes =4kb and tile blk_bytes >=64kb). - */ - if (!surf_vert && vp_width > (2560 + 16) && bytes_per_element >= 4 && log2_vmpg_bytes == 12 - && log2_blk_bytes >= 16) { - log2_dpte_row_height = log2_dpte_row_height - 1; /*half of the full height */ - } - - *o_dpte_row_height = 1 << log2_dpte_row_height; -} - -static void get_surf_rq_param( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_display_data_rq_sizing_params_st *rq_sizing_param, - struct _vcs_dpi_display_data_rq_dlg_params_st *rq_dlg_param, - struct _vcs_dpi_display_data_rq_misc_params_st *rq_misc_param, - const struct _vcs_dpi_display_pipe_source_params_st pipe_src_param, - bool is_chroma) -{ - bool mode_422 = 0; - unsigned int vp_width = 0; - unsigned int vp_height = 0; - unsigned int data_pitch = 0; - unsigned int meta_pitch = 0; - unsigned int ppe = mode_422 ? 2 : 1; - bool surf_linear; - bool surf_vert; - unsigned int bytes_per_element; + unsigned int blk256_width_y = 0; + unsigned int blk256_height_y = 0; + unsigned int blk256_width_c = 0; + unsigned int blk256_height_c = 0; unsigned int log2_bytes_per_element; - unsigned int blk256_width; - unsigned int blk256_height; unsigned int log2_blk256_width; unsigned int log2_blk256_height; unsigned int blk_bytes; @@ -556,6 +322,8 @@ static void get_surf_rq_param( unsigned int meta_row_width_ub; unsigned int log2_meta_chunk_bytes; unsigned int log2_meta_chunk_height; + + //full sized meta chunk width in unit of data elements unsigned int log2_meta_chunk_width; unsigned int log2_min_meta_chunk_bytes; unsigned int min_meta_chunk_width; @@ -570,93 +338,72 @@ static void get_surf_rq_param( unsigned int vmpg_bytes; unsigned int meta_pte_req_per_frame_ub; unsigned int meta_pte_bytes_per_frame_ub; - unsigned int log2_vmpg_bytes; - unsigned int dpte_buf_in_pte_reqs; - unsigned int log2_vmpg_height; - unsigned int log2_vmpg_width; - unsigned int log2_dpte_req_height_ptes; - unsigned int log2_dpte_req_width_ptes; - unsigned int log2_dpte_req_height; - unsigned int log2_dpte_req_width; - unsigned int log2_dpte_row_height_linear; - unsigned int log2_dpte_row_height; - unsigned int log2_dpte_group_width; - unsigned int dpte_row_width_ub; - unsigned int dpte_row_height; - unsigned int dpte_req_height; - unsigned int dpte_req_width; - unsigned int dpte_group_width; - unsigned int log2_dpte_group_bytes; - unsigned int log2_dpte_group_length; - unsigned int func_meta_row_height, func_dpte_row_height; - - /* FIXME check if ppe apply for both luma and chroma in 422 case */ - if (is_chroma) { - vp_width = pipe_src_param.viewport_width_c / ppe; - vp_height = pipe_src_param.viewport_height_c; - data_pitch = pipe_src_param.data_pitch_c; - meta_pitch = pipe_src_param.meta_pitch_c; + const unsigned int log2_vmpg_bytes = dml_log2(mode_lib->soc.vmm_page_size_bytes); + const unsigned int dpte_buf_in_pte_reqs = mode_lib->ip.dpte_buffer_size_in_pte_reqs; + const unsigned int pde_proc_buffer_size_64k_reqs = + mode_lib->ip.pde_proc_buffer_size_64k_reqs; + + unsigned int log2_vmpg_height = 0; + unsigned int log2_vmpg_width = 0; + unsigned int log2_dpte_req_height_ptes = 0; + unsigned int log2_dpte_req_height = 0; + unsigned int log2_dpte_req_width = 0; + unsigned int log2_dpte_row_height_linear = 0; + unsigned int log2_dpte_row_height = 0; + unsigned int log2_dpte_group_width = 0; + unsigned int dpte_row_width_ub = 0; + unsigned int dpte_req_height = 0; + unsigned int dpte_req_width = 0; + unsigned int dpte_group_width = 0; + unsigned int log2_dpte_group_bytes = 0; + unsigned int log2_dpte_group_length = 0; + unsigned int pde_buf_entries; + bool yuv420 = (source_format == dm_420_8 || source_format == dm_420_10); + + Calculate256BBlockSizes((enum source_format_class)(source_format), + (enum dm_swizzle_mode)(tiling), + bytes_per_element_y, + bytes_per_element_c, + &blk256_height_y, + &blk256_height_c, + &blk256_width_y, + &blk256_width_c); + + if (!is_chroma) { + blk256_width = blk256_width_y; + blk256_height = blk256_height_y; + bytes_per_element = bytes_per_element_y; } else { - vp_width = pipe_src_param.viewport_width / ppe; - vp_height = pipe_src_param.viewport_height; - data_pitch = pipe_src_param.data_pitch; - meta_pitch = pipe_src_param.meta_pitch; + blk256_width = blk256_width_c; + blk256_height = blk256_height_c; + bytes_per_element = bytes_per_element_c; } - rq_sizing_param->chunk_bytes = 8192; - - if (rq_sizing_param->chunk_bytes == 64 * 1024) - rq_sizing_param->min_chunk_bytes = 0; - else - rq_sizing_param->min_chunk_bytes = 1024; - - rq_sizing_param->meta_chunk_bytes = 2048; - rq_sizing_param->min_meta_chunk_bytes = 256; - - rq_sizing_param->mpte_group_bytes = 2048; - - surf_linear = (pipe_src_param.sw_mode == dm_sw_linear); - surf_vert = (pipe_src_param.source_scan == dm_vert); - - bytes_per_element = get_bytes_per_element( - (enum source_format_class) pipe_src_param.source_format, - is_chroma); log2_bytes_per_element = dml_log2(bytes_per_element); - blk256_width = 0; - blk256_height = 0; - - if (surf_linear) { - blk256_width = 256 / bytes_per_element; - blk256_height = 1; - } else { - get_blk256_size(&blk256_width, &blk256_height, bytes_per_element); - } - DTRACE("DLG: %s: surf_linear = %d", __func__, surf_linear); - DTRACE("DLG: %s: surf_vert = %d", __func__, surf_vert); - DTRACE("DLG: %s: blk256_width = %d", __func__, blk256_width); - DTRACE("DLG: %s: blk256_height = %d", __func__, blk256_height); + dml_print("DML_DLG: %s: surf_linear = %d\n", __func__, surf_linear); + dml_print("DML_DLG: %s: surf_vert = %d\n", __func__, surf_vert); + dml_print("DML_DLG: %s: blk256_width = %d\n", __func__, blk256_width); + dml_print("DML_DLG: %s: blk256_height = %d\n", __func__, blk256_height); log2_blk256_width = dml_log2((double) blk256_width); log2_blk256_height = dml_log2((double) blk256_height); - blk_bytes = - surf_linear ? 256 : get_blk_size_bytes( - (enum source_macro_tile_size) pipe_src_param.macro_tile_size); + blk_bytes = surf_linear ? + 256 : get_blk_size_bytes((enum source_macro_tile_size) macro_tile_size); log2_blk_bytes = dml_log2((double) blk_bytes); log2_blk_height = 0; log2_blk_width = 0; - /* remember log rule - * "+" in log is multiply - * "-" in log is divide - * "/2" is like square root - * blk is vertical biased - */ - if (pipe_src_param.sw_mode != dm_sw_linear) + // remember log rule + // "+" in log is multiply + // "-" in log is divide + // "/2" is like square root + // blk is vertical biased + if (tiling != dm_sw_linear) log2_blk_height = log2_blk256_height - + dml_ceil((double) (log2_blk_bytes - 8) / 2.0); + + dml_ceil((double) (log2_blk_bytes - 8) / 2.0, 1); else - log2_blk_height = 0; /* blk height of 1 */ + log2_blk_height = 0; // blk height of 1 log2_blk_width = log2_blk_bytes - log2_bytes_per_element - log2_blk_height; @@ -665,10 +412,8 @@ static void get_surf_rq_param( + blk256_width; rq_dlg_param->req_per_swath_ub = rq_dlg_param->swath_width_ub >> log2_blk256_width; } else { - rq_dlg_param->swath_width_ub = dml_round_to_multiple( - vp_height - 1, - blk256_height, - 1) + blk256_height; + rq_dlg_param->swath_width_ub = dml_round_to_multiple(vp_height - 1, blk256_height, 1) + + blk256_height; rq_dlg_param->req_per_swath_ub = rq_dlg_param->swath_width_ub >> log2_blk256_height; } @@ -682,15 +427,14 @@ static void get_surf_rq_param( rq_misc_param->blk256_height = blk256_height; rq_misc_param->blk256_width = blk256_width; - /* ------- */ - /* meta */ - /* ------- */ - log2_meta_req_bytes = 6; /* meta request is 64b and is 8x8byte meta element */ + // ------- + // meta + // ------- + log2_meta_req_bytes = 6; // meta request is 64b and is 8x8byte meta element - /* each 64b meta request for dcn is 8x8 meta elements and - * a meta element covers one 256b block of the the data surface. - */ - log2_meta_req_height = log2_blk256_height + 3; /* meta req is 8x8 byte, each byte represent 1 blk256 */ + // each 64b meta request for dcn is 8x8 meta elements and + // a meta element covers one 256b block of the the data surface. + log2_meta_req_height = log2_blk256_height + 3; // meta req is 8x8 byte, each byte represent 1 blk256 log2_meta_req_width = log2_meta_req_bytes + 8 - log2_bytes_per_element - log2_meta_req_height; meta_req_width = 1 << log2_meta_req_width; @@ -698,9 +442,8 @@ static void get_surf_rq_param( log2_meta_row_height = 0; meta_row_width_ub = 0; - /* the dimensions of a meta row are meta_row_width x meta_row_height in elements. - * calculate upper bound of the meta_row_width - */ + // the dimensions of a meta row are meta_row_width x meta_row_height in elements. + // calculate upper bound of the meta_row_width if (!surf_vert) { log2_meta_row_height = log2_meta_req_height; meta_row_width_ub = dml_round_to_multiple(vp_width - 1, meta_req_width, 1) @@ -714,10 +457,12 @@ static void get_surf_rq_param( } rq_dlg_param->meta_bytes_per_row_ub = rq_dlg_param->meta_req_per_row_ub * 64; + rq_dlg_param->meta_row_height = 1 << log2_meta_row_height; + log2_meta_chunk_bytes = dml_log2(rq_sizing_param->meta_chunk_bytes); log2_meta_chunk_height = log2_meta_row_height; - /*full sized meta chunk width in unit of data elements */ + //full sized meta chunk width in unit of data elements log2_meta_chunk_width = log2_meta_chunk_bytes + 8 - log2_bytes_per_element - log2_meta_chunk_height; log2_min_meta_chunk_bytes = dml_log2(rq_sizing_param->min_meta_chunk_bytes); @@ -732,21 +477,24 @@ static void get_surf_rq_param( meta_blk_height = blk256_height * 64; meta_blk_width = meta_blk_bytes * 256 / bytes_per_element / meta_blk_height; meta_surface_bytes = meta_pitch - * (dml_round_to_multiple(vp_height - 1, meta_blk_height, 1) - + meta_blk_height) * bytes_per_element / 256; + * (dml_round_to_multiple(vp_height - 1, meta_blk_height, 1) + meta_blk_height) + * bytes_per_element / 256; vmpg_bytes = mode_lib->soc.vmm_page_size_bytes; - meta_pte_req_per_frame_ub = (dml_round_to_multiple( - meta_surface_bytes - vmpg_bytes, + meta_pte_req_per_frame_ub = (dml_round_to_multiple(meta_surface_bytes - vmpg_bytes, 8 * vmpg_bytes, 1) + 8 * vmpg_bytes) / (8 * vmpg_bytes); - meta_pte_bytes_per_frame_ub = meta_pte_req_per_frame_ub * 64; /*64B mpte request */ + meta_pte_bytes_per_frame_ub = meta_pte_req_per_frame_ub * 64; //64B mpte request rq_dlg_param->meta_pte_bytes_per_frame_ub = meta_pte_bytes_per_frame_ub; - DTRACE("DLG: %s: meta_blk_height = %d", __func__, meta_blk_height); - DTRACE("DLG: %s: meta_blk_width = %d", __func__, meta_blk_width); - DTRACE("DLG: %s: meta_surface_bytes = %d", __func__, meta_surface_bytes); - DTRACE("DLG: %s: meta_pte_req_per_frame_ub = %d", __func__, meta_pte_req_per_frame_ub); - DTRACE("DLG: %s: meta_pte_bytes_per_frame_ub = %d", __func__, meta_pte_bytes_per_frame_ub); + dml_print("DML_DLG: %s: meta_blk_height = %d\n", __func__, meta_blk_height); + dml_print("DML_DLG: %s: meta_blk_width = %d\n", __func__, meta_blk_width); + dml_print("DML_DLG: %s: meta_surface_bytes = %d\n", __func__, meta_surface_bytes); + dml_print("DML_DLG: %s: meta_pte_req_per_frame_ub = %d\n", + __func__, + meta_pte_req_per_frame_ub); + dml_print("DML_DLG: %s: meta_pte_bytes_per_frame_ub = %d\n", + __func__, + meta_pte_bytes_per_frame_ub); if (!surf_vert) meta_chunk_threshold = 2 * min_meta_chunk_width - meta_req_width; @@ -758,67 +506,58 @@ static void get_surf_rq_param( else rq_dlg_param->meta_chunks_per_row_ub = meta_chunk_per_row_int + 2; - rq_dlg_param->meta_row_height = 1 << log2_meta_row_height; - - /* ------ */ - /* dpte */ - /* ------ */ - log2_vmpg_bytes = dml_log2(mode_lib->soc.vmm_page_size_bytes); - dpte_buf_in_pte_reqs = mode_lib->ip.dpte_buffer_size_in_pte_reqs; - - log2_vmpg_height = 0; - log2_vmpg_width = 0; - log2_dpte_req_height_ptes = 0; - log2_dpte_req_width_ptes = 0; - log2_dpte_req_height = 0; - log2_dpte_req_width = 0; - log2_dpte_row_height_linear = 0; - log2_dpte_row_height = 0; - log2_dpte_group_width = 0; - dpte_row_width_ub = 0; - dpte_row_height = 0; - dpte_req_height = 0; /* 64b dpte req height in data element */ - dpte_req_width = 0; /* 64b dpte req width in data element */ - dpte_group_width = 0; - log2_dpte_group_bytes = 0; - log2_dpte_group_length = 0; - + // ------ + // dpte + // ------ if (surf_linear) { - log2_vmpg_height = 0; /* one line high */ + log2_vmpg_height = 0; // one line high } else { log2_vmpg_height = (log2_vmpg_bytes - 8) / 2 + log2_blk256_height; } log2_vmpg_width = log2_vmpg_bytes - log2_bytes_per_element - log2_vmpg_height; - /* only 3 possible shapes for dpte request in dimensions of ptes: 8x1, 4x2, 2x4. */ - if (log2_blk_bytes <= log2_vmpg_bytes) + // only 3 possible shapes for dpte request in dimensions of ptes: 8x1, 4x2, 2x4. + if (surf_linear) { //one 64B PTE request returns 8 PTEs log2_dpte_req_height_ptes = 0; - else if (log2_blk_height - log2_vmpg_height >= 2) - log2_dpte_req_height_ptes = 2; - else - log2_dpte_req_height_ptes = log2_blk_height - log2_vmpg_height; - log2_dpte_req_width_ptes = 3 - log2_dpte_req_height_ptes; - - /* Ensure we only have the 3 shapes */ - ASSERT((log2_dpte_req_width_ptes == 3 && log2_dpte_req_height_ptes == 0) || /* 8x1 */ - (log2_dpte_req_width_ptes == 2 && log2_dpte_req_height_ptes == 1) || /* 4x2 */ - (log2_dpte_req_width_ptes == 1 && log2_dpte_req_height_ptes == 2)); /* 2x4 */ - - /* The dpte request dimensions in data elements is dpte_req_width x dpte_req_height - * log2_vmpg_width is how much 1 pte represent, now calculating how much a 64b pte req represent - * That depends on the pte shape (i.e. 8x1, 4x2, 2x4) - */ - log2_dpte_req_height = log2_vmpg_height + log2_dpte_req_height_ptes; - log2_dpte_req_width = log2_vmpg_width + log2_dpte_req_width_ptes; + log2_dpte_req_width = log2_vmpg_width + 3; + log2_dpte_req_height = 0; + } else if (log2_blk_bytes == 12) { //4KB tile means 4kB page size + //one 64B req gives 8x1 PTEs for 4KB tile + log2_dpte_req_height_ptes = 0; + log2_dpte_req_width = log2_blk_width + 3; + log2_dpte_req_height = log2_blk_height + 0; + } else if ((log2_blk_bytes >= 16) && (log2_vmpg_bytes == 12)) { // tile block >= 64KB + //two 64B reqs of 2x4 PTEs give 16 PTEs to cover 64KB + log2_dpte_req_height_ptes = 4; + log2_dpte_req_width = log2_blk256_width + 4; // log2_64KB_width + log2_dpte_req_height = log2_blk256_height + 4; // log2_64KB_height + } else { //64KB page size and must 64KB tile block + //one 64B req gives 8x1 PTEs for 64KB tile + log2_dpte_req_height_ptes = 0; + log2_dpte_req_width = log2_blk_width + 3; + log2_dpte_req_height = log2_blk_height + 0; + } + + // The dpte request dimensions in data elements is dpte_req_width x dpte_req_height + // log2_vmpg_width is how much 1 pte represent, now calculating how much a 64b pte req represent + // That depends on the pte shape (i.e. 8x1, 4x2, 2x4) + //log2_dpte_req_height = log2_vmpg_height + log2_dpte_req_height_ptes; + //log2_dpte_req_width = log2_vmpg_width + log2_dpte_req_width_ptes; dpte_req_height = 1 << log2_dpte_req_height; dpte_req_width = 1 << log2_dpte_req_width; - /* calculate pitch dpte row buffer can hold - * round the result down to a power of two. - */ + // calculate pitch dpte row buffer can hold + // round the result down to a power of two. + pde_buf_entries = yuv420 ? (pde_proc_buffer_size_64k_reqs >> 1) : pde_proc_buffer_size_64k_reqs; if (surf_linear) { - log2_dpte_row_height_linear = dml_floor( - dml_log2(dpte_buf_in_pte_reqs * dpte_req_width / data_pitch)); + unsigned int dpte_row_height; + + log2_dpte_row_height_linear = dml_floor(dml_log2(dml_min(64 * 1024 * pde_buf_entries + / bytes_per_element, + dpte_buf_in_pte_reqs + * dpte_req_width) + / data_pitch), + 1); ASSERT(log2_dpte_row_height_linear >= 3); @@ -826,18 +565,16 @@ static void get_surf_rq_param( log2_dpte_row_height_linear = 7; log2_dpte_row_height = log2_dpte_row_height_linear; - rq_dlg_param->dpte_row_height = 1 << log2_dpte_row_height; - - /* For linear, the dpte row is pitch dependent and the pte requests wrap at the pitch boundary. - * the dpte_row_width_ub is the upper bound of data_pitch*dpte_row_height in elements with this unique buffering. - */ - dpte_row_width_ub = dml_round_to_multiple( - data_pitch * dpte_row_height - 1, + // For linear, the dpte row is pitch dependent and the pte requests wrap at the pitch boundary. + // the dpte_row_width_ub is the upper bound of data_pitch*dpte_row_height in elements with this unique buffering. + dpte_row_height = 1 << log2_dpte_row_height; + dpte_row_width_ub = dml_round_to_multiple(data_pitch * dpte_row_height - 1, dpte_req_width, 1) + dpte_req_width; rq_dlg_param->dpte_req_per_row_ub = dpte_row_width_ub / dpte_req_width; } else { - /* for tiled mode, row height is the same as req height and row store up to vp size upper bound */ + // the upper bound of the dpte_row_width without dependency on viewport position follows. + // for tiled mode, row height is the same as req height and row store up to vp size upper bound if (!surf_vert) { log2_dpte_row_height = log2_dpte_req_height; dpte_row_width_ub = dml_round_to_multiple(vp_width - 1, dpte_req_width, 1) @@ -851,103 +588,117 @@ static void get_surf_rq_param( + dpte_req_height; rq_dlg_param->dpte_req_per_row_ub = dpte_row_width_ub / dpte_req_height; } - rq_dlg_param->dpte_row_height = 1 << log2_dpte_row_height; - } - rq_dlg_param->dpte_bytes_per_row_ub = rq_dlg_param->dpte_req_per_row_ub * 64; - - /* From programming guide: - * There is a special case of saving only half of ptes returned due to buffer space limits. - * this case applies to 4 and 8bpe in horizontal access of a vp_width greater than 2560+16 - * when the pte request is 2x4 ptes (which happens when vmpg_bytes =4kb and tile blk_bytes >=64kb). - */ - if (!surf_vert && vp_width > (2560 + 16) && bytes_per_element >= 4 && log2_vmpg_bytes == 12 - && log2_blk_bytes >= 16) { - log2_dpte_row_height = log2_dpte_row_height - 1; /*half of the full height */ - rq_dlg_param->dpte_row_height = 1 << log2_dpte_row_height; } + if (log2_blk_bytes >= 16 && log2_vmpg_bytes == 12) // tile block >= 64KB + rq_dlg_param->dpte_bytes_per_row_ub = rq_dlg_param->dpte_req_per_row_ub * 128; //2*64B dpte request + else + rq_dlg_param->dpte_bytes_per_row_ub = rq_dlg_param->dpte_req_per_row_ub * 64; //64B dpte request - /* the dpte_group_bytes is reduced for the specific case of vertical - * access of a tile surface that has dpte request of 8x1 ptes. - */ - if (!surf_linear & (log2_dpte_req_height_ptes == 0) & surf_vert) /*reduced, in this case, will have page fault within a group */ + rq_dlg_param->dpte_row_height = 1 << log2_dpte_row_height; + + // the dpte_group_bytes is reduced for the specific case of vertical + // access of a tile surface that has dpte request of 8x1 ptes. + if (!surf_linear & (log2_dpte_req_height_ptes == 0) & surf_vert) //reduced, in this case, will have page fault within a group rq_sizing_param->dpte_group_bytes = 512; else - /*full size */ + //full size rq_sizing_param->dpte_group_bytes = 2048; - /*since pte request size is 64byte, the number of data pte requests per full sized group is as follows. */ + //since pte request size is 64byte, the number of data pte requests per full sized group is as follows. log2_dpte_group_bytes = dml_log2(rq_sizing_param->dpte_group_bytes); - log2_dpte_group_length = log2_dpte_group_bytes - 6; /*length in 64b requests */ + log2_dpte_group_length = log2_dpte_group_bytes - 6; //length in 64b requests - /* full sized data pte group width in elements */ + // full sized data pte group width in elements if (!surf_vert) log2_dpte_group_width = log2_dpte_group_length + log2_dpte_req_width; else log2_dpte_group_width = log2_dpte_group_length + log2_dpte_req_height; + //But if the tile block >=64KB and the page size is 4KB, then each dPTE request is 2*64B + if ((log2_blk_bytes >= 16) && (log2_vmpg_bytes == 12)) // tile block >= 64KB + log2_dpte_group_width = log2_dpte_group_width - 1; + dpte_group_width = 1 << log2_dpte_group_width; - /* since dpte groups are only aligned to dpte_req_width and not dpte_group_width, - * the upper bound for the dpte groups per row is as follows. - */ - rq_dlg_param->dpte_groups_per_row_ub = dml_ceil( - (double) dpte_row_width_ub / dpte_group_width); + // since dpte groups are only aligned to dpte_req_width and not dpte_group_width, + // the upper bound for the dpte groups per row is as follows. + rq_dlg_param->dpte_groups_per_row_ub = dml_ceil((double) dpte_row_width_ub / dpte_group_width, + 1); +} + +static void get_surf_rq_param(struct display_mode_lib *mode_lib, + display_data_rq_sizing_params_st *rq_sizing_param, + display_data_rq_dlg_params_st *rq_dlg_param, + display_data_rq_misc_params_st *rq_misc_param, + const display_pipe_source_params_st pipe_src_param, + bool is_chroma) +{ + bool mode_422 = 0; + unsigned int vp_width = 0; + unsigned int vp_height = 0; + unsigned int data_pitch = 0; + unsigned int meta_pitch = 0; + unsigned int ppe = mode_422 ? 2 : 1; + + // FIXME check if ppe apply for both luma and chroma in 422 case + if (is_chroma) { + vp_width = pipe_src_param.viewport_width_c / ppe; + vp_height = pipe_src_param.viewport_height_c; + data_pitch = pipe_src_param.data_pitch_c; + meta_pitch = pipe_src_param.meta_pitch_c; + } else { + vp_width = pipe_src_param.viewport_width / ppe; + vp_height = pipe_src_param.viewport_height; + data_pitch = pipe_src_param.data_pitch; + meta_pitch = pipe_src_param.meta_pitch; + } + + rq_sizing_param->chunk_bytes = 8192; + + if (rq_sizing_param->chunk_bytes == 64 * 1024) + rq_sizing_param->min_chunk_bytes = 0; + else + rq_sizing_param->min_chunk_bytes = 1024; + + rq_sizing_param->meta_chunk_bytes = 2048; + rq_sizing_param->min_meta_chunk_bytes = 256; + + rq_sizing_param->mpte_group_bytes = 2048; - dml_rq_dlg_get_row_heights( - mode_lib, - &func_dpte_row_height, - &func_meta_row_height, + get_meta_and_pte_attr(mode_lib, + rq_dlg_param, + rq_misc_param, + rq_sizing_param, vp_width, + vp_height, data_pitch, + meta_pitch, pipe_src_param.source_format, pipe_src_param.sw_mode, pipe_src_param.macro_tile_size, pipe_src_param.source_scan, is_chroma); - - /* Just a check to make sure this function and the new one give the same - * result. The standalone get_row_heights() function is based off of the - * code in this function so the same changes need to be made to both. - */ - if (rq_dlg_param->meta_row_height != func_meta_row_height) { - DTRACE( - "MISMATCH: rq_dlg_param->meta_row_height = %d", - rq_dlg_param->meta_row_height); - DTRACE("MISMATCH: func_meta_row_height = %d", func_meta_row_height); - ASSERT(0); - } - - if (rq_dlg_param->dpte_row_height != func_dpte_row_height) { - DTRACE( - "MISMATCH: rq_dlg_param->dpte_row_height = %d", - rq_dlg_param->dpte_row_height); - DTRACE("MISMATCH: func_dpte_row_height = %d", func_dpte_row_height); - ASSERT(0); - } } -void dml_rq_dlg_get_rq_params( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_display_rq_params_st *rq_param, - const struct _vcs_dpi_display_pipe_source_params_st pipe_src_param) +void dml_rq_dlg_get_rq_params(struct display_mode_lib *mode_lib, + display_rq_params_st *rq_param, + const display_pipe_source_params_st pipe_src_param) { - /* get param for luma surface */ + // get param for luma surface rq_param->yuv420 = pipe_src_param.source_format == dm_420_8 || pipe_src_param.source_format == dm_420_10; rq_param->yuv420_10bpc = pipe_src_param.source_format == dm_420_10; - get_surf_rq_param( - mode_lib, + get_surf_rq_param(mode_lib, &(rq_param->sizing.rq_l), &(rq_param->dlg.rq_l), &(rq_param->misc.rq_l), pipe_src_param, 0); - if (is_dual_plane((enum source_format_class) pipe_src_param.source_format)) { - /* get param for chroma surface */ - get_surf_rq_param( - mode_lib, + if (is_dual_plane((enum source_format_class)(pipe_src_param.source_format))) { + // get param for chroma surface + get_surf_rq_param(mode_lib, &(rq_param->sizing.rq_c), &(rq_param->dlg.rq_c), &(rq_param->misc.rq_c), @@ -955,355 +706,126 @@ void dml_rq_dlg_get_rq_params( 1); } - /* calculate how to split the det buffer space between luma and chroma */ + // calculate how to split the det buffer space between luma and chroma handle_det_buf_split(mode_lib, rq_param, pipe_src_param); print__rq_params_st(mode_lib, *rq_param); } -void dml_rq_dlg_get_rq_reg( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_display_rq_regs_st *rq_regs, - const struct _vcs_dpi_display_pipe_source_params_st pipe_src_param) +void dml_rq_dlg_get_rq_reg(struct display_mode_lib *mode_lib, + display_rq_regs_st *rq_regs, + const display_pipe_source_params_st pipe_src_param) { - struct _vcs_dpi_display_rq_params_st rq_param = {0}; + display_rq_params_st rq_param = {0}; memset(rq_regs, 0, sizeof(*rq_regs)); - dml_rq_dlg_get_rq_params(mode_lib, &rq_param, pipe_src_param); extract_rq_regs(mode_lib, rq_regs, rq_param); print__rq_regs_st(mode_lib, *rq_regs); } -/* TODO: Need refactor, so this is used by dml_rq_dlg_get_dlg_params as well - * The problem is that there are some intermediate terms that would need by - * some dlg calculation (i.e. rest of prefetch and active prog guide calculation) - */ -void dml_rq_dlg_get_dlg_params_prefetch( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_display_dlg_prefetch_param_st *prefetch_param, - struct _vcs_dpi_display_rq_dlg_params_st rq_dlg_param, - struct _vcs_dpi_display_dlg_sys_params_st dlg_sys_param, - struct _vcs_dpi_display_e2e_pipe_params_st e2e_pipe_param, +// Note: currently taken in as is. +// Nice to decouple code from hw register implement and extract code that are repeated for luma and chroma. +void dml_rq_dlg_get_dlg_params(struct display_mode_lib *mode_lib, + const display_e2e_pipe_params_st *e2e_pipe_param, + const unsigned int num_pipes, + const unsigned int pipe_idx, + display_dlg_regs_st *disp_dlg_regs, + display_ttu_regs_st *disp_ttu_regs, + const display_rq_dlg_params_st rq_dlg_param, + const display_dlg_sys_params_st dlg_sys_param, const bool cstate_en, const bool pstate_en, - const bool vm_en) + const bool vm_en, + const bool ignore_viewport_pos, + const bool immediate_flip_support) { - /* Prefetch */ - unsigned int htotal = e2e_pipe_param.pipe.dest.htotal; - bool interlaced = e2e_pipe_param.pipe.dest.interlaced; + const display_pipe_source_params_st *src = &e2e_pipe_param[pipe_idx].pipe.src; + const display_pipe_dest_params_st *dst = &e2e_pipe_param[pipe_idx].pipe.dest; + const display_output_params_st *dout = &e2e_pipe_param[pipe_idx].dout; + const display_clocks_and_cfg_st *clks = &e2e_pipe_param[pipe_idx].clks_cfg; + const scaler_ratio_depth_st *scl = &e2e_pipe_param[pipe_idx].pipe.scale_ratio_depth; + const scaler_taps_st *taps = &e2e_pipe_param[pipe_idx].pipe.scale_taps; + + // ------------------------- + // Section 1.15.2.1: OTG dependent Params + // ------------------------- + // Timing + unsigned int htotal = dst->htotal; +// unsigned int hblank_start = dst.hblank_start; // TODO: Remove + unsigned int hblank_end = dst->hblank_end; + unsigned int vblank_start = dst->vblank_start; + unsigned int vblank_end = dst->vblank_end; unsigned int min_vblank = mode_lib->ip.min_vblank_lines; - const double prefetch_xy_calc_in_dcfclk = 24.0; /* FIXME: ip_param */ - double min_dcfclk_mhz = dlg_sys_param.deepsleep_dcfclk_mhz; - double t_calc_us = prefetch_xy_calc_in_dcfclk / min_dcfclk_mhz; - - bool dcc_en = e2e_pipe_param.pipe.src.dcc; - bool dual_plane = is_dual_plane( - (enum source_format_class) e2e_pipe_param.pipe.src.source_format); - unsigned int bytes_per_element_l = get_bytes_per_element( - (enum source_format_class) e2e_pipe_param.pipe.src.source_format, - 0); - unsigned int bytes_per_element_c = get_bytes_per_element( - (enum source_format_class) e2e_pipe_param.pipe.src.source_format, - 1); - - double pclk_freq_in_mhz = e2e_pipe_param.pipe.dest.pixel_rate_mhz; - double dppclk_freq_in_mhz = e2e_pipe_param.clks_cfg.dppclk_mhz; - double dispclk_freq_in_mhz = e2e_pipe_param.clks_cfg.dispclk_mhz; - - double line_time_in_us = (htotal / pclk_freq_in_mhz); - double vinit_l = e2e_pipe_param.pipe.scale_ratio_depth.vinit; - double vinit_c = e2e_pipe_param.pipe.scale_ratio_depth.vinit_c; - double vinit_bot_l = e2e_pipe_param.pipe.scale_ratio_depth.vinit_bot; - double vinit_bot_c = e2e_pipe_param.pipe.scale_ratio_depth.vinit_bot_c; - - unsigned int swath_height_l = rq_dlg_param.rq_l.swath_height; - unsigned int swath_width_ub_l = rq_dlg_param.rq_l.swath_width_ub; - unsigned int dpte_bytes_per_row_ub_l = rq_dlg_param.rq_l.dpte_bytes_per_row_ub; - unsigned int meta_pte_bytes_per_frame_ub_l = rq_dlg_param.rq_l.meta_pte_bytes_per_frame_ub; - unsigned int meta_bytes_per_row_ub_l = rq_dlg_param.rq_l.meta_bytes_per_row_ub; - - unsigned int swath_height_c = rq_dlg_param.rq_c.swath_height; - unsigned int swath_width_ub_c = rq_dlg_param.rq_c.swath_width_ub; - unsigned int dpte_bytes_per_row_ub_c = rq_dlg_param.rq_c.dpte_bytes_per_row_ub; - unsigned int vupdate_offset = e2e_pipe_param.pipe.dest.vupdate_offset; - unsigned int vupdate_width = e2e_pipe_param.pipe.dest.vupdate_width; - unsigned int vready_offset = e2e_pipe_param.pipe.dest.vready_offset; - - const unsigned int dppclk_delay_subtotal = mode_lib->ip.dppclk_delay_subtotal; - const unsigned int dispclk_delay_subtotal = mode_lib->ip.dispclk_delay_subtotal; - unsigned int pixel_rate_delay_subtotal = dppclk_delay_subtotal * pclk_freq_in_mhz - / dppclk_freq_in_mhz - + dispclk_delay_subtotal * pclk_freq_in_mhz / dispclk_freq_in_mhz; - unsigned int dst_y_after_scaler = 0; - unsigned int dst_x_after_scaler = 0; - unsigned int vstartup_start = e2e_pipe_param.pipe.dest.vstartup_start; + double dppclk_freq_in_mhz = clks->dppclk_mhz; + double dispclk_freq_in_mhz = clks->dispclk_mhz; + double refclk_freq_in_mhz = clks->refclk_mhz; + double pclk_freq_in_mhz = dst->pixel_rate_mhz; + bool interlaced = dst->interlaced; - double line_wait; - double line_o; - double line_setup; - double line_calc; - double dst_y_prefetch; - double t_pre_us; - int unsigned vm_bytes; - int unsigned meta_row_bytes; - int unsigned max_num_sw_l; - int unsigned max_num_sw_c; - int unsigned max_partial_sw_l; - int unsigned max_partial_sw_c; - - double max_vinit_l; - double max_vinit_c; - int unsigned lsw_l; - int unsigned lsw_c; - int unsigned sw_bytes_ub_l; - int unsigned sw_bytes_ub_c; - int unsigned sw_bytes; - int unsigned dpte_row_bytes; + double ref_freq_to_pix_freq = refclk_freq_in_mhz / pclk_freq_in_mhz; - if (interlaced) - vstartup_start = vstartup_start / 2; + double min_dcfclk_mhz; + double t_calc_us; + double min_ttu_vblank; - if (vstartup_start >= min_vblank) { - min_vblank = vstartup_start + 1; - DTRACE( - "WARNING_DLG: %s: vstartup_start=%d should be less than min_vblank=%d", - __func__, - vstartup_start, - min_vblank); - } + double min_dst_y_ttu_vblank; + unsigned int dlg_vblank_start; + bool dual_plane; + bool mode_422; + unsigned int access_dir; + unsigned int vp_height_l; + unsigned int vp_width_l; + unsigned int vp_height_c; + unsigned int vp_width_c; - if (e2e_pipe_param.pipe.src.is_hsplit) - dst_x_after_scaler = pixel_rate_delay_subtotal - + e2e_pipe_param.pipe.dest.recout_width; - else - dst_x_after_scaler = pixel_rate_delay_subtotal; + // Scaling + unsigned int htaps_l; + unsigned int htaps_c; + double hratio_l; + double hratio_c; + double vratio_l; + double vratio_c; + bool scl_enable; - if (e2e_pipe_param.dout.output_format == dm_420) - dst_y_after_scaler = 1; - else - dst_y_after_scaler = 0; + double line_time_in_us; + // double vinit_l; + // double vinit_c; + // double vinit_bot_l; + // double vinit_bot_c; - if (dst_x_after_scaler >= htotal) { - dst_x_after_scaler = dst_x_after_scaler - htotal; - dst_y_after_scaler = dst_y_after_scaler + 1; - } - - DTRACE("DLG: %s: htotal = %d", __func__, htotal); - DTRACE( - "DLG: %s: pixel_rate_delay_subtotal = %d", - __func__, - pixel_rate_delay_subtotal); - DTRACE("DLG: %s: dst_x_after_scaler = %d", __func__, dst_x_after_scaler); - DTRACE("DLG: %s: dst_y_after_scaler = %d", __func__, dst_y_after_scaler); - - line_wait = mode_lib->soc.urgent_latency_us; - if (cstate_en) - line_wait = dml_max(mode_lib->soc.sr_enter_plus_exit_time_us, line_wait); - if (pstate_en) - line_wait = dml_max( - mode_lib->soc.dram_clock_change_latency_us - + mode_lib->soc.urgent_latency_us, - line_wait); - line_wait = line_wait / line_time_in_us; - - line_o = (double) dst_y_after_scaler + dst_x_after_scaler / (double) htotal; - line_setup = (double) (vupdate_offset + vupdate_width + vready_offset) / (double) htotal; - line_calc = t_calc_us / line_time_in_us; - - DTRACE( - "DLG: %s: soc.sr_enter_plus_exit_time_us = %3.2f", - __func__, - (double) mode_lib->soc.sr_enter_plus_exit_time_us); - DTRACE( - "DLG: %s: soc.dram_clock_change_latency_us = %3.2f", - __func__, - (double) mode_lib->soc.dram_clock_change_latency_us); - - DTRACE("DLG: %s: urgent_latency_us = %3.2f", __func__, mode_lib->soc.urgent_latency_us); - DTRACE( - "DLG: %s: t_srx_delay_us = %3.2f", - __func__, - (double) dlg_sys_param.t_srx_delay_us); - DTRACE("DLG: %s: line_time_in_us = %3.2f", __func__, (double) line_time_in_us); - DTRACE("DLG: %s: vupdate_offset = %d", __func__, vupdate_offset); - DTRACE("DLG: %s: vupdate_width = %d", __func__, vupdate_width); - DTRACE("DLG: %s: vready_offset = %d", __func__, vready_offset); - DTRACE("DLG: %s: line_wait = %3.2f", __func__, line_wait); - DTRACE("DLG: %s: line_o = %3.2f", __func__, line_o); - DTRACE("DLG: %s: line_setup = %3.2f", __func__, line_setup); - DTRACE("DLG: %s: line_calc = %3.2f", __func__, line_calc); - - dst_y_prefetch = ((double) min_vblank - 1.0) - - (line_setup + line_calc + line_wait + line_o); - DTRACE("DLG: %s: dst_y_prefetch (before rnd) = %3.2f", __func__, dst_y_prefetch); - ASSERT(dst_y_prefetch >= 2.0); - - dst_y_prefetch = dml_floor(4.0 * (dst_y_prefetch + 0.125)) / 4; - DTRACE("DLG: %s: dst_y_prefetch (after rnd) = %3.2f", __func__, dst_y_prefetch); - - t_pre_us = dst_y_prefetch * line_time_in_us; - vm_bytes = 0; - meta_row_bytes = 0; - - if (dcc_en && vm_en) - vm_bytes = meta_pte_bytes_per_frame_ub_l; - if (dcc_en) - meta_row_bytes = meta_bytes_per_row_ub_l; - - max_num_sw_l = 0; - max_num_sw_c = 0; - max_partial_sw_l = 0; - max_partial_sw_c = 0; - - max_vinit_l = interlaced ? dml_max(vinit_l, vinit_bot_l) : vinit_l; - max_vinit_c = interlaced ? dml_max(vinit_c, vinit_bot_c) : vinit_c; - - get_swath_need(mode_lib, &max_num_sw_l, &max_partial_sw_l, swath_height_l, max_vinit_l); - if (dual_plane) - get_swath_need( - mode_lib, - &max_num_sw_c, - &max_partial_sw_c, - swath_height_c, - max_vinit_c); - - lsw_l = max_num_sw_l * swath_height_l + max_partial_sw_l; - lsw_c = max_num_sw_c * swath_height_c + max_partial_sw_c; - sw_bytes_ub_l = lsw_l * swath_width_ub_l * bytes_per_element_l; - sw_bytes_ub_c = lsw_c * swath_width_ub_c * bytes_per_element_c; - sw_bytes = 0; - dpte_row_bytes = 0; - - if (vm_en) { - if (dual_plane) - dpte_row_bytes = dpte_bytes_per_row_ub_l + dpte_bytes_per_row_ub_c; - else - dpte_row_bytes = dpte_bytes_per_row_ub_l; - } else { - dpte_row_bytes = 0; - } - - if (dual_plane) - sw_bytes = sw_bytes_ub_l + sw_bytes_ub_c; - else - sw_bytes = sw_bytes_ub_l; - - DTRACE("DLG: %s: sw_bytes_ub_l = %d", __func__, sw_bytes_ub_l); - DTRACE("DLG: %s: sw_bytes_ub_c = %d", __func__, sw_bytes_ub_c); - DTRACE("DLG: %s: sw_bytes = %d", __func__, sw_bytes); - DTRACE("DLG: %s: vm_bytes = %d", __func__, vm_bytes); - DTRACE("DLG: %s: meta_row_bytes = %d", __func__, meta_row_bytes); - DTRACE("DLG: %s: dpte_row_bytes = %d", __func__, dpte_row_bytes); - - prefetch_param->prefetch_bw = - (vm_bytes + 2 * dpte_row_bytes + 2 * meta_row_bytes + sw_bytes) / t_pre_us; - prefetch_param->flip_bytes = (vm_bytes + dpte_row_bytes + meta_row_bytes); -} - -/* Note: currently taken in as is. - * Nice to decouple code from hw register implement and extract code that are repeated for luma and chroma. - */ -void dml_rq_dlg_get_dlg_params( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_display_dlg_regs_st *disp_dlg_regs, - struct _vcs_dpi_display_ttu_regs_st *disp_ttu_regs, - const struct _vcs_dpi_display_rq_dlg_params_st rq_dlg_param, - const struct _vcs_dpi_display_dlg_sys_params_st dlg_sys_param, - const struct _vcs_dpi_display_e2e_pipe_params_st e2e_pipe_param, - const bool cstate_en, - const bool pstate_en, - const bool vm_en, - const bool iflip_en) -{ - /* Timing */ - unsigned int htotal = e2e_pipe_param.pipe.dest.htotal; - unsigned int hblank_end = e2e_pipe_param.pipe.dest.hblank_end; - unsigned int vblank_start = e2e_pipe_param.pipe.dest.vblank_start; - unsigned int vblank_end = e2e_pipe_param.pipe.dest.vblank_end; - bool interlaced = e2e_pipe_param.pipe.dest.interlaced; - unsigned int min_vblank = mode_lib->ip.min_vblank_lines; - - double pclk_freq_in_mhz = e2e_pipe_param.pipe.dest.pixel_rate_mhz; - double refclk_freq_in_mhz = e2e_pipe_param.clks_cfg.refclk_mhz; - double dppclk_freq_in_mhz = e2e_pipe_param.clks_cfg.dppclk_mhz; - double dispclk_freq_in_mhz = e2e_pipe_param.clks_cfg.dispclk_mhz; - - double ref_freq_to_pix_freq; - double prefetch_xy_calc_in_dcfclk; - double min_dcfclk_mhz; - double t_calc_us; - double min_ttu_vblank; - double min_dst_y_ttu_vblank; - int unsigned dlg_vblank_start; - bool dcc_en; - bool dual_plane; - bool mode_422; - unsigned int access_dir; - unsigned int bytes_per_element_l; - unsigned int bytes_per_element_c; - unsigned int vp_height_l; - unsigned int vp_width_l; - unsigned int vp_height_c; - unsigned int vp_width_c; - unsigned int htaps_l; - unsigned int htaps_c; - double hratios_l; - double hratios_c; - double vratio_l; - double vratio_c; - double line_time_in_us; - double vinit_l; - double vinit_c; - double vinit_bot_l; - double vinit_bot_c; - unsigned int swath_height_l; + // unsigned int swath_height_l; unsigned int swath_width_ub_l; - unsigned int dpte_bytes_per_row_ub_l; + // unsigned int dpte_bytes_per_row_ub_l; unsigned int dpte_groups_per_row_ub_l; - unsigned int meta_pte_bytes_per_frame_ub_l; - unsigned int meta_bytes_per_row_ub_l; - unsigned int swath_height_c; + // unsigned int meta_pte_bytes_per_frame_ub_l; + // unsigned int meta_bytes_per_row_ub_l; + + // unsigned int swath_height_c; unsigned int swath_width_ub_c; - unsigned int dpte_bytes_per_row_ub_c; + // unsigned int dpte_bytes_per_row_ub_c; unsigned int dpte_groups_per_row_ub_c; + unsigned int meta_chunks_per_row_ub_l; + unsigned int meta_chunks_per_row_ub_c; unsigned int vupdate_offset; unsigned int vupdate_width; unsigned int vready_offset; + unsigned int dppclk_delay_subtotal; unsigned int dispclk_delay_subtotal; unsigned int pixel_rate_delay_subtotal; + unsigned int vstartup_start; unsigned int dst_x_after_scaler; unsigned int dst_y_after_scaler; double line_wait; - double line_o; - double line_setup; - double line_calc; double dst_y_prefetch; - double t_pre_us; - int unsigned vm_bytes; - int unsigned meta_row_bytes; - int unsigned max_num_sw_l; - int unsigned max_num_sw_c; - int unsigned max_partial_sw_l; - int unsigned max_partial_sw_c; - double max_vinit_l; - double max_vinit_c; - int unsigned lsw_l; - int unsigned lsw_c; - int unsigned sw_bytes_ub_l; - int unsigned sw_bytes_ub_c; - int unsigned sw_bytes; - int unsigned dpte_row_bytes; - double prefetch_bw; - double flip_bw; - double t_vm_us; - double t_r0_us; double dst_y_per_vm_vblank; double dst_y_per_row_vblank; + double dst_y_per_vm_flip; + double dst_y_per_row_flip; double min_dst_y_per_vm_vblank; double min_dst_y_per_row_vblank; double lsw; @@ -1312,6 +834,7 @@ void dml_rq_dlg_get_dlg_params( unsigned int req_per_swath_ub_l; unsigned int req_per_swath_ub_c; unsigned int meta_row_height_l; + unsigned int meta_row_height_c; unsigned int swath_width_pixels_ub_l; unsigned int swath_width_pixels_ub_c; unsigned int scaler_rec_in_width_l; @@ -1326,59 +849,52 @@ void dml_rq_dlg_get_dlg_params( double refcyc_per_line_delivery_pre_c; double refcyc_per_line_delivery_l; double refcyc_per_line_delivery_c; + double refcyc_per_req_delivery_pre_l; double refcyc_per_req_delivery_pre_c; double refcyc_per_req_delivery_l; double refcyc_per_req_delivery_c; + + unsigned int full_recout_width; + double xfc_transfer_delay; + double xfc_precharge_delay; + double xfc_remote_surface_flip_latency; + double xfc_dst_y_delta_drq_limit; + double xfc_prefetch_margin; double refcyc_per_req_delivery_pre_cur0; double refcyc_per_req_delivery_cur0; - int unsigned full_recout_width; - double hratios_cur0; - unsigned int cur0_src_width; - enum cursor_bpp cur0_bpp; - unsigned int cur0_req_size; - unsigned int cur0_req_width; - double cur0_width_ub; - double cur0_req_per_width; - double hactive_cur0; + double refcyc_per_req_delivery_pre_cur1; + double refcyc_per_req_delivery_cur1; memset(disp_dlg_regs, 0, sizeof(*disp_dlg_regs)); memset(disp_ttu_regs, 0, sizeof(*disp_ttu_regs)); - DTRACE("DLG: %s: cstate_en = %d", __func__, cstate_en); - DTRACE("DLG: %s: pstate_en = %d", __func__, pstate_en); - DTRACE("DLG: %s: vm_en = %d", __func__, vm_en); - DTRACE("DLG: %s: iflip_en = %d", __func__, iflip_en); - - /* ------------------------- */ - /* Section 1.5.2.1: OTG dependent Params */ - /* ------------------------- */ - DTRACE("DLG: %s: dppclk_freq_in_mhz = %3.2f", __func__, dppclk_freq_in_mhz); - DTRACE("DLG: %s: dispclk_freq_in_mhz = %3.2f", __func__, dispclk_freq_in_mhz); - DTRACE("DLG: %s: refclk_freq_in_mhz = %3.2f", __func__, refclk_freq_in_mhz); - DTRACE("DLG: %s: pclk_freq_in_mhz = %3.2f", __func__, pclk_freq_in_mhz); - DTRACE("DLG: %s: interlaced = %d", __func__, interlaced); - - ref_freq_to_pix_freq = refclk_freq_in_mhz / pclk_freq_in_mhz; + dml_print("DML_DLG: %s: cstate_en = %d\n", __func__, cstate_en); + dml_print("DML_DLG: %s: pstate_en = %d\n", __func__, pstate_en); + dml_print("DML_DLG: %s: vm_en = %d\n", __func__, vm_en); + dml_print("DML_DLG: %s: ignore_viewport_pos = %d\n", __func__, ignore_viewport_pos); + dml_print("DML_DLG: %s: immediate_flip_support = %d\n", __func__, immediate_flip_support); + + dml_print("DML_DLG: %s: dppclk_freq_in_mhz = %3.2f\n", __func__, dppclk_freq_in_mhz); + dml_print("DML_DLG: %s: dispclk_freq_in_mhz = %3.2f\n", __func__, dispclk_freq_in_mhz); + dml_print("DML_DLG: %s: refclk_freq_in_mhz = %3.2f\n", __func__, refclk_freq_in_mhz); + dml_print("DML_DLG: %s: pclk_freq_in_mhz = %3.2f\n", __func__, pclk_freq_in_mhz); + dml_print("DML_DLG: %s: interlaced = %d\n", __func__, interlaced); ASSERT(ref_freq_to_pix_freq < 4.0); + disp_dlg_regs->ref_freq_to_pix_freq = (unsigned int) (ref_freq_to_pix_freq * dml_pow(2, 19)); disp_dlg_regs->refcyc_per_htotal = (unsigned int) (ref_freq_to_pix_freq * (double) htotal * dml_pow(2, 8)); + disp_dlg_regs->dlg_vblank_end = interlaced ? (vblank_end / 2) : vblank_end; // 15 bits disp_dlg_regs->refcyc_h_blank_end = (unsigned int) ((double) hblank_end * (double) ref_freq_to_pix_freq); ASSERT(disp_dlg_regs->refcyc_h_blank_end < (unsigned int) dml_pow(2, 13)); - disp_dlg_regs->dlg_vblank_end = interlaced ? (vblank_end / 2) : vblank_end; /* 15 bits */ - prefetch_xy_calc_in_dcfclk = 24.0; /* FIXME: ip_param */ min_dcfclk_mhz = dlg_sys_param.deepsleep_dcfclk_mhz; - t_calc_us = prefetch_xy_calc_in_dcfclk / min_dcfclk_mhz; - min_ttu_vblank = dlg_sys_param.t_urg_wm_us; - if (cstate_en) - min_ttu_vblank = dml_max(dlg_sys_param.t_sr_wm_us, min_ttu_vblank); - if (pstate_en) - min_ttu_vblank = dml_max(dlg_sys_param.t_mclk_wm_us, min_ttu_vblank); - min_ttu_vblank = min_ttu_vblank + t_calc_us; + set_prefetch_mode(mode_lib, cstate_en, pstate_en, ignore_viewport_pos, immediate_flip_support); + t_calc_us = get_tcalc(mode_lib, e2e_pipe_param, num_pipes); + min_ttu_vblank = get_min_ttu_vblank(mode_lib, e2e_pipe_param, num_pipes, pipe_idx); min_dst_y_ttu_vblank = min_ttu_vblank * pclk_freq_in_mhz / (double) htotal; dlg_vblank_start = interlaced ? (vblank_start / 2) : vblank_start; @@ -1387,383 +903,202 @@ void dml_rq_dlg_get_dlg_params( + min_dst_y_ttu_vblank) * dml_pow(2, 2)); ASSERT(disp_dlg_regs->min_dst_y_next_start < (unsigned int) dml_pow(2, 18)); - DTRACE("DLG: %s: min_dcfclk_mhz = %3.2f", __func__, min_dcfclk_mhz); - DTRACE("DLG: %s: min_ttu_vblank = %3.2f", __func__, min_ttu_vblank); - DTRACE( - "DLG: %s: min_dst_y_ttu_vblank = %3.2f", + dml_print("DML_DLG: %s: min_dcfclk_mhz = %3.2f\n", + __func__, + min_dcfclk_mhz); + dml_print("DML_DLG: %s: min_ttu_vblank = %3.2f\n", + __func__, + min_ttu_vblank); + dml_print("DML_DLG: %s: min_dst_y_ttu_vblank = %3.2f\n", __func__, min_dst_y_ttu_vblank); - DTRACE("DLG: %s: t_calc_us = %3.2f", __func__, t_calc_us); - DTRACE( - "DLG: %s: disp_dlg_regs->min_dst_y_next_start = 0x%0x", + dml_print("DML_DLG: %s: t_calc_us = %3.2f\n", + __func__, + t_calc_us); + dml_print("DML_DLG: %s: disp_dlg_regs->min_dst_y_next_start = 0x%0x\n", __func__, disp_dlg_regs->min_dst_y_next_start); - DTRACE( - "DLG: %s: ref_freq_to_pix_freq = %3.2f", + dml_print("DML_DLG: %s: ref_freq_to_pix_freq = %3.2f\n", __func__, ref_freq_to_pix_freq); - /* ------------------------- */ - /* Section 1.5.2.2: Prefetch, Active and TTU */ - /* ------------------------- */ - /* Prefetch Calc */ - /* Source */ - dcc_en = e2e_pipe_param.pipe.src.dcc; - dual_plane = is_dual_plane( - (enum source_format_class) e2e_pipe_param.pipe.src.source_format); - mode_422 = 0; /* FIXME */ - access_dir = (e2e_pipe_param.pipe.src.source_scan == dm_vert); /* vp access direction: horizontal or vertical accessed */ - bytes_per_element_l = get_bytes_per_element( - (enum source_format_class) e2e_pipe_param.pipe.src.source_format, - 0); - bytes_per_element_c = get_bytes_per_element( - (enum source_format_class) e2e_pipe_param.pipe.src.source_format, - 1); - vp_height_l = e2e_pipe_param.pipe.src.viewport_height; - vp_width_l = e2e_pipe_param.pipe.src.viewport_width; - vp_height_c = e2e_pipe_param.pipe.src.viewport_height_c; - vp_width_c = e2e_pipe_param.pipe.src.viewport_width_c; - - /* Scaling */ - htaps_l = e2e_pipe_param.pipe.scale_taps.htaps; - htaps_c = e2e_pipe_param.pipe.scale_taps.htaps_c; - hratios_l = e2e_pipe_param.pipe.scale_ratio_depth.hscl_ratio; - hratios_c = e2e_pipe_param.pipe.scale_ratio_depth.hscl_ratio_c; - vratio_l = e2e_pipe_param.pipe.scale_ratio_depth.vscl_ratio; - vratio_c = e2e_pipe_param.pipe.scale_ratio_depth.vscl_ratio_c; + // ------------------------- + // Section 1.15.2.2: Prefetch, Active and TTU + // ------------------------- + // Prefetch Calc + // Source +// dcc_en = src.dcc; + dual_plane = is_dual_plane((enum source_format_class)(src->source_format)); + mode_422 = 0; // FIXME + access_dir = (src->source_scan == dm_vert); // vp access direction: horizontal or vertical accessed +// bytes_per_element_l = get_bytes_per_element(source_format_class(src.source_format), 0); +// bytes_per_element_c = get_bytes_per_element(source_format_class(src.source_format), 1); + vp_height_l = src->viewport_height; + vp_width_l = src->viewport_width; + vp_height_c = src->viewport_height_c; + vp_width_c = src->viewport_width_c; + + // Scaling + htaps_l = taps->htaps; + htaps_c = taps->htaps_c; + hratio_l = scl->hscl_ratio; + hratio_c = scl->hscl_ratio_c; + vratio_l = scl->vscl_ratio; + vratio_c = scl->vscl_ratio_c; + scl_enable = scl->scl_enable; line_time_in_us = (htotal / pclk_freq_in_mhz); - vinit_l = e2e_pipe_param.pipe.scale_ratio_depth.vinit; - vinit_c = e2e_pipe_param.pipe.scale_ratio_depth.vinit_c; - vinit_bot_l = e2e_pipe_param.pipe.scale_ratio_depth.vinit_bot; - vinit_bot_c = e2e_pipe_param.pipe.scale_ratio_depth.vinit_bot_c; +// vinit_l = scl.vinit; +// vinit_c = scl.vinit_c; +// vinit_bot_l = scl.vinit_bot; +// vinit_bot_c = scl.vinit_bot_c; - swath_height_l = rq_dlg_param.rq_l.swath_height; +// unsigned int swath_height_l = rq_dlg_param.rq_l.swath_height; swath_width_ub_l = rq_dlg_param.rq_l.swath_width_ub; - dpte_bytes_per_row_ub_l = rq_dlg_param.rq_l.dpte_bytes_per_row_ub; +// unsigned int dpte_bytes_per_row_ub_l = rq_dlg_param.rq_l.dpte_bytes_per_row_ub; dpte_groups_per_row_ub_l = rq_dlg_param.rq_l.dpte_groups_per_row_ub; - meta_pte_bytes_per_frame_ub_l = rq_dlg_param.rq_l.meta_pte_bytes_per_frame_ub; - meta_bytes_per_row_ub_l = rq_dlg_param.rq_l.meta_bytes_per_row_ub; +// unsigned int meta_pte_bytes_per_frame_ub_l = rq_dlg_param.rq_l.meta_pte_bytes_per_frame_ub; +// unsigned int meta_bytes_per_row_ub_l = rq_dlg_param.rq_l.meta_bytes_per_row_ub; - swath_height_c = rq_dlg_param.rq_c.swath_height; +// unsigned int swath_height_c = rq_dlg_param.rq_c.swath_height; swath_width_ub_c = rq_dlg_param.rq_c.swath_width_ub; - dpte_bytes_per_row_ub_c = rq_dlg_param.rq_c.dpte_bytes_per_row_ub; + // dpte_bytes_per_row_ub_c = rq_dlg_param.rq_c.dpte_bytes_per_row_ub; dpte_groups_per_row_ub_c = rq_dlg_param.rq_c.dpte_groups_per_row_ub; meta_chunks_per_row_ub_l = rq_dlg_param.rq_l.meta_chunks_per_row_ub; - vupdate_offset = e2e_pipe_param.pipe.dest.vupdate_offset; - vupdate_width = e2e_pipe_param.pipe.dest.vupdate_width; - vready_offset = e2e_pipe_param.pipe.dest.vready_offset; + meta_chunks_per_row_ub_c = rq_dlg_param.rq_c.meta_chunks_per_row_ub; + vupdate_offset = dst->vupdate_offset; + vupdate_width = dst->vupdate_width; + vready_offset = dst->vready_offset; dppclk_delay_subtotal = mode_lib->ip.dppclk_delay_subtotal; dispclk_delay_subtotal = mode_lib->ip.dispclk_delay_subtotal; + + if (scl_enable) + dppclk_delay_subtotal += mode_lib->ip.dppclk_delay_scl; + else + dppclk_delay_subtotal += mode_lib->ip.dppclk_delay_scl_lb_only; + + dppclk_delay_subtotal += mode_lib->ip.dppclk_delay_cnvc_formatter + + src->num_cursors * mode_lib->ip.dppclk_delay_cnvc_cursor; + + if (dout->dsc_enable) { + double dsc_delay = get_dsc_delay(mode_lib, e2e_pipe_param, num_pipes, pipe_idx); + + dispclk_delay_subtotal += dsc_delay; + } + pixel_rate_delay_subtotal = dppclk_delay_subtotal * pclk_freq_in_mhz / dppclk_freq_in_mhz + dispclk_delay_subtotal * pclk_freq_in_mhz / dispclk_freq_in_mhz; - vstartup_start = e2e_pipe_param.pipe.dest.vstartup_start; + vstartup_start = dst->vstartup_start; + if (interlaced) { + if (vstartup_start / 2.0 + - (double) (vready_offset + vupdate_width + vupdate_offset) / htotal + <= vblank_end / 2.0) + disp_dlg_regs->vready_after_vcount0 = 1; + else + disp_dlg_regs->vready_after_vcount0 = 0; + } else { + if (vstartup_start + - (double) (vready_offset + vupdate_width + vupdate_offset) / htotal + <= vblank_end) + disp_dlg_regs->vready_after_vcount0 = 1; + else + disp_dlg_regs->vready_after_vcount0 = 0; + } + // TODO: Where is this coming from? if (interlaced) vstartup_start = vstartup_start / 2; + // TODO: What if this min_vblank doesn't match the value in the dml_config_settings.cpp? if (vstartup_start >= min_vblank) { - DTRACE( - "WARNING_DLG: %s: vblank_start=%d vblank_end=%d", + dml_print("WARNING: DML_DLG: %s: vblank_start=%d vblank_end=%d\n", __func__, vblank_start, vblank_end); - DTRACE( - "WARNING_DLG: %s: vstartup_start=%d should be less than min_vblank=%d", + dml_print("WARNING: DML_DLG: %s: vstartup_start=%d should be less than min_vblank=%d\n", __func__, vstartup_start, min_vblank); min_vblank = vstartup_start + 1; - DTRACE( - "WARNING_DLG: %s: vstartup_start=%d should be less than min_vblank=%d", + dml_print("WARNING: DML_DLG: %s: vstartup_start=%d should be less than min_vblank=%d\n", __func__, vstartup_start, min_vblank); } - dst_x_after_scaler = 0; - dst_y_after_scaler = 0; - - if (e2e_pipe_param.pipe.src.is_hsplit) - dst_x_after_scaler = pixel_rate_delay_subtotal - + e2e_pipe_param.pipe.dest.recout_width; - else - dst_x_after_scaler = pixel_rate_delay_subtotal; - - if (e2e_pipe_param.dout.output_format == dm_420) - dst_y_after_scaler = 1; - else - dst_y_after_scaler = 0; - - if (dst_x_after_scaler >= htotal) { - dst_x_after_scaler = dst_x_after_scaler - htotal; - dst_y_after_scaler = dst_y_after_scaler + 1; - } + dst_x_after_scaler = get_dst_x_after_scaler(mode_lib, e2e_pipe_param, num_pipes, pipe_idx); + dst_y_after_scaler = get_dst_y_after_scaler(mode_lib, e2e_pipe_param, num_pipes, pipe_idx); - DTRACE("DLG: %s: htotal = %d", __func__, htotal); - DTRACE( - "DLG: %s: pixel_rate_delay_subtotal = %d", + dml_print("DML_DLG: %s: htotal = %d\n", __func__, htotal); + dml_print("DML_DLG: %s: pixel_rate_delay_subtotal = %d\n", __func__, pixel_rate_delay_subtotal); - DTRACE("DLG: %s: dst_x_after_scaler = %d", __func__, dst_x_after_scaler); - DTRACE("DLG: %s: dst_y_after_scaler = %d", __func__, dst_y_after_scaler); + dml_print("DML_DLG: %s: dst_x_after_scaler = %d\n", + __func__, + dst_x_after_scaler); + dml_print("DML_DLG: %s: dst_y_after_scaler = %d\n", + __func__, + dst_y_after_scaler); + // Lwait line_wait = mode_lib->soc.urgent_latency_us; if (cstate_en) line_wait = dml_max(mode_lib->soc.sr_enter_plus_exit_time_us, line_wait); if (pstate_en) - line_wait = dml_max( - mode_lib->soc.dram_clock_change_latency_us + line_wait = dml_max(mode_lib->soc.dram_clock_change_latency_us + mode_lib->soc.urgent_latency_us, line_wait); line_wait = line_wait / line_time_in_us; - line_o = (double) dst_y_after_scaler + dst_x_after_scaler / (double) htotal; - line_setup = (double) (vupdate_offset + vupdate_width + vready_offset) / (double) htotal; - line_calc = t_calc_us / line_time_in_us; + dst_y_prefetch = get_dst_y_prefetch(mode_lib, e2e_pipe_param, num_pipes, pipe_idx); + dml_print("DML_DLG: %s: dst_y_prefetch (after rnd) = %3.2f\n", __func__, dst_y_prefetch); - DTRACE( - "DLG: %s: soc.sr_enter_plus_exit_time_us = %3.2f", - __func__, - (double) mode_lib->soc.sr_enter_plus_exit_time_us); - DTRACE( - "DLG: %s: soc.dram_clock_change_latency_us = %3.2f", - __func__, - (double) mode_lib->soc.dram_clock_change_latency_us); - DTRACE( - "DLG: %s: soc.urgent_latency_us = %3.2f", - __func__, - mode_lib->soc.urgent_latency_us); - - DTRACE("DLG: %s: swath_height_l = %d", __func__, swath_height_l); - if (dual_plane) - DTRACE("DLG: %s: swath_height_c = %d", __func__, swath_height_c); - - DTRACE( - "DLG: %s: t_srx_delay_us = %3.2f", - __func__, - (double) dlg_sys_param.t_srx_delay_us); - DTRACE("DLG: %s: line_time_in_us = %3.2f", __func__, (double) line_time_in_us); - DTRACE("DLG: %s: vupdate_offset = %d", __func__, vupdate_offset); - DTRACE("DLG: %s: vupdate_width = %d", __func__, vupdate_width); - DTRACE("DLG: %s: vready_offset = %d", __func__, vready_offset); - DTRACE("DLG: %s: line_time_in_us = %3.2f", __func__, line_time_in_us); - DTRACE("DLG: %s: line_wait = %3.2f", __func__, line_wait); - DTRACE("DLG: %s: line_o = %3.2f", __func__, line_o); - DTRACE("DLG: %s: line_setup = %3.2f", __func__, line_setup); - DTRACE("DLG: %s: line_calc = %3.2f", __func__, line_calc); - - dst_y_prefetch = ((double) min_vblank - 1.0) - - (line_setup + line_calc + line_wait + line_o); - DTRACE("DLG: %s: dst_y_prefetch (before rnd) = %3.2f", __func__, dst_y_prefetch); - ASSERT(dst_y_prefetch >= 2.0); - - dst_y_prefetch = dml_floor(4.0 * (dst_y_prefetch + 0.125)) / 4; - DTRACE("DLG: %s: dst_y_prefetch (after rnd) = %3.2f", __func__, dst_y_prefetch); - - t_pre_us = dst_y_prefetch * line_time_in_us; - vm_bytes = 0; - meta_row_bytes = 0; - - if (dcc_en && vm_en) - vm_bytes = meta_pte_bytes_per_frame_ub_l; - if (dcc_en) - meta_row_bytes = meta_bytes_per_row_ub_l; - - max_num_sw_l = 0; - max_num_sw_c = 0; - max_partial_sw_l = 0; - max_partial_sw_c = 0; - - max_vinit_l = interlaced ? dml_max(vinit_l, vinit_bot_l) : vinit_l; - max_vinit_c = interlaced ? dml_max(vinit_c, vinit_bot_c) : vinit_c; - - get_swath_need(mode_lib, &max_num_sw_l, &max_partial_sw_l, swath_height_l, max_vinit_l); - if (dual_plane) - get_swath_need( - mode_lib, - &max_num_sw_c, - &max_partial_sw_c, - swath_height_c, - max_vinit_c); - - lsw_l = max_num_sw_l * swath_height_l + max_partial_sw_l; - lsw_c = max_num_sw_c * swath_height_c + max_partial_sw_c; - sw_bytes_ub_l = lsw_l * swath_width_ub_l * bytes_per_element_l; - sw_bytes_ub_c = lsw_c * swath_width_ub_c * bytes_per_element_c; - sw_bytes = 0; - dpte_row_bytes = 0; - - if (vm_en) { - if (dual_plane) - dpte_row_bytes = dpte_bytes_per_row_ub_l + dpte_bytes_per_row_ub_c; - else - dpte_row_bytes = dpte_bytes_per_row_ub_l; - } else { - dpte_row_bytes = 0; - } - - if (dual_plane) - sw_bytes = sw_bytes_ub_l + sw_bytes_ub_c; - else - sw_bytes = sw_bytes_ub_l; - - DTRACE("DLG: %s: sw_bytes_ub_l = %d", __func__, sw_bytes_ub_l); - DTRACE("DLG: %s: sw_bytes_ub_c = %d", __func__, sw_bytes_ub_c); - DTRACE("DLG: %s: sw_bytes = %d", __func__, sw_bytes); - DTRACE("DLG: %s: vm_bytes = %d", __func__, vm_bytes); - DTRACE("DLG: %s: meta_row_bytes = %d", __func__, meta_row_bytes); - DTRACE("DLG: %s: dpte_row_bytes = %d", __func__, dpte_row_bytes); - - prefetch_bw = (vm_bytes + 2 * dpte_row_bytes + 2 * meta_row_bytes + sw_bytes) / t_pre_us; - flip_bw = ((vm_bytes + dpte_row_bytes + meta_row_bytes) * dlg_sys_param.total_flip_bw) - / (double) dlg_sys_param.total_flip_bytes; - t_vm_us = line_time_in_us / 4.0; - if (vm_en && dcc_en) { - t_vm_us = dml_max( - dlg_sys_param.t_extra_us, - dml_max((double) vm_bytes / prefetch_bw, t_vm_us)); - - if (iflip_en && !dual_plane) { - t_vm_us = dml_max(mode_lib->soc.urgent_latency_us, t_vm_us); - if (flip_bw > 0.) - t_vm_us = dml_max(vm_bytes / flip_bw, t_vm_us); - } - } - - t_r0_us = dml_max(dlg_sys_param.t_extra_us - t_vm_us, line_time_in_us - t_vm_us); - - if (vm_en || dcc_en) { - t_r0_us = dml_max( - (double) (dpte_row_bytes + meta_row_bytes) / prefetch_bw, - dlg_sys_param.t_extra_us); - t_r0_us = dml_max((double) (line_time_in_us - t_vm_us), t_r0_us); - - if (iflip_en && !dual_plane) { - t_r0_us = dml_max(mode_lib->soc.urgent_latency_us * 2.0, t_r0_us); - if (flip_bw > 0.) - t_r0_us = dml_max( - (dpte_row_bytes + meta_row_bytes) / flip_bw, - t_r0_us); - } - } - - disp_dlg_regs->dst_y_after_scaler = dst_y_after_scaler; /* in terms of line */ - disp_dlg_regs->refcyc_x_after_scaler = dst_x_after_scaler * ref_freq_to_pix_freq; /* in terms of refclk */ - ASSERT(disp_dlg_regs->refcyc_x_after_scaler < (unsigned int) dml_pow(2, 13)); - DTRACE( - "DLG: %s: disp_dlg_regs->dst_y_after_scaler = 0x%0x", - __func__, - disp_dlg_regs->dst_y_after_scaler); - DTRACE( - "DLG: %s: disp_dlg_regs->refcyc_x_after_scaler = 0x%0x", - __func__, - disp_dlg_regs->refcyc_x_after_scaler); - - disp_dlg_regs->dst_y_prefetch = (unsigned int) (dst_y_prefetch * dml_pow(2, 2)); - DTRACE( - "DLG: %s: disp_dlg_regs->dst_y_prefetch = %d", - __func__, - disp_dlg_regs->dst_y_prefetch); - - dst_y_per_vm_vblank = 0.0; - dst_y_per_row_vblank = 0.0; - - dst_y_per_vm_vblank = t_vm_us / line_time_in_us; - dst_y_per_vm_vblank = dml_floor(4.0 * (dst_y_per_vm_vblank + 0.125)) / 4.0; - disp_dlg_regs->dst_y_per_vm_vblank = (unsigned int) (dst_y_per_vm_vblank * dml_pow(2, 2)); - - dst_y_per_row_vblank = t_r0_us / line_time_in_us; - dst_y_per_row_vblank = dml_floor(4.0 * (dst_y_per_row_vblank + 0.125)) / 4.0; - disp_dlg_regs->dst_y_per_row_vblank = (unsigned int) (dst_y_per_row_vblank * dml_pow(2, 2)); - - DTRACE("DLG: %s: lsw_l = %d", __func__, lsw_l); - DTRACE("DLG: %s: lsw_c = %d", __func__, lsw_c); - DTRACE("DLG: %s: dpte_bytes_per_row_ub_l = %d", __func__, dpte_bytes_per_row_ub_l); - DTRACE("DLG: %s: dpte_bytes_per_row_ub_c = %d", __func__, dpte_bytes_per_row_ub_c); - - DTRACE("DLG: %s: prefetch_bw = %3.2f", __func__, prefetch_bw); - DTRACE("DLG: %s: flip_bw = %3.2f", __func__, flip_bw); - DTRACE("DLG: %s: t_pre_us = %3.2f", __func__, t_pre_us); - DTRACE("DLG: %s: t_vm_us = %3.2f", __func__, t_vm_us); - DTRACE("DLG: %s: t_r0_us = %3.2f", __func__, t_r0_us); - DTRACE("DLG: %s: dst_y_per_vm_vblank = %3.2f", __func__, dst_y_per_vm_vblank); - DTRACE("DLG: %s: dst_y_per_row_vblank = %3.2f", __func__, dst_y_per_row_vblank); - DTRACE("DLG: %s: dst_y_prefetch = %3.2f", __func__, dst_y_prefetch); + dst_y_per_vm_vblank = get_dst_y_per_vm_vblank(mode_lib, + e2e_pipe_param, + num_pipes, + pipe_idx); + dst_y_per_row_vblank = get_dst_y_per_row_vblank(mode_lib, + e2e_pipe_param, + num_pipes, + pipe_idx); + dst_y_per_vm_flip = get_dst_y_per_vm_flip(mode_lib, e2e_pipe_param, num_pipes, pipe_idx); + dst_y_per_row_flip = get_dst_y_per_row_flip(mode_lib, e2e_pipe_param, num_pipes, pipe_idx); min_dst_y_per_vm_vblank = 8.0; min_dst_y_per_row_vblank = 16.0; + + // magic! if (htotal <= 75) { min_vblank = 300; min_dst_y_per_vm_vblank = 100.0; min_dst_y_per_row_vblank = 100.0; } + dml_print("DML_DLG: %s: dst_y_per_vm_vblank = %3.2f\n", __func__, dst_y_per_vm_vblank); + dml_print("DML_DLG: %s: dst_y_per_row_vblank = %3.2f\n", __func__, dst_y_per_row_vblank); + ASSERT(dst_y_per_vm_vblank < min_dst_y_per_vm_vblank); ASSERT(dst_y_per_row_vblank < min_dst_y_per_row_vblank); ASSERT(dst_y_prefetch > (dst_y_per_vm_vblank + dst_y_per_row_vblank)); lsw = dst_y_prefetch - (dst_y_per_vm_vblank + dst_y_per_row_vblank); - DTRACE("DLG: %s: lsw = %3.2f", __func__, lsw); - - vratio_pre_l = get_vratio_pre( - mode_lib, - max_num_sw_l, - max_partial_sw_l, - swath_height_l, - max_vinit_l, - lsw); - vratio_pre_c = 1.0; - if (dual_plane) - vratio_pre_c = get_vratio_pre( - mode_lib, - max_num_sw_c, - max_partial_sw_c, - swath_height_c, - max_vinit_c, - lsw); - - DTRACE("DLG: %s: vratio_pre_l=%3.2f", __func__, vratio_pre_l); - DTRACE("DLG: %s: vratio_pre_c=%3.2f", __func__, vratio_pre_c); - - ASSERT(vratio_pre_l <= 4.0); - if (vratio_pre_l >= 4.0) - disp_dlg_regs->vratio_prefetch = (unsigned int) dml_pow(2, 21) - 1; - else - disp_dlg_regs->vratio_prefetch = (unsigned int) (vratio_pre_l * dml_pow(2, 19)); - - ASSERT(vratio_pre_c <= 4.0); - if (vratio_pre_c >= 4.0) - disp_dlg_regs->vratio_prefetch_c = (unsigned int) dml_pow(2, 21) - 1; - else - disp_dlg_regs->vratio_prefetch_c = (unsigned int) (vratio_pre_c * dml_pow(2, 19)); - - disp_dlg_regs->refcyc_per_pte_group_vblank_l = - (unsigned int) (dst_y_per_row_vblank * (double) htotal - * ref_freq_to_pix_freq / (double) dpte_groups_per_row_ub_l); - ASSERT(disp_dlg_regs->refcyc_per_pte_group_vblank_l < (unsigned int) dml_pow(2, 13)); - - disp_dlg_regs->refcyc_per_pte_group_vblank_c = - (unsigned int) (dst_y_per_row_vblank * (double) htotal - * ref_freq_to_pix_freq / (double) dpte_groups_per_row_ub_c); - ASSERT(disp_dlg_regs->refcyc_per_pte_group_vblank_c < (unsigned int) dml_pow(2, 13)); + dml_print("DML_DLG: %s: lsw = %3.2f\n", __func__, lsw); - disp_dlg_regs->refcyc_per_meta_chunk_vblank_l = - (unsigned int) (dst_y_per_row_vblank * (double) htotal - * ref_freq_to_pix_freq / (double) meta_chunks_per_row_ub_l); - ASSERT(disp_dlg_regs->refcyc_per_meta_chunk_vblank_l < (unsigned int) dml_pow(2, 13)); + vratio_pre_l = get_vratio_prefetch_l(mode_lib, e2e_pipe_param, num_pipes, pipe_idx); + vratio_pre_c = get_vratio_prefetch_c(mode_lib, e2e_pipe_param, num_pipes, pipe_idx); - disp_dlg_regs->refcyc_per_meta_chunk_vblank_c = - disp_dlg_regs->refcyc_per_meta_chunk_vblank_l;/* dcc for 4:2:0 is not supported in dcn1.0. assigned to be the same as _l for now */ + dml_print("DML_DLG: %s: vratio_pre_l=%3.2f\n", __func__, vratio_pre_l); + dml_print("DML_DLG: %s: vratio_pre_c=%3.2f\n", __func__, vratio_pre_c); - /* Active */ + // Active req_per_swath_ub_l = rq_dlg_param.rq_l.req_per_swath_ub; req_per_swath_ub_c = rq_dlg_param.rq_c.req_per_swath_ub; meta_row_height_l = rq_dlg_param.rq_l.meta_row_height; + meta_row_height_c = rq_dlg_param.rq_c.meta_row_height; swath_width_pixels_ub_l = 0; swath_width_pixels_ub_c = 0; scaler_rec_in_width_l = 0; @@ -1771,40 +1106,8 @@ void dml_rq_dlg_get_dlg_params( dpte_row_height_l = rq_dlg_param.rq_l.dpte_row_height; dpte_row_height_c = rq_dlg_param.rq_c.dpte_row_height; - disp_dlg_regs->dst_y_per_pte_row_nom_l = (unsigned int) ((double) dpte_row_height_l - / (double) vratio_l * dml_pow(2, 2)); - ASSERT(disp_dlg_regs->dst_y_per_pte_row_nom_l < (unsigned int) dml_pow(2, 17)); - - disp_dlg_regs->dst_y_per_pte_row_nom_c = (unsigned int) ((double) dpte_row_height_c - / (double) vratio_c * dml_pow(2, 2)); - ASSERT(disp_dlg_regs->dst_y_per_pte_row_nom_c < (unsigned int) dml_pow(2, 17)); - - disp_dlg_regs->dst_y_per_meta_row_nom_l = (unsigned int) ((double) meta_row_height_l - / (double) vratio_l * dml_pow(2, 2)); - ASSERT(disp_dlg_regs->dst_y_per_meta_row_nom_l < (unsigned int) dml_pow(2, 17)); - - disp_dlg_regs->dst_y_per_meta_row_nom_c = disp_dlg_regs->dst_y_per_meta_row_nom_l; /* dcc for 4:2:0 is not supported in dcn1.0. assigned to be the same as _l for now */ - - disp_dlg_regs->refcyc_per_pte_group_nom_l = (unsigned int) ((double) dpte_row_height_l - / (double) vratio_l * (double) htotal * ref_freq_to_pix_freq - / (double) dpte_groups_per_row_ub_l); - if (disp_dlg_regs->refcyc_per_pte_group_nom_l >= (unsigned int) dml_pow(2, 23)) - disp_dlg_regs->refcyc_per_pte_group_nom_l = dml_pow(2, 23) - 1; - - disp_dlg_regs->refcyc_per_pte_group_nom_c = (unsigned int) ((double) dpte_row_height_c - / (double) vratio_c * (double) htotal * ref_freq_to_pix_freq - / (double) dpte_groups_per_row_ub_c); - if (disp_dlg_regs->refcyc_per_pte_group_nom_c >= (unsigned int) dml_pow(2, 23)) - disp_dlg_regs->refcyc_per_pte_group_nom_c = dml_pow(2, 23) - 1; - - disp_dlg_regs->refcyc_per_meta_chunk_nom_l = (unsigned int) ((double) meta_row_height_l - / (double) vratio_l * (double) htotal * ref_freq_to_pix_freq - / (double) meta_chunks_per_row_ub_l); - if (disp_dlg_regs->refcyc_per_meta_chunk_nom_l >= (unsigned int) dml_pow(2, 23)) - disp_dlg_regs->refcyc_per_meta_chunk_nom_l = dml_pow(2, 23) - 1; - if (mode_422) { - swath_width_pixels_ub_l = swath_width_ub_l * 2; /* *2 for 2 pixel per element */ + swath_width_pixels_ub_l = swath_width_ub_l * 2; // *2 for 2 pixel per element swath_width_pixels_ub_c = swath_width_ub_c * 2; } else { swath_width_pixels_ub_l = swath_width_ub_l * 1; @@ -1819,15 +1122,15 @@ void dml_rq_dlg_get_dlg_params( if (htaps_l <= 1) min_hratio_fact_l = 2.0; else if (htaps_l <= 6) { - if ((hratios_l * 2.0) > 4.0) + if ((hratio_l * 2.0) > 4.0) min_hratio_fact_l = 4.0; else - min_hratio_fact_l = hratios_l * 2.0; + min_hratio_fact_l = hratio_l * 2.0; } else { - if (hratios_l > 4.0) + if (hratio_l > 4.0) min_hratio_fact_l = 4.0; else - min_hratio_fact_l = hratios_l; + min_hratio_fact_l = hratio_l; } hscale_pixel_rate_l = min_hratio_fact_l * dppclk_freq_in_mhz; @@ -1835,15 +1138,15 @@ void dml_rq_dlg_get_dlg_params( if (htaps_c <= 1) min_hratio_fact_c = 2.0; else if (htaps_c <= 6) { - if ((hratios_c * 2.0) > 4.0) + if ((hratio_c * 2.0) > 4.0) min_hratio_fact_c = 4.0; else - min_hratio_fact_c = hratios_c * 2.0; + min_hratio_fact_c = hratio_c * 2.0; } else { - if (hratios_c > 4.0) + if (hratio_c > 4.0) min_hratio_fact_c = 4.0; else - min_hratio_fact_c = hratios_c; + min_hratio_fact_c = hratio_c; } hscale_pixel_rate_c = min_hratio_fact_c * dppclk_freq_in_mhz; @@ -1857,97 +1160,90 @@ void dml_rq_dlg_get_dlg_params( refcyc_per_req_delivery_pre_c = 0.; refcyc_per_req_delivery_l = 0.; refcyc_per_req_delivery_c = 0.; - refcyc_per_req_delivery_pre_cur0 = 0.; - refcyc_per_req_delivery_cur0 = 0.; full_recout_width = 0; - if (e2e_pipe_param.pipe.src.is_hsplit) { - if (e2e_pipe_param.pipe.dest.full_recout_width == 0) { - DTRACE("DLG: %s: Warningfull_recout_width not set in hsplit mode", __func__); - full_recout_width = e2e_pipe_param.pipe.dest.recout_width * 2; /* assume half split for dcn1 */ + // In ODM + if (src->is_hsplit) { + // This "hack" is only allowed (and valid) for MPC combine. In ODM + // combine, you MUST specify the full_recout_width...according to Oswin + if (dst->full_recout_width == 0 && !dst->odm_combine) { + dml_print("DML_DLG: %s: Warning: full_recout_width not set in hsplit mode\n", + __func__); + full_recout_width = dst->recout_width * 2; // assume half split for dcn1 } else - full_recout_width = e2e_pipe_param.pipe.dest.full_recout_width; + full_recout_width = dst->full_recout_width; } else - full_recout_width = e2e_pipe_param.pipe.dest.recout_width; + full_recout_width = dst->recout_width; - refcyc_per_line_delivery_pre_l = get_refcyc_per_delivery( - mode_lib, + // mpc_combine and odm_combine are mutually exclusive + refcyc_per_line_delivery_pre_l = get_refcyc_per_delivery(mode_lib, refclk_freq_in_mhz, pclk_freq_in_mhz, + dst->odm_combine, full_recout_width, + dst->hactive, vratio_pre_l, hscale_pixel_rate_l, swath_width_pixels_ub_l, - 1); /* per line */ + 1); // per line - refcyc_per_line_delivery_l = get_refcyc_per_delivery( - mode_lib, + refcyc_per_line_delivery_l = get_refcyc_per_delivery(mode_lib, refclk_freq_in_mhz, pclk_freq_in_mhz, + dst->odm_combine, full_recout_width, + dst->hactive, vratio_l, hscale_pixel_rate_l, swath_width_pixels_ub_l, - 1); /* per line */ + 1); // per line - DTRACE("DLG: %s: full_recout_width = %d", __func__, full_recout_width); - DTRACE("DLG: %s: hscale_pixel_rate_l = %3.2f", __func__, hscale_pixel_rate_l); - DTRACE( - "DLG: %s: refcyc_per_line_delivery_pre_l = %3.2f", + dml_print("DML_DLG: %s: full_recout_width = %d\n", __func__, - refcyc_per_line_delivery_pre_l); - DTRACE( - "DLG: %s: refcyc_per_line_delivery_l = %3.2f", + full_recout_width); + dml_print("DML_DLG: %s: hscale_pixel_rate_l = %3.2f\n", + __func__, + hscale_pixel_rate_l); + dml_print("DML_DLG: %s: refcyc_per_line_delivery_pre_l = %3.2f\n", __func__, - refcyc_per_line_delivery_l); - - disp_dlg_regs->refcyc_per_line_delivery_pre_l = (unsigned int) dml_floor( refcyc_per_line_delivery_pre_l); - disp_dlg_regs->refcyc_per_line_delivery_l = (unsigned int) dml_floor( + dml_print("DML_DLG: %s: refcyc_per_line_delivery_l = %3.2f\n", + __func__, refcyc_per_line_delivery_l); - ASSERT(disp_dlg_regs->refcyc_per_line_delivery_pre_l < (unsigned int) dml_pow(2, 13)); - ASSERT(disp_dlg_regs->refcyc_per_line_delivery_l < (unsigned int) dml_pow(2, 13)); if (dual_plane) { - refcyc_per_line_delivery_pre_c = get_refcyc_per_delivery( - mode_lib, + refcyc_per_line_delivery_pre_c = get_refcyc_per_delivery(mode_lib, refclk_freq_in_mhz, pclk_freq_in_mhz, + dst->odm_combine, full_recout_width, + dst->hactive, vratio_pre_c, hscale_pixel_rate_c, swath_width_pixels_ub_c, - 1); /* per line */ + 1); // per line - refcyc_per_line_delivery_c = get_refcyc_per_delivery( - mode_lib, + refcyc_per_line_delivery_c = get_refcyc_per_delivery(mode_lib, refclk_freq_in_mhz, pclk_freq_in_mhz, + dst->odm_combine, full_recout_width, + dst->hactive, vratio_c, hscale_pixel_rate_c, swath_width_pixels_ub_c, - 1); /* per line */ + 1); // per line - DTRACE( - "DLG: %s: refcyc_per_line_delivery_pre_c = %3.2f", + dml_print("DML_DLG: %s: refcyc_per_line_delivery_pre_c = %3.2f\n", __func__, refcyc_per_line_delivery_pre_c); - DTRACE( - "DLG: %s: refcyc_per_line_delivery_c = %3.2f", + dml_print("DML_DLG: %s: refcyc_per_line_delivery_c = %3.2f\n", __func__, refcyc_per_line_delivery_c); - - disp_dlg_regs->refcyc_per_line_delivery_pre_c = (unsigned int) dml_floor( - refcyc_per_line_delivery_pre_c); - disp_dlg_regs->refcyc_per_line_delivery_c = (unsigned int) dml_floor( - refcyc_per_line_delivery_c); - ASSERT(disp_dlg_regs->refcyc_per_line_delivery_pre_c < (unsigned int) dml_pow(2, 13)); ASSERT(disp_dlg_regs->refcyc_per_line_delivery_c < (unsigned int) dml_pow(2, 13)); } - disp_dlg_regs->chunk_hdl_adjust_cur0 = 3; - /* TTU - Luma / Chroma */ - if (access_dir) { /* vertical access */ + // TTU - Luma / Chroma + if (access_dir) { // vertical access scaler_rec_in_width_l = vp_height_l; scaler_rec_in_width_c = vp_height_c; } else { @@ -1955,167 +1251,264 @@ void dml_rq_dlg_get_dlg_params( scaler_rec_in_width_c = vp_width_c; } - refcyc_per_req_delivery_pre_l = get_refcyc_per_delivery( - mode_lib, + refcyc_per_req_delivery_pre_l = get_refcyc_per_delivery(mode_lib, refclk_freq_in_mhz, pclk_freq_in_mhz, + dst->odm_combine, full_recout_width, + dst->hactive, vratio_pre_l, hscale_pixel_rate_l, scaler_rec_in_width_l, - req_per_swath_ub_l); /* per req */ - refcyc_per_req_delivery_l = get_refcyc_per_delivery( - mode_lib, + req_per_swath_ub_l); // per req + refcyc_per_req_delivery_l = get_refcyc_per_delivery(mode_lib, refclk_freq_in_mhz, pclk_freq_in_mhz, + dst->odm_combine, full_recout_width, + dst->hactive, vratio_l, hscale_pixel_rate_l, scaler_rec_in_width_l, - req_per_swath_ub_l); /* per req */ + req_per_swath_ub_l); // per req - DTRACE( - "DLG: %s: refcyc_per_req_delivery_pre_l = %3.2f", + dml_print("DML_DLG: %s: refcyc_per_req_delivery_pre_l = %3.2f\n", __func__, refcyc_per_req_delivery_pre_l); - DTRACE( - "DLG: %s: refcyc_per_req_delivery_l = %3.2f", + dml_print("DML_DLG: %s: refcyc_per_req_delivery_l = %3.2f\n", __func__, refcyc_per_req_delivery_l); - disp_ttu_regs->refcyc_per_req_delivery_pre_l = (unsigned int) (refcyc_per_req_delivery_pre_l - * dml_pow(2, 10)); - disp_ttu_regs->refcyc_per_req_delivery_l = (unsigned int) (refcyc_per_req_delivery_l - * dml_pow(2, 10)); - ASSERT(refcyc_per_req_delivery_pre_l < dml_pow(2, 13)); ASSERT(refcyc_per_req_delivery_l < dml_pow(2, 13)); if (dual_plane) { - refcyc_per_req_delivery_pre_c = get_refcyc_per_delivery( - mode_lib, + refcyc_per_req_delivery_pre_c = get_refcyc_per_delivery(mode_lib, refclk_freq_in_mhz, pclk_freq_in_mhz, + dst->odm_combine, full_recout_width, + dst->hactive, vratio_pre_c, hscale_pixel_rate_c, scaler_rec_in_width_c, - req_per_swath_ub_c); /* per req */ - refcyc_per_req_delivery_c = get_refcyc_per_delivery( - mode_lib, + req_per_swath_ub_c); // per req + refcyc_per_req_delivery_c = get_refcyc_per_delivery(mode_lib, refclk_freq_in_mhz, pclk_freq_in_mhz, + dst->odm_combine, full_recout_width, + dst->hactive, vratio_c, hscale_pixel_rate_c, scaler_rec_in_width_c, - req_per_swath_ub_c); /* per req */ + req_per_swath_ub_c); // per req - DTRACE( - "DLG: %s: refcyc_per_req_delivery_pre_c = %3.2f", + dml_print("DML_DLG: %s: refcyc_per_req_delivery_pre_c = %3.2f\n", __func__, refcyc_per_req_delivery_pre_c); - DTRACE( - "DLG: %s: refcyc_per_req_delivery_c = %3.2f", + dml_print("DML_DLG: %s: refcyc_per_req_delivery_c = %3.2f\n", __func__, refcyc_per_req_delivery_c); - disp_ttu_regs->refcyc_per_req_delivery_pre_c = - (unsigned int) (refcyc_per_req_delivery_pre_c * dml_pow(2, 10)); - disp_ttu_regs->refcyc_per_req_delivery_c = (unsigned int) (refcyc_per_req_delivery_c - * dml_pow(2, 10)); - ASSERT(refcyc_per_req_delivery_pre_c < dml_pow(2, 13)); ASSERT(refcyc_per_req_delivery_c < dml_pow(2, 13)); } - /* TTU - Cursor */ - hratios_cur0 = e2e_pipe_param.pipe.scale_ratio_depth.hscl_ratio; - cur0_src_width = e2e_pipe_param.pipe.src.cur0_src_width; /* cursor source width */ - cur0_bpp = (enum cursor_bpp) e2e_pipe_param.pipe.src.cur0_bpp; - cur0_req_size = 0; - cur0_req_width = 0; - cur0_width_ub = 0.0; - cur0_req_per_width = 0.0; - hactive_cur0 = 0.0; - - ASSERT(cur0_src_width <= 256); - - if (cur0_src_width > 0) { - unsigned int cur0_bit_per_pixel = 0; - - if (cur0_bpp == dm_cur_2bit) { - cur0_req_size = 64; /* byte */ - cur0_bit_per_pixel = 2; - } else { /* 32bit */ - cur0_bit_per_pixel = 32; - if (cur0_src_width >= 1 && cur0_src_width <= 16) - cur0_req_size = 64; - else if (cur0_src_width >= 17 && cur0_src_width <= 31) - cur0_req_size = 128; - else - cur0_req_size = 256; - } + // XFC + xfc_transfer_delay = get_xfc_transfer_delay(mode_lib, e2e_pipe_param, num_pipes, pipe_idx); + xfc_precharge_delay = get_xfc_precharge_delay(mode_lib, + e2e_pipe_param, + num_pipes, + pipe_idx); + xfc_remote_surface_flip_latency = get_xfc_remote_surface_flip_latency(mode_lib, + e2e_pipe_param, + num_pipes, + pipe_idx); + xfc_dst_y_delta_drq_limit = xfc_remote_surface_flip_latency; + xfc_prefetch_margin = get_xfc_prefetch_margin(mode_lib, + e2e_pipe_param, + num_pipes, + pipe_idx); + + // TTU - Cursor + refcyc_per_req_delivery_pre_cur0 = 0.0; + refcyc_per_req_delivery_cur0 = 0.0; + if (src->num_cursors > 0) { + calculate_ttu_cursor(mode_lib, + &refcyc_per_req_delivery_pre_cur0, + &refcyc_per_req_delivery_cur0, + refclk_freq_in_mhz, + ref_freq_to_pix_freq, + hscale_pixel_rate_l, + scl->hscl_ratio, + vratio_pre_l, + vratio_l, + src->cur0_src_width, + (enum cursor_bpp)(src->cur0_bpp)); + } + + refcyc_per_req_delivery_pre_cur1 = 0.0; + refcyc_per_req_delivery_cur1 = 0.0; + if (src->num_cursors > 1) { + calculate_ttu_cursor(mode_lib, + &refcyc_per_req_delivery_pre_cur1, + &refcyc_per_req_delivery_cur1, + refclk_freq_in_mhz, + ref_freq_to_pix_freq, + hscale_pixel_rate_l, + scl->hscl_ratio, + vratio_pre_l, + vratio_l, + src->cur1_src_width, + (enum cursor_bpp)(src->cur1_bpp)); + } - cur0_req_width = (double) cur0_req_size / ((double) cur0_bit_per_pixel / 8.0); - cur0_width_ub = dml_ceil((double) cur0_src_width / (double) cur0_req_width) - * (double) cur0_req_width; - cur0_req_per_width = cur0_width_ub / (double) cur0_req_width; - hactive_cur0 = (double) cur0_src_width / hratios_cur0; /* FIXME: oswin to think about what to do for cursor */ + // TTU - Misc + // all hard-coded - if (vratio_pre_l <= 1.0) { - refcyc_per_req_delivery_pre_cur0 = hactive_cur0 * ref_freq_to_pix_freq - / (double) cur0_req_per_width; - } else { - refcyc_per_req_delivery_pre_cur0 = (double) refclk_freq_in_mhz - * (double) cur0_src_width / hscale_pixel_rate_l - / (double) cur0_req_per_width; - } + // Assignment to register structures + disp_dlg_regs->dst_y_after_scaler = dst_y_after_scaler; // in terms of line + disp_dlg_regs->refcyc_x_after_scaler = dst_x_after_scaler * ref_freq_to_pix_freq; // in terms of refclk + ASSERT(disp_dlg_regs->refcyc_x_after_scaler < (unsigned int) dml_pow(2, 13)); + disp_dlg_regs->dst_y_prefetch = (unsigned int) (dst_y_prefetch * dml_pow(2, 2)); + disp_dlg_regs->dst_y_per_vm_vblank = (unsigned int) (dst_y_per_vm_vblank * dml_pow(2, 2)); + disp_dlg_regs->dst_y_per_row_vblank = (unsigned int) (dst_y_per_row_vblank * dml_pow(2, 2)); + disp_dlg_regs->dst_y_per_vm_flip = (unsigned int) (dst_y_per_vm_flip * dml_pow(2, 2)); + disp_dlg_regs->dst_y_per_row_flip = (unsigned int) (dst_y_per_row_flip * dml_pow(2, 2)); - disp_ttu_regs->refcyc_per_req_delivery_pre_cur0 = - (unsigned int) (refcyc_per_req_delivery_pre_cur0 * dml_pow(2, 10)); - ASSERT(refcyc_per_req_delivery_pre_cur0 < dml_pow(2, 13)); + disp_dlg_regs->vratio_prefetch = (unsigned int) (vratio_pre_l * dml_pow(2, 19)); + disp_dlg_regs->vratio_prefetch_c = (unsigned int) (vratio_pre_c * dml_pow(2, 19)); - if (vratio_l <= 1.0) { - refcyc_per_req_delivery_cur0 = hactive_cur0 * ref_freq_to_pix_freq - / (double) cur0_req_per_width; - } else { - refcyc_per_req_delivery_cur0 = (double) refclk_freq_in_mhz - * (double) cur0_src_width / hscale_pixel_rate_l - / (double) cur0_req_per_width; + disp_dlg_regs->refcyc_per_pte_group_vblank_l = + (unsigned int) (dst_y_per_row_vblank * (double) htotal + * ref_freq_to_pix_freq / (double) dpte_groups_per_row_ub_l); + ASSERT(disp_dlg_regs->refcyc_per_pte_group_vblank_l < (unsigned int) dml_pow(2, 13)); + + if (dual_plane) { + disp_dlg_regs->refcyc_per_pte_group_vblank_c = (unsigned int) (dst_y_per_row_vblank + * (double) htotal * ref_freq_to_pix_freq + / (double) dpte_groups_per_row_ub_c); + ASSERT(disp_dlg_regs->refcyc_per_pte_group_vblank_c + < (unsigned int) dml_pow(2, 13)); + } + + disp_dlg_regs->refcyc_per_meta_chunk_vblank_l = + (unsigned int) (dst_y_per_row_vblank * (double) htotal + * ref_freq_to_pix_freq / (double) meta_chunks_per_row_ub_l); + ASSERT(disp_dlg_regs->refcyc_per_meta_chunk_vblank_l < (unsigned int) dml_pow(2, 13)); + + disp_dlg_regs->refcyc_per_meta_chunk_vblank_c = + disp_dlg_regs->refcyc_per_meta_chunk_vblank_l; // dcc for 4:2:0 is not supported in dcn1.0. assigned to be the same as _l for now + + disp_dlg_regs->refcyc_per_pte_group_flip_l = (unsigned int) (dst_y_per_row_flip * htotal + * ref_freq_to_pix_freq) / dpte_groups_per_row_ub_l; + disp_dlg_regs->refcyc_per_meta_chunk_flip_l = (unsigned int) (dst_y_per_row_flip * htotal + * ref_freq_to_pix_freq) / meta_chunks_per_row_ub_l; + + if (dual_plane) { + disp_dlg_regs->refcyc_per_pte_group_flip_c = (unsigned int) (dst_y_per_row_flip + * htotal * ref_freq_to_pix_freq) / dpte_groups_per_row_ub_c; + disp_dlg_regs->refcyc_per_meta_chunk_flip_c = (unsigned int) (dst_y_per_row_flip + * htotal * ref_freq_to_pix_freq) / meta_chunks_per_row_ub_c; + } + + disp_dlg_regs->dst_y_per_pte_row_nom_l = (unsigned int) ((double) dpte_row_height_l + / (double) vratio_l * dml_pow(2, 2)); + ASSERT(disp_dlg_regs->dst_y_per_pte_row_nom_l < (unsigned int) dml_pow(2, 17)); + + if (dual_plane) { + disp_dlg_regs->dst_y_per_pte_row_nom_c = (unsigned int) ((double) dpte_row_height_c + / (double) vratio_c * dml_pow(2, 2)); + if (disp_dlg_regs->dst_y_per_pte_row_nom_c >= (unsigned int) dml_pow(2, 17)) { + dml_print("DML_DLG: %s: Warning dst_y_per_pte_row_nom_c %u larger than supported by register format U15.2 %u\n", + __func__, + disp_dlg_regs->dst_y_per_pte_row_nom_c, + (unsigned int) dml_pow(2, 17) - 1); } + } - DTRACE("DLG: %s: cur0_req_width = %d", __func__, cur0_req_width); - DTRACE( - "DLG: %s: cur0_width_ub = %3.2f", - __func__, - cur0_width_ub); - DTRACE( - "DLG: %s: cur0_req_per_width = %3.2f", - __func__, - cur0_req_per_width); - DTRACE( - "DLG: %s: hactive_cur0 = %3.2f", - __func__, - hactive_cur0); - DTRACE( - "DLG: %s: refcyc_per_req_delivery_pre_cur0 = %3.2f", - __func__, - refcyc_per_req_delivery_pre_cur0); - DTRACE( - "DLG: %s: refcyc_per_req_delivery_cur0 = %3.2f", - __func__, - refcyc_per_req_delivery_cur0); + disp_dlg_regs->dst_y_per_meta_row_nom_l = (unsigned int) ((double) meta_row_height_l + / (double) vratio_l * dml_pow(2, 2)); + ASSERT(disp_dlg_regs->dst_y_per_meta_row_nom_l < (unsigned int) dml_pow(2, 17)); - disp_ttu_regs->refcyc_per_req_delivery_cur0 = - (unsigned int) (refcyc_per_req_delivery_cur0 * dml_pow(2, 10)); - ASSERT(refcyc_per_req_delivery_cur0 < dml_pow(2, 13)); - } else { - disp_ttu_regs->refcyc_per_req_delivery_pre_cur0 = 0; - disp_ttu_regs->refcyc_per_req_delivery_cur0 = 0; + disp_dlg_regs->dst_y_per_meta_row_nom_c = disp_dlg_regs->dst_y_per_meta_row_nom_l; // TODO: dcc for 4:2:0 is not supported in dcn1.0. assigned to be the same as _l for now + + disp_dlg_regs->refcyc_per_pte_group_nom_l = (unsigned int) ((double) dpte_row_height_l + / (double) vratio_l * (double) htotal * ref_freq_to_pix_freq + / (double) dpte_groups_per_row_ub_l); + if (disp_dlg_regs->refcyc_per_pte_group_nom_l >= (unsigned int) dml_pow(2, 23)) + disp_dlg_regs->refcyc_per_pte_group_nom_l = dml_pow(2, 23) - 1; + disp_dlg_regs->refcyc_per_meta_chunk_nom_l = (unsigned int) ((double) meta_row_height_l + / (double) vratio_l * (double) htotal * ref_freq_to_pix_freq + / (double) meta_chunks_per_row_ub_l); + if (disp_dlg_regs->refcyc_per_meta_chunk_nom_l >= (unsigned int) dml_pow(2, 23)) + disp_dlg_regs->refcyc_per_meta_chunk_nom_l = dml_pow(2, 23) - 1; + + if (dual_plane) { + disp_dlg_regs->refcyc_per_pte_group_nom_c = + (unsigned int) ((double) dpte_row_height_c / (double) vratio_c + * (double) htotal * ref_freq_to_pix_freq + / (double) dpte_groups_per_row_ub_c); + if (disp_dlg_regs->refcyc_per_pte_group_nom_c >= (unsigned int) dml_pow(2, 23)) + disp_dlg_regs->refcyc_per_pte_group_nom_c = dml_pow(2, 23) - 1; + + // TODO: Is this the right calculation? Does htotal need to be halved? + disp_dlg_regs->refcyc_per_meta_chunk_nom_c = + (unsigned int) ((double) meta_row_height_c / (double) vratio_c + * (double) htotal * ref_freq_to_pix_freq + / (double) meta_chunks_per_row_ub_c); + if (disp_dlg_regs->refcyc_per_meta_chunk_nom_c >= (unsigned int) dml_pow(2, 23)) + disp_dlg_regs->refcyc_per_meta_chunk_nom_c = dml_pow(2, 23) - 1; } - /* TTU - Misc */ + disp_dlg_regs->refcyc_per_line_delivery_pre_l = (unsigned int) dml_floor(refcyc_per_line_delivery_pre_l, + 1); + disp_dlg_regs->refcyc_per_line_delivery_l = (unsigned int) dml_floor(refcyc_per_line_delivery_l, + 1); + ASSERT(disp_dlg_regs->refcyc_per_line_delivery_pre_l < (unsigned int) dml_pow(2, 13)); + ASSERT(disp_dlg_regs->refcyc_per_line_delivery_l < (unsigned int) dml_pow(2, 13)); + + disp_dlg_regs->refcyc_per_line_delivery_pre_c = (unsigned int) dml_floor(refcyc_per_line_delivery_pre_c, + 1); + disp_dlg_regs->refcyc_per_line_delivery_c = (unsigned int) dml_floor(refcyc_per_line_delivery_c, + 1); + ASSERT(disp_dlg_regs->refcyc_per_line_delivery_pre_c < (unsigned int) dml_pow(2, 13)); + ASSERT(disp_dlg_regs->refcyc_per_line_delivery_c < (unsigned int) dml_pow(2, 13)); + + disp_dlg_regs->chunk_hdl_adjust_cur0 = 3; + disp_dlg_regs->dst_y_offset_cur0 = 0; + disp_dlg_regs->chunk_hdl_adjust_cur1 = 3; + disp_dlg_regs->dst_y_offset_cur1 = 0; + + disp_dlg_regs->xfc_reg_transfer_delay = xfc_transfer_delay; + disp_dlg_regs->xfc_reg_precharge_delay = xfc_precharge_delay; + disp_dlg_regs->xfc_reg_remote_surface_flip_latency = xfc_remote_surface_flip_latency; + disp_dlg_regs->xfc_reg_prefetch_margin = dml_ceil(xfc_prefetch_margin * refclk_freq_in_mhz, + 1); + + // slave has to have this value also set to off + if (src->xfc_enable && !src->xfc_slave) + disp_dlg_regs->dst_y_delta_drq_limit = dml_ceil(xfc_dst_y_delta_drq_limit, 1); + else + disp_dlg_regs->dst_y_delta_drq_limit = 0x7fff; // off + + disp_ttu_regs->refcyc_per_req_delivery_pre_l = (unsigned int) (refcyc_per_req_delivery_pre_l + * dml_pow(2, 10)); + disp_ttu_regs->refcyc_per_req_delivery_l = (unsigned int) (refcyc_per_req_delivery_l + * dml_pow(2, 10)); + disp_ttu_regs->refcyc_per_req_delivery_pre_c = (unsigned int) (refcyc_per_req_delivery_pre_c + * dml_pow(2, 10)); + disp_ttu_regs->refcyc_per_req_delivery_c = (unsigned int) (refcyc_per_req_delivery_c + * dml_pow(2, 10)); + disp_ttu_regs->refcyc_per_req_delivery_pre_cur0 = + (unsigned int) (refcyc_per_req_delivery_pre_cur0 * dml_pow(2, 10)); + disp_ttu_regs->refcyc_per_req_delivery_cur0 = (unsigned int) (refcyc_per_req_delivery_cur0 + * dml_pow(2, 10)); + disp_ttu_regs->refcyc_per_req_delivery_pre_cur1 = + (unsigned int) (refcyc_per_req_delivery_pre_cur1 * dml_pow(2, 10)); + disp_ttu_regs->refcyc_per_req_delivery_cur1 = (unsigned int) (refcyc_per_req_delivery_cur1 + * dml_pow(2, 10)); disp_ttu_regs->qos_level_low_wm = 0; ASSERT(disp_ttu_regs->qos_level_low_wm < dml_pow(2, 14)); disp_ttu_regs->qos_level_high_wm = (unsigned int) (4.0 * (double) htotal @@ -2137,118 +1530,232 @@ void dml_rq_dlg_get_dlg_params( print__dlg_regs_st(mode_lib, *disp_dlg_regs); } -void dml_rq_dlg_get_dlg_reg( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_display_dlg_regs_st *dlg_regs, - struct _vcs_dpi_display_ttu_regs_st *ttu_regs, - struct _vcs_dpi_display_e2e_pipe_params_st *e2e_pipe_param, - const int unsigned num_pipes, - const int unsigned pipe_idx, +void dml_rq_dlg_get_dlg_reg(struct display_mode_lib *mode_lib, + display_dlg_regs_st *dlg_regs, + display_ttu_regs_st *ttu_regs, + display_e2e_pipe_params_st *e2e_pipe_param, + const unsigned int num_pipes, + const unsigned int pipe_idx, const bool cstate_en, const bool pstate_en, const bool vm_en, - const bool iflip_en) + const bool ignore_viewport_pos, + const bool immediate_flip_support) { - struct _vcs_dpi_display_rq_params_st rq_param = {0}; - struct _vcs_dpi_display_dlg_sys_params_st dlg_sys_param = {0}; - struct _vcs_dpi_wm_calc_pipe_params_st *wm_param = mode_lib->wm_param; - struct _vcs_dpi_cstate_pstate_watermarks_st cstate_pstate_wm; - struct _vcs_dpi_display_dlg_prefetch_param_st prefetch_param; - double total_ret_bw; - double total_active_bw; - double total_prefetch_bw; - int unsigned total_flip_bytes; - int unsigned num_planes; - int i; - - memset(wm_param, 0, sizeof(mode_lib->wm_param)); - - /* Get watermark and Tex. */ - DTRACE("DLG: Start calculating system setting related parameters. num_pipes=%d", num_pipes); - num_planes = dml_wm_e2e_to_wm(mode_lib, e2e_pipe_param, num_pipes, wm_param); - - cstate_pstate_wm = dml_wm_cstate_pstate_e2e(mode_lib, e2e_pipe_param, num_pipes); - dlg_sys_param.t_mclk_wm_us = cstate_pstate_wm.pstate_change_us; - dlg_sys_param.t_sr_wm_us = cstate_pstate_wm.cstate_enter_plus_exit_us; - dlg_sys_param.t_urg_wm_us = dml_wm_urgent_e2e(mode_lib, e2e_pipe_param, num_pipes); - dlg_sys_param.t_srx_delay_us = mode_lib->ip.dcfclk_cstate_latency - / dml_wm_dcfclk_deepsleep_mhz_e2e(mode_lib, e2e_pipe_param, num_pipes); - dlg_sys_param.t_extra_us = dml_wm_urgent_extra(mode_lib, wm_param, num_planes); - dlg_sys_param.deepsleep_dcfclk_mhz = dml_wm_dcfclk_deepsleep_mhz_e2e( - mode_lib, + display_rq_params_st rq_param = {0}; + display_dlg_sys_params_st dlg_sys_param = {0}; + + // Get watermark and Tex. + dlg_sys_param.t_urg_wm_us = get_wm_urgent(mode_lib, e2e_pipe_param, num_pipes); + dlg_sys_param.deepsleep_dcfclk_mhz = get_clk_dcf_deepsleep(mode_lib, + e2e_pipe_param, + num_pipes); + dlg_sys_param.t_extra_us = get_urgent_extra_latency(mode_lib, e2e_pipe_param, num_pipes); + dlg_sys_param.mem_trip_us = get_wm_memory_trip(mode_lib, e2e_pipe_param, num_pipes); + dlg_sys_param.t_mclk_wm_us = get_wm_dram_clock_change(mode_lib, e2e_pipe_param, num_pipes); + dlg_sys_param.t_sr_wm_us = get_wm_stutter_enter_exit(mode_lib, e2e_pipe_param, num_pipes); + dlg_sys_param.total_flip_bw = get_total_immediate_flip_bw(mode_lib, e2e_pipe_param, num_pipes); + dlg_sys_param.total_flip_bytes = get_total_immediate_flip_bytes(mode_lib, + e2e_pipe_param, + num_pipes); + dlg_sys_param.t_srx_delay_us = mode_lib->ip.dcfclk_cstate_latency + / dlg_sys_param.deepsleep_dcfclk_mhz; // TODO: Deprecated print__dlg_sys_params_st(mode_lib, dlg_sys_param); - DTRACE("DLG: Start calculating total prefetch bw. num_planes=%d", num_planes); - total_ret_bw = dml_wm_calc_return_bw(mode_lib, wm_param, num_planes); - total_active_bw = dml_wm_calc_total_data_read_bw(mode_lib, wm_param, num_planes); - total_prefetch_bw = 0.0; - total_flip_bytes = 0; + // system parameter calculation done - for (i = 0; i < num_pipes; i++) { - dml_rq_dlg_get_rq_params(mode_lib, &rq_param, e2e_pipe_param[i].pipe.src); - dml_rq_dlg_get_dlg_params_prefetch( - mode_lib, - &prefetch_param, - rq_param.dlg, - dlg_sys_param, - e2e_pipe_param[i], - cstate_en, - pstate_en, - vm_en); - total_prefetch_bw += prefetch_param.prefetch_bw; - total_flip_bytes += prefetch_param.flip_bytes; - DTRACE( - "DLG: pipe=%d, total_prefetch_bw=%3.2f total_flip_bytes=%d", - i, - total_prefetch_bw, - total_flip_bytes); - } - - dlg_sys_param.total_flip_bw = total_ret_bw - dml_max(total_active_bw, total_prefetch_bw); - - DTRACE("DLG: Done calculating total prefetch bw"); - DTRACE("DLG: num_pipes = %d", num_pipes); - DTRACE("DLG: total_ret_bw = %3.2f", total_ret_bw); - DTRACE("DLG: total_active_bw = %3.2f", total_active_bw); - DTRACE("DLG: total_prefetch_bw = %3.2f", total_prefetch_bw); - DTRACE("DLG: total_flip_bw = %3.2f", dlg_sys_param.total_flip_bw); - - if (dlg_sys_param.total_flip_bw < 0.0 && iflip_en) { - DTRACE("WARNING_DLG Insufficient bw for immediate flip!"); - dlg_sys_param.total_flip_bw = 0; - } - - dlg_sys_param.total_flip_bytes = total_flip_bytes; - DTRACE("DLG: total_flip_bytes = %d", dlg_sys_param.total_flip_bytes); - DTRACE("DLG: Done calculating system setting related parameters."); - - /* system parameter calculation done */ - - DTRACE("DLG: Calculation for pipe[%d] start", pipe_idx); + dml_print("DML_DLG: Calculation for pipe[%d] start\n\n", pipe_idx); dml_rq_dlg_get_rq_params(mode_lib, &rq_param, e2e_pipe_param[pipe_idx].pipe.src); - dml_rq_dlg_get_dlg_params( - mode_lib, + dml_rq_dlg_get_dlg_params(mode_lib, + e2e_pipe_param, + num_pipes, + pipe_idx, dlg_regs, ttu_regs, rq_param.dlg, dlg_sys_param, - e2e_pipe_param[pipe_idx], cstate_en, pstate_en, vm_en, - iflip_en); - DTRACE("DLG: Calculation for pipe[%d] end", pipe_idx); + ignore_viewport_pos, + immediate_flip_support); + dml_print("DML_DLG: Calculation for pipe[%d] end\n", pipe_idx); } -void dml_rq_dlg_get_arb_params( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_display_arb_params_st *arb_param) +void dml_rq_dlg_get_arb_params(struct display_mode_lib *mode_lib, display_arb_params_st *arb_param) { memset(arb_param, 0, sizeof(*arb_param)); arb_param->max_req_outstanding = 256; arb_param->min_req_outstanding = 68; arb_param->sat_level_us = 60; } + +void calculate_ttu_cursor(struct display_mode_lib *mode_lib, + double *refcyc_per_req_delivery_pre_cur, + double *refcyc_per_req_delivery_cur, + double refclk_freq_in_mhz, + double ref_freq_to_pix_freq, + double hscale_pixel_rate_l, + double hscl_ratio, + double vratio_pre_l, + double vratio_l, + unsigned int cur_width, + enum cursor_bpp cur_bpp) +{ + unsigned int cur_src_width = cur_width; + unsigned int cur_req_size = 0; + unsigned int cur_req_width = 0; + double cur_width_ub = 0.0; + double cur_req_per_width = 0.0; + double hactive_cur = 0.0; + + ASSERT(cur_src_width <= 256); + + *refcyc_per_req_delivery_pre_cur = 0.0; + *refcyc_per_req_delivery_cur = 0.0; + if (cur_src_width > 0) { + unsigned int cur_bit_per_pixel = 0; + + if (cur_bpp == dm_cur_2bit) { + cur_req_size = 64; // byte + cur_bit_per_pixel = 2; + } else { // 32bit + cur_bit_per_pixel = 32; + if (cur_src_width >= 1 && cur_src_width <= 16) + cur_req_size = 64; + else if (cur_src_width >= 17 && cur_src_width <= 31) + cur_req_size = 128; + else + cur_req_size = 256; + } + + cur_req_width = (double) cur_req_size / ((double) cur_bit_per_pixel / 8.0); + cur_width_ub = dml_ceil((double) cur_src_width / (double) cur_req_width, 1) + * (double) cur_req_width; + cur_req_per_width = cur_width_ub / (double) cur_req_width; + hactive_cur = (double) cur_src_width / hscl_ratio; // FIXME: oswin to think about what to do for cursor + + if (vratio_pre_l <= 1.0) { + *refcyc_per_req_delivery_pre_cur = hactive_cur * ref_freq_to_pix_freq + / (double) cur_req_per_width; + } else { + *refcyc_per_req_delivery_pre_cur = (double) refclk_freq_in_mhz + * (double) cur_src_width / hscale_pixel_rate_l + / (double) cur_req_per_width; + } + + ASSERT(*refcyc_per_req_delivery_pre_cur < dml_pow(2, 13)); + + if (vratio_l <= 1.0) { + *refcyc_per_req_delivery_cur = hactive_cur * ref_freq_to_pix_freq + / (double) cur_req_per_width; + } else { + *refcyc_per_req_delivery_cur = (double) refclk_freq_in_mhz + * (double) cur_src_width / hscale_pixel_rate_l + / (double) cur_req_per_width; + } + + dml_print("DML_DLG: %s: cur_req_width = %d\n", + __func__, + cur_req_width); + dml_print("DML_DLG: %s: cur_width_ub = %3.2f\n", + __func__, + cur_width_ub); + dml_print("DML_DLG: %s: cur_req_per_width = %3.2f\n", + __func__, + cur_req_per_width); + dml_print("DML_DLG: %s: hactive_cur = %3.2f\n", + __func__, + hactive_cur); + dml_print("DML_DLG: %s: refcyc_per_req_delivery_pre_cur = %3.2f\n", + __func__, + *refcyc_per_req_delivery_pre_cur); + dml_print("DML_DLG: %s: refcyc_per_req_delivery_cur = %3.2f\n", + __func__, + *refcyc_per_req_delivery_cur); + + ASSERT(*refcyc_per_req_delivery_cur < dml_pow(2, 13)); + } +} + +unsigned int dml_rq_dlg_get_calculated_vstartup(struct display_mode_lib *mode_lib, + display_e2e_pipe_params_st *e2e_pipe_param, + const unsigned int num_pipes, + const unsigned int pipe_idx) +{ + unsigned int vstartup_pipe[DC__NUM_PIPES__MAX]; + bool visited[DC__NUM_PIPES__MAX]; + unsigned int pipe_inst = 0; + unsigned int i, j, k; + + for (k = 0; k < num_pipes; ++k) + visited[k] = false; + + for (i = 0; i < num_pipes; i++) { + if (e2e_pipe_param[i].pipe.src.is_hsplit && !visited[i]) { + unsigned int grp = e2e_pipe_param[i].pipe.src.hsplit_grp; + + for (j = i; j < num_pipes; j++) { + if (e2e_pipe_param[j].pipe.src.hsplit_grp == grp + && e2e_pipe_param[j].pipe.src.is_hsplit + && !visited[j]) { + vstartup_pipe[j] = get_vstartup_calculated(mode_lib, + e2e_pipe_param, + num_pipes, + pipe_inst); + visited[j] = true; + } + } + + pipe_inst++; + } + + if (!visited[i]) { + vstartup_pipe[i] = get_vstartup_calculated(mode_lib, + e2e_pipe_param, + num_pipes, + pipe_inst); + visited[i] = true; + pipe_inst++; + } + } + + return vstartup_pipe[pipe_idx]; + +} + +void dml_rq_dlg_get_row_heights(struct display_mode_lib *mode_lib, + unsigned int *o_dpte_row_height, + unsigned int *o_meta_row_height, + unsigned int vp_width, + unsigned int data_pitch, + int source_format, + int tiling, + int macro_tile_size, + int source_scan, + int is_chroma) +{ + display_data_rq_dlg_params_st rq_dlg_param; + display_data_rq_misc_params_st rq_misc_param; + display_data_rq_sizing_params_st rq_sizing_param; + + get_meta_and_pte_attr(mode_lib, + &rq_dlg_param, + &rq_misc_param, + &rq_sizing_param, + vp_width, + 0, // dummy + data_pitch, + 0, // dummy + source_format, + tiling, + macro_tile_size, + source_scan, + is_chroma); + + *o_dpte_row_height = rq_dlg_param.dpte_row_height; + *o_meta_row_height = rq_dlg_param.meta_row_height; +} diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_calc.h b/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_calc.h index e63b13fb2887e..efdd4c73d8f34 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_calc.h +++ b/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_calc.h @@ -22,103 +22,114 @@ * Authors: AMD * */ -#ifndef __DISPLAY_RQ_DLG_CALC_H__ -#define __DISPLAY_RQ_DLG_CALC_H__ + +#ifndef __DML2_DISPLAY_RQ_DLG_CALC_H__ +#define __DML2_DISPLAY_RQ_DLG_CALC_H__ #include "dml_common_defs.h" #include "display_rq_dlg_helpers.h" struct display_mode_lib; -void extract_rq_regs( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_display_rq_regs_st *rq_regs, - const struct _vcs_dpi_display_rq_params_st rq_param); -/* Function: dml_rq_dlg_get_rq_params - * Calculate requestor related parameters that register definition agnostic - * (i.e. this layer does try to separate real values from register defintion) - * Input: - * pipe_src_param - pipe source configuration (e.g. vp, pitch, etc.) - * Output: - * rq_param - values that can be used to setup RQ (e.g. swath_height, plane1_addr, etc.) - */ +// Function: dml_rq_dlg_get_rq_params +// Calculate requestor related parameters that register definition agnostic +// (i.e. this layer does try to separate real values from register definition) +// Input: +// pipe_src_param - pipe source configuration (e.g. vp, pitch, etc.) +// Output: +// rq_param - values that can be used to setup RQ (e.g. swath_height, plane1_addr, etc.) +// void dml_rq_dlg_get_rq_params( struct display_mode_lib *mode_lib, - struct _vcs_dpi_display_rq_params_st *rq_param, - const struct _vcs_dpi_display_pipe_source_params_st pipe_src_param); + display_rq_params_st *rq_param, + const display_pipe_source_params_st pipe_src_param); -/* Function: dml_rq_dlg_get_rq_reg - * Main entry point for test to get the register values out of this DML class. - * This function calls and fucntions to calculate - * and then populate the rq_regs struct - * Input: - * pipe_src_param - pipe source configuration (e.g. vp, pitch, etc.) - * Output: - * rq_regs - struct that holds all the RQ registers field value. - * See also: - */ +// Function: dml_rq_dlg_get_rq_reg +// Main entry point for test to get the register values out of this DML class. +// This function calls and fucntions to calculate +// and then populate the rq_regs struct +// Input: +// pipe_src_param - pipe source configuration (e.g. vp, pitch, etc.) +// Output: +// rq_regs - struct that holds all the RQ registers field value. +// See also: void dml_rq_dlg_get_rq_reg( struct display_mode_lib *mode_lib, - struct _vcs_dpi_display_rq_regs_st *rq_regs, - const struct _vcs_dpi_display_pipe_source_params_st pipe_src_param); + display_rq_regs_st *rq_regs, + const display_pipe_source_params_st pipe_src_param); -/* Function: dml_rq_dlg_get_dlg_params - * Calculate deadline related parameters - */ -void dml_rq_dlg_get_dlg_params( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_display_dlg_regs_st *dlg_regs, - struct _vcs_dpi_display_ttu_regs_st *ttu_regs, - const struct _vcs_dpi_display_rq_dlg_params_st rq_dlg_param, - const struct _vcs_dpi_display_dlg_sys_params_st dlg_sys_param, - const struct _vcs_dpi_display_e2e_pipe_params_st e2e_pipe_param, +// Function: dml_rq_dlg_get_dlg_params +// Calculate deadline related parameters +// +void dml_rq_dlg_get_dlg_params(struct display_mode_lib *mode_lib, + const display_e2e_pipe_params_st *e2e_pipe_param, + const unsigned int num_pipes, + const unsigned int pipe_idx, + display_dlg_regs_st *disp_dlg_regs, + display_ttu_regs_st *disp_ttu_regs, + const display_rq_dlg_params_st rq_dlg_param, + const display_dlg_sys_params_st dlg_sys_param, const bool cstate_en, const bool pstate_en, const bool vm_en, - const bool iflip_en); + const bool ignore_viewport_pos, + const bool immediate_flip_support); -/* Function: dml_rq_dlg_get_dlg_param_prefetch - * For flip_bw programming guide change, now dml needs to calculate the flip_bytes and prefetch_bw - * for ALL pipes and use this info to calculate the prefetch programming. - * Output: prefetch_param.prefetch_bw and flip_bytes - */ +// Function: dml_rq_dlg_get_dlg_param_prefetch +// For flip_bw programming guide change, now dml needs to calculate the flip_bytes and prefetch_bw +// for ALL pipes and use this info to calculate the prefetch programming. +// Output: prefetch_param.prefetch_bw and flip_bytes void dml_rq_dlg_get_dlg_params_prefetch( struct display_mode_lib *mode_lib, - struct _vcs_dpi_display_dlg_prefetch_param_st *prefetch_param, - struct _vcs_dpi_display_rq_dlg_params_st rq_dlg_param, - struct _vcs_dpi_display_dlg_sys_params_st dlg_sys_param, - struct _vcs_dpi_display_e2e_pipe_params_st e2e_pipe_param, + display_dlg_prefetch_param_st *prefetch_param, + display_rq_dlg_params_st rq_dlg_param, + display_dlg_sys_params_st dlg_sys_param, + display_e2e_pipe_params_st e2e_pipe_param, const bool cstate_en, const bool pstate_en, const bool vm_en); -/* Function: dml_rq_dlg_get_dlg_reg - * Calculate and return DLG and TTU register struct given the system setting - * Output: - * dlg_regs - output DLG register struct - * ttu_regs - output DLG TTU register struct - * Input: - * e2e_pipe_param - "compacted" array of e2e pipe param struct - * num_pipes - num of active "pipe" or "route" - * pipe_idx - index that identifies the e2e_pipe_param that corresponding to this dlg - * cstate - 0: when calculate min_ttu_vblank it is assumed cstate is not required. 1: Normal mode, cstate is considered. - * Added for legacy or unrealistic timing tests. - */ +// Function: dml_rq_dlg_get_dlg_reg +// Calculate and return DLG and TTU register struct given the system setting +// Output: +// dlg_regs - output DLG register struct +// ttu_regs - output DLG TTU register struct +// Input: +// e2e_pipe_param - "compacted" array of e2e pipe param struct +// num_pipes - num of active "pipe" or "route" +// pipe_idx - index that identifies the e2e_pipe_param that corresponding to this dlg +// cstate - 0: when calculate min_ttu_vblank it is assumed cstate is not required. 1: Normal mode, cstate is considered. +// Added for legacy or unrealistic timing tests. void dml_rq_dlg_get_dlg_reg( struct display_mode_lib *mode_lib, - struct _vcs_dpi_display_dlg_regs_st *dlg_regs, - struct _vcs_dpi_display_ttu_regs_st *ttu_regs, - struct _vcs_dpi_display_e2e_pipe_params_st *e2e_pipe_param, + display_dlg_regs_st *dlg_regs, + display_ttu_regs_st *ttu_regs, + display_e2e_pipe_params_st *e2e_pipe_param, const unsigned int num_pipes, const unsigned int pipe_idx, const bool cstate_en, const bool pstate_en, const bool vm_en, - const bool iflip_en); + const bool ignore_viewport_pos, + const bool immediate_flip_support); -/* Function: dml_rq_dlg_get_row_heights - * Calculate dpte and meta row heights - */ +// Function: dml_rq_dlg_get_calculated_vstartup +// Calculate and return vstartup +// Output: +// unsigned int vstartup +// Input: +// e2e_pipe_param - "compacted" array of e2e pipe param struct +// num_pipes - num of active "pipe" or "route" +// pipe_idx - index that identifies the e2e_pipe_param that corresponding to this dlg +// NOTE: this MUST be called after setting the prefetch mode! +unsigned int dml_rq_dlg_get_calculated_vstartup( + struct display_mode_lib *mode_lib, + display_e2e_pipe_params_st *e2e_pipe_param, + const unsigned int num_pipes, + const unsigned int pipe_idx); + +// Function: dml_rq_dlg_get_row_heights +// Calculate dpte and meta row heights void dml_rq_dlg_get_row_heights( struct display_mode_lib *mode_lib, unsigned int *o_dpte_row_height, @@ -131,9 +142,7 @@ void dml_rq_dlg_get_row_heights( int source_scan, int is_chroma); -/* Function: dml_rq_dlg_get_arb_params */ -void dml_rq_dlg_get_arb_params( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_display_arb_params_st *arb_param); +// Function: dml_rq_dlg_get_arb_params +void dml_rq_dlg_get_arb_params(struct display_mode_lib *mode_lib, display_arb_params_st *arb_param); #endif diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_helpers.c b/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_helpers.c index 3dc11366cd366..189052e911fce 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_helpers.c +++ b/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_helpers.c @@ -25,296 +25,368 @@ #include "display_rq_dlg_helpers.h" -void print__rq_params_st( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_display_rq_params_st rq_param) +void print__rq_params_st(struct display_mode_lib *mode_lib, display_rq_params_st rq_param) { - DTRACE("RQ_DLG_CALC: *************************** "); - DTRACE("RQ_DLG_CALC: DISPLAY_RQ_PARAM_ST"); - DTRACE("RQ_DLG_CALC: "); + dml_print("DML_RQ_DLG_CALC: ***************************\n"); + dml_print("DML_RQ_DLG_CALC: DISPLAY_RQ_PARAM_ST\n"); + dml_print("DML_RQ_DLG_CALC: \n"); print__data_rq_sizing_params_st(mode_lib, rq_param.sizing.rq_l); - DTRACE("RQ_DLG_CALC: === "); + dml_print("DML_RQ_DLG_CALC: ===\n"); print__data_rq_sizing_params_st(mode_lib, rq_param.sizing.rq_c); - DTRACE("RQ_DLG_CALC: "); + dml_print("DML_RQ_DLG_CALC: \n"); print__data_rq_dlg_params_st(mode_lib, rq_param.dlg.rq_l); - DTRACE("RQ_DLG_CALC: "); + dml_print("DML_RQ_DLG_CALC: \n"); print__data_rq_dlg_params_st(mode_lib, rq_param.dlg.rq_c); - DTRACE("RQ_DLG_CALC: "); + dml_print("DML_RQ_DLG_CALC: \n"); print__data_rq_misc_params_st(mode_lib, rq_param.misc.rq_l); - DTRACE("RQ_DLG_CALC: "); + dml_print("DML_RQ_DLG_CALC: \n"); print__data_rq_misc_params_st(mode_lib, rq_param.misc.rq_c); - DTRACE("RQ_DLG_CALC: *************************** "); + dml_print("DML_RQ_DLG_CALC: ***************************\n"); } -void print__data_rq_sizing_params_st( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_display_data_rq_sizing_params_st rq_sizing) +void print__data_rq_sizing_params_st(struct display_mode_lib *mode_lib, display_data_rq_sizing_params_st rq_sizing) { - DTRACE("RQ_DLG_CALC: ===================================== "); - DTRACE("RQ_DLG_CALC: DISPLAY_DATA_RQ_SIZING_PARAM_ST"); - DTRACE("RQ_DLG_CALC: chunk_bytes = %0d", rq_sizing.chunk_bytes); - DTRACE("RQ_DLG_CALC: min_chunk_bytes = %0d", rq_sizing.min_chunk_bytes); - DTRACE("RQ_DLG_CALC: meta_chunk_bytes = %0d", rq_sizing.meta_chunk_bytes); - DTRACE("RQ_DLG_CALC: min_meta_chunk_bytes = %0d", rq_sizing.min_meta_chunk_bytes); - DTRACE("RQ_DLG_CALC: mpte_group_bytes = %0d", rq_sizing.mpte_group_bytes); - DTRACE("RQ_DLG_CALC: dpte_group_bytes = %0d", rq_sizing.dpte_group_bytes); - DTRACE("RQ_DLG_CALC: ===================================== "); + dml_print("DML_RQ_DLG_CALC: =====================================\n"); + dml_print("DML_RQ_DLG_CALC: DISPLAY_DATA_RQ_SIZING_PARAM_ST\n"); + dml_print("DML_RQ_DLG_CALC: chunk_bytes = %0d\n", rq_sizing.chunk_bytes); + dml_print("DML_RQ_DLG_CALC: min_chunk_bytes = %0d\n", rq_sizing.min_chunk_bytes); + dml_print("DML_RQ_DLG_CALC: meta_chunk_bytes = %0d\n", rq_sizing.meta_chunk_bytes); + dml_print( + "DML_RQ_DLG_CALC: min_meta_chunk_bytes = %0d\n", + rq_sizing.min_meta_chunk_bytes); + dml_print("DML_RQ_DLG_CALC: mpte_group_bytes = %0d\n", rq_sizing.mpte_group_bytes); + dml_print("DML_RQ_DLG_CALC: dpte_group_bytes = %0d\n", rq_sizing.dpte_group_bytes); + dml_print("DML_RQ_DLG_CALC: =====================================\n"); } -void print__data_rq_dlg_params_st( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_display_data_rq_dlg_params_st rq_dlg_param) +void print__data_rq_dlg_params_st(struct display_mode_lib *mode_lib, display_data_rq_dlg_params_st rq_dlg_param) { - DTRACE("RQ_DLG_CALC: ===================================== "); - DTRACE("RQ_DLG_CALC: DISPLAY_DATA_RQ_DLG_PARAM_ST"); - DTRACE("RQ_DLG_CALC: swath_width_ub = %0d", rq_dlg_param.swath_width_ub); - DTRACE("RQ_DLG_CALC: swath_height = %0d", rq_dlg_param.swath_height); - DTRACE("RQ_DLG_CALC: req_per_swath_ub = %0d", rq_dlg_param.req_per_swath_ub); - DTRACE( - "RQ_DLG_CALC: meta_pte_bytes_per_frame_ub = %0d", + dml_print("DML_RQ_DLG_CALC: =====================================\n"); + dml_print("DML_RQ_DLG_CALC: DISPLAY_DATA_RQ_DLG_PARAM_ST\n"); + dml_print( + "DML_RQ_DLG_CALC: swath_width_ub = %0d\n", + rq_dlg_param.swath_width_ub); + dml_print( + "DML_RQ_DLG_CALC: swath_height = %0d\n", + rq_dlg_param.swath_height); + dml_print( + "DML_RQ_DLG_CALC: req_per_swath_ub = %0d\n", + rq_dlg_param.req_per_swath_ub); + dml_print( + "DML_RQ_DLG_CALC: meta_pte_bytes_per_frame_ub = %0d\n", rq_dlg_param.meta_pte_bytes_per_frame_ub); - DTRACE( - "RQ_DLG_CALC: dpte_req_per_row_ub = %0d", + dml_print( + "DML_RQ_DLG_CALC: dpte_req_per_row_ub = %0d\n", rq_dlg_param.dpte_req_per_row_ub); - DTRACE( - "RQ_DLG_CALC: dpte_groups_per_row_ub = %0d", + dml_print( + "DML_RQ_DLG_CALC: dpte_groups_per_row_ub = %0d\n", rq_dlg_param.dpte_groups_per_row_ub); - DTRACE("RQ_DLG_CALC: dpte_row_height = %0d", rq_dlg_param.dpte_row_height); - DTRACE( - "RQ_DLG_CALC: dpte_bytes_per_row_ub = %0d", + dml_print( + "DML_RQ_DLG_CALC: dpte_row_height = %0d\n", + rq_dlg_param.dpte_row_height); + dml_print( + "DML_RQ_DLG_CALC: dpte_bytes_per_row_ub = %0d\n", rq_dlg_param.dpte_bytes_per_row_ub); - DTRACE( - "RQ_DLG_CALC: meta_chunks_per_row_ub = %0d", + dml_print( + "DML_RQ_DLG_CALC: meta_chunks_per_row_ub = %0d\n", rq_dlg_param.meta_chunks_per_row_ub); - DTRACE( - "RQ_DLG_CALC: meta_req_per_row_ub = %0d", + dml_print( + "DML_RQ_DLG_CALC: meta_req_per_row_ub = %0d\n", rq_dlg_param.meta_req_per_row_ub); - DTRACE("RQ_DLG_CALC: meta_row_height = %0d", rq_dlg_param.meta_row_height); - DTRACE( - "RQ_DLG_CALC: meta_bytes_per_row_ub = %0d", + dml_print( + "DML_RQ_DLG_CALC: meta_row_height = %0d\n", + rq_dlg_param.meta_row_height); + dml_print( + "DML_RQ_DLG_CALC: meta_bytes_per_row_ub = %0d\n", rq_dlg_param.meta_bytes_per_row_ub); - DTRACE("RQ_DLG_CALC: ===================================== "); + dml_print("DML_RQ_DLG_CALC: =====================================\n"); } -void print__data_rq_misc_params_st( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_display_data_rq_misc_params_st rq_misc_param) +void print__data_rq_misc_params_st(struct display_mode_lib *mode_lib, display_data_rq_misc_params_st rq_misc_param) { - DTRACE("RQ_DLG_CALC: ===================================== "); - DTRACE("RQ_DLG_CALC: DISPLAY_DATA_RQ_MISC_PARAM_ST"); - DTRACE("RQ_DLG_CALC: full_swath_bytes = %0d", rq_misc_param.full_swath_bytes); - DTRACE("RQ_DLG_CALC: stored_swath_bytes = %0d", rq_misc_param.stored_swath_bytes); - DTRACE("RQ_DLG_CALC: blk256_width = %0d", rq_misc_param.blk256_width); - DTRACE("RQ_DLG_CALC: blk256_height = %0d", rq_misc_param.blk256_height); - DTRACE("RQ_DLG_CALC: req_width = %0d", rq_misc_param.req_width); - DTRACE("RQ_DLG_CALC: req_height = %0d", rq_misc_param.req_height); - DTRACE("RQ_DLG_CALC: ===================================== "); + dml_print("DML_RQ_DLG_CALC: =====================================\n"); + dml_print("DML_RQ_DLG_CALC: DISPLAY_DATA_RQ_MISC_PARAM_ST\n"); + dml_print( + "DML_RQ_DLG_CALC: full_swath_bytes = %0d\n", + rq_misc_param.full_swath_bytes); + dml_print( + "DML_RQ_DLG_CALC: stored_swath_bytes = %0d\n", + rq_misc_param.stored_swath_bytes); + dml_print("DML_RQ_DLG_CALC: blk256_width = %0d\n", rq_misc_param.blk256_width); + dml_print("DML_RQ_DLG_CALC: blk256_height = %0d\n", rq_misc_param.blk256_height); + dml_print("DML_RQ_DLG_CALC: req_width = %0d\n", rq_misc_param.req_width); + dml_print("DML_RQ_DLG_CALC: req_height = %0d\n", rq_misc_param.req_height); + dml_print("DML_RQ_DLG_CALC: =====================================\n"); } -void print__rq_dlg_params_st( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_display_rq_dlg_params_st rq_dlg_param) +void print__rq_dlg_params_st(struct display_mode_lib *mode_lib, display_rq_dlg_params_st rq_dlg_param) { - DTRACE("RQ_DLG_CALC: ===================================== "); - DTRACE("RQ_DLG_CALC: DISPLAY_RQ_DLG_PARAM_ST"); - DTRACE("RQ_DLG_CALC: "); + dml_print("DML_RQ_DLG_CALC: =====================================\n"); + dml_print("DML_RQ_DLG_CALC: DISPLAY_RQ_DLG_PARAM_ST\n"); + dml_print("DML_RQ_DLG_CALC: \n"); print__data_rq_dlg_params_st(mode_lib, rq_dlg_param.rq_l); - DTRACE("RQ_DLG_CALC: "); + dml_print("DML_RQ_DLG_CALC: \n"); print__data_rq_dlg_params_st(mode_lib, rq_dlg_param.rq_c); - DTRACE("RQ_DLG_CALC: ===================================== "); + dml_print("DML_RQ_DLG_CALC: =====================================\n"); } -void print__dlg_sys_params_st( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_display_dlg_sys_params_st dlg_sys_param) +void print__dlg_sys_params_st(struct display_mode_lib *mode_lib, display_dlg_sys_params_st dlg_sys_param) { - DTRACE("RQ_DLG_CALC: ===================================== "); - DTRACE("RQ_DLG_CALC: DISPLAY_RQ_DLG_PARAM_ST"); - DTRACE("RQ_DLG_CALC: t_mclk_wm_us = %3.2f", dlg_sys_param.t_mclk_wm_us); - DTRACE("RQ_DLG_CALC: t_urg_wm_us = %3.2f", dlg_sys_param.t_urg_wm_us); - DTRACE("RQ_DLG_CALC: t_sr_wm_us = %3.2f", dlg_sys_param.t_sr_wm_us); - DTRACE("RQ_DLG_CALC: t_extra_us = %3.2f", dlg_sys_param.t_extra_us); - DTRACE("RQ_DLG_CALC: t_srx_delay_us = %3.2f", dlg_sys_param.t_srx_delay_us); - DTRACE("RQ_DLG_CALC: deepsleep_dcfclk_mhz = %3.2f", dlg_sys_param.deepsleep_dcfclk_mhz); - DTRACE("RQ_DLG_CALC: ===================================== "); + dml_print("DML_RQ_DLG_CALC: =====================================\n"); + dml_print("DML_RQ_DLG_CALC: DISPLAY_RQ_DLG_PARAM_ST\n"); + dml_print("DML_RQ_DLG_CALC: t_mclk_wm_us = %3.2f\n", dlg_sys_param.t_mclk_wm_us); + dml_print("DML_RQ_DLG_CALC: t_urg_wm_us = %3.2f\n", dlg_sys_param.t_urg_wm_us); + dml_print("DML_RQ_DLG_CALC: t_sr_wm_us = %3.2f\n", dlg_sys_param.t_sr_wm_us); + dml_print("DML_RQ_DLG_CALC: t_extra_us = %3.2f\n", dlg_sys_param.t_extra_us); + dml_print( + "DML_RQ_DLG_CALC: t_srx_delay_us = %3.2f\n", + dlg_sys_param.t_srx_delay_us); + dml_print( + "DML_RQ_DLG_CALC: deepsleep_dcfclk_mhz = %3.2f\n", + dlg_sys_param.deepsleep_dcfclk_mhz); + dml_print( + "DML_RQ_DLG_CALC: total_flip_bw = %3.2f\n", + dlg_sys_param.total_flip_bw); + dml_print( + "DML_RQ_DLG_CALC: total_flip_bytes = %i\n", + dlg_sys_param.total_flip_bytes); + dml_print("DML_RQ_DLG_CALC: =====================================\n"); } -void print__data_rq_regs_st( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_display_data_rq_regs_st rq_regs) +void print__data_rq_regs_st(struct display_mode_lib *mode_lib, display_data_rq_regs_st rq_regs) { - DTRACE("RQ_DLG_CALC: ===================================== "); - DTRACE("RQ_DLG_CALC: DISPLAY_DATA_RQ_REGS_ST"); - DTRACE("RQ_DLG_CALC: chunk_size = 0x%0x", rq_regs.chunk_size); - DTRACE("RQ_DLG_CALC: min_chunk_size = 0x%0x", rq_regs.min_chunk_size); - DTRACE("RQ_DLG_CALC: meta_chunk_size = 0x%0x", rq_regs.meta_chunk_size); - DTRACE("RQ_DLG_CALC: min_meta_chunk_size = 0x%0x", rq_regs.min_meta_chunk_size); - DTRACE("RQ_DLG_CALC: dpte_group_size = 0x%0x", rq_regs.dpte_group_size); - DTRACE("RQ_DLG_CALC: mpte_group_size = 0x%0x", rq_regs.mpte_group_size); - DTRACE("RQ_DLG_CALC: swath_height = 0x%0x", rq_regs.swath_height); - DTRACE("RQ_DLG_CALC: pte_row_height_linear = 0x%0x", rq_regs.pte_row_height_linear); - DTRACE("RQ_DLG_CALC: ===================================== "); + dml_print("DML_RQ_DLG_CALC: =====================================\n"); + dml_print("DML_RQ_DLG_CALC: DISPLAY_DATA_RQ_REGS_ST\n"); + dml_print("DML_RQ_DLG_CALC: chunk_size = 0x%0x\n", rq_regs.chunk_size); + dml_print("DML_RQ_DLG_CALC: min_chunk_size = 0x%0x\n", rq_regs.min_chunk_size); + dml_print("DML_RQ_DLG_CALC: meta_chunk_size = 0x%0x\n", rq_regs.meta_chunk_size); + dml_print( + "DML_RQ_DLG_CALC: min_meta_chunk_size = 0x%0x\n", + rq_regs.min_meta_chunk_size); + dml_print("DML_RQ_DLG_CALC: dpte_group_size = 0x%0x\n", rq_regs.dpte_group_size); + dml_print("DML_RQ_DLG_CALC: mpte_group_size = 0x%0x\n", rq_regs.mpte_group_size); + dml_print("DML_RQ_DLG_CALC: swath_height = 0x%0x\n", rq_regs.swath_height); + dml_print( + "DML_RQ_DLG_CALC: pte_row_height_linear = 0x%0x\n", + rq_regs.pte_row_height_linear); + dml_print("DML_RQ_DLG_CALC: =====================================\n"); } -void print__rq_regs_st( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_display_rq_regs_st rq_regs) +void print__rq_regs_st(struct display_mode_lib *mode_lib, display_rq_regs_st rq_regs) { - DTRACE("RQ_DLG_CALC: ===================================== "); - DTRACE("RQ_DLG_CALC: DISPLAY_RQ_REGS_ST"); - DTRACE("RQ_DLG_CALC: "); + dml_print("DML_RQ_DLG_CALC: =====================================\n"); + dml_print("DML_RQ_DLG_CALC: DISPLAY_RQ_REGS_ST\n"); + dml_print("DML_RQ_DLG_CALC: \n"); print__data_rq_regs_st(mode_lib, rq_regs.rq_regs_l); - DTRACE("RQ_DLG_CALC: "); + dml_print("DML_RQ_DLG_CALC: \n"); print__data_rq_regs_st(mode_lib, rq_regs.rq_regs_c); - DTRACE("RQ_DLG_CALC: drq_expansion_mode = 0x%0x", rq_regs.drq_expansion_mode); - DTRACE("RQ_DLG_CALC: prq_expansion_mode = 0x%0x", rq_regs.prq_expansion_mode); - DTRACE("RQ_DLG_CALC: mrq_expansion_mode = 0x%0x", rq_regs.mrq_expansion_mode); - DTRACE("RQ_DLG_CALC: crq_expansion_mode = 0x%0x", rq_regs.crq_expansion_mode); - DTRACE("RQ_DLG_CALC: plane1_base_address = 0x%0x", rq_regs.plane1_base_address); - DTRACE("RQ_DLG_CALC: ===================================== "); + dml_print("DML_RQ_DLG_CALC: drq_expansion_mode = 0x%0x\n", rq_regs.drq_expansion_mode); + dml_print("DML_RQ_DLG_CALC: prq_expansion_mode = 0x%0x\n", rq_regs.prq_expansion_mode); + dml_print("DML_RQ_DLG_CALC: mrq_expansion_mode = 0x%0x\n", rq_regs.mrq_expansion_mode); + dml_print("DML_RQ_DLG_CALC: crq_expansion_mode = 0x%0x\n", rq_regs.crq_expansion_mode); + dml_print("DML_RQ_DLG_CALC: plane1_base_address = 0x%0x\n", rq_regs.plane1_base_address); + dml_print("DML_RQ_DLG_CALC: =====================================\n"); } -void print__dlg_regs_st( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_display_dlg_regs_st dlg_regs) +void print__dlg_regs_st(struct display_mode_lib *mode_lib, display_dlg_regs_st dlg_regs) { - DTRACE("RQ_DLG_CALC: ===================================== "); - DTRACE("RQ_DLG_CALC: DISPLAY_DLG_REGS_ST "); - DTRACE( - "RQ_DLG_CALC: refcyc_h_blank_end = 0x%0x", + dml_print("DML_RQ_DLG_CALC: =====================================\n"); + dml_print("DML_RQ_DLG_CALC: DISPLAY_DLG_REGS_ST\n"); + dml_print( + "DML_RQ_DLG_CALC: refcyc_h_blank_end = 0x%0x\n", dlg_regs.refcyc_h_blank_end); - DTRACE("RQ_DLG_CALC: dlg_vblank_end = 0x%0x", dlg_regs.dlg_vblank_end); - DTRACE( - "RQ_DLG_CALC: min_dst_y_next_start = 0x%0x", + dml_print( + "DML_RQ_DLG_CALC: dlg_vblank_end = 0x%0x\n", + dlg_regs.dlg_vblank_end); + dml_print( + "DML_RQ_DLG_CALC: min_dst_y_next_start = 0x%0x\n", dlg_regs.min_dst_y_next_start); - DTRACE( - "RQ_DLG_CALC: refcyc_per_htotal = 0x%0x", + dml_print( + "DML_RQ_DLG_CALC: refcyc_per_htotal = 0x%0x\n", dlg_regs.refcyc_per_htotal); - DTRACE( - "RQ_DLG_CALC: refcyc_x_after_scaler = 0x%0x", + dml_print( + "DML_RQ_DLG_CALC: refcyc_x_after_scaler = 0x%0x\n", dlg_regs.refcyc_x_after_scaler); - DTRACE( - "RQ_DLG_CALC: dst_y_after_scaler = 0x%0x", + dml_print( + "DML_RQ_DLG_CALC: dst_y_after_scaler = 0x%0x\n", dlg_regs.dst_y_after_scaler); - DTRACE("RQ_DLG_CALC: dst_y_prefetch = 0x%0x", dlg_regs.dst_y_prefetch); - DTRACE( - "RQ_DLG_CALC: dst_y_per_vm_vblank = 0x%0x", + dml_print( + "DML_RQ_DLG_CALC: dst_y_prefetch = 0x%0x\n", + dlg_regs.dst_y_prefetch); + dml_print( + "DML_RQ_DLG_CALC: dst_y_per_vm_vblank = 0x%0x\n", dlg_regs.dst_y_per_vm_vblank); - DTRACE( - "RQ_DLG_CALC: dst_y_per_row_vblank = 0x%0x", + dml_print( + "DML_RQ_DLG_CALC: dst_y_per_row_vblank = 0x%0x\n", dlg_regs.dst_y_per_row_vblank); - DTRACE( - "RQ_DLG_CALC: ref_freq_to_pix_freq = 0x%0x", + dml_print( + "DML_RQ_DLG_CALC: dst_y_per_vm_flip = 0x%0x\n", + dlg_regs.dst_y_per_vm_flip); + dml_print( + "DML_RQ_DLG_CALC: dst_y_per_row_flip = 0x%0x\n", + dlg_regs.dst_y_per_row_flip); + dml_print( + "DML_RQ_DLG_CALC: ref_freq_to_pix_freq = 0x%0x\n", dlg_regs.ref_freq_to_pix_freq); - DTRACE("RQ_DLG_CALC: vratio_prefetch = 0x%0x", dlg_regs.vratio_prefetch); - DTRACE( - "RQ_DLG_CALC: vratio_prefetch_c = 0x%0x", + dml_print( + "DML_RQ_DLG_CALC: vratio_prefetch = 0x%0x\n", + dlg_regs.vratio_prefetch); + dml_print( + "DML_RQ_DLG_CALC: vratio_prefetch_c = 0x%0x\n", dlg_regs.vratio_prefetch_c); - DTRACE( - "RQ_DLG_CALC: refcyc_per_pte_group_vblank_l = 0x%0x", + dml_print( + "DML_RQ_DLG_CALC: refcyc_per_pte_group_vblank_l = 0x%0x\n", dlg_regs.refcyc_per_pte_group_vblank_l); - DTRACE( - "RQ_DLG_CALC: refcyc_per_pte_group_vblank_c = 0x%0x", + dml_print( + "DML_RQ_DLG_CALC: refcyc_per_pte_group_vblank_c = 0x%0x\n", dlg_regs.refcyc_per_pte_group_vblank_c); - DTRACE( - "RQ_DLG_CALC: refcyc_per_meta_chunk_vblank_l = 0x%0x", + dml_print( + "DML_RQ_DLG_CALC: refcyc_per_meta_chunk_vblank_l = 0x%0x\n", dlg_regs.refcyc_per_meta_chunk_vblank_l); - DTRACE( - "RQ_DLG_CALC: refcyc_per_meta_chunk_vblank_c = 0x%0x", + dml_print( + "DML_RQ_DLG_CALC: refcyc_per_meta_chunk_vblank_c = 0x%0x\n", dlg_regs.refcyc_per_meta_chunk_vblank_c); - DTRACE( - "RQ_DLG_CALC: dst_y_per_pte_row_nom_l = 0x%0x", + dml_print( + "DML_RQ_DLG_CALC: refcyc_per_pte_group_flip_l = 0x%0x\n", + dlg_regs.refcyc_per_pte_group_flip_l); + dml_print( + "DML_RQ_DLG_CALC: refcyc_per_pte_group_flip_c = 0x%0x\n", + dlg_regs.refcyc_per_pte_group_flip_c); + dml_print( + "DML_RQ_DLG_CALC: refcyc_per_meta_chunk_flip_l = 0x%0x\n", + dlg_regs.refcyc_per_meta_chunk_flip_l); + dml_print( + "DML_RQ_DLG_CALC: refcyc_per_meta_chunk_flip_c = 0x%0x\n", + dlg_regs.refcyc_per_meta_chunk_flip_c); + dml_print( + "DML_RQ_DLG_CALC: dst_y_per_pte_row_nom_l = 0x%0x\n", dlg_regs.dst_y_per_pte_row_nom_l); - DTRACE( - "RQ_DLG_CALC: dst_y_per_pte_row_nom_c = 0x%0x", + dml_print( + "DML_RQ_DLG_CALC: dst_y_per_pte_row_nom_c = 0x%0x\n", dlg_regs.dst_y_per_pte_row_nom_c); - DTRACE( - "RQ_DLG_CALC: refcyc_per_pte_group_nom_l = 0x%0x", + dml_print( + "DML_RQ_DLG_CALC: refcyc_per_pte_group_nom_l = 0x%0x\n", dlg_regs.refcyc_per_pte_group_nom_l); - DTRACE( - "RQ_DLG_CALC: refcyc_per_pte_group_nom_c = 0x%0x", + dml_print( + "DML_RQ_DLG_CALC: refcyc_per_pte_group_nom_c = 0x%0x\n", dlg_regs.refcyc_per_pte_group_nom_c); - DTRACE( - "RQ_DLG_CALC: dst_y_per_meta_row_nom_l = 0x%0x", + dml_print( + "DML_RQ_DLG_CALC: dst_y_per_meta_row_nom_l = 0x%0x\n", dlg_regs.dst_y_per_meta_row_nom_l); - DTRACE( - "RQ_DLG_CALC: dst_y_per_meta_row_nom_c = 0x%0x", + dml_print( + "DML_RQ_DLG_CALC: dst_y_per_meta_row_nom_c = 0x%0x\n", dlg_regs.dst_y_per_meta_row_nom_c); - DTRACE( - "RQ_DLG_CALC: refcyc_per_meta_chunk_nom_l = 0x%0x", + dml_print( + "DML_RQ_DLG_CALC: refcyc_per_meta_chunk_nom_l = 0x%0x\n", dlg_regs.refcyc_per_meta_chunk_nom_l); - DTRACE( - "RQ_DLG_CALC: refcyc_per_meta_chunk_nom_c = 0x%0x", + dml_print( + "DML_RQ_DLG_CALC: refcyc_per_meta_chunk_nom_c = 0x%0x\n", dlg_regs.refcyc_per_meta_chunk_nom_c); - DTRACE( - "RQ_DLG_CALC: refcyc_per_line_delivery_pre_l = 0x%0x", + dml_print( + "DML_RQ_DLG_CALC: refcyc_per_line_delivery_pre_l = 0x%0x\n", dlg_regs.refcyc_per_line_delivery_pre_l); - DTRACE( - "RQ_DLG_CALC: refcyc_per_line_delivery_pre_c = 0x%0x", + dml_print( + "DML_RQ_DLG_CALC: refcyc_per_line_delivery_pre_c = 0x%0x\n", dlg_regs.refcyc_per_line_delivery_pre_c); - DTRACE( - "RQ_DLG_CALC: refcyc_per_line_delivery_l = 0x%0x", + dml_print( + "DML_RQ_DLG_CALC: refcyc_per_line_delivery_l = 0x%0x\n", dlg_regs.refcyc_per_line_delivery_l); - DTRACE( - "RQ_DLG_CALC: refcyc_per_line_delivery_c = 0x%0x", + dml_print( + "DML_RQ_DLG_CALC: refcyc_per_line_delivery_c = 0x%0x\n", dlg_regs.refcyc_per_line_delivery_c); - DTRACE( - "RQ_DLG_CALC: chunk_hdl_adjust_cur0 = 0x%0x", + dml_print( + "DML_RQ_DLG_CALC: chunk_hdl_adjust_cur0 = 0x%0x\n", dlg_regs.chunk_hdl_adjust_cur0); - DTRACE("RQ_DLG_CALC: ===================================== "); + dml_print( + "DML_RQ_DLG_CALC: dst_y_offset_cur1 = 0x%0x\n", + dlg_regs.dst_y_offset_cur1); + dml_print( + "DML_RQ_DLG_CALC: chunk_hdl_adjust_cur1 = 0x%0x\n", + dlg_regs.chunk_hdl_adjust_cur1); + dml_print( + "DML_RQ_DLG_CALC: vready_after_vcount0 = 0x%0x\n", + dlg_regs.vready_after_vcount0); + dml_print( + "DML_RQ_DLG_CALC: dst_y_delta_drq_limit = 0x%0x\n", + dlg_regs.dst_y_delta_drq_limit); + dml_print( + "DML_RQ_DLG_CALC: xfc_reg_transfer_delay = 0x%0x\n", + dlg_regs.xfc_reg_transfer_delay); + dml_print( + "DML_RQ_DLG_CALC: xfc_reg_precharge_delay = 0x%0x\n", + dlg_regs.xfc_reg_precharge_delay); + dml_print( + "DML_RQ_DLG_CALC: xfc_reg_remote_surface_flip_latency = 0x%0x\n", + dlg_regs.xfc_reg_remote_surface_flip_latency); + + dml_print("DML_RQ_DLG_CALC: =====================================\n"); } -void print__ttu_regs_st( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_display_ttu_regs_st ttu_regs) +void print__ttu_regs_st(struct display_mode_lib *mode_lib, display_ttu_regs_st ttu_regs) { - DTRACE("RQ_DLG_CALC: ===================================== "); - DTRACE("RQ_DLG_CALC: DISPLAY_TTU_REGS_ST "); - DTRACE( - "RQ_DLG_CALC: qos_level_low_wm = 0x%0x", + dml_print("DML_RQ_DLG_CALC: =====================================\n"); + dml_print("DML_RQ_DLG_CALC: DISPLAY_TTU_REGS_ST\n"); + dml_print( + "DML_RQ_DLG_CALC: qos_level_low_wm = 0x%0x\n", ttu_regs.qos_level_low_wm); - DTRACE( - "RQ_DLG_CALC: qos_level_high_wm = 0x%0x", + dml_print( + "DML_RQ_DLG_CALC: qos_level_high_wm = 0x%0x\n", ttu_regs.qos_level_high_wm); - DTRACE("RQ_DLG_CALC: min_ttu_vblank = 0x%0x", ttu_regs.min_ttu_vblank); - DTRACE("RQ_DLG_CALC: qos_level_flip = 0x%0x", ttu_regs.qos_level_flip); - DTRACE( - "RQ_DLG_CALC: refcyc_per_req_delivery_pre_l = 0x%0x", + dml_print( + "DML_RQ_DLG_CALC: min_ttu_vblank = 0x%0x\n", + ttu_regs.min_ttu_vblank); + dml_print( + "DML_RQ_DLG_CALC: qos_level_flip = 0x%0x\n", + ttu_regs.qos_level_flip); + dml_print( + "DML_RQ_DLG_CALC: refcyc_per_req_delivery_pre_l = 0x%0x\n", ttu_regs.refcyc_per_req_delivery_pre_l); - DTRACE( - "RQ_DLG_CALC: refcyc_per_req_delivery_l = 0x%0x", + dml_print( + "DML_RQ_DLG_CALC: refcyc_per_req_delivery_l = 0x%0x\n", ttu_regs.refcyc_per_req_delivery_l); - DTRACE( - "RQ_DLG_CALC: refcyc_per_req_delivery_pre_c = 0x%0x", + dml_print( + "DML_RQ_DLG_CALC: refcyc_per_req_delivery_pre_c = 0x%0x\n", ttu_regs.refcyc_per_req_delivery_pre_c); - DTRACE( - "RQ_DLG_CALC: refcyc_per_req_delivery_c = 0x%0x", + dml_print( + "DML_RQ_DLG_CALC: refcyc_per_req_delivery_c = 0x%0x\n", ttu_regs.refcyc_per_req_delivery_c); - DTRACE( - "RQ_DLG_CALC: refcyc_per_req_delivery_cur0 = 0x%0x", + dml_print( + "DML_RQ_DLG_CALC: refcyc_per_req_delivery_cur0 = 0x%0x\n", ttu_regs.refcyc_per_req_delivery_cur0); - DTRACE( - "RQ_DLG_CALC: refcyc_per_req_delivery_pre_cur0 = 0x%0x", + dml_print( + "DML_RQ_DLG_CALC: refcyc_per_req_delivery_pre_cur0 = 0x%0x\n", ttu_regs.refcyc_per_req_delivery_pre_cur0); - DTRACE( - "RQ_DLG_CALC: qos_level_fixed_l = 0x%0x", + dml_print( + "DML_RQ_DLG_CALC: refcyc_per_req_delivery_cur1 = 0x%0x\n", + ttu_regs.refcyc_per_req_delivery_cur1); + dml_print( + "DML_RQ_DLG_CALC: refcyc_per_req_delivery_pre_cur1 = 0x%0x\n", + ttu_regs.refcyc_per_req_delivery_pre_cur1); + dml_print( + "DML_RQ_DLG_CALC: qos_level_fixed_l = 0x%0x\n", ttu_regs.qos_level_fixed_l); - DTRACE( - "RQ_DLG_CALC: qos_ramp_disable_l = 0x%0x", + dml_print( + "DML_RQ_DLG_CALC: qos_ramp_disable_l = 0x%0x\n", ttu_regs.qos_ramp_disable_l); - DTRACE( - "RQ_DLG_CALC: qos_level_fixed_c = 0x%0x", + dml_print( + "DML_RQ_DLG_CALC: qos_level_fixed_c = 0x%0x\n", ttu_regs.qos_level_fixed_c); - DTRACE( - "RQ_DLG_CALC: qos_ramp_disable_c = 0x%0x", + dml_print( + "DML_RQ_DLG_CALC: qos_ramp_disable_c = 0x%0x\n", ttu_regs.qos_ramp_disable_c); - DTRACE( - "RQ_DLG_CALC: qos_level_fixed_cur0 = 0x%0x", + dml_print( + "DML_RQ_DLG_CALC: qos_level_fixed_cur0 = 0x%0x\n", ttu_regs.qos_level_fixed_cur0); - DTRACE( - "RQ_DLG_CALC: qos_ramp_disable_cur0 = 0x%0x", + dml_print( + "DML_RQ_DLG_CALC: qos_ramp_disable_cur0 = 0x%0x\n", ttu_regs.qos_ramp_disable_cur0); - DTRACE("RQ_DLG_CALC: ===================================== "); + dml_print( + "DML_RQ_DLG_CALC: qos_level_fixed_cur1 = 0x%0x\n", + ttu_regs.qos_level_fixed_cur1); + dml_print( + "DML_RQ_DLG_CALC: qos_ramp_disable_cur1 = 0x%0x\n", + ttu_regs.qos_ramp_disable_cur1); + dml_print("DML_RQ_DLG_CALC: =====================================\n"); } diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_helpers.h b/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_helpers.h index 7403ccaf637b6..1f24db830737c 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_helpers.h +++ b/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_helpers.h @@ -22,6 +22,7 @@ * Authors: AMD * */ + #ifndef __DISPLAY_RQ_DLG_HELPERS_H__ #define __DISPLAY_RQ_DLG_HELPERS_H__ @@ -31,36 +32,16 @@ /* Function: Printer functions * Print various struct */ -void print__rq_params_st( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_display_rq_params_st rq_param); -void print__data_rq_sizing_params_st( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_display_data_rq_sizing_params_st rq_sizing); -void print__data_rq_dlg_params_st( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_display_data_rq_dlg_params_st rq_dlg_param); -void print__data_rq_misc_params_st( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_display_data_rq_misc_params_st rq_misc_param); -void print__rq_dlg_params_st( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_display_rq_dlg_params_st rq_dlg_param); -void print__dlg_sys_params_st( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_display_dlg_sys_params_st dlg_sys_param); +void print__rq_params_st(struct display_mode_lib *mode_lib, display_rq_params_st rq_param); +void print__data_rq_sizing_params_st(struct display_mode_lib *mode_lib, display_data_rq_sizing_params_st rq_sizing); +void print__data_rq_dlg_params_st(struct display_mode_lib *mode_lib, display_data_rq_dlg_params_st rq_dlg_param); +void print__data_rq_misc_params_st(struct display_mode_lib *mode_lib, display_data_rq_misc_params_st rq_misc_param); +void print__rq_dlg_params_st(struct display_mode_lib *mode_lib, display_rq_dlg_params_st rq_dlg_param); +void print__dlg_sys_params_st(struct display_mode_lib *mode_lib, display_dlg_sys_params_st dlg_sys_param); -void print__data_rq_regs_st( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_display_data_rq_regs_st data_rq_regs); -void print__rq_regs_st( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_display_rq_regs_st rq_regs); -void print__dlg_regs_st( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_display_dlg_regs_st dlg_regs); -void print__ttu_regs_st( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_display_ttu_regs_st ttu_regs); +void print__data_rq_regs_st(struct display_mode_lib *mode_lib, display_data_rq_regs_st data_rq_regs); +void print__rq_regs_st(struct display_mode_lib *mode_lib, display_rq_regs_st rq_regs); +void print__dlg_regs_st(struct display_mode_lib *mode_lib, display_dlg_regs_st dlg_regs); +void print__ttu_regs_st(struct display_mode_lib *mode_lib, display_ttu_regs_st ttu_regs); #endif diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_watermark.c b/drivers/gpu/drm/amd/display/dc/dml/display_watermark.c deleted file mode 100644 index 390f093914339..0000000000000 --- a/drivers/gpu/drm/amd/display/dc/dml/display_watermark.c +++ /dev/null @@ -1,1281 +0,0 @@ -/* - * Copyright 2017 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: AMD - * - */ -#include "display_watermark.h" -#include "display_mode_lib.h" - -static void get_bytes_per_pixel( - enum source_format_class format, - struct _vcs_dpi_wm_calc_pipe_params_st *plane) -{ - switch (format) { - case dm_444_64: - plane->bytes_per_pixel_y = 8.0; - plane->bytes_per_pixel_c = 0.0; - break; - case dm_444_32: - plane->bytes_per_pixel_y = 4.0; - plane->bytes_per_pixel_c = 0.0; - break; - case dm_444_16: - plane->bytes_per_pixel_y = 2.0; - plane->bytes_per_pixel_c = 0.0; - break; - case dm_422_10: - plane->bytes_per_pixel_y = 4.0; - plane->bytes_per_pixel_c = 0.0; - break; - case dm_422_8: - plane->bytes_per_pixel_y = 2.0; - plane->bytes_per_pixel_c = 0.0; - break; - case dm_420_8: - plane->bytes_per_pixel_y = 1.0; - plane->bytes_per_pixel_c = 2.0; - break; - case dm_420_10: - plane->bytes_per_pixel_y = 4.0 / 3; - plane->bytes_per_pixel_c = 8.0 / 3; - break; - default: - BREAK_TO_DEBUGGER(); /* invalid format in get_bytes_per_pixel */ - } -} - -static unsigned int get_swath_width_y( - struct _vcs_dpi_display_pipe_source_params_st *src_param, - unsigned int num_dpp) -{ - unsigned int val; - - /* note that we don't divide by num_dpp here because we have an interface which has already split - * any viewports - */ - if (src_param->source_scan == dm_horz) { - val = src_param->viewport_width; - } else { - val = src_param->viewport_height; - } - - return val; -} - -static void get_swath_height( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_display_pipe_source_params_st *src_param, - struct _vcs_dpi_wm_calc_pipe_params_st *plane, - unsigned int swath_width_y) -{ - double buffer_width; - - if (src_param->source_format == dm_444_64 || src_param->source_format == dm_444_32 - || src_param->source_format == dm_444_16) { - if (src_param->sw_mode == dm_sw_linear) { - plane->swath_height_y = 1; - } else if (src_param->source_format == dm_444_64) { - plane->swath_height_y = 4; - } else { - plane->swath_height_y = 8; - } - - if (src_param->source_scan != dm_horz) { - plane->swath_height_y = 256 / (unsigned int) plane->bytes_per_pixel_y - / plane->swath_height_y; - } - - plane->swath_height_c = 0; - - } else { - if (src_param->sw_mode == dm_sw_linear) { - plane->swath_height_y = 1; - plane->swath_height_c = 1; - } else if (src_param->source_format == dm_420_8) { - plane->swath_height_y = 16; - plane->swath_height_c = 8; - } else { - plane->swath_height_y = 8; - plane->swath_height_c = 8; - } - - if (src_param->source_scan != dm_horz) { - double bytes_per_pixel_c_ceil; - - plane->swath_height_y = 256 / dml_ceil(plane->bytes_per_pixel_y) - / plane->swath_height_y; - - bytes_per_pixel_c_ceil = dml_ceil_2(plane->bytes_per_pixel_c); - - plane->swath_height_c = 256 / bytes_per_pixel_c_ceil - / plane->swath_height_c; - } - } - - /* use swath height min if buffer isn't big enough */ - - buffer_width = ((double) mode_lib->ip.det_buffer_size_kbytes * 1024.0 / 2.0) - / (plane->bytes_per_pixel_y * (double) plane->swath_height_y - + (plane->bytes_per_pixel_c / 2.0 - * (double) plane->swath_height_c)); - - if ((double) swath_width_y <= buffer_width) { - /* do nothing, just keep code structure from Gabes vba */ - } else { - /* substitute swath height with swath height min */ - if (src_param->source_format == dm_444_64 || src_param->source_format == dm_444_32 - || src_param->source_format == dm_444_16) { - if ((src_param->sw_mode == dm_sw_linear) - || (src_param->source_format == dm_444_64 - && (src_param->sw_mode == dm_sw_4kb_s - || src_param->sw_mode - == dm_sw_4kb_s_x - || src_param->sw_mode - == dm_sw_64kb_s - || src_param->sw_mode - == dm_sw_64kb_s_t - || src_param->sw_mode - == dm_sw_64kb_s_x - || src_param->sw_mode - == dm_sw_var_s - || src_param->sw_mode - == dm_sw_var_s_x) - && src_param->source_scan == dm_horz)) { - /* do nothing, just keep code structure from Gabes vba */ - } else { - plane->swath_height_y = plane->swath_height_y / 2; - } - } else { - if (src_param->sw_mode == dm_sw_linear) { - /* do nothing, just keep code structure from Gabes vba */ - } else if (src_param->source_format == dm_420_8 - && src_param->source_scan == dm_horz) { - plane->swath_height_y = plane->swath_height_y / 2; - } else if (src_param->source_format == dm_420_10 - && src_param->source_scan == dm_horz) { - plane->swath_height_c = plane->swath_height_c / 2; - } - } - } - - if (plane->swath_height_c == 0) { - plane->det_buffer_size_y = mode_lib->ip.det_buffer_size_kbytes * 1024.0; - } else if (plane->swath_height_c <= plane->swath_height_y) { - plane->det_buffer_size_y = mode_lib->ip.det_buffer_size_kbytes * 1024.0 / 2.0; - } else { - plane->det_buffer_size_y = mode_lib->ip.det_buffer_size_kbytes * 1024.0 * 2.0 / 3.0; - } -} - -static void calc_display_pipe_line_delivery_time( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_wm_calc_pipe_params_st *planes, - unsigned int num_planes) -{ - unsigned int i; - - for (i = 0; i < num_planes; i++) { - if (planes[i].v_ratio <= 1.0) { - planes[i].display_pipe_line_delivery_time = planes[i].swath_width_y - * planes[i].num_dpp / planes[i].h_ratio - / planes[i].pixclk_mhz; - } else { - double dchub_pscl_bw_per_clk; - - if (planes[i].h_ratio > 1) { - double num_hscl_kernels; - - num_hscl_kernels = dml_ceil((double) planes[i].h_taps / 6); - dchub_pscl_bw_per_clk = - dml_min( - (double) mode_lib->ip.max_dchub_pscl_bw_pix_per_clk, - mode_lib->ip.max_pscl_lb_bw_pix_per_clk - * planes[i].h_ratio - / num_hscl_kernels); - } else { - dchub_pscl_bw_per_clk = - dml_min( - (double) mode_lib->ip.max_dchub_pscl_bw_pix_per_clk, - (double) mode_lib->ip.max_pscl_lb_bw_pix_per_clk); - } - - planes[i].display_pipe_line_delivery_time = planes[i].swath_width_y - / dchub_pscl_bw_per_clk / planes[i].dppclk_mhz; - } - } -} - -static double calc_total_data_read_bw( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_wm_calc_pipe_params_st *planes, - unsigned int num_planes) -{ - double val = 0.0; - unsigned int i; - - for (i = 0; i < num_planes; i++) { - double swath_width_y_plane = planes[i].swath_width_y * planes[i].num_dpp; - - planes[i].read_bw = swath_width_y_plane - * (dml_ceil(planes[i].bytes_per_pixel_y) - + dml_ceil_2(planes[i].bytes_per_pixel_c) / 2) - / (planes[i].h_total / planes[i].pixclk_mhz) * planes[i].v_ratio; - - val += planes[i].read_bw; - - DTRACE("plane[%d] start", i); - DTRACE("read_bw = %f", planes[i].read_bw); - DTRACE("plane[%d] end", i); - } - - return val; -} - -double dml_wm_calc_total_data_read_bw( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_wm_calc_pipe_params_st *planes, - unsigned int num_planes) -{ - return calc_total_data_read_bw(mode_lib, planes, num_planes); -} - -static double calc_dcfclk_mhz( - struct _vcs_dpi_wm_calc_pipe_params_st *planes, - unsigned int num_planes) -{ - double dcfclk_mhz = -1.0; - unsigned int i; - - for (i = 0; i < num_planes; i++) { - /* voltage and dcfclk must be the same for all pipes */ - ASSERT(dcfclk_mhz == -1.0 || dcfclk_mhz == planes[i].dcfclk_mhz); - dcfclk_mhz = planes[i].dcfclk_mhz; - } - - return dcfclk_mhz; -} - -static enum voltage_state find_voltage( - struct _vcs_dpi_wm_calc_pipe_params_st *planes, - unsigned int num_planes) -{ - int voltage = -1; - unsigned int i; - - for (i = 0; i < num_planes; i++) { - ASSERT(voltage == -1 || voltage == planes[i].voltage); - voltage = planes[i].voltage; - } - - return (enum voltage_state) voltage; -} - -static bool find_dcc_enable(struct _vcs_dpi_wm_calc_pipe_params_st *planes, unsigned int num_planes) -{ - unsigned int i; - - for (i = 0; i < num_planes; i++) { - if (planes[i].dcc_enable) { - return true; - } - } - - return false; -} - -static double calc_return_bw( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_wm_calc_pipe_params_st *planes, - unsigned int num_planes) -{ - struct _vcs_dpi_soc_bounding_box_st *soc; - double return_bw_mbps; - double dcfclk_mhz; - double return_bus_bw; - enum voltage_state voltage; - double return_bw_to_dcn; - bool dcc_enable; - double rob_chunk_diff; - double urgent_latency_traffic; - double critical_compression; - struct _vcs_dpi_voltage_scaling_st state; - - soc = &mode_lib->soc; - - dcfclk_mhz = calc_dcfclk_mhz(planes, num_planes); - return_bus_bw = dcfclk_mhz * soc->return_bus_width_bytes; - - DTRACE("INTERMEDIATE dcfclk_mhz = %f", dcfclk_mhz); - DTRACE("INTERMEDIATE return_bus_bw = %f", return_bus_bw); - - voltage = find_voltage(planes, num_planes); - return_bw_to_dcn = dml_socbb_return_bw_mhz(soc, voltage); - - dcc_enable = find_dcc_enable(planes, num_planes); - - return_bw_mbps = return_bw_to_dcn; - DTRACE("INTERMEDIATE return_bw_mbps = %f", return_bw_mbps); - - rob_chunk_diff = - (mode_lib->ip.rob_buffer_size_kbytes - mode_lib->ip.pixel_chunk_size_kbytes) - * 1024.0; - DTRACE("INTERMEDIATE rob_chunk_diff = %f", rob_chunk_diff); - - if (dcc_enable && return_bw_to_dcn > return_bus_bw / 4) { - double dcc_return_bw = - return_bw_to_dcn * 4.0 - * (1.0 - - soc->urgent_latency_us - / (rob_chunk_diff - / (return_bw_to_dcn - - return_bus_bw - / 4.0) - + soc->urgent_latency_us)); - return_bw_mbps = dml_min(return_bw_mbps, dcc_return_bw); - DTRACE("INTERMEDIATE dcc_return_bw = %f", dcc_return_bw); - } - - urgent_latency_traffic = return_bus_bw * soc->urgent_latency_us; - DTRACE("INTERMEDIATE urgent_latency_traffic = %f", urgent_latency_traffic); - critical_compression = 2.0 * urgent_latency_traffic - / (return_bw_to_dcn * soc->urgent_latency_us + rob_chunk_diff); - DTRACE("INTERMEDIATE critical_compression = %f", critical_compression); - - if (dcc_enable && critical_compression > 1.0 && critical_compression < 4.0) { - double crit_return_bw = (4 * return_bw_to_dcn * rob_chunk_diff - * urgent_latency_traffic); - crit_return_bw = crit_return_bw - / dml_pow( - return_bw_to_dcn * soc->urgent_latency_us - + rob_chunk_diff, - 2); - DTRACE("INTERMEDIATE critical_return_bw = %f", crit_return_bw); - return_bw_mbps = dml_min(return_bw_mbps, crit_return_bw); - } - - /* Gabe does this again for some reason using the value of return_bw_mpbs from the previous calculation - * and a lightly different return_bw_to_dcn - */ - - state = dml_socbb_voltage_scaling(soc, voltage); - return_bw_to_dcn = dml_min( - soc->return_bus_width_bytes * dcfclk_mhz, - state.dram_bw_per_chan_gbps * 1000.0 * (double) soc->num_chans); - - DTRACE("INTERMEDIATE rob_chunk_diff = %f", rob_chunk_diff); - - if (dcc_enable && return_bw_to_dcn > return_bus_bw / 4) { - double dcc_return_bw = - return_bw_to_dcn * 4.0 - * (1.0 - - soc->urgent_latency_us - / (rob_chunk_diff - / (return_bw_to_dcn - - return_bus_bw - / 4.0) - + soc->urgent_latency_us)); - return_bw_mbps = dml_min(return_bw_mbps, dcc_return_bw); - DTRACE("INTERMEDIATE dcc_return_bw = %f", dcc_return_bw); - } - - urgent_latency_traffic = return_bus_bw * soc->urgent_latency_us; - DTRACE("INTERMEDIATE urgent_latency_traffic = %f", urgent_latency_traffic); - critical_compression = 2.0 * urgent_latency_traffic - / (return_bw_to_dcn * soc->urgent_latency_us + rob_chunk_diff); - DTRACE("INTERMEDIATE critical_compression = %f", critical_compression); - - /* problem here? */ - if (dcc_enable && critical_compression > 1.0 && critical_compression < 4.0) { - double crit_return_bw = (4 * return_bw_to_dcn * rob_chunk_diff - * urgent_latency_traffic); - crit_return_bw = crit_return_bw - / dml_pow( - return_bw_to_dcn * soc->urgent_latency_us - + rob_chunk_diff, - 2); - DTRACE("INTERMEDIATE critical_return_bw = %f", crit_return_bw); - DTRACE("INTERMEDIATE return_bw_to_dcn = %f", return_bw_to_dcn); - DTRACE("INTERMEDIATE rob_chunk_diff = %f", rob_chunk_diff); - DTRACE("INTERMEDIATE urgent_latency_traffic = %f", urgent_latency_traffic); - - return_bw_mbps = dml_min(return_bw_mbps, crit_return_bw); - } - - DTRACE("INTERMEDIATE final return_bw_mbps = %f", return_bw_mbps); - return return_bw_mbps; -} - -double dml_wm_calc_return_bw( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_wm_calc_pipe_params_st *planes, - unsigned int num_planes) -{ - return calc_return_bw(mode_lib, planes, num_planes); -} - -static double calc_last_pixel_of_line_extra_wm_us( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_wm_calc_pipe_params_st *planes, - unsigned int num_planes) -{ - double val = 0.0; - double total_data_read_bw = calc_total_data_read_bw(mode_lib, planes, num_planes); - int voltage = -1; - unsigned int i; - double return_bw_mbps; - - for (i = 0; i < num_planes; i++) { - /* voltage mode must be the same for all pipes */ - ASSERT(voltage == -1 || voltage == planes[i].voltage); - voltage = planes[i].voltage; - } - return_bw_mbps = calc_return_bw(mode_lib, planes, num_planes); - - for (i = 0; i < num_planes; i++) { - double bytes_pp_y = dml_ceil(planes[i].bytes_per_pixel_y); - double bytes_pp_c = dml_ceil_2(planes[i].bytes_per_pixel_c); - double swath_bytes_y = (double) planes[i].swath_width_y - * (double) planes[i].swath_height_y * (double) bytes_pp_y; - double swath_bytes_c = ((double) planes[i].swath_width_y / 2.0) - * (double) planes[i].swath_height_c * (double) bytes_pp_c; - double data_fabric_line_delivery_time = (swath_bytes_y + swath_bytes_c) - / (return_bw_mbps * planes[i].read_bw / (double) planes[i].num_dpp - / total_data_read_bw); - - DTRACE( - "bytes_pp_y = %f, swath_width_y = %f, swath_height_y = %f, swath_bytes_y = %f", - bytes_pp_y, - (double) planes[i].swath_width_y, - (double) planes[i].swath_height_y, - swath_bytes_y); - DTRACE( - "bytes_pp_c = %f, swath_width_c = %f, swath_height_c = %f, swath_bytes_c = %f", - bytes_pp_c, - ((double) planes[i].swath_width_y / 2.0), - (double) planes[i].swath_height_c, - swath_bytes_c); - DTRACE( - "return_bw_mbps = %f, read_bw = %f, num_dpp = %d, total_data_read_bw = %f", - return_bw_mbps, - planes[i].read_bw, - planes[i].num_dpp, - total_data_read_bw); - DTRACE("data_fabric_line_delivery_time = %f", data_fabric_line_delivery_time); - DTRACE( - "display_pipe_line_delivery_time = %f", - planes[i].display_pipe_line_delivery_time); - - val = dml_max( - val, - data_fabric_line_delivery_time - - planes[i].display_pipe_line_delivery_time); - } - - DTRACE("last_pixel_of_line_extra_wm is %f us", val); - return val; -} - -static bool calc_pte_enable(struct _vcs_dpi_wm_calc_pipe_params_st *planes, unsigned int num_planes) -{ - unsigned int i; - - for (i = 0; i < num_planes; i++) { - if (planes[i].pte_enable) { - return true; - } - } - - return false; -} - -static void calc_lines_in_det_y(struct _vcs_dpi_wm_calc_pipe_params_st *plane) -{ - plane->lines_in_det_y = plane->det_buffer_size_y / plane->bytes_per_pixel_y - / plane->swath_width_y; - plane->lines_in_det_y_rounded_down_to_swath = dml_floor( - (double) plane->lines_in_det_y / plane->swath_height_y) - * plane->swath_height_y; - plane->full_det_buffering_time = plane->lines_in_det_y_rounded_down_to_swath - * (plane->h_total / plane->pixclk_mhz); -} - -/* CHECKME: not obviously 1:1 with calculation described in architectural - * document or spreadsheet */ -static void calc_dcfclk_deepsleep_mhz_per_plane( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_wm_calc_pipe_params_st *plane) -{ - double bus_width_per_pixel; - - if (plane->swath_height_c == 0) { - bus_width_per_pixel = dml_ceil(plane->bytes_per_pixel_y) / 64; - } else { - double bus_width_per_pixel_c; - - bus_width_per_pixel = dml_ceil(plane->bytes_per_pixel_y) / 32; - bus_width_per_pixel_c = dml_ceil(plane->bytes_per_pixel_c) / 32; - if (bus_width_per_pixel < bus_width_per_pixel_c) - bus_width_per_pixel = bus_width_per_pixel_c; - } - - if (plane->v_ratio <= 1) { - plane->dcfclk_deepsleep_mhz_per_plane = 1.1 * plane->pixclk_mhz / plane->num_dpp - * plane->h_ratio * bus_width_per_pixel; - } else if (plane->h_ratio > 1) { - double num_hscl_kernels = dml_ceil((double) plane->h_taps / 6); - double dchub_pscl_bw_per_clk = dml_min( - (double) mode_lib->ip.max_dchub_pscl_bw_pix_per_clk, - mode_lib->ip.max_pscl_lb_bw_pix_per_clk * plane->h_ratio - / num_hscl_kernels); - - plane->dcfclk_deepsleep_mhz_per_plane = 1.1 * plane->dppclk_mhz - * dchub_pscl_bw_per_clk * bus_width_per_pixel; - } else { - double dchub_pscl_bw_per_clk = dml_min( - (double) mode_lib->ip.max_dchub_pscl_bw_pix_per_clk, - (double) mode_lib->ip.max_pscl_lb_bw_pix_per_clk); - - plane->dcfclk_deepsleep_mhz_per_plane = 1.1 * plane->dppclk_mhz - * dchub_pscl_bw_per_clk * bus_width_per_pixel; - } - - plane->dcfclk_deepsleep_mhz_per_plane = dml_max( - plane->dcfclk_deepsleep_mhz_per_plane, - plane->pixclk_mhz / 16); -} - -/* Implementation of expected stutter efficiency from DCN1_Display_Mode.docx */ -double dml_wm_expected_stutter_eff_e2e( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_display_e2e_pipe_params_st *e2e, - unsigned int num_pipes) -{ - double min_full_det_buffering_time_us; - double frame_time_for_min_full_det_buffering_time_us = 0.0; - struct _vcs_dpi_wm_calc_pipe_params_st *planes = mode_lib->wm_param; - unsigned int num_planes; - unsigned int i; - double total_data_read_bw_mbps; - double average_read_bw_gbps; - double min_full_det_buffer_size_bytes; - double rob_fill_size_bytes; - double part_of_burst_that_fits_in_rob; - int voltage; - double dcfclk_mhz; - unsigned int total_writeback; - double return_bw_mbps; - double stutter_burst_time_us; - double stutter_eff_not_including_vblank; - double smallest_vblank_us; - double stutter_eff; - - memset(mode_lib->wm_param, 0, sizeof(mode_lib->wm_param)); - DTRACE("calculating expected stutter efficiency"); - - num_planes = dml_wm_e2e_to_wm(mode_lib, e2e, num_pipes, planes); - - for (i = 0; i < num_planes; i++) { - calc_lines_in_det_y(&planes[i]); - - DTRACE("swath width y plane %d = %d", i, planes[i].swath_width_y); - DTRACE("swath height y plane %d = %d", i, planes[i].swath_height_y); - DTRACE( - "bytes per pixel det y plane %d = %f", - i, - planes[i].bytes_per_pixel_y); - DTRACE( - "bytes per pixel det c plane %d = %f", - i, - planes[i].bytes_per_pixel_c); - DTRACE( - "det buffer size plane %d = %d", - i, - planes[i].det_buffer_size_y); - DTRACE("lines in det plane %d = %d", i, planes[i].lines_in_det_y); - DTRACE( - "lines in det rounded to swaths plane %d = %d", - i, - planes[i].lines_in_det_y_rounded_down_to_swath); - } - - min_full_det_buffering_time_us = 9999.0; - for (i = 0; i < num_planes; i++) { - if (planes[i].full_det_buffering_time < min_full_det_buffering_time_us) { - min_full_det_buffering_time_us = planes[i].full_det_buffering_time; - frame_time_for_min_full_det_buffering_time_us = (double) planes[i].v_total - * planes[i].h_total / planes[i].pixclk_mhz; - } - } - - DTRACE("INTERMEDIATE: min_full_det_buffering_time_us = %f", min_full_det_buffering_time_us); - - total_data_read_bw_mbps = calc_total_data_read_bw(mode_lib, planes, num_planes); - - average_read_bw_gbps = 0.0; - - for (i = 0; i < num_planes; i++) { - if (planes[i].dcc_enable) { - average_read_bw_gbps += planes[i].read_bw / planes[i].dcc_rate / 1000; - } else { - average_read_bw_gbps += planes[i].read_bw / 1000; - } - - if (planes[i].dcc_enable) { - average_read_bw_gbps += planes[i].read_bw / 1000 / 256; - } - - if (planes[i].pte_enable) { - average_read_bw_gbps += planes[i].read_bw / 1000 / 512; - } - } - - min_full_det_buffer_size_bytes = min_full_det_buffering_time_us * total_data_read_bw_mbps; - rob_fill_size_bytes = mode_lib->ip.rob_buffer_size_kbytes * 1024 * total_data_read_bw_mbps - / (average_read_bw_gbps * 1000); - part_of_burst_that_fits_in_rob = dml_min( - min_full_det_buffer_size_bytes, - rob_fill_size_bytes); - - voltage = -1; - dcfclk_mhz = -1.0; - total_writeback = 0; - - for (i = 0; i < num_pipes; i++) { - /* voltage and dcfclk must be the same for all pipes */ - ASSERT(voltage == -1 || voltage == e2e[i].clks_cfg.voltage); - voltage = e2e[i].clks_cfg.voltage; - ASSERT(dcfclk_mhz == -1.0 || dcfclk_mhz == e2e[i].clks_cfg.dcfclk_mhz); - dcfclk_mhz = e2e[i].clks_cfg.dcfclk_mhz; - - if (e2e[i].dout.output_type == dm_wb) - total_writeback++; - } - - return_bw_mbps = calc_return_bw(mode_lib, planes, num_planes); - - DTRACE("INTERMEDIATE: part_of_burst_that_fits_in_rob = %f", part_of_burst_that_fits_in_rob); - DTRACE("INTERMEDIATE: average_read_bw_gbps = %f", average_read_bw_gbps); - DTRACE("INTERMEDIATE: total_data_read_bw_mbps = %f", total_data_read_bw_mbps); - DTRACE("INTERMEDIATE: return_bw_mbps = %f", return_bw_mbps); - - stutter_burst_time_us = part_of_burst_that_fits_in_rob * (average_read_bw_gbps * 1000) - / total_data_read_bw_mbps / return_bw_mbps - + (min_full_det_buffering_time_us * total_data_read_bw_mbps - - part_of_burst_that_fits_in_rob) / (dcfclk_mhz * 64); - DTRACE("INTERMEDIATE: stutter_burst_time_us = %f", stutter_burst_time_us); - - if (total_writeback == 0) { - stutter_eff_not_including_vblank = (1.0 - - ((mode_lib->soc.sr_exit_time_us + stutter_burst_time_us) - / min_full_det_buffering_time_us)) * 100.0; - } else { - stutter_eff_not_including_vblank = 0.0; - } - - DTRACE("stutter_efficiency_not_including_vblank = %f", stutter_eff_not_including_vblank); - - smallest_vblank_us = 9999.0; - - for (i = 0; i < num_pipes; i++) { - double vblank_us; - if (e2e[i].pipe.dest.syncronized_vblank_all_planes != 0 || num_pipes == 1) { - vblank_us = (double) (e2e[i].pipe.dest.vtotal + 1 - - e2e[i].pipe.dest.vblank_start - + e2e[i].pipe.dest.vblank_end * e2e[i].pipe.dest.htotal) - / e2e[i].pipe.dest.pixel_rate_mhz; - } else { - vblank_us = 0.0; - } - - smallest_vblank_us = dml_min(smallest_vblank_us, vblank_us); - } - - DTRACE("smallest vblank = %f us", smallest_vblank_us); - - stutter_eff = 100.0 - * (((stutter_eff_not_including_vblank / 100.0) - * (frame_time_for_min_full_det_buffering_time_us - - smallest_vblank_us) + smallest_vblank_us) - / frame_time_for_min_full_det_buffering_time_us); - - DTRACE("stutter_efficiency = %f", stutter_eff); - - return stutter_eff_not_including_vblank; -} - -double dml_wm_expected_stutter_eff_e2e_with_vblank( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_display_e2e_pipe_params_st *e2e, - unsigned int num_pipes) -{ - double min_full_det_buffering_time_us; - double frame_time_for_min_full_det_buffering_time_us = 0.0; - struct _vcs_dpi_wm_calc_pipe_params_st *planes = mode_lib->wm_param; - unsigned int num_planes; - unsigned int i; - double total_data_read_bw_mbps; - double average_read_bw_gbps; - double min_full_det_buffer_size_bytes; - double rob_fill_size_bytes; - double part_of_burst_that_fits_in_rob; - int voltage; - double dcfclk_mhz; - unsigned int total_writeback; - double return_bw_mbps; - double stutter_burst_time_us; - double stutter_eff_not_including_vblank; - double smallest_vblank_us; - double stutter_eff; - - memset(mode_lib->wm_param, 0, sizeof(mode_lib->wm_param)); - num_planes = dml_wm_e2e_to_wm(mode_lib, e2e, num_pipes, planes); - - for (i = 0; i < num_planes; i++) { - calc_lines_in_det_y(&planes[i]); - } - - min_full_det_buffering_time_us = 9999.0; - for (i = 0; i < num_planes; i++) { - if (planes[i].full_det_buffering_time < min_full_det_buffering_time_us) { - min_full_det_buffering_time_us = planes[i].full_det_buffering_time; - frame_time_for_min_full_det_buffering_time_us = (double) planes[i].v_total - * planes[i].h_total / planes[i].pixclk_mhz; - } - } - - total_data_read_bw_mbps = calc_total_data_read_bw(mode_lib, planes, num_planes); - average_read_bw_gbps = 0.0; - - for (i = 0; i < num_planes; i++) { - if (planes[i].dcc_enable) { - average_read_bw_gbps += planes[i].read_bw / planes[i].dcc_rate / 1000; - } else { - average_read_bw_gbps += planes[i].read_bw / 1000; - } - - if (planes[i].dcc_enable) { - average_read_bw_gbps += planes[i].read_bw / 1000 / 256; - } - - if (planes[i].pte_enable) { - average_read_bw_gbps += planes[i].read_bw / 1000 / 512; - } - } - - min_full_det_buffer_size_bytes = min_full_det_buffering_time_us * total_data_read_bw_mbps; - rob_fill_size_bytes = mode_lib->ip.rob_buffer_size_kbytes * 1024 * total_data_read_bw_mbps - / (average_read_bw_gbps * 1000); - part_of_burst_that_fits_in_rob = dml_min( - min_full_det_buffer_size_bytes, - rob_fill_size_bytes); - - voltage = -1; - dcfclk_mhz = -1.0; - total_writeback = 0; - - for (i = 0; i < num_pipes; i++) { - /* voltage and dcfclk must be the same for all pipes */ - ASSERT(voltage == -1 || voltage == e2e[i].clks_cfg.voltage); - voltage = e2e[i].clks_cfg.voltage; - ASSERT(dcfclk_mhz == -1.0 || dcfclk_mhz == e2e[i].clks_cfg.dcfclk_mhz); - dcfclk_mhz = e2e[i].clks_cfg.dcfclk_mhz; - - if (e2e[i].dout.output_type == dm_wb) - total_writeback++; - } - - return_bw_mbps = calc_return_bw(mode_lib, planes, num_planes); - - stutter_burst_time_us = part_of_burst_that_fits_in_rob * (average_read_bw_gbps * 1000) - / total_data_read_bw_mbps / return_bw_mbps - + (min_full_det_buffering_time_us * total_data_read_bw_mbps - - part_of_burst_that_fits_in_rob) / (dcfclk_mhz * 64); - - if (total_writeback == 0) { - stutter_eff_not_including_vblank = (1.0 - - ((mode_lib->soc.sr_exit_time_us + stutter_burst_time_us) - / min_full_det_buffering_time_us)) * 100.0; - } else { - stutter_eff_not_including_vblank = 0.0; - } - - smallest_vblank_us = 9999.0; - - for (i = 0; i < num_pipes; i++) { - double vblank_us; - if (e2e[i].pipe.dest.syncronized_vblank_all_planes != 0 || num_pipes == 1) { - vblank_us = (double) (e2e[i].pipe.dest.vtotal + 1 - - e2e[i].pipe.dest.vblank_start - + e2e[i].pipe.dest.vblank_end * e2e[i].pipe.dest.htotal) - / e2e[i].pipe.dest.pixel_rate_mhz; - } else { - vblank_us = 0.0; - } - - smallest_vblank_us = dml_min(smallest_vblank_us, vblank_us); - } - - stutter_eff = 100.0 - * (((stutter_eff_not_including_vblank / 100.0) - * (frame_time_for_min_full_det_buffering_time_us - - smallest_vblank_us) + smallest_vblank_us) - / frame_time_for_min_full_det_buffering_time_us); - - - return stutter_eff; -} - -double urgent_extra_calc( - struct display_mode_lib *mode_lib, - double dcfclk_mhz, - double return_bw_mbps, - unsigned int total_active_dpp, - unsigned int total_dcc_active_dpp) -{ - double urgent_extra_latency_us = 0.0; - double urgent_round_trip_ooo_latency_us; - - urgent_round_trip_ooo_latency_us = - (((double) mode_lib->soc.round_trip_ping_latency_dcfclk_cycles + 32) - / dcfclk_mhz) - + (((double) (mode_lib->soc.urgent_out_of_order_return_per_channel_bytes - * mode_lib->soc.num_chans)) / return_bw_mbps); - - DTRACE( - "INTERMEDIATE round_trip_ping_latency_dcfclk_cycles = %d", - mode_lib->soc.round_trip_ping_latency_dcfclk_cycles); - DTRACE("INTERMEDIATE dcfclk_mhz = %f", dcfclk_mhz); - DTRACE( - "INTERMEDIATE urgent_out_of_order_return_per_channel_bytes = %d", - mode_lib->soc.urgent_out_of_order_return_per_channel_bytes); - - urgent_extra_latency_us = urgent_round_trip_ooo_latency_us - + ((double) total_active_dpp * mode_lib->ip.pixel_chunk_size_kbytes - + (double) total_dcc_active_dpp - * mode_lib->ip.meta_chunk_size_kbytes) - * 1024.0 / return_bw_mbps; /* to us */ - - DTRACE( - "INTERMEDIATE urgent_round_trip_ooo_latency_us = %f", - urgent_round_trip_ooo_latency_us); - DTRACE("INTERMEDIATE total_active_dpp = %d", total_active_dpp); - DTRACE( - "INTERMEDIATE pixel_chunk_size_kbytes = %d", - mode_lib->ip.pixel_chunk_size_kbytes); - DTRACE("INTERMEDIATE total_dcc_active_dpp = %d", total_dcc_active_dpp); - DTRACE( - "INTERMEDIATE meta_chunk_size_kbyte = %d", - mode_lib->ip.meta_chunk_size_kbytes); - DTRACE("INTERMEDIATE return_bw_mbps = %f", return_bw_mbps); - - return urgent_extra_latency_us; -} - -double dml_wm_urgent_extra_max(struct display_mode_lib *mode_lib) -{ - unsigned int total_active_dpp = DC__NUM_DPP; - unsigned int total_dcc_active_dpp = total_active_dpp; - double urgent_extra_latency_us = 0.0; - double dcfclk_mhz = 0.0; - double return_bw_mbps = 0.0; - int voltage = dm_vmin; - - /* use minimum voltage */ - return_bw_mbps = dml_socbb_return_bw_mhz(&mode_lib->soc, (enum voltage_state) voltage); - /* use minimum dcfclk */ - dcfclk_mhz = mode_lib->soc.vmin.dcfclk_mhz; - /* use max dpps and dpps with dcc */ - - urgent_extra_latency_us = urgent_extra_calc( - mode_lib, - dcfclk_mhz, - return_bw_mbps, - total_active_dpp, - total_dcc_active_dpp); - - DTRACE("urgent extra max = %f", urgent_extra_latency_us); - return urgent_extra_latency_us; -} - -double dml_wm_urgent_extra( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_wm_calc_pipe_params_st *pipes, - unsigned int num_pipes) -{ - unsigned int total_active_dpp = 0; - unsigned int total_dcc_active_dpp = 0; - double urgent_extra_latency_us = 0.0; - double dcfclk_mhz = 0.0; - double return_bw_mbps = 0.0; - int voltage = -1; - bool pte_enable = false; - unsigned int i; - - for (i = 0; i < num_pipes; i++) { - /* num_dpp must be greater than 0 */ - ASSERT(pipes[i].num_dpp > 0); - - /* voltage mode must be the same for all pipes */ - ASSERT(voltage == -1 || voltage == pipes[i].voltage); - voltage = pipes[i].voltage; - - /* dcfclk for all pipes must be the same */ - ASSERT(dcfclk_mhz == 0.0 || dcfclk_mhz == pipes[i].dcfclk_mhz); - dcfclk_mhz = pipes[i].dcfclk_mhz; - - total_active_dpp += pipes[i].num_dpp; - - if (pipes[i].dcc_enable) { - total_dcc_active_dpp += pipes[i].num_dpp; - } - } - - DTRACE("total active dpps %d", total_active_dpp); - DTRACE("total active dpps with dcc %d", total_dcc_active_dpp); - DTRACE("voltage state is %d", voltage); - - return_bw_mbps = calc_return_bw(mode_lib, pipes, num_pipes); - - DTRACE("return_bandwidth is %f MBps", return_bw_mbps); - - pte_enable = calc_pte_enable(pipes, num_pipes); - - /* calculate the maximum extra latency just for comparison purposes */ - /* dml_wm_urgent_extra_max(); */ - urgent_extra_latency_us = urgent_extra_calc( - mode_lib, - dcfclk_mhz, - return_bw_mbps, - total_active_dpp, - total_dcc_active_dpp); - - DTRACE("INTERMEDIATE urgent_extra_latency_us_before_pte = %f", urgent_extra_latency_us); - - if (pte_enable) { - urgent_extra_latency_us += total_active_dpp * mode_lib->ip.pte_chunk_size_kbytes - * 1024.0 / return_bw_mbps; - - DTRACE("INTERMEDIATE pte_enable = true"); - DTRACE("INTERMEDIATE total_active_dpp = %d", total_active_dpp); - DTRACE( - "INTERMEDIATE pte_chunk_size_kbytes = %d", - mode_lib->ip.pte_chunk_size_kbytes); - DTRACE("INTERMEDIATE return_bw_mbps = %f", return_bw_mbps); - } - - return urgent_extra_latency_us; -} - -double dml_wm_urgent_e2e( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_display_e2e_pipe_params_st *pipes, - unsigned int num_pipes) -{ - struct _vcs_dpi_wm_calc_pipe_params_st *wm = mode_lib->wm_param; - unsigned int combined_pipes; - double urgent_wm; - - memset(mode_lib->wm_param, 0, sizeof(mode_lib->wm_param)); - combined_pipes = dml_wm_e2e_to_wm(mode_lib, pipes, num_pipes, wm); - - urgent_wm = dml_wm_urgent(mode_lib, wm, combined_pipes); - - return urgent_wm; -} - -double dml_wm_urgent( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_wm_calc_pipe_params_st *planes, - unsigned int num_planes) -{ - double urgent_watermark; - double urgent_extra_latency_us; - double last_pixel_of_line_extra_wm_us = 0.0; - - DTRACE("calculating urgent watermark"); - calc_display_pipe_line_delivery_time(mode_lib, planes, num_planes); - urgent_extra_latency_us = dml_wm_urgent_extra(mode_lib, planes, num_planes); - - last_pixel_of_line_extra_wm_us = calc_last_pixel_of_line_extra_wm_us( - mode_lib, - planes, - num_planes); - - urgent_watermark = mode_lib->soc.urgent_latency_us + last_pixel_of_line_extra_wm_us - + urgent_extra_latency_us; - - DTRACE("INTERMEDIATE urgent_latency_us = %f", mode_lib->soc.urgent_latency_us); - DTRACE("INTERMEDIATE last_pixel_of_line_extra_wm_us = %f", last_pixel_of_line_extra_wm_us); - DTRACE("INTERMEDIATE urgent_extra_latency_us = %f", urgent_extra_latency_us); - - DTRACE("urgent_watermark_us = %f", urgent_watermark); - return urgent_watermark; -} - -double dml_wm_pte_meta_urgent(struct display_mode_lib *mode_lib, double urgent_wm_us) -{ - double val; - - val = urgent_wm_us + 2.0 * mode_lib->soc.urgent_latency_us; - DTRACE("pte_meta_urgent_watermark_us = %f", val); - - return val; -} - -double dml_wm_dcfclk_deepsleep_mhz_e2e( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_display_e2e_pipe_params_st *pipes, - unsigned int num_pipes) -{ - struct _vcs_dpi_wm_calc_pipe_params_st *planes = mode_lib->wm_param; - unsigned int num_planes; - double val; - - memset(mode_lib->wm_param, 0, sizeof(mode_lib->wm_param)); - num_planes = dml_wm_e2e_to_wm(mode_lib, pipes, num_pipes, planes); - - val = dml_wm_dcfclk_deepsleep_mhz(mode_lib, planes, num_planes); - - return val; -} - -double dml_wm_dcfclk_deepsleep_mhz( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_wm_calc_pipe_params_st *planes, - unsigned int num_planes) -{ - double val = 8.0; - unsigned int i; - - for (i = 0; i < num_planes; i++) { - calc_dcfclk_deepsleep_mhz_per_plane(mode_lib, &planes[i]); - - if (val < planes[i].dcfclk_deepsleep_mhz_per_plane) { - val = planes[i].dcfclk_deepsleep_mhz_per_plane; - } - - DTRACE("plane[%d] start", i); - DTRACE("dcfclk_deepsleep_per_plane = %f", planes[i].dcfclk_deepsleep_mhz_per_plane); - DTRACE("plane[%d] end", i); - } - - DTRACE("dcfclk_deepsleep_mhz = %f", val); - - return val; -} - -struct _vcs_dpi_cstate_pstate_watermarks_st dml_wm_cstate_pstate_e2e( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_display_e2e_pipe_params_st *pipes, - unsigned int num_pipes) -{ - struct _vcs_dpi_wm_calc_pipe_params_st *wm = mode_lib->wm_param; - unsigned int combined_pipes; - struct _vcs_dpi_cstate_pstate_watermarks_st cstate_pstate_wm; - - memset(mode_lib->wm_param, 0, sizeof(mode_lib->wm_param)); - combined_pipes = dml_wm_e2e_to_wm(mode_lib, pipes, num_pipes, wm); - cstate_pstate_wm = dml_wm_cstate_pstate(mode_lib, wm, combined_pipes); - - - return cstate_pstate_wm; -} - -struct _vcs_dpi_cstate_pstate_watermarks_st dml_wm_cstate_pstate( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_wm_calc_pipe_params_st *pipes, - unsigned int num_pipes) -{ - struct _vcs_dpi_cstate_pstate_watermarks_st wm; - double urgent_extra_latency_us; - double urgent_watermark_us; - double last_pixel_of_line_extra_wm_us; - double dcfclk_deepsleep_freq; - - DTRACE("calculating cstate and pstate watermarks"); - urgent_extra_latency_us = dml_wm_urgent_extra(mode_lib, pipes, num_pipes); - urgent_watermark_us = dml_wm_urgent(mode_lib, pipes, num_pipes); - - last_pixel_of_line_extra_wm_us = calc_last_pixel_of_line_extra_wm_us( - mode_lib, - pipes, - num_pipes); - dcfclk_deepsleep_freq = dml_wm_dcfclk_deepsleep_mhz(mode_lib, pipes, num_pipes); - - wm.cstate_exit_us = mode_lib->soc.sr_exit_time_us + last_pixel_of_line_extra_wm_us - + urgent_extra_latency_us - + mode_lib->ip.dcfclk_cstate_latency / dcfclk_deepsleep_freq; - wm.cstate_enter_plus_exit_us = mode_lib->soc.sr_enter_plus_exit_time_us - + last_pixel_of_line_extra_wm_us + urgent_extra_latency_us; - wm.pstate_change_us = mode_lib->soc.dram_clock_change_latency_us + urgent_watermark_us; - - DTRACE("stutter_exit_watermark_us = %f", wm.cstate_exit_us); - DTRACE("stutter_enter_plus_exit_watermark_us = %f", wm.cstate_enter_plus_exit_us); - DTRACE("dram_clock_change_watermark_us = %f", wm.pstate_change_us); - - return wm; -} - -double dml_wm_writeback_pstate_e2e( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_display_e2e_pipe_params_st *pipes, - unsigned int num_pipes) -{ - struct _vcs_dpi_wm_calc_pipe_params_st *wm = mode_lib->wm_param; - unsigned int combined_pipes; - - memset(mode_lib->wm_param, 0, sizeof(mode_lib->wm_param)); - combined_pipes = dml_wm_e2e_to_wm(mode_lib, pipes, num_pipes, wm); - - - return dml_wm_writeback_pstate(mode_lib, wm, combined_pipes); -} - -double dml_wm_writeback_pstate( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_wm_calc_pipe_params_st *pipes, - unsigned int num_pipes) -{ - unsigned int total_active_wb = 0; - double wm = 0.0; - double socclk_mhz = 0.0; - unsigned int i; - - DTRACE("calculating wb pstate watermark"); - for (i = 0; i < num_pipes; i++) { - if (pipes[i].output_type == dm_wb) - total_active_wb++; - ASSERT(socclk_mhz == 0.0 || socclk_mhz == pipes[i].socclk_mhz); - socclk_mhz = pipes[i].socclk_mhz; - } - - DTRACE("total wb outputs %d", total_active_wb); - DTRACE("socclk frequency %f Mhz", socclk_mhz); - - if (total_active_wb <= 1) { - wm = mode_lib->soc.writeback_dram_clock_change_latency_us; - } else { - wm = mode_lib->soc.writeback_dram_clock_change_latency_us - + (mode_lib->ip.writeback_chunk_size_kbytes * 1024.0) / 32.0 - / socclk_mhz; - } - - DTRACE("wb pstate watermark %f us", wm); - return wm; -} - -unsigned int dml_wm_e2e_to_wm( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_display_e2e_pipe_params_st *e2e, - unsigned int num_pipes, - struct _vcs_dpi_wm_calc_pipe_params_st *wm) -{ - unsigned int num_planes = 0; - bool visited[DC__NUM_PIPES]; - unsigned int i, j; - - for (i = 0; i < num_pipes; i++) { - visited[i] = false; - } - - for (i = 0; i < num_pipes; i++) { - unsigned int num_dpp = 1; - - if (visited[i]) { - continue; - } - - visited[i] = true; - - if (e2e[i].pipe.src.is_hsplit) { - for (j = i + 1; j < num_pipes; j++) { - if (e2e[j].pipe.src.is_hsplit && !visited[j] - && (e2e[i].pipe.src.hsplit_grp - == e2e[j].pipe.src.hsplit_grp)) { - num_dpp++; - visited[j] = true; - } - } - } - - wm[num_planes].num_dpp = num_dpp; - wm[num_planes].voltage = e2e[i].clks_cfg.voltage; - wm[num_planes].output_type = e2e[i].dout.output_type; - wm[num_planes].dcfclk_mhz = e2e[i].clks_cfg.dcfclk_mhz; - wm[num_planes].socclk_mhz = e2e[i].clks_cfg.socclk_mhz; - wm[num_planes].dppclk_mhz = e2e[i].clks_cfg.dppclk_mhz; - wm[num_planes].pixclk_mhz = e2e[i].pipe.dest.pixel_rate_mhz; - - wm[num_planes].pte_enable = e2e[i].pipe.src.vm; - wm[num_planes].dcc_enable = e2e[i].pipe.src.dcc; - wm[num_planes].dcc_rate = e2e[i].pipe.src.dcc_rate; - - get_bytes_per_pixel( - (enum source_format_class) e2e[i].pipe.src.source_format, - &wm[num_planes]); - wm[num_planes].swath_width_y = get_swath_width_y(&e2e[i].pipe.src, num_dpp); - get_swath_height( - mode_lib, - &e2e[i].pipe.src, - &wm[num_planes], - wm[num_planes].swath_width_y); - - wm[num_planes].interlace_en = e2e[i].pipe.dest.interlaced; - wm[num_planes].h_ratio = e2e[i].pipe.scale_ratio_depth.hscl_ratio; - wm[num_planes].v_ratio = e2e[i].pipe.scale_ratio_depth.vscl_ratio; - if (wm[num_planes].interlace_en) { - wm[num_planes].v_ratio = 2 * wm[num_planes].v_ratio; - } - wm[num_planes].h_taps = e2e[i].pipe.scale_taps.htaps; - wm[num_planes].h_total = e2e[i].pipe.dest.htotal; - wm[num_planes].v_total = e2e[i].pipe.dest.vtotal; - wm[num_planes].v_active = e2e[i].pipe.dest.vactive; - wm[num_planes].e2e_index = i; - num_planes++; - } - - for (i = 0; i < num_planes; i++) { - DTRACE("plane[%d] start", i); - DTRACE("voltage = %d", wm[i].voltage); - DTRACE("v_active = %d", wm[i].v_active); - DTRACE("h_total = %d", wm[i].h_total); - DTRACE("v_total = %d", wm[i].v_total); - DTRACE("pixclk_mhz = %f", wm[i].pixclk_mhz); - DTRACE("dcfclk_mhz = %f", wm[i].dcfclk_mhz); - DTRACE("dppclk_mhz = %f", wm[i].dppclk_mhz); - DTRACE("h_ratio = %f", wm[i].h_ratio); - DTRACE("v_ratio = %f", wm[i].v_ratio); - DTRACE("interlaced = %d", wm[i].interlace_en); - DTRACE("h_taps = %d", wm[i].h_taps); - DTRACE("num_dpp = %d", wm[i].num_dpp); - DTRACE("swath_width_y = %d", wm[i].swath_width_y); - DTRACE("swath_height_y = %d", wm[i].swath_height_y); - DTRACE("swath_height_c = %d", wm[i].swath_height_c); - DTRACE("det_buffer_size_y = %d", wm[i].det_buffer_size_y); - DTRACE("dcc_rate = %f", wm[i].dcc_rate); - DTRACE("dcc_enable = %s", wm[i].dcc_enable ? "true" : "false"); - DTRACE("pte_enable = %s", wm[i].pte_enable ? "true" : "false"); - DTRACE("plane[%d] end", i); - } - - return num_planes; -} diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_watermark.h b/drivers/gpu/drm/amd/display/dc/dml/display_watermark.h deleted file mode 100644 index 94cde8b55e085..0000000000000 --- a/drivers/gpu/drm/amd/display/dc/dml/display_watermark.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright 2017 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: AMD - * - */ -#ifndef __DISPLAY_WATERMARK_H__ -#define __DISPLAY_WATERMARK_H__ - -#include "dml_common_defs.h" - -struct display_mode_lib; - -double dml_wm_urgent_extra( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_wm_calc_pipe_params_st *pipes, - unsigned int num_pipes); -double dml_wm_urgent_extra_max(struct display_mode_lib *mode_lib); - -double dml_wm_urgent_e2e( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_display_e2e_pipe_params_st *pipes, - unsigned int num_pipes); -double dml_wm_urgent( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_wm_calc_pipe_params_st *planes, - unsigned int num_planes); -double dml_wm_pte_meta_urgent(struct display_mode_lib *mode_lib, double urgent_wm_us); -double dml_wm_dcfclk_deepsleep_mhz_e2e( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_display_e2e_pipe_params_st *pipes, - unsigned int num_pipes); -double dml_wm_dcfclk_deepsleep_mhz( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_wm_calc_pipe_params_st *planes, - unsigned int num_planes); - -struct _vcs_dpi_cstate_pstate_watermarks_st dml_wm_cstate_pstate_e2e( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_display_e2e_pipe_params_st *pipes, - unsigned int num_pipes); -struct _vcs_dpi_cstate_pstate_watermarks_st dml_wm_cstate_pstate( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_wm_calc_pipe_params_st *pipes, - unsigned int num_pipes); - -double dml_wm_writeback_pstate_e2e( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_display_e2e_pipe_params_st *pipes, - unsigned int num_pipes); -double dml_wm_writeback_pstate( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_wm_calc_pipe_params_st *pipes, - unsigned int num_pipes); - -double dml_wm_expected_stutter_eff_e2e( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_display_e2e_pipe_params_st *e2e, - unsigned int num_pipes); -double dml_wm_expected_stutter_eff_e2e_with_vblank( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_display_e2e_pipe_params_st *e2e, - unsigned int num_pipes); - -unsigned int dml_wm_e2e_to_wm( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_display_e2e_pipe_params_st *e2e, - unsigned int num_pipes, - struct _vcs_dpi_wm_calc_pipe_params_st *wm); - -double dml_wm_calc_total_data_read_bw( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_wm_calc_pipe_params_st *planes, - unsigned int num_planes); -double dml_wm_calc_return_bw( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_wm_calc_pipe_params_st *planes, - unsigned int num_planes); - -#endif diff --git a/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c b/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c new file mode 100644 index 0000000000000..8229f782260b6 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c @@ -0,0 +1,1903 @@ +/* + * Copyright 2017 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: AMD + * + */ + +#include "dml1_display_rq_dlg_calc.h" +#include "display_mode_lib.h" + +static unsigned int get_bytes_per_element(enum source_format_class source_format, bool is_chroma) +{ + unsigned int ret_val = 0; + + if (source_format == dm_444_16) { + if (!is_chroma) + ret_val = 2; + } else if (source_format == dm_444_32) { + if (!is_chroma) + ret_val = 4; + } else if (source_format == dm_444_64) { + if (!is_chroma) + ret_val = 8; + } else if (source_format == dm_420_8) { + if (is_chroma) + ret_val = 2; + else + ret_val = 1; + } else if (source_format == dm_420_10) { + if (is_chroma) + ret_val = 4; + else + ret_val = 2; + } + return ret_val; +} + +static bool is_dual_plane(enum source_format_class source_format) +{ + bool ret_val = 0; + + if ((source_format == dm_420_8) || (source_format == dm_420_10)) + ret_val = 1; + + return ret_val; +} + +static void get_blk256_size( + unsigned int *blk256_width, + unsigned int *blk256_height, + unsigned int bytes_per_element) +{ + if (bytes_per_element == 1) { + *blk256_width = 16; + *blk256_height = 16; + } else if (bytes_per_element == 2) { + *blk256_width = 16; + *blk256_height = 8; + } else if (bytes_per_element == 4) { + *blk256_width = 8; + *blk256_height = 8; + } else if (bytes_per_element == 8) { + *blk256_width = 8; + *blk256_height = 4; + } +} + +static double get_refcyc_per_delivery( + struct display_mode_lib *mode_lib, + double refclk_freq_in_mhz, + double pclk_freq_in_mhz, + unsigned int recout_width, + double vratio, + double hscale_pixel_rate, + unsigned int delivery_width, + unsigned int req_per_swath_ub) +{ + double refcyc_per_delivery = 0.0; + + if (vratio <= 1.0) { + refcyc_per_delivery = (double) refclk_freq_in_mhz * (double) recout_width + / pclk_freq_in_mhz / (double) req_per_swath_ub; + } else { + refcyc_per_delivery = (double) refclk_freq_in_mhz * (double) delivery_width + / (double) hscale_pixel_rate / (double) req_per_swath_ub; + } + + DTRACE("DLG: %s: refclk_freq_in_mhz = %3.2f", __func__, refclk_freq_in_mhz); + DTRACE("DLG: %s: pclk_freq_in_mhz = %3.2f", __func__, pclk_freq_in_mhz); + DTRACE("DLG: %s: recout_width = %d", __func__, recout_width); + DTRACE("DLG: %s: vratio = %3.2f", __func__, vratio); + DTRACE("DLG: %s: req_per_swath_ub = %d", __func__, req_per_swath_ub); + DTRACE("DLG: %s: refcyc_per_delivery= %3.2f", __func__, refcyc_per_delivery); + + return refcyc_per_delivery; + +} + +static double get_vratio_pre( + struct display_mode_lib *mode_lib, + unsigned int max_num_sw, + unsigned int max_partial_sw, + unsigned int swath_height, + double vinit, + double l_sw) +{ + double prefill = dml_floor(vinit, 1); + double vratio_pre = 1.0; + + vratio_pre = (max_num_sw * swath_height + max_partial_sw) / l_sw; + + if (swath_height > 4) { + double tmp0 = (max_num_sw * swath_height) / (l_sw - (prefill - 3.0) / 2.0); + + if (tmp0 > vratio_pre) + vratio_pre = tmp0; + } + + DTRACE("DLG: %s: max_num_sw = %0d", __func__, max_num_sw); + DTRACE("DLG: %s: max_partial_sw = %0d", __func__, max_partial_sw); + DTRACE("DLG: %s: swath_height = %0d", __func__, swath_height); + DTRACE("DLG: %s: vinit = %3.2f", __func__, vinit); + DTRACE("DLG: %s: vratio_pre = %3.2f", __func__, vratio_pre); + + if (vratio_pre < 1.0) { + DTRACE("WARNING_DLG: %s: vratio_pre=%3.2f < 1.0, set to 1.0", __func__, vratio_pre); + vratio_pre = 1.0; + } + + if (vratio_pre > 4.0) { + DTRACE( + "WARNING_DLG: %s: vratio_pre=%3.2f > 4.0 (max scaling ratio). set to 4.0", + __func__, + vratio_pre); + vratio_pre = 4.0; + } + + return vratio_pre; +} + +static void get_swath_need( + struct display_mode_lib *mode_lib, + unsigned int *max_num_sw, + unsigned int *max_partial_sw, + unsigned int swath_height, + double vinit) +{ + double prefill = dml_floor(vinit, 1); + unsigned int max_partial_sw_int; + + DTRACE("DLG: %s: swath_height = %0d", __func__, swath_height); + DTRACE("DLG: %s: vinit = %3.2f", __func__, vinit); + + ASSERT(prefill > 0.0 && prefill <= 8.0); + + *max_num_sw = (unsigned int) (dml_ceil((prefill - 1.0) / (double) swath_height, 1) + 1.0); /* prefill has to be >= 1 */ + max_partial_sw_int = + (prefill == 1) ? + (swath_height - 1) : + ((unsigned int) (prefill - 2.0) % swath_height); + *max_partial_sw = (max_partial_sw_int < 1) ? 1 : max_partial_sw_int; /* ensure minimum of 1 is used */ + + DTRACE("DLG: %s: max_num_sw = %0d", __func__, *max_num_sw); + DTRACE("DLG: %s: max_partial_sw = %0d", __func__, *max_partial_sw); +} + +static unsigned int get_blk_size_bytes(const enum source_macro_tile_size tile_size) +{ + if (tile_size == dm_256k_tile) + return (256 * 1024); + else if (tile_size == dm_64k_tile) + return (64 * 1024); + else + return (4 * 1024); +} + +static void extract_rq_sizing_regs( + struct display_mode_lib *mode_lib, + struct _vcs_dpi_display_data_rq_regs_st *rq_regs, + const struct _vcs_dpi_display_data_rq_sizing_params_st rq_sizing) +{ + DTRACE("DLG: %s: rq_sizing param", __func__); + print__data_rq_sizing_params_st(mode_lib, rq_sizing); + + rq_regs->chunk_size = dml_log2(rq_sizing.chunk_bytes) - 10; + + if (rq_sizing.min_chunk_bytes == 0) + rq_regs->min_chunk_size = 0; + else + rq_regs->min_chunk_size = dml_log2(rq_sizing.min_chunk_bytes) - 8 + 1; + + rq_regs->meta_chunk_size = dml_log2(rq_sizing.meta_chunk_bytes) - 10; + if (rq_sizing.min_meta_chunk_bytes == 0) + rq_regs->min_meta_chunk_size = 0; + else + rq_regs->min_meta_chunk_size = dml_log2(rq_sizing.min_meta_chunk_bytes) - 6 + 1; + + rq_regs->dpte_group_size = dml_log2(rq_sizing.dpte_group_bytes) - 6; + rq_regs->mpte_group_size = dml_log2(rq_sizing.mpte_group_bytes) - 6; +} + +void dml1_extract_rq_regs( + struct display_mode_lib *mode_lib, + struct _vcs_dpi_display_rq_regs_st *rq_regs, + const struct _vcs_dpi_display_rq_params_st rq_param) +{ + unsigned int detile_buf_size_in_bytes = mode_lib->ip.det_buffer_size_kbytes * 1024; + unsigned int detile_buf_plane1_addr = 0; + + extract_rq_sizing_regs(mode_lib, &(rq_regs->rq_regs_l), rq_param.sizing.rq_l); + if (rq_param.yuv420) + extract_rq_sizing_regs(mode_lib, &(rq_regs->rq_regs_c), rq_param.sizing.rq_c); + + rq_regs->rq_regs_l.swath_height = dml_log2(rq_param.dlg.rq_l.swath_height); + rq_regs->rq_regs_c.swath_height = dml_log2(rq_param.dlg.rq_c.swath_height); + + /* FIXME: take the max between luma, chroma chunk size? + * okay for now, as we are setting chunk_bytes to 8kb anyways + */ + if (rq_param.sizing.rq_l.chunk_bytes >= 32 * 1024) { /*32kb */ + rq_regs->drq_expansion_mode = 0; + } else { + rq_regs->drq_expansion_mode = 2; + } + rq_regs->prq_expansion_mode = 1; + rq_regs->mrq_expansion_mode = 1; + rq_regs->crq_expansion_mode = 1; + + if (rq_param.yuv420) { + if ((double) rq_param.misc.rq_l.stored_swath_bytes + / (double) rq_param.misc.rq_c.stored_swath_bytes <= 1.5) { + detile_buf_plane1_addr = (detile_buf_size_in_bytes / 2.0 / 64.0); /* half to chroma */ + } else { + detile_buf_plane1_addr = dml_round_to_multiple( + (unsigned int) ((2.0 * detile_buf_size_in_bytes) / 3.0), + 256, + 0) / 64.0; /* 2/3 to chroma */ + } + } + rq_regs->plane1_base_address = detile_buf_plane1_addr; +} + +static void handle_det_buf_split( + struct display_mode_lib *mode_lib, + struct _vcs_dpi_display_rq_params_st *rq_param, + const struct _vcs_dpi_display_pipe_source_params_st pipe_src_param) +{ + unsigned int total_swath_bytes = 0; + unsigned int swath_bytes_l = 0; + unsigned int swath_bytes_c = 0; + unsigned int full_swath_bytes_packed_l = 0; + unsigned int full_swath_bytes_packed_c = 0; + bool req128_l = 0; + bool req128_c = 0; + bool surf_linear = (pipe_src_param.sw_mode == dm_sw_linear); + bool surf_vert = (pipe_src_param.source_scan == dm_vert); + unsigned int log2_swath_height_l = 0; + unsigned int log2_swath_height_c = 0; + unsigned int detile_buf_size_in_bytes = mode_lib->ip.det_buffer_size_kbytes * 1024; + + full_swath_bytes_packed_l = rq_param->misc.rq_l.full_swath_bytes; + full_swath_bytes_packed_c = rq_param->misc.rq_c.full_swath_bytes; + + if (rq_param->yuv420_10bpc) { + full_swath_bytes_packed_l = dml_round_to_multiple( + rq_param->misc.rq_l.full_swath_bytes * 2 / 3, + 256, + 1) + 256; + full_swath_bytes_packed_c = dml_round_to_multiple( + rq_param->misc.rq_c.full_swath_bytes * 2 / 3, + 256, + 1) + 256; + } + + if (rq_param->yuv420) { + total_swath_bytes = 2 * full_swath_bytes_packed_l + 2 * full_swath_bytes_packed_c; + + if (total_swath_bytes <= detile_buf_size_in_bytes) { /*full 256b request */ + req128_l = 0; + req128_c = 0; + swath_bytes_l = full_swath_bytes_packed_l; + swath_bytes_c = full_swath_bytes_packed_c; + } else { /*128b request (for luma only for yuv420 8bpc) */ + req128_l = 1; + req128_c = 0; + swath_bytes_l = full_swath_bytes_packed_l / 2; + swath_bytes_c = full_swath_bytes_packed_c; + } + + /* Bug workaround, luma and chroma req size needs to be the same. (see: DEGVIDCN10-137) + * TODO: Remove after rtl fix + */ + if (req128_l == 1) { + req128_c = 1; + DTRACE("DLG: %s: bug workaround DEGVIDCN10-137", __func__); + } + + /* Note: assumption, the config that pass in will fit into + * the detiled buffer. + */ + } else { + total_swath_bytes = 2 * full_swath_bytes_packed_l; + + if (total_swath_bytes <= detile_buf_size_in_bytes) + req128_l = 0; + else + req128_l = 1; + + swath_bytes_l = total_swath_bytes; + swath_bytes_c = 0; + } + rq_param->misc.rq_l.stored_swath_bytes = swath_bytes_l; + rq_param->misc.rq_c.stored_swath_bytes = swath_bytes_c; + + if (surf_linear) { + log2_swath_height_l = 0; + log2_swath_height_c = 0; + } else if (!surf_vert) { + log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_height) - req128_l; + log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_height) - req128_c; + } else { + log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_width) - req128_l; + log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_width) - req128_c; + } + rq_param->dlg.rq_l.swath_height = 1 << log2_swath_height_l; + rq_param->dlg.rq_c.swath_height = 1 << log2_swath_height_c; + + DTRACE("DLG: %s: req128_l = %0d", __func__, req128_l); + DTRACE("DLG: %s: req128_c = %0d", __func__, req128_c); + DTRACE("DLG: %s: full_swath_bytes_packed_l = %0d", __func__, full_swath_bytes_packed_l); + DTRACE("DLG: %s: full_swath_bytes_packed_c = %0d", __func__, full_swath_bytes_packed_c); +} + +/* Need refactor. */ +static void dml1_rq_dlg_get_row_heights( + struct display_mode_lib *mode_lib, + unsigned int *o_dpte_row_height, + unsigned int *o_meta_row_height, + unsigned int vp_width, + unsigned int data_pitch, + int source_format, + int tiling, + int macro_tile_size, + int source_scan, + int is_chroma) +{ + bool surf_linear = (tiling == dm_sw_linear); + bool surf_vert = (source_scan == dm_vert); + + unsigned int bytes_per_element = get_bytes_per_element( + (enum source_format_class) source_format, + is_chroma); + unsigned int log2_bytes_per_element = dml_log2(bytes_per_element); + unsigned int blk256_width = 0; + unsigned int blk256_height = 0; + + unsigned int log2_blk256_height; + unsigned int blk_bytes; + unsigned int log2_blk_bytes; + unsigned int log2_blk_height; + unsigned int log2_blk_width; + unsigned int log2_meta_req_bytes; + unsigned int log2_meta_req_height; + unsigned int log2_meta_req_width; + unsigned int log2_meta_row_height; + unsigned int log2_vmpg_bytes; + unsigned int dpte_buf_in_pte_reqs; + unsigned int log2_vmpg_height; + unsigned int log2_vmpg_width; + unsigned int log2_dpte_req_height_ptes; + unsigned int log2_dpte_req_width_ptes; + unsigned int log2_dpte_req_height; + unsigned int log2_dpte_req_width; + unsigned int log2_dpte_row_height_linear; + unsigned int log2_dpte_row_height; + unsigned int dpte_req_width; + + if (surf_linear) { + blk256_width = 256; + blk256_height = 1; + } else { + get_blk256_size(&blk256_width, &blk256_height, bytes_per_element); + } + + log2_blk256_height = dml_log2((double) blk256_height); + blk_bytes = surf_linear ? + 256 : get_blk_size_bytes((enum source_macro_tile_size) macro_tile_size); + log2_blk_bytes = dml_log2((double) blk_bytes); + log2_blk_height = 0; + log2_blk_width = 0; + + /* remember log rule + * "+" in log is multiply + * "-" in log is divide + * "/2" is like square root + * blk is vertical biased + */ + if (tiling != dm_sw_linear) + log2_blk_height = log2_blk256_height + + dml_ceil((double) (log2_blk_bytes - 8) / 2.0, 1); + else + log2_blk_height = 0; /* blk height of 1 */ + + log2_blk_width = log2_blk_bytes - log2_bytes_per_element - log2_blk_height; + + /* ------- */ + /* meta */ + /* ------- */ + log2_meta_req_bytes = 6; /* meta request is 64b and is 8x8byte meta element */ + + /* each 64b meta request for dcn is 8x8 meta elements and + * a meta element covers one 256b block of the the data surface. + */ + log2_meta_req_height = log2_blk256_height + 3; /* meta req is 8x8 */ + log2_meta_req_width = log2_meta_req_bytes + 8 - log2_bytes_per_element + - log2_meta_req_height; + log2_meta_row_height = 0; + + /* the dimensions of a meta row are meta_row_width x meta_row_height in elements. + * calculate upper bound of the meta_row_width + */ + if (!surf_vert) + log2_meta_row_height = log2_meta_req_height; + else + log2_meta_row_height = log2_meta_req_width; + + *o_meta_row_height = 1 << log2_meta_row_height; + + /* ------ */ + /* dpte */ + /* ------ */ + log2_vmpg_bytes = dml_log2(mode_lib->soc.vmm_page_size_bytes); + dpte_buf_in_pte_reqs = mode_lib->ip.dpte_buffer_size_in_pte_reqs; + + log2_vmpg_height = 0; + log2_vmpg_width = 0; + log2_dpte_req_height_ptes = 0; + log2_dpte_req_width_ptes = 0; + log2_dpte_req_height = 0; + log2_dpte_req_width = 0; + log2_dpte_row_height_linear = 0; + log2_dpte_row_height = 0; + dpte_req_width = 0; /* 64b dpte req width in data element */ + + if (surf_linear) + log2_vmpg_height = 0; /* one line high */ + else + log2_vmpg_height = (log2_vmpg_bytes - 8) / 2 + log2_blk256_height; + log2_vmpg_width = log2_vmpg_bytes - log2_bytes_per_element - log2_vmpg_height; + + /* only 3 possible shapes for dpte request in dimensions of ptes: 8x1, 4x2, 2x4. */ + if (log2_blk_bytes <= log2_vmpg_bytes) + log2_dpte_req_height_ptes = 0; + else if (log2_blk_height - log2_vmpg_height >= 2) + log2_dpte_req_height_ptes = 2; + else + log2_dpte_req_height_ptes = log2_blk_height - log2_vmpg_height; + log2_dpte_req_width_ptes = 3 - log2_dpte_req_height_ptes; + + ASSERT((log2_dpte_req_width_ptes == 3 && log2_dpte_req_height_ptes == 0) || /* 8x1 */ + (log2_dpte_req_width_ptes == 2 && log2_dpte_req_height_ptes == 1) || /* 4x2 */ + (log2_dpte_req_width_ptes == 1 && log2_dpte_req_height_ptes == 2)); /* 2x4 */ + + /* the dpte request dimensions in data elements is dpte_req_width x dpte_req_height + * log2_wmpg_width is how much 1 pte represent, now trying to calculate how much 64b pte req represent + */ + log2_dpte_req_height = log2_vmpg_height + log2_dpte_req_height_ptes; + log2_dpte_req_width = log2_vmpg_width + log2_dpte_req_width_ptes; + dpte_req_width = 1 << log2_dpte_req_width; + + /* calculate pitch dpte row buffer can hold + * round the result down to a power of two. + */ + if (surf_linear) { + log2_dpte_row_height_linear = dml_floor( + dml_log2(dpte_buf_in_pte_reqs * dpte_req_width / data_pitch), + 1); + + ASSERT(log2_dpte_row_height_linear >= 3); + + if (log2_dpte_row_height_linear > 7) + log2_dpte_row_height_linear = 7; + + log2_dpte_row_height = log2_dpte_row_height_linear; + } else { + /* the upper bound of the dpte_row_width without dependency on viewport position follows. */ + if (!surf_vert) + log2_dpte_row_height = log2_dpte_req_height; + else + log2_dpte_row_height = + (log2_blk_width < log2_dpte_req_width) ? + log2_blk_width : log2_dpte_req_width; + } + + /* From programming guide: + * There is a special case of saving only half of ptes returned due to buffer space limits. + * this case applies to 4 and 8bpe in horizontal access of a vp_width greater than 2560+16 + * when the pte request is 2x4 ptes (which happens when vmpg_bytes =4kb and tile blk_bytes >=64kb). + */ + if (!surf_vert && vp_width > (2560 + 16) && bytes_per_element >= 4 && log2_vmpg_bytes == 12 + && log2_blk_bytes >= 16) + log2_dpte_row_height = log2_dpte_row_height - 1; /*half of the full height */ + + *o_dpte_row_height = 1 << log2_dpte_row_height; +} + +static void get_surf_rq_param( + struct display_mode_lib *mode_lib, + struct _vcs_dpi_display_data_rq_sizing_params_st *rq_sizing_param, + struct _vcs_dpi_display_data_rq_dlg_params_st *rq_dlg_param, + struct _vcs_dpi_display_data_rq_misc_params_st *rq_misc_param, + const struct _vcs_dpi_display_pipe_source_params_st pipe_src_param, + bool is_chroma) +{ + bool mode_422 = 0; + unsigned int vp_width = 0; + unsigned int vp_height = 0; + unsigned int data_pitch = 0; + unsigned int meta_pitch = 0; + unsigned int ppe = mode_422 ? 2 : 1; + bool surf_linear; + bool surf_vert; + unsigned int bytes_per_element; + unsigned int log2_bytes_per_element; + unsigned int blk256_width; + unsigned int blk256_height; + unsigned int log2_blk256_width; + unsigned int log2_blk256_height; + unsigned int blk_bytes; + unsigned int log2_blk_bytes; + unsigned int log2_blk_height; + unsigned int log2_blk_width; + unsigned int log2_meta_req_bytes; + unsigned int log2_meta_req_height; + unsigned int log2_meta_req_width; + unsigned int meta_req_width; + unsigned int meta_req_height; + unsigned int log2_meta_row_height; + unsigned int meta_row_width_ub; + unsigned int log2_meta_chunk_bytes; + unsigned int log2_meta_chunk_height; + unsigned int log2_meta_chunk_width; + unsigned int log2_min_meta_chunk_bytes; + unsigned int min_meta_chunk_width; + unsigned int meta_chunk_width; + unsigned int meta_chunk_per_row_int; + unsigned int meta_row_remainder; + unsigned int meta_chunk_threshold; + unsigned int meta_blk_bytes; + unsigned int meta_blk_height; + unsigned int meta_blk_width; + unsigned int meta_surface_bytes; + unsigned int vmpg_bytes; + unsigned int meta_pte_req_per_frame_ub; + unsigned int meta_pte_bytes_per_frame_ub; + unsigned int log2_vmpg_bytes; + unsigned int dpte_buf_in_pte_reqs; + unsigned int log2_vmpg_height; + unsigned int log2_vmpg_width; + unsigned int log2_dpte_req_height_ptes; + unsigned int log2_dpte_req_width_ptes; + unsigned int log2_dpte_req_height; + unsigned int log2_dpte_req_width; + unsigned int log2_dpte_row_height_linear; + unsigned int log2_dpte_row_height; + unsigned int log2_dpte_group_width; + unsigned int dpte_row_width_ub; + unsigned int dpte_row_height; + unsigned int dpte_req_height; + unsigned int dpte_req_width; + unsigned int dpte_group_width; + unsigned int log2_dpte_group_bytes; + unsigned int log2_dpte_group_length; + unsigned int func_meta_row_height, func_dpte_row_height; + + /* FIXME check if ppe apply for both luma and chroma in 422 case */ + if (is_chroma) { + vp_width = pipe_src_param.viewport_width_c / ppe; + vp_height = pipe_src_param.viewport_height_c; + data_pitch = pipe_src_param.data_pitch_c; + meta_pitch = pipe_src_param.meta_pitch_c; + } else { + vp_width = pipe_src_param.viewport_width / ppe; + vp_height = pipe_src_param.viewport_height; + data_pitch = pipe_src_param.data_pitch; + meta_pitch = pipe_src_param.meta_pitch; + } + + rq_sizing_param->chunk_bytes = 8192; + + if (rq_sizing_param->chunk_bytes == 64 * 1024) + rq_sizing_param->min_chunk_bytes = 0; + else + rq_sizing_param->min_chunk_bytes = 1024; + + rq_sizing_param->meta_chunk_bytes = 2048; + rq_sizing_param->min_meta_chunk_bytes = 256; + + rq_sizing_param->mpte_group_bytes = 2048; + + surf_linear = (pipe_src_param.sw_mode == dm_sw_linear); + surf_vert = (pipe_src_param.source_scan == dm_vert); + + bytes_per_element = get_bytes_per_element( + (enum source_format_class) pipe_src_param.source_format, + is_chroma); + log2_bytes_per_element = dml_log2(bytes_per_element); + blk256_width = 0; + blk256_height = 0; + + if (surf_linear) { + blk256_width = 256 / bytes_per_element; + blk256_height = 1; + } else { + get_blk256_size(&blk256_width, &blk256_height, bytes_per_element); + } + + DTRACE("DLG: %s: surf_linear = %d", __func__, surf_linear); + DTRACE("DLG: %s: surf_vert = %d", __func__, surf_vert); + DTRACE("DLG: %s: blk256_width = %d", __func__, blk256_width); + DTRACE("DLG: %s: blk256_height = %d", __func__, blk256_height); + + log2_blk256_width = dml_log2((double) blk256_width); + log2_blk256_height = dml_log2((double) blk256_height); + blk_bytes = + surf_linear ? 256 : get_blk_size_bytes( + (enum source_macro_tile_size) pipe_src_param.macro_tile_size); + log2_blk_bytes = dml_log2((double) blk_bytes); + log2_blk_height = 0; + log2_blk_width = 0; + + /* remember log rule + * "+" in log is multiply + * "-" in log is divide + * "/2" is like square root + * blk is vertical biased + */ + if (pipe_src_param.sw_mode != dm_sw_linear) + log2_blk_height = log2_blk256_height + + dml_ceil((double) (log2_blk_bytes - 8) / 2.0, 1); + else + log2_blk_height = 0; /* blk height of 1 */ + + log2_blk_width = log2_blk_bytes - log2_bytes_per_element - log2_blk_height; + + if (!surf_vert) { + rq_dlg_param->swath_width_ub = dml_round_to_multiple(vp_width - 1, blk256_width, 1) + + blk256_width; + rq_dlg_param->req_per_swath_ub = rq_dlg_param->swath_width_ub >> log2_blk256_width; + } else { + rq_dlg_param->swath_width_ub = dml_round_to_multiple( + vp_height - 1, + blk256_height, + 1) + blk256_height; + rq_dlg_param->req_per_swath_ub = rq_dlg_param->swath_width_ub >> log2_blk256_height; + } + + if (!surf_vert) + rq_misc_param->full_swath_bytes = rq_dlg_param->swath_width_ub * blk256_height + * bytes_per_element; + else + rq_misc_param->full_swath_bytes = rq_dlg_param->swath_width_ub * blk256_width + * bytes_per_element; + + rq_misc_param->blk256_height = blk256_height; + rq_misc_param->blk256_width = blk256_width; + + /* ------- */ + /* meta */ + /* ------- */ + log2_meta_req_bytes = 6; /* meta request is 64b and is 8x8byte meta element */ + + /* each 64b meta request for dcn is 8x8 meta elements and + * a meta element covers one 256b block of the the data surface. + */ + log2_meta_req_height = log2_blk256_height + 3; /* meta req is 8x8 byte, each byte represent 1 blk256 */ + log2_meta_req_width = log2_meta_req_bytes + 8 - log2_bytes_per_element + - log2_meta_req_height; + meta_req_width = 1 << log2_meta_req_width; + meta_req_height = 1 << log2_meta_req_height; + log2_meta_row_height = 0; + meta_row_width_ub = 0; + + /* the dimensions of a meta row are meta_row_width x meta_row_height in elements. + * calculate upper bound of the meta_row_width + */ + if (!surf_vert) { + log2_meta_row_height = log2_meta_req_height; + meta_row_width_ub = dml_round_to_multiple(vp_width - 1, meta_req_width, 1) + + meta_req_width; + rq_dlg_param->meta_req_per_row_ub = meta_row_width_ub / meta_req_width; + } else { + log2_meta_row_height = log2_meta_req_width; + meta_row_width_ub = dml_round_to_multiple(vp_height - 1, meta_req_height, 1) + + meta_req_height; + rq_dlg_param->meta_req_per_row_ub = meta_row_width_ub / meta_req_height; + } + rq_dlg_param->meta_bytes_per_row_ub = rq_dlg_param->meta_req_per_row_ub * 64; + + log2_meta_chunk_bytes = dml_log2(rq_sizing_param->meta_chunk_bytes); + log2_meta_chunk_height = log2_meta_row_height; + + /*full sized meta chunk width in unit of data elements */ + log2_meta_chunk_width = log2_meta_chunk_bytes + 8 - log2_bytes_per_element + - log2_meta_chunk_height; + log2_min_meta_chunk_bytes = dml_log2(rq_sizing_param->min_meta_chunk_bytes); + min_meta_chunk_width = 1 + << (log2_min_meta_chunk_bytes + 8 - log2_bytes_per_element + - log2_meta_chunk_height); + meta_chunk_width = 1 << log2_meta_chunk_width; + meta_chunk_per_row_int = (unsigned int) (meta_row_width_ub / meta_chunk_width); + meta_row_remainder = meta_row_width_ub % meta_chunk_width; + meta_chunk_threshold = 0; + meta_blk_bytes = 4096; + meta_blk_height = blk256_height * 64; + meta_blk_width = meta_blk_bytes * 256 / bytes_per_element / meta_blk_height; + meta_surface_bytes = meta_pitch + * (dml_round_to_multiple(vp_height - 1, meta_blk_height, 1) + + meta_blk_height) * bytes_per_element / 256; + vmpg_bytes = mode_lib->soc.vmm_page_size_bytes; + meta_pte_req_per_frame_ub = (dml_round_to_multiple( + meta_surface_bytes - vmpg_bytes, + 8 * vmpg_bytes, + 1) + 8 * vmpg_bytes) / (8 * vmpg_bytes); + meta_pte_bytes_per_frame_ub = meta_pte_req_per_frame_ub * 64; /*64B mpte request */ + rq_dlg_param->meta_pte_bytes_per_frame_ub = meta_pte_bytes_per_frame_ub; + + DTRACE("DLG: %s: meta_blk_height = %d", __func__, meta_blk_height); + DTRACE("DLG: %s: meta_blk_width = %d", __func__, meta_blk_width); + DTRACE("DLG: %s: meta_surface_bytes = %d", __func__, meta_surface_bytes); + DTRACE("DLG: %s: meta_pte_req_per_frame_ub = %d", __func__, meta_pte_req_per_frame_ub); + DTRACE("DLG: %s: meta_pte_bytes_per_frame_ub = %d", __func__, meta_pte_bytes_per_frame_ub); + + if (!surf_vert) + meta_chunk_threshold = 2 * min_meta_chunk_width - meta_req_width; + else + meta_chunk_threshold = 2 * min_meta_chunk_width - meta_req_height; + + if (meta_row_remainder <= meta_chunk_threshold) + rq_dlg_param->meta_chunks_per_row_ub = meta_chunk_per_row_int + 1; + else + rq_dlg_param->meta_chunks_per_row_ub = meta_chunk_per_row_int + 2; + + rq_dlg_param->meta_row_height = 1 << log2_meta_row_height; + + /* ------ */ + /* dpte */ + /* ------ */ + log2_vmpg_bytes = dml_log2(mode_lib->soc.vmm_page_size_bytes); + dpte_buf_in_pte_reqs = mode_lib->ip.dpte_buffer_size_in_pte_reqs; + + log2_vmpg_height = 0; + log2_vmpg_width = 0; + log2_dpte_req_height_ptes = 0; + log2_dpte_req_width_ptes = 0; + log2_dpte_req_height = 0; + log2_dpte_req_width = 0; + log2_dpte_row_height_linear = 0; + log2_dpte_row_height = 0; + log2_dpte_group_width = 0; + dpte_row_width_ub = 0; + dpte_row_height = 0; + dpte_req_height = 0; /* 64b dpte req height in data element */ + dpte_req_width = 0; /* 64b dpte req width in data element */ + dpte_group_width = 0; + log2_dpte_group_bytes = 0; + log2_dpte_group_length = 0; + + if (surf_linear) + log2_vmpg_height = 0; /* one line high */ + else + log2_vmpg_height = (log2_vmpg_bytes - 8) / 2 + log2_blk256_height; + log2_vmpg_width = log2_vmpg_bytes - log2_bytes_per_element - log2_vmpg_height; + + /* only 3 possible shapes for dpte request in dimensions of ptes: 8x1, 4x2, 2x4. */ + if (log2_blk_bytes <= log2_vmpg_bytes) + log2_dpte_req_height_ptes = 0; + else if (log2_blk_height - log2_vmpg_height >= 2) + log2_dpte_req_height_ptes = 2; + else + log2_dpte_req_height_ptes = log2_blk_height - log2_vmpg_height; + log2_dpte_req_width_ptes = 3 - log2_dpte_req_height_ptes; + + /* Ensure we only have the 3 shapes */ + ASSERT((log2_dpte_req_width_ptes == 3 && log2_dpte_req_height_ptes == 0) || /* 8x1 */ + (log2_dpte_req_width_ptes == 2 && log2_dpte_req_height_ptes == 1) || /* 4x2 */ + (log2_dpte_req_width_ptes == 1 && log2_dpte_req_height_ptes == 2)); /* 2x4 */ + + /* The dpte request dimensions in data elements is dpte_req_width x dpte_req_height + * log2_vmpg_width is how much 1 pte represent, now calculating how much a 64b pte req represent + * That depends on the pte shape (i.e. 8x1, 4x2, 2x4) + */ + log2_dpte_req_height = log2_vmpg_height + log2_dpte_req_height_ptes; + log2_dpte_req_width = log2_vmpg_width + log2_dpte_req_width_ptes; + dpte_req_height = 1 << log2_dpte_req_height; + dpte_req_width = 1 << log2_dpte_req_width; + + /* calculate pitch dpte row buffer can hold + * round the result down to a power of two. + */ + if (surf_linear) { + log2_dpte_row_height_linear = dml_floor( + dml_log2(dpte_buf_in_pte_reqs * dpte_req_width / data_pitch), + 1); + + ASSERT(log2_dpte_row_height_linear >= 3); + + if (log2_dpte_row_height_linear > 7) + log2_dpte_row_height_linear = 7; + + log2_dpte_row_height = log2_dpte_row_height_linear; + rq_dlg_param->dpte_row_height = 1 << log2_dpte_row_height; + + /* For linear, the dpte row is pitch dependent and the pte requests wrap at the pitch boundary. + * the dpte_row_width_ub is the upper bound of data_pitch*dpte_row_height in elements with this unique buffering. + */ + dpte_row_width_ub = dml_round_to_multiple( + data_pitch * dpte_row_height - 1, + dpte_req_width, + 1) + dpte_req_width; + rq_dlg_param->dpte_req_per_row_ub = dpte_row_width_ub / dpte_req_width; + } else { + /* for tiled mode, row height is the same as req height and row store up to vp size upper bound */ + if (!surf_vert) { + log2_dpte_row_height = log2_dpte_req_height; + dpte_row_width_ub = dml_round_to_multiple(vp_width - 1, dpte_req_width, 1) + + dpte_req_width; + rq_dlg_param->dpte_req_per_row_ub = dpte_row_width_ub / dpte_req_width; + } else { + log2_dpte_row_height = + (log2_blk_width < log2_dpte_req_width) ? + log2_blk_width : log2_dpte_req_width; + dpte_row_width_ub = dml_round_to_multiple(vp_height - 1, dpte_req_height, 1) + + dpte_req_height; + rq_dlg_param->dpte_req_per_row_ub = dpte_row_width_ub / dpte_req_height; + } + rq_dlg_param->dpte_row_height = 1 << log2_dpte_row_height; + } + rq_dlg_param->dpte_bytes_per_row_ub = rq_dlg_param->dpte_req_per_row_ub * 64; + + /* From programming guide: + * There is a special case of saving only half of ptes returned due to buffer space limits. + * this case applies to 4 and 8bpe in horizontal access of a vp_width greater than 2560+16 + * when the pte request is 2x4 ptes (which happens when vmpg_bytes =4kb and tile blk_bytes >=64kb). + */ + if (!surf_vert && vp_width > (2560 + 16) && bytes_per_element >= 4 && log2_vmpg_bytes == 12 + && log2_blk_bytes >= 16) { + log2_dpte_row_height = log2_dpte_row_height - 1; /*half of the full height */ + rq_dlg_param->dpte_row_height = 1 << log2_dpte_row_height; + } + + /* the dpte_group_bytes is reduced for the specific case of vertical + * access of a tile surface that has dpte request of 8x1 ptes. + */ + if (!surf_linear & (log2_dpte_req_height_ptes == 0) & surf_vert) /*reduced, in this case, will have page fault within a group */ + rq_sizing_param->dpte_group_bytes = 512; + else + /*full size */ + rq_sizing_param->dpte_group_bytes = 2048; + + /*since pte request size is 64byte, the number of data pte requests per full sized group is as follows. */ + log2_dpte_group_bytes = dml_log2(rq_sizing_param->dpte_group_bytes); + log2_dpte_group_length = log2_dpte_group_bytes - 6; /*length in 64b requests */ + + /* full sized data pte group width in elements */ + if (!surf_vert) + log2_dpte_group_width = log2_dpte_group_length + log2_dpte_req_width; + else + log2_dpte_group_width = log2_dpte_group_length + log2_dpte_req_height; + + dpte_group_width = 1 << log2_dpte_group_width; + + /* since dpte groups are only aligned to dpte_req_width and not dpte_group_width, + * the upper bound for the dpte groups per row is as follows. + */ + rq_dlg_param->dpte_groups_per_row_ub = dml_ceil( + (double) dpte_row_width_ub / dpte_group_width, + 1); + + dml1_rq_dlg_get_row_heights( + mode_lib, + &func_dpte_row_height, + &func_meta_row_height, + vp_width, + data_pitch, + pipe_src_param.source_format, + pipe_src_param.sw_mode, + pipe_src_param.macro_tile_size, + pipe_src_param.source_scan, + is_chroma); + + /* Just a check to make sure this function and the new one give the same + * result. The standalone get_row_heights() function is based off of the + * code in this function so the same changes need to be made to both. + */ + if (rq_dlg_param->meta_row_height != func_meta_row_height) { + DTRACE( + "MISMATCH: rq_dlg_param->meta_row_height = %d", + rq_dlg_param->meta_row_height); + DTRACE("MISMATCH: func_meta_row_height = %d", func_meta_row_height); + ASSERT(0); + } + + if (rq_dlg_param->dpte_row_height != func_dpte_row_height) { + DTRACE( + "MISMATCH: rq_dlg_param->dpte_row_height = %d", + rq_dlg_param->dpte_row_height); + DTRACE("MISMATCH: func_dpte_row_height = %d", func_dpte_row_height); + ASSERT(0); + } +} + +void dml1_rq_dlg_get_rq_params( + struct display_mode_lib *mode_lib, + struct _vcs_dpi_display_rq_params_st *rq_param, + const struct _vcs_dpi_display_pipe_source_params_st pipe_src_param) +{ + /* get param for luma surface */ + rq_param->yuv420 = pipe_src_param.source_format == dm_420_8 + || pipe_src_param.source_format == dm_420_10; + rq_param->yuv420_10bpc = pipe_src_param.source_format == dm_420_10; + + get_surf_rq_param( + mode_lib, + &(rq_param->sizing.rq_l), + &(rq_param->dlg.rq_l), + &(rq_param->misc.rq_l), + pipe_src_param, + 0); + + if (is_dual_plane((enum source_format_class) pipe_src_param.source_format)) { + /* get param for chroma surface */ + get_surf_rq_param( + mode_lib, + &(rq_param->sizing.rq_c), + &(rq_param->dlg.rq_c), + &(rq_param->misc.rq_c), + pipe_src_param, + 1); + } + + /* calculate how to split the det buffer space between luma and chroma */ + handle_det_buf_split(mode_lib, rq_param, pipe_src_param); + print__rq_params_st(mode_lib, *rq_param); +} + +/* Note: currently taken in as is. + * Nice to decouple code from hw register implement and extract code that are repeated for luma and chroma. + */ +void dml1_rq_dlg_get_dlg_params( + struct display_mode_lib *mode_lib, + struct _vcs_dpi_display_dlg_regs_st *disp_dlg_regs, + struct _vcs_dpi_display_ttu_regs_st *disp_ttu_regs, + const struct _vcs_dpi_display_rq_dlg_params_st rq_dlg_param, + const struct _vcs_dpi_display_dlg_sys_params_st dlg_sys_param, + const struct _vcs_dpi_display_e2e_pipe_params_st e2e_pipe_param, + const bool cstate_en, + const bool pstate_en, + const bool vm_en, + const bool iflip_en) +{ + /* Timing */ + unsigned int htotal = e2e_pipe_param.pipe.dest.htotal; + unsigned int hblank_end = e2e_pipe_param.pipe.dest.hblank_end; + unsigned int vblank_start = e2e_pipe_param.pipe.dest.vblank_start; + unsigned int vblank_end = e2e_pipe_param.pipe.dest.vblank_end; + bool interlaced = e2e_pipe_param.pipe.dest.interlaced; + unsigned int min_vblank = mode_lib->ip.min_vblank_lines; + + double pclk_freq_in_mhz = e2e_pipe_param.pipe.dest.pixel_rate_mhz; + double refclk_freq_in_mhz = e2e_pipe_param.clks_cfg.refclk_mhz; + double dppclk_freq_in_mhz = e2e_pipe_param.clks_cfg.dppclk_mhz; + double dispclk_freq_in_mhz = e2e_pipe_param.clks_cfg.dispclk_mhz; + + double ref_freq_to_pix_freq; + double prefetch_xy_calc_in_dcfclk; + double min_dcfclk_mhz; + double t_calc_us; + double min_ttu_vblank; + double min_dst_y_ttu_vblank; + unsigned int dlg_vblank_start; + bool dcc_en; + bool dual_plane; + bool mode_422; + unsigned int access_dir; + unsigned int bytes_per_element_l; + unsigned int bytes_per_element_c; + unsigned int vp_height_l; + unsigned int vp_width_l; + unsigned int vp_height_c; + unsigned int vp_width_c; + unsigned int htaps_l; + unsigned int htaps_c; + double hratios_l; + double hratios_c; + double vratio_l; + double vratio_c; + double line_time_in_us; + double vinit_l; + double vinit_c; + double vinit_bot_l; + double vinit_bot_c; + unsigned int swath_height_l; + unsigned int swath_width_ub_l; + unsigned int dpte_bytes_per_row_ub_l; + unsigned int dpte_groups_per_row_ub_l; + unsigned int meta_pte_bytes_per_frame_ub_l; + unsigned int meta_bytes_per_row_ub_l; + unsigned int swath_height_c; + unsigned int swath_width_ub_c; + unsigned int dpte_bytes_per_row_ub_c; + unsigned int dpte_groups_per_row_ub_c; + unsigned int meta_chunks_per_row_ub_l; + unsigned int vupdate_offset; + unsigned int vupdate_width; + unsigned int vready_offset; + unsigned int dppclk_delay_subtotal; + unsigned int dispclk_delay_subtotal; + unsigned int pixel_rate_delay_subtotal; + unsigned int vstartup_start; + unsigned int dst_x_after_scaler; + unsigned int dst_y_after_scaler; + double line_wait; + double line_o; + double line_setup; + double line_calc; + double dst_y_prefetch; + double t_pre_us; + unsigned int vm_bytes; + unsigned int meta_row_bytes; + unsigned int max_num_sw_l; + unsigned int max_num_sw_c; + unsigned int max_partial_sw_l; + unsigned int max_partial_sw_c; + double max_vinit_l; + double max_vinit_c; + unsigned int lsw_l; + unsigned int lsw_c; + unsigned int sw_bytes_ub_l; + unsigned int sw_bytes_ub_c; + unsigned int sw_bytes; + unsigned int dpte_row_bytes; + double prefetch_bw; + double flip_bw; + double t_vm_us; + double t_r0_us; + double dst_y_per_vm_vblank; + double dst_y_per_row_vblank; + double min_dst_y_per_vm_vblank; + double min_dst_y_per_row_vblank; + double lsw; + double vratio_pre_l; + double vratio_pre_c; + unsigned int req_per_swath_ub_l; + unsigned int req_per_swath_ub_c; + unsigned int meta_row_height_l; + unsigned int swath_width_pixels_ub_l; + unsigned int swath_width_pixels_ub_c; + unsigned int scaler_rec_in_width_l; + unsigned int scaler_rec_in_width_c; + unsigned int dpte_row_height_l; + unsigned int dpte_row_height_c; + double hscale_pixel_rate_l; + double hscale_pixel_rate_c; + double min_hratio_fact_l; + double min_hratio_fact_c; + double refcyc_per_line_delivery_pre_l; + double refcyc_per_line_delivery_pre_c; + double refcyc_per_line_delivery_l; + double refcyc_per_line_delivery_c; + double refcyc_per_req_delivery_pre_l; + double refcyc_per_req_delivery_pre_c; + double refcyc_per_req_delivery_l; + double refcyc_per_req_delivery_c; + double refcyc_per_req_delivery_pre_cur0; + double refcyc_per_req_delivery_cur0; + unsigned int full_recout_width; + double hratios_cur0; + unsigned int cur0_src_width; + enum cursor_bpp cur0_bpp; + unsigned int cur0_req_size; + unsigned int cur0_req_width; + double cur0_width_ub; + double cur0_req_per_width; + double hactive_cur0; + + memset(disp_dlg_regs, 0, sizeof(*disp_dlg_regs)); + memset(disp_ttu_regs, 0, sizeof(*disp_ttu_regs)); + + DTRACE("DLG: %s: cstate_en = %d", __func__, cstate_en); + DTRACE("DLG: %s: pstate_en = %d", __func__, pstate_en); + DTRACE("DLG: %s: vm_en = %d", __func__, vm_en); + DTRACE("DLG: %s: iflip_en = %d", __func__, iflip_en); + + /* ------------------------- */ + /* Section 1.5.2.1: OTG dependent Params */ + /* ------------------------- */ + DTRACE("DLG: %s: dppclk_freq_in_mhz = %3.2f", __func__, dppclk_freq_in_mhz); + DTRACE("DLG: %s: dispclk_freq_in_mhz = %3.2f", __func__, dispclk_freq_in_mhz); + DTRACE("DLG: %s: refclk_freq_in_mhz = %3.2f", __func__, refclk_freq_in_mhz); + DTRACE("DLG: %s: pclk_freq_in_mhz = %3.2f", __func__, pclk_freq_in_mhz); + DTRACE("DLG: %s: interlaced = %d", __func__, interlaced); + + ref_freq_to_pix_freq = refclk_freq_in_mhz / pclk_freq_in_mhz; + ASSERT(ref_freq_to_pix_freq < 4.0); + disp_dlg_regs->ref_freq_to_pix_freq = + (unsigned int) (ref_freq_to_pix_freq * dml_pow(2, 19)); + disp_dlg_regs->refcyc_per_htotal = (unsigned int) (ref_freq_to_pix_freq * (double) htotal + * dml_pow(2, 8)); + disp_dlg_regs->refcyc_h_blank_end = (unsigned int) ((double) hblank_end + * (double) ref_freq_to_pix_freq); + ASSERT(disp_dlg_regs->refcyc_h_blank_end < (unsigned int) dml_pow(2, 13)); + disp_dlg_regs->dlg_vblank_end = interlaced ? (vblank_end / 2) : vblank_end; /* 15 bits */ + + prefetch_xy_calc_in_dcfclk = 24.0; /* FIXME: ip_param */ + min_dcfclk_mhz = dlg_sys_param.deepsleep_dcfclk_mhz; + t_calc_us = prefetch_xy_calc_in_dcfclk / min_dcfclk_mhz; + min_ttu_vblank = dlg_sys_param.t_urg_wm_us; + if (cstate_en) + min_ttu_vblank = dml_max(dlg_sys_param.t_sr_wm_us, min_ttu_vblank); + if (pstate_en) + min_ttu_vblank = dml_max(dlg_sys_param.t_mclk_wm_us, min_ttu_vblank); + min_ttu_vblank = min_ttu_vblank + t_calc_us; + + min_dst_y_ttu_vblank = min_ttu_vblank * pclk_freq_in_mhz / (double) htotal; + dlg_vblank_start = interlaced ? (vblank_start / 2) : vblank_start; + + disp_dlg_regs->min_dst_y_next_start = (unsigned int) (((double) dlg_vblank_start + + min_dst_y_ttu_vblank) * dml_pow(2, 2)); + ASSERT(disp_dlg_regs->min_dst_y_next_start < (unsigned int) dml_pow(2, 18)); + + DTRACE("DLG: %s: min_dcfclk_mhz = %3.2f", __func__, min_dcfclk_mhz); + DTRACE("DLG: %s: min_ttu_vblank = %3.2f", __func__, min_ttu_vblank); + DTRACE( + "DLG: %s: min_dst_y_ttu_vblank = %3.2f", + __func__, + min_dst_y_ttu_vblank); + DTRACE("DLG: %s: t_calc_us = %3.2f", __func__, t_calc_us); + DTRACE( + "DLG: %s: disp_dlg_regs->min_dst_y_next_start = 0x%0x", + __func__, + disp_dlg_regs->min_dst_y_next_start); + DTRACE( + "DLG: %s: ref_freq_to_pix_freq = %3.2f", + __func__, + ref_freq_to_pix_freq); + + /* ------------------------- */ + /* Section 1.5.2.2: Prefetch, Active and TTU */ + /* ------------------------- */ + /* Prefetch Calc */ + /* Source */ + dcc_en = e2e_pipe_param.pipe.src.dcc; + dual_plane = is_dual_plane( + (enum source_format_class) e2e_pipe_param.pipe.src.source_format); + mode_422 = 0; /* FIXME */ + access_dir = (e2e_pipe_param.pipe.src.source_scan == dm_vert); /* vp access direction: horizontal or vertical accessed */ + bytes_per_element_l = get_bytes_per_element( + (enum source_format_class) e2e_pipe_param.pipe.src.source_format, + 0); + bytes_per_element_c = get_bytes_per_element( + (enum source_format_class) e2e_pipe_param.pipe.src.source_format, + 1); + vp_height_l = e2e_pipe_param.pipe.src.viewport_height; + vp_width_l = e2e_pipe_param.pipe.src.viewport_width; + vp_height_c = e2e_pipe_param.pipe.src.viewport_height_c; + vp_width_c = e2e_pipe_param.pipe.src.viewport_width_c; + + /* Scaling */ + htaps_l = e2e_pipe_param.pipe.scale_taps.htaps; + htaps_c = e2e_pipe_param.pipe.scale_taps.htaps_c; + hratios_l = e2e_pipe_param.pipe.scale_ratio_depth.hscl_ratio; + hratios_c = e2e_pipe_param.pipe.scale_ratio_depth.hscl_ratio_c; + vratio_l = e2e_pipe_param.pipe.scale_ratio_depth.vscl_ratio; + vratio_c = e2e_pipe_param.pipe.scale_ratio_depth.vscl_ratio_c; + + line_time_in_us = (htotal / pclk_freq_in_mhz); + vinit_l = e2e_pipe_param.pipe.scale_ratio_depth.vinit; + vinit_c = e2e_pipe_param.pipe.scale_ratio_depth.vinit_c; + vinit_bot_l = e2e_pipe_param.pipe.scale_ratio_depth.vinit_bot; + vinit_bot_c = e2e_pipe_param.pipe.scale_ratio_depth.vinit_bot_c; + + swath_height_l = rq_dlg_param.rq_l.swath_height; + swath_width_ub_l = rq_dlg_param.rq_l.swath_width_ub; + dpte_bytes_per_row_ub_l = rq_dlg_param.rq_l.dpte_bytes_per_row_ub; + dpte_groups_per_row_ub_l = rq_dlg_param.rq_l.dpte_groups_per_row_ub; + meta_pte_bytes_per_frame_ub_l = rq_dlg_param.rq_l.meta_pte_bytes_per_frame_ub; + meta_bytes_per_row_ub_l = rq_dlg_param.rq_l.meta_bytes_per_row_ub; + + swath_height_c = rq_dlg_param.rq_c.swath_height; + swath_width_ub_c = rq_dlg_param.rq_c.swath_width_ub; + dpte_bytes_per_row_ub_c = rq_dlg_param.rq_c.dpte_bytes_per_row_ub; + dpte_groups_per_row_ub_c = rq_dlg_param.rq_c.dpte_groups_per_row_ub; + + meta_chunks_per_row_ub_l = rq_dlg_param.rq_l.meta_chunks_per_row_ub; + vupdate_offset = e2e_pipe_param.pipe.dest.vupdate_offset; + vupdate_width = e2e_pipe_param.pipe.dest.vupdate_width; + vready_offset = e2e_pipe_param.pipe.dest.vready_offset; + + dppclk_delay_subtotal = mode_lib->ip.dppclk_delay_subtotal; + dispclk_delay_subtotal = mode_lib->ip.dispclk_delay_subtotal; + pixel_rate_delay_subtotal = dppclk_delay_subtotal * pclk_freq_in_mhz / dppclk_freq_in_mhz + + dispclk_delay_subtotal * pclk_freq_in_mhz / dispclk_freq_in_mhz; + + vstartup_start = e2e_pipe_param.pipe.dest.vstartup_start; + + if (interlaced) + vstartup_start = vstartup_start / 2; + + if (vstartup_start >= min_vblank) { + DTRACE( + "WARNING_DLG: %s: vblank_start=%d vblank_end=%d", + __func__, + vblank_start, + vblank_end); + DTRACE( + "WARNING_DLG: %s: vstartup_start=%d should be less than min_vblank=%d", + __func__, + vstartup_start, + min_vblank); + min_vblank = vstartup_start + 1; + DTRACE( + "WARNING_DLG: %s: vstartup_start=%d should be less than min_vblank=%d", + __func__, + vstartup_start, + min_vblank); + } + + dst_x_after_scaler = 0; + dst_y_after_scaler = 0; + + if (e2e_pipe_param.pipe.src.is_hsplit) + dst_x_after_scaler = pixel_rate_delay_subtotal + + e2e_pipe_param.pipe.dest.recout_width; + else + dst_x_after_scaler = pixel_rate_delay_subtotal; + + if (e2e_pipe_param.dout.output_format == dm_420) + dst_y_after_scaler = 1; + else + dst_y_after_scaler = 0; + + if (dst_x_after_scaler >= htotal) { + dst_x_after_scaler = dst_x_after_scaler - htotal; + dst_y_after_scaler = dst_y_after_scaler + 1; + } + + DTRACE("DLG: %s: htotal = %d", __func__, htotal); + DTRACE( + "DLG: %s: pixel_rate_delay_subtotal = %d", + __func__, + pixel_rate_delay_subtotal); + DTRACE("DLG: %s: dst_x_after_scaler = %d", __func__, dst_x_after_scaler); + DTRACE("DLG: %s: dst_y_after_scaler = %d", __func__, dst_y_after_scaler); + + line_wait = mode_lib->soc.urgent_latency_us; + if (cstate_en) + line_wait = dml_max(mode_lib->soc.sr_enter_plus_exit_time_us, line_wait); + if (pstate_en) + line_wait = dml_max( + mode_lib->soc.dram_clock_change_latency_us + + mode_lib->soc.urgent_latency_us, + line_wait); + line_wait = line_wait / line_time_in_us; + + line_o = (double) dst_y_after_scaler + dst_x_after_scaler / (double) htotal; + line_setup = (double) (vupdate_offset + vupdate_width + vready_offset) / (double) htotal; + line_calc = t_calc_us / line_time_in_us; + + DTRACE( + "DLG: %s: soc.sr_enter_plus_exit_time_us = %3.2f", + __func__, + (double) mode_lib->soc.sr_enter_plus_exit_time_us); + DTRACE( + "DLG: %s: soc.dram_clock_change_latency_us = %3.2f", + __func__, + (double) mode_lib->soc.dram_clock_change_latency_us); + DTRACE( + "DLG: %s: soc.urgent_latency_us = %3.2f", + __func__, + mode_lib->soc.urgent_latency_us); + + DTRACE("DLG: %s: swath_height_l = %d", __func__, swath_height_l); + if (dual_plane) + DTRACE("DLG: %s: swath_height_c = %d", __func__, swath_height_c); + + DTRACE( + "DLG: %s: t_srx_delay_us = %3.2f", + __func__, + (double) dlg_sys_param.t_srx_delay_us); + DTRACE("DLG: %s: line_time_in_us = %3.2f", __func__, (double) line_time_in_us); + DTRACE("DLG: %s: vupdate_offset = %d", __func__, vupdate_offset); + DTRACE("DLG: %s: vupdate_width = %d", __func__, vupdate_width); + DTRACE("DLG: %s: vready_offset = %d", __func__, vready_offset); + DTRACE("DLG: %s: line_time_in_us = %3.2f", __func__, line_time_in_us); + DTRACE("DLG: %s: line_wait = %3.2f", __func__, line_wait); + DTRACE("DLG: %s: line_o = %3.2f", __func__, line_o); + DTRACE("DLG: %s: line_setup = %3.2f", __func__, line_setup); + DTRACE("DLG: %s: line_calc = %3.2f", __func__, line_calc); + + dst_y_prefetch = ((double) min_vblank - 1.0) + - (line_setup + line_calc + line_wait + line_o); + DTRACE("DLG: %s: dst_y_prefetch (before rnd) = %3.2f", __func__, dst_y_prefetch); + ASSERT(dst_y_prefetch >= 2.0); + + dst_y_prefetch = dml_floor(4.0 * (dst_y_prefetch + 0.125), 1) / 4; + DTRACE("DLG: %s: dst_y_prefetch (after rnd) = %3.2f", __func__, dst_y_prefetch); + + t_pre_us = dst_y_prefetch * line_time_in_us; + vm_bytes = 0; + meta_row_bytes = 0; + + if (dcc_en && vm_en) + vm_bytes = meta_pte_bytes_per_frame_ub_l; + if (dcc_en) + meta_row_bytes = meta_bytes_per_row_ub_l; + + max_num_sw_l = 0; + max_num_sw_c = 0; + max_partial_sw_l = 0; + max_partial_sw_c = 0; + + max_vinit_l = interlaced ? dml_max(vinit_l, vinit_bot_l) : vinit_l; + max_vinit_c = interlaced ? dml_max(vinit_c, vinit_bot_c) : vinit_c; + + get_swath_need(mode_lib, &max_num_sw_l, &max_partial_sw_l, swath_height_l, max_vinit_l); + if (dual_plane) + get_swath_need( + mode_lib, + &max_num_sw_c, + &max_partial_sw_c, + swath_height_c, + max_vinit_c); + + lsw_l = max_num_sw_l * swath_height_l + max_partial_sw_l; + lsw_c = max_num_sw_c * swath_height_c + max_partial_sw_c; + sw_bytes_ub_l = lsw_l * swath_width_ub_l * bytes_per_element_l; + sw_bytes_ub_c = lsw_c * swath_width_ub_c * bytes_per_element_c; + sw_bytes = 0; + dpte_row_bytes = 0; + + if (vm_en) { + if (dual_plane) + dpte_row_bytes = dpte_bytes_per_row_ub_l + dpte_bytes_per_row_ub_c; + else + dpte_row_bytes = dpte_bytes_per_row_ub_l; + } else { + dpte_row_bytes = 0; + } + + if (dual_plane) + sw_bytes = sw_bytes_ub_l + sw_bytes_ub_c; + else + sw_bytes = sw_bytes_ub_l; + + DTRACE("DLG: %s: sw_bytes_ub_l = %d", __func__, sw_bytes_ub_l); + DTRACE("DLG: %s: sw_bytes_ub_c = %d", __func__, sw_bytes_ub_c); + DTRACE("DLG: %s: sw_bytes = %d", __func__, sw_bytes); + DTRACE("DLG: %s: vm_bytes = %d", __func__, vm_bytes); + DTRACE("DLG: %s: meta_row_bytes = %d", __func__, meta_row_bytes); + DTRACE("DLG: %s: dpte_row_bytes = %d", __func__, dpte_row_bytes); + + prefetch_bw = (vm_bytes + 2 * dpte_row_bytes + 2 * meta_row_bytes + sw_bytes) / t_pre_us; + flip_bw = ((vm_bytes + dpte_row_bytes + meta_row_bytes) * dlg_sys_param.total_flip_bw) + / (double) dlg_sys_param.total_flip_bytes; + t_vm_us = line_time_in_us / 4.0; + if (vm_en && dcc_en) { + t_vm_us = dml_max( + dlg_sys_param.t_extra_us, + dml_max((double) vm_bytes / prefetch_bw, t_vm_us)); + + if (iflip_en && !dual_plane) { + t_vm_us = dml_max(mode_lib->soc.urgent_latency_us, t_vm_us); + if (flip_bw > 0.) + t_vm_us = dml_max(vm_bytes / flip_bw, t_vm_us); + } + } + + t_r0_us = dml_max(dlg_sys_param.t_extra_us - t_vm_us, line_time_in_us - t_vm_us); + + if (vm_en || dcc_en) { + t_r0_us = dml_max( + (double) (dpte_row_bytes + meta_row_bytes) / prefetch_bw, + dlg_sys_param.t_extra_us); + t_r0_us = dml_max((double) (line_time_in_us - t_vm_us), t_r0_us); + + if (iflip_en && !dual_plane) { + t_r0_us = dml_max(mode_lib->soc.urgent_latency_us * 2.0, t_r0_us); + if (flip_bw > 0.) + t_r0_us = dml_max( + (dpte_row_bytes + meta_row_bytes) / flip_bw, + t_r0_us); + } + } + + disp_dlg_regs->dst_y_after_scaler = dst_y_after_scaler; /* in terms of line */ + disp_dlg_regs->refcyc_x_after_scaler = dst_x_after_scaler * ref_freq_to_pix_freq; /* in terms of refclk */ + ASSERT(disp_dlg_regs->refcyc_x_after_scaler < (unsigned int) dml_pow(2, 13)); + DTRACE( + "DLG: %s: disp_dlg_regs->dst_y_after_scaler = 0x%0x", + __func__, + disp_dlg_regs->dst_y_after_scaler); + DTRACE( + "DLG: %s: disp_dlg_regs->refcyc_x_after_scaler = 0x%0x", + __func__, + disp_dlg_regs->refcyc_x_after_scaler); + + disp_dlg_regs->dst_y_prefetch = (unsigned int) (dst_y_prefetch * dml_pow(2, 2)); + DTRACE( + "DLG: %s: disp_dlg_regs->dst_y_prefetch = %d", + __func__, + disp_dlg_regs->dst_y_prefetch); + + dst_y_per_vm_vblank = 0.0; + dst_y_per_row_vblank = 0.0; + + dst_y_per_vm_vblank = t_vm_us / line_time_in_us; + dst_y_per_vm_vblank = dml_floor(4.0 * (dst_y_per_vm_vblank + 0.125), 1) / 4.0; + disp_dlg_regs->dst_y_per_vm_vblank = (unsigned int) (dst_y_per_vm_vblank * dml_pow(2, 2)); + + dst_y_per_row_vblank = t_r0_us / line_time_in_us; + dst_y_per_row_vblank = dml_floor(4.0 * (dst_y_per_row_vblank + 0.125), 1) / 4.0; + disp_dlg_regs->dst_y_per_row_vblank = (unsigned int) (dst_y_per_row_vblank * dml_pow(2, 2)); + + DTRACE("DLG: %s: lsw_l = %d", __func__, lsw_l); + DTRACE("DLG: %s: lsw_c = %d", __func__, lsw_c); + DTRACE("DLG: %s: dpte_bytes_per_row_ub_l = %d", __func__, dpte_bytes_per_row_ub_l); + DTRACE("DLG: %s: dpte_bytes_per_row_ub_c = %d", __func__, dpte_bytes_per_row_ub_c); + + DTRACE("DLG: %s: prefetch_bw = %3.2f", __func__, prefetch_bw); + DTRACE("DLG: %s: flip_bw = %3.2f", __func__, flip_bw); + DTRACE("DLG: %s: t_pre_us = %3.2f", __func__, t_pre_us); + DTRACE("DLG: %s: t_vm_us = %3.2f", __func__, t_vm_us); + DTRACE("DLG: %s: t_r0_us = %3.2f", __func__, t_r0_us); + DTRACE("DLG: %s: dst_y_per_vm_vblank = %3.2f", __func__, dst_y_per_vm_vblank); + DTRACE("DLG: %s: dst_y_per_row_vblank = %3.2f", __func__, dst_y_per_row_vblank); + DTRACE("DLG: %s: dst_y_prefetch = %3.2f", __func__, dst_y_prefetch); + + min_dst_y_per_vm_vblank = 8.0; + min_dst_y_per_row_vblank = 16.0; + if (htotal <= 75) { + min_vblank = 300; + min_dst_y_per_vm_vblank = 100.0; + min_dst_y_per_row_vblank = 100.0; + } + + ASSERT(dst_y_per_vm_vblank < min_dst_y_per_vm_vblank); + ASSERT(dst_y_per_row_vblank < min_dst_y_per_row_vblank); + + ASSERT(dst_y_prefetch > (dst_y_per_vm_vblank + dst_y_per_row_vblank)); + lsw = dst_y_prefetch - (dst_y_per_vm_vblank + dst_y_per_row_vblank); + + DTRACE("DLG: %s: lsw = %3.2f", __func__, lsw); + + vratio_pre_l = get_vratio_pre( + mode_lib, + max_num_sw_l, + max_partial_sw_l, + swath_height_l, + max_vinit_l, + lsw); + vratio_pre_c = 1.0; + if (dual_plane) + vratio_pre_c = get_vratio_pre( + mode_lib, + max_num_sw_c, + max_partial_sw_c, + swath_height_c, + max_vinit_c, + lsw); + + DTRACE("DLG: %s: vratio_pre_l=%3.2f", __func__, vratio_pre_l); + DTRACE("DLG: %s: vratio_pre_c=%3.2f", __func__, vratio_pre_c); + + ASSERT(vratio_pre_l <= 4.0); + if (vratio_pre_l >= 4.0) + disp_dlg_regs->vratio_prefetch = (unsigned int) dml_pow(2, 21) - 1; + else + disp_dlg_regs->vratio_prefetch = (unsigned int) (vratio_pre_l * dml_pow(2, 19)); + + ASSERT(vratio_pre_c <= 4.0); + if (vratio_pre_c >= 4.0) + disp_dlg_regs->vratio_prefetch_c = (unsigned int) dml_pow(2, 21) - 1; + else + disp_dlg_regs->vratio_prefetch_c = (unsigned int) (vratio_pre_c * dml_pow(2, 19)); + + disp_dlg_regs->refcyc_per_pte_group_vblank_l = + (unsigned int) (dst_y_per_row_vblank * (double) htotal + * ref_freq_to_pix_freq / (double) dpte_groups_per_row_ub_l); + ASSERT(disp_dlg_regs->refcyc_per_pte_group_vblank_l < (unsigned int) dml_pow(2, 13)); + + disp_dlg_regs->refcyc_per_pte_group_vblank_c = + (unsigned int) (dst_y_per_row_vblank * (double) htotal + * ref_freq_to_pix_freq / (double) dpte_groups_per_row_ub_c); + ASSERT(disp_dlg_regs->refcyc_per_pte_group_vblank_c < (unsigned int) dml_pow(2, 13)); + + disp_dlg_regs->refcyc_per_meta_chunk_vblank_l = + (unsigned int) (dst_y_per_row_vblank * (double) htotal + * ref_freq_to_pix_freq / (double) meta_chunks_per_row_ub_l); + ASSERT(disp_dlg_regs->refcyc_per_meta_chunk_vblank_l < (unsigned int) dml_pow(2, 13)); + + disp_dlg_regs->refcyc_per_meta_chunk_vblank_c = + disp_dlg_regs->refcyc_per_meta_chunk_vblank_l;/* dcc for 4:2:0 is not supported in dcn1.0. assigned to be the same as _l for now */ + + /* Active */ + req_per_swath_ub_l = rq_dlg_param.rq_l.req_per_swath_ub; + req_per_swath_ub_c = rq_dlg_param.rq_c.req_per_swath_ub; + meta_row_height_l = rq_dlg_param.rq_l.meta_row_height; + swath_width_pixels_ub_l = 0; + swath_width_pixels_ub_c = 0; + scaler_rec_in_width_l = 0; + scaler_rec_in_width_c = 0; + dpte_row_height_l = rq_dlg_param.rq_l.dpte_row_height; + dpte_row_height_c = rq_dlg_param.rq_c.dpte_row_height; + + disp_dlg_regs->dst_y_per_pte_row_nom_l = (unsigned int) ((double) dpte_row_height_l + / (double) vratio_l * dml_pow(2, 2)); + ASSERT(disp_dlg_regs->dst_y_per_pte_row_nom_l < (unsigned int) dml_pow(2, 17)); + + disp_dlg_regs->dst_y_per_pte_row_nom_c = (unsigned int) ((double) dpte_row_height_c + / (double) vratio_c * dml_pow(2, 2)); + ASSERT(disp_dlg_regs->dst_y_per_pte_row_nom_c < (unsigned int) dml_pow(2, 17)); + + disp_dlg_regs->dst_y_per_meta_row_nom_l = (unsigned int) ((double) meta_row_height_l + / (double) vratio_l * dml_pow(2, 2)); + ASSERT(disp_dlg_regs->dst_y_per_meta_row_nom_l < (unsigned int) dml_pow(2, 17)); + + disp_dlg_regs->dst_y_per_meta_row_nom_c = disp_dlg_regs->dst_y_per_meta_row_nom_l; /* dcc for 4:2:0 is not supported in dcn1.0. assigned to be the same as _l for now */ + + disp_dlg_regs->refcyc_per_pte_group_nom_l = (unsigned int) ((double) dpte_row_height_l + / (double) vratio_l * (double) htotal * ref_freq_to_pix_freq + / (double) dpte_groups_per_row_ub_l); + if (disp_dlg_regs->refcyc_per_pte_group_nom_l >= (unsigned int) dml_pow(2, 23)) + disp_dlg_regs->refcyc_per_pte_group_nom_l = dml_pow(2, 23) - 1; + + disp_dlg_regs->refcyc_per_pte_group_nom_c = (unsigned int) ((double) dpte_row_height_c + / (double) vratio_c * (double) htotal * ref_freq_to_pix_freq + / (double) dpte_groups_per_row_ub_c); + if (disp_dlg_regs->refcyc_per_pte_group_nom_c >= (unsigned int) dml_pow(2, 23)) + disp_dlg_regs->refcyc_per_pte_group_nom_c = dml_pow(2, 23) - 1; + + disp_dlg_regs->refcyc_per_meta_chunk_nom_l = (unsigned int) ((double) meta_row_height_l + / (double) vratio_l * (double) htotal * ref_freq_to_pix_freq + / (double) meta_chunks_per_row_ub_l); + if (disp_dlg_regs->refcyc_per_meta_chunk_nom_l >= (unsigned int) dml_pow(2, 23)) + disp_dlg_regs->refcyc_per_meta_chunk_nom_l = dml_pow(2, 23) - 1; + + if (mode_422) { + swath_width_pixels_ub_l = swath_width_ub_l * 2; /* *2 for 2 pixel per element */ + swath_width_pixels_ub_c = swath_width_ub_c * 2; + } else { + swath_width_pixels_ub_l = swath_width_ub_l * 1; + swath_width_pixels_ub_c = swath_width_ub_c * 1; + } + + hscale_pixel_rate_l = 0.; + hscale_pixel_rate_c = 0.; + min_hratio_fact_l = 1.0; + min_hratio_fact_c = 1.0; + + if (htaps_l <= 1) + min_hratio_fact_l = 2.0; + else if (htaps_l <= 6) { + if ((hratios_l * 2.0) > 4.0) + min_hratio_fact_l = 4.0; + else + min_hratio_fact_l = hratios_l * 2.0; + } else { + if (hratios_l > 4.0) + min_hratio_fact_l = 4.0; + else + min_hratio_fact_l = hratios_l; + } + + hscale_pixel_rate_l = min_hratio_fact_l * dppclk_freq_in_mhz; + + if (htaps_c <= 1) + min_hratio_fact_c = 2.0; + else if (htaps_c <= 6) { + if ((hratios_c * 2.0) > 4.0) + min_hratio_fact_c = 4.0; + else + min_hratio_fact_c = hratios_c * 2.0; + } else { + if (hratios_c > 4.0) + min_hratio_fact_c = 4.0; + else + min_hratio_fact_c = hratios_c; + } + + hscale_pixel_rate_c = min_hratio_fact_c * dppclk_freq_in_mhz; + + refcyc_per_line_delivery_pre_l = 0.; + refcyc_per_line_delivery_pre_c = 0.; + refcyc_per_line_delivery_l = 0.; + refcyc_per_line_delivery_c = 0.; + + refcyc_per_req_delivery_pre_l = 0.; + refcyc_per_req_delivery_pre_c = 0.; + refcyc_per_req_delivery_l = 0.; + refcyc_per_req_delivery_c = 0.; + refcyc_per_req_delivery_pre_cur0 = 0.; + refcyc_per_req_delivery_cur0 = 0.; + + full_recout_width = 0; + if (e2e_pipe_param.pipe.src.is_hsplit) { + if (e2e_pipe_param.pipe.dest.full_recout_width == 0) { + DTRACE("DLG: %s: Warningfull_recout_width not set in hsplit mode", __func__); + full_recout_width = e2e_pipe_param.pipe.dest.recout_width * 2; /* assume half split for dcn1 */ + } else + full_recout_width = e2e_pipe_param.pipe.dest.full_recout_width; + } else + full_recout_width = e2e_pipe_param.pipe.dest.recout_width; + + refcyc_per_line_delivery_pre_l = get_refcyc_per_delivery( + mode_lib, + refclk_freq_in_mhz, + pclk_freq_in_mhz, + full_recout_width, + vratio_pre_l, + hscale_pixel_rate_l, + swath_width_pixels_ub_l, + 1); /* per line */ + + refcyc_per_line_delivery_l = get_refcyc_per_delivery( + mode_lib, + refclk_freq_in_mhz, + pclk_freq_in_mhz, + full_recout_width, + vratio_l, + hscale_pixel_rate_l, + swath_width_pixels_ub_l, + 1); /* per line */ + + DTRACE("DLG: %s: full_recout_width = %d", __func__, full_recout_width); + DTRACE("DLG: %s: hscale_pixel_rate_l = %3.2f", __func__, hscale_pixel_rate_l); + DTRACE( + "DLG: %s: refcyc_per_line_delivery_pre_l = %3.2f", + __func__, + refcyc_per_line_delivery_pre_l); + DTRACE( + "DLG: %s: refcyc_per_line_delivery_l = %3.2f", + __func__, + refcyc_per_line_delivery_l); + + disp_dlg_regs->refcyc_per_line_delivery_pre_l = (unsigned int) dml_floor( + refcyc_per_line_delivery_pre_l, + 1); + disp_dlg_regs->refcyc_per_line_delivery_l = (unsigned int) dml_floor( + refcyc_per_line_delivery_l, + 1); + ASSERT(disp_dlg_regs->refcyc_per_line_delivery_pre_l < (unsigned int) dml_pow(2, 13)); + ASSERT(disp_dlg_regs->refcyc_per_line_delivery_l < (unsigned int) dml_pow(2, 13)); + + if (dual_plane) { + refcyc_per_line_delivery_pre_c = get_refcyc_per_delivery( + mode_lib, + refclk_freq_in_mhz, + pclk_freq_in_mhz, + full_recout_width, + vratio_pre_c, + hscale_pixel_rate_c, + swath_width_pixels_ub_c, + 1); /* per line */ + + refcyc_per_line_delivery_c = get_refcyc_per_delivery( + mode_lib, + refclk_freq_in_mhz, + pclk_freq_in_mhz, + full_recout_width, + vratio_c, + hscale_pixel_rate_c, + swath_width_pixels_ub_c, + 1); /* per line */ + + DTRACE( + "DLG: %s: refcyc_per_line_delivery_pre_c = %3.2f", + __func__, + refcyc_per_line_delivery_pre_c); + DTRACE( + "DLG: %s: refcyc_per_line_delivery_c = %3.2f", + __func__, + refcyc_per_line_delivery_c); + + disp_dlg_regs->refcyc_per_line_delivery_pre_c = (unsigned int) dml_floor( + refcyc_per_line_delivery_pre_c, + 1); + disp_dlg_regs->refcyc_per_line_delivery_c = (unsigned int) dml_floor( + refcyc_per_line_delivery_c, + 1); + ASSERT(disp_dlg_regs->refcyc_per_line_delivery_pre_c < (unsigned int) dml_pow(2, 13)); + ASSERT(disp_dlg_regs->refcyc_per_line_delivery_c < (unsigned int) dml_pow(2, 13)); + } + disp_dlg_regs->chunk_hdl_adjust_cur0 = 3; + + /* TTU - Luma / Chroma */ + if (access_dir) { /* vertical access */ + scaler_rec_in_width_l = vp_height_l; + scaler_rec_in_width_c = vp_height_c; + } else { + scaler_rec_in_width_l = vp_width_l; + scaler_rec_in_width_c = vp_width_c; + } + + refcyc_per_req_delivery_pre_l = get_refcyc_per_delivery( + mode_lib, + refclk_freq_in_mhz, + pclk_freq_in_mhz, + full_recout_width, + vratio_pre_l, + hscale_pixel_rate_l, + scaler_rec_in_width_l, + req_per_swath_ub_l); /* per req */ + refcyc_per_req_delivery_l = get_refcyc_per_delivery( + mode_lib, + refclk_freq_in_mhz, + pclk_freq_in_mhz, + full_recout_width, + vratio_l, + hscale_pixel_rate_l, + scaler_rec_in_width_l, + req_per_swath_ub_l); /* per req */ + + DTRACE( + "DLG: %s: refcyc_per_req_delivery_pre_l = %3.2f", + __func__, + refcyc_per_req_delivery_pre_l); + DTRACE( + "DLG: %s: refcyc_per_req_delivery_l = %3.2f", + __func__, + refcyc_per_req_delivery_l); + + disp_ttu_regs->refcyc_per_req_delivery_pre_l = (unsigned int) (refcyc_per_req_delivery_pre_l + * dml_pow(2, 10)); + disp_ttu_regs->refcyc_per_req_delivery_l = (unsigned int) (refcyc_per_req_delivery_l + * dml_pow(2, 10)); + + ASSERT(refcyc_per_req_delivery_pre_l < dml_pow(2, 13)); + ASSERT(refcyc_per_req_delivery_l < dml_pow(2, 13)); + + if (dual_plane) { + refcyc_per_req_delivery_pre_c = get_refcyc_per_delivery( + mode_lib, + refclk_freq_in_mhz, + pclk_freq_in_mhz, + full_recout_width, + vratio_pre_c, + hscale_pixel_rate_c, + scaler_rec_in_width_c, + req_per_swath_ub_c); /* per req */ + refcyc_per_req_delivery_c = get_refcyc_per_delivery( + mode_lib, + refclk_freq_in_mhz, + pclk_freq_in_mhz, + full_recout_width, + vratio_c, + hscale_pixel_rate_c, + scaler_rec_in_width_c, + req_per_swath_ub_c); /* per req */ + + DTRACE( + "DLG: %s: refcyc_per_req_delivery_pre_c = %3.2f", + __func__, + refcyc_per_req_delivery_pre_c); + DTRACE( + "DLG: %s: refcyc_per_req_delivery_c = %3.2f", + __func__, + refcyc_per_req_delivery_c); + + disp_ttu_regs->refcyc_per_req_delivery_pre_c = + (unsigned int) (refcyc_per_req_delivery_pre_c * dml_pow(2, 10)); + disp_ttu_regs->refcyc_per_req_delivery_c = (unsigned int) (refcyc_per_req_delivery_c + * dml_pow(2, 10)); + + ASSERT(refcyc_per_req_delivery_pre_c < dml_pow(2, 13)); + ASSERT(refcyc_per_req_delivery_c < dml_pow(2, 13)); + } + + /* TTU - Cursor */ + hratios_cur0 = e2e_pipe_param.pipe.scale_ratio_depth.hscl_ratio; + cur0_src_width = e2e_pipe_param.pipe.src.cur0_src_width; /* cursor source width */ + cur0_bpp = (enum cursor_bpp) e2e_pipe_param.pipe.src.cur0_bpp; + cur0_req_size = 0; + cur0_req_width = 0; + cur0_width_ub = 0.0; + cur0_req_per_width = 0.0; + hactive_cur0 = 0.0; + + ASSERT(cur0_src_width <= 256); + + if (cur0_src_width > 0) { + unsigned int cur0_bit_per_pixel = 0; + + if (cur0_bpp == dm_cur_2bit) { + cur0_req_size = 64; /* byte */ + cur0_bit_per_pixel = 2; + } else { /* 32bit */ + cur0_bit_per_pixel = 32; + if (cur0_src_width >= 1 && cur0_src_width <= 16) + cur0_req_size = 64; + else if (cur0_src_width >= 17 && cur0_src_width <= 31) + cur0_req_size = 128; + else + cur0_req_size = 256; + } + + cur0_req_width = (double) cur0_req_size / ((double) cur0_bit_per_pixel / 8.0); + cur0_width_ub = dml_ceil((double) cur0_src_width / (double) cur0_req_width, 1) + * (double) cur0_req_width; + cur0_req_per_width = cur0_width_ub / (double) cur0_req_width; + hactive_cur0 = (double) cur0_src_width / hratios_cur0; /* FIXME: oswin to think about what to do for cursor */ + + if (vratio_pre_l <= 1.0) { + refcyc_per_req_delivery_pre_cur0 = hactive_cur0 * ref_freq_to_pix_freq + / (double) cur0_req_per_width; + } else { + refcyc_per_req_delivery_pre_cur0 = (double) refclk_freq_in_mhz + * (double) cur0_src_width / hscale_pixel_rate_l + / (double) cur0_req_per_width; + } + + disp_ttu_regs->refcyc_per_req_delivery_pre_cur0 = + (unsigned int) (refcyc_per_req_delivery_pre_cur0 * dml_pow(2, 10)); + ASSERT(refcyc_per_req_delivery_pre_cur0 < dml_pow(2, 13)); + + if (vratio_l <= 1.0) { + refcyc_per_req_delivery_cur0 = hactive_cur0 * ref_freq_to_pix_freq + / (double) cur0_req_per_width; + } else { + refcyc_per_req_delivery_cur0 = (double) refclk_freq_in_mhz + * (double) cur0_src_width / hscale_pixel_rate_l + / (double) cur0_req_per_width; + } + + DTRACE("DLG: %s: cur0_req_width = %d", __func__, cur0_req_width); + DTRACE( + "DLG: %s: cur0_width_ub = %3.2f", + __func__, + cur0_width_ub); + DTRACE( + "DLG: %s: cur0_req_per_width = %3.2f", + __func__, + cur0_req_per_width); + DTRACE( + "DLG: %s: hactive_cur0 = %3.2f", + __func__, + hactive_cur0); + DTRACE( + "DLG: %s: refcyc_per_req_delivery_pre_cur0 = %3.2f", + __func__, + refcyc_per_req_delivery_pre_cur0); + DTRACE( + "DLG: %s: refcyc_per_req_delivery_cur0 = %3.2f", + __func__, + refcyc_per_req_delivery_cur0); + + disp_ttu_regs->refcyc_per_req_delivery_cur0 = + (unsigned int) (refcyc_per_req_delivery_cur0 * dml_pow(2, 10)); + ASSERT(refcyc_per_req_delivery_cur0 < dml_pow(2, 13)); + } else { + disp_ttu_regs->refcyc_per_req_delivery_pre_cur0 = 0; + disp_ttu_regs->refcyc_per_req_delivery_cur0 = 0; + } + + /* TTU - Misc */ + disp_ttu_regs->qos_level_low_wm = 0; + ASSERT(disp_ttu_regs->qos_level_low_wm < dml_pow(2, 14)); + disp_ttu_regs->qos_level_high_wm = (unsigned int) (4.0 * (double) htotal + * ref_freq_to_pix_freq); + ASSERT(disp_ttu_regs->qos_level_high_wm < dml_pow(2, 14)); + + disp_ttu_regs->qos_level_flip = 14; + disp_ttu_regs->qos_level_fixed_l = 8; + disp_ttu_regs->qos_level_fixed_c = 8; + disp_ttu_regs->qos_level_fixed_cur0 = 8; + disp_ttu_regs->qos_ramp_disable_l = 0; + disp_ttu_regs->qos_ramp_disable_c = 0; + disp_ttu_regs->qos_ramp_disable_cur0 = 0; + + disp_ttu_regs->min_ttu_vblank = min_ttu_vblank * refclk_freq_in_mhz; + ASSERT(disp_ttu_regs->min_ttu_vblank < dml_pow(2, 24)); + + print__ttu_regs_st(mode_lib, *disp_ttu_regs); + print__dlg_regs_st(mode_lib, *disp_dlg_regs); +} diff --git a/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.h b/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.h new file mode 100644 index 0000000000000..987d7671cd0f9 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.h @@ -0,0 +1,67 @@ +/* + * Copyright 2017 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: AMD + * + */ + +#ifndef __DISPLAY_RQ_DLG_CALC_H__ +#define __DISPLAY_RQ_DLG_CALC_H__ + +#include "dml_common_defs.h" +#include "display_rq_dlg_helpers.h" + +struct display_mode_lib; + +void dml1_extract_rq_regs( + struct display_mode_lib *mode_lib, + struct _vcs_dpi_display_rq_regs_st *rq_regs, + const struct _vcs_dpi_display_rq_params_st rq_param); +/* Function: dml_rq_dlg_get_rq_params + * Calculate requestor related parameters that register definition agnostic + * (i.e. this layer does try to separate real values from register definition) + * Input: + * pipe_src_param - pipe source configuration (e.g. vp, pitch, etc.) + * Output: + * rq_param - values that can be used to setup RQ (e.g. swath_height, plane1_addr, etc.) + */ +void dml1_rq_dlg_get_rq_params( + struct display_mode_lib *mode_lib, + struct _vcs_dpi_display_rq_params_st *rq_param, + const struct _vcs_dpi_display_pipe_source_params_st pipe_src_param); + + +/* Function: dml_rq_dlg_get_dlg_params + * Calculate deadline related parameters + */ +void dml1_rq_dlg_get_dlg_params( + struct display_mode_lib *mode_lib, + struct _vcs_dpi_display_dlg_regs_st *dlg_regs, + struct _vcs_dpi_display_ttu_regs_st *ttu_regs, + const struct _vcs_dpi_display_rq_dlg_params_st rq_dlg_param, + const struct _vcs_dpi_display_dlg_sys_params_st dlg_sys_param, + const struct _vcs_dpi_display_e2e_pipe_params_st e2e_pipe_param, + const bool cstate_en, + const bool pstate_en, + const bool vm_en, + const bool iflip_en); + +#endif diff --git a/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.c b/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.c index 21349a022de3b..9cbd415e508d3 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.c @@ -36,21 +36,21 @@ double dml_max(double a, double b) return (double) dcn_bw_max2(a, b); } -double dml_ceil(double a) +double dml_ceil(double a, double granularity) { - return (double) dcn_bw_ceil2(a, 1); + return (double) dcn_bw_ceil2(a, granularity); } -double dml_floor(double a) +double dml_floor(double a, double granularity) { - return (double) dcn_bw_floor2(a, 1); + return (double) dcn_bw_floor2(a, granularity); } double dml_round(double a) { double round_pt = 0.5; - double ceil = dml_ceil(a); - double floor = dml_floor(a); + double ceil = dml_ceil(a, 1); + double floor = dml_floor(a, 1); if (a - floor >= round_pt) return ceil; diff --git a/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.h b/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.h index c5340d41eedb7..19271e79abcc8 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.h +++ b/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.h @@ -22,6 +22,7 @@ * Authors: AMD * */ + #ifndef __DC_COMMON_DEFS_H__ #define __DC_COMMON_DEFS_H__ @@ -30,7 +31,8 @@ #include "display_mode_structs.h" #include "display_mode_enums.h" -#define DTRACE(str, ...) dm_logger_write(mode_lib->logger, LOG_DML, str, ##__VA_ARGS__); +#define dml_print(str, ...) {dm_logger_write(mode_lib->logger, LOG_DML, str, ##__VA_ARGS__); } +#define DTRACE(str, ...) {dm_logger_write(mode_lib->logger, LOG_DML, str, ##__VA_ARGS__); } double dml_min(double a, double b); double dml_max(double a, double b); @@ -38,8 +40,8 @@ bool dml_util_is_420(enum source_format_class sorce_format); double dml_ceil_ex(double x, double granularity); double dml_floor_ex(double x, double granularity); double dml_log(double x, double base); -double dml_ceil(double a); -double dml_floor(double a); +double dml_ceil(double a, double granularity); +double dml_floor(double a, double granularity); double dml_round(double a); int dml_log2(double x); double dml_pow(double a, int exp); diff --git a/drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.c b/drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.c index 112b0b728b4d4..8b8512528af5d 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.c +++ b/drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.c @@ -24,49 +24,45 @@ */ #include "soc_bounding_box.h" #include "display_mode_lib.h" +#include "dc_features.h" -void dml_socbb_set_latencies( - struct display_mode_lib *mode_lib, - struct _vcs_dpi_soc_bounding_box_st *from_box) +void dml_socbb_set_latencies(soc_bounding_box_st *to_box, soc_bounding_box_st *from_box) { - struct _vcs_dpi_soc_bounding_box_st *to_box = &mode_lib->soc; - to_box->dram_clock_change_latency_us = from_box->dram_clock_change_latency_us; to_box->sr_exit_time_us = from_box->sr_exit_time_us; to_box->sr_enter_plus_exit_time_us = from_box->sr_enter_plus_exit_time_us; to_box->urgent_latency_us = from_box->urgent_latency_us; to_box->writeback_latency_us = from_box->writeback_latency_us; - DTRACE("box.dram_clock_change_latency_us: %f", from_box->dram_clock_change_latency_us); - DTRACE("box.sr_exit_time_us: %f", from_box->sr_exit_time_us); - DTRACE("box.sr_enter_plus_exit_time_us: %f", from_box->sr_enter_plus_exit_time_us); - DTRACE("box.urgent_latency_us: %f", from_box->urgent_latency_us); - DTRACE("box.writeback_latency_us: %f", from_box->writeback_latency_us); - } -struct _vcs_dpi_voltage_scaling_st dml_socbb_voltage_scaling( - struct _vcs_dpi_soc_bounding_box_st *box, +voltage_scaling_st dml_socbb_voltage_scaling( + const soc_bounding_box_st *soc, enum voltage_state voltage) { - switch (voltage) { - case dm_vmin: - return box->vmin; - case dm_vnom: - return box->vnom; - case dm_vmax: - default: - return box->vmax; + const voltage_scaling_st *voltage_state; + const voltage_scaling_st * const voltage_end = soc->clock_limits + DC__VOLTAGE_STATES; + + for (voltage_state = soc->clock_limits; + voltage_state < voltage_end && voltage_state->state != voltage; + voltage_state++) { } + + if (voltage_state < voltage_end) + return *voltage_state; + return soc->clock_limits[DC__VOLTAGE_STATES - 1]; } -double dml_socbb_return_bw_mhz(struct _vcs_dpi_soc_bounding_box_st *box, enum voltage_state voltage) +double dml_socbb_return_bw_mhz(soc_bounding_box_st *box, enum voltage_state voltage) { double return_bw; - struct _vcs_dpi_voltage_scaling_st state = dml_socbb_voltage_scaling(box, voltage); + voltage_scaling_st state = dml_socbb_voltage_scaling(box, voltage); + + return_bw = dml_min((double) box->return_bus_width_bytes * state.dcfclk_mhz, + state.dram_bw_per_chan_gbps * 1000.0 * (double) box->num_chans + * box->ideal_dram_bw_after_urgent_percent / 100.0); + + return_bw = dml_min((double) box->return_bus_width_bytes * state.fabricclk_mhz, return_bw); - return_bw = dml_min( - ((double) box->return_bus_width_bytes) * state.dcfclk_mhz, - state.dram_bw_per_chan_gbps * 1000.0 * box->ideal_dram_bw_after_urgent_percent / 100.0); return return_bw; } diff --git a/drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.h b/drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.h index 7bbae33f163ec..7a65206a6d21a 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.h +++ b/drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.h @@ -22,15 +22,14 @@ * Authors: AMD * */ + #ifndef __SOC_BOUNDING_BOX_H__ #define __SOC_BOUNDING_BOX_H__ #include "dml_common_defs.h" -struct display_mode_lib; - -void dml_socbb_set_latencies(struct display_mode_lib *mode_lib, struct _vcs_dpi_soc_bounding_box_st *from_box); -struct _vcs_dpi_voltage_scaling_st dml_socbb_voltage_scaling(struct _vcs_dpi_soc_bounding_box_st *box, enum voltage_state voltage); -double dml_socbb_return_bw_mhz(struct _vcs_dpi_soc_bounding_box_st *box, enum voltage_state voltage); +void dml_socbb_set_latencies(soc_bounding_box_st *to_box, soc_bounding_box_st *from_box); +voltage_scaling_st dml_socbb_voltage_scaling(const soc_bounding_box_st *box, enum voltage_state voltage); +double dml_socbb_return_bw_mhz(soc_bounding_box_st *box, enum voltage_state voltage); #endif From cb94f78e3665ef23aabfe547962748d49471cf45 Mon Sep 17 00:00:00 2001 From: Dmytro Laktyushkin Date: Fri, 15 Sep 2017 16:03:09 -0400 Subject: [PATCH 058/155] drm/amd/display: add mode support check to dml vba code Signed-off-by: Dmytro Laktyushkin Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../amd/display/dc/dml/display_mode_enums.h | 10 +- .../amd/display/dc/dml/display_mode_structs.h | 5 + .../drm/amd/display/dc/dml/display_mode_vba.c | 5701 ++++++++++++----- .../drm/amd/display/dc/dml/display_mode_vba.h | 456 +- .../drm/amd/display/dc/dml/dml_common_defs.c | 12 + .../drm/amd/display/dc/dml/dml_common_defs.h | 3 + 6 files changed, 4604 insertions(+), 1583 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_enums.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_enums.h index eebaeb1fb61cf..b1ad3553f900d 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_enums.h +++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_enums.h @@ -26,7 +26,7 @@ #define __DISPLAY_MODE_ENUMS_H__ enum output_encoder_class { - dm_dp = 0, dm_hdmi = 1, dm_wb = 2 + dm_dp = 0, dm_hdmi = 1, dm_wb = 2, dm_edp }; enum output_format_class { dm_444 = 0, dm_420 = 1, dm_n422, dm_s422 @@ -39,7 +39,9 @@ enum source_format_class { dm_420_10 = 4, dm_422_8 = 5, dm_422_10 = 6, - dm_444_8 = 7 + dm_444_8 = 7, + dm_mono_8, + dm_mono_16 }; enum output_bpc_class { dm_out_6 = 0, dm_out_8 = 1, dm_out_10 = 2, dm_out_12 = 3, dm_out_16 = 4 @@ -79,7 +81,9 @@ enum dm_swizzle_mode { dm_sw_SPARE_15 = 28, dm_sw_var_s_x = 29, dm_sw_var_d_x = 30, - dm_sw_64kb_r_x + dm_sw_64kb_r_x, + dm_sw_gfx7_2d_thin_lvp, + dm_sw_gfx7_2d_thin_gl }; enum lb_depth { dm_lb_10 = 0, dm_lb_8 = 1, dm_lb_6 = 2, dm_lb_12 = 3, dm_lb_16 diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h index e5b7f7042e0bc..27e20460c71b5 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h +++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h @@ -66,6 +66,7 @@ struct _vcs_dpi_mode_evaluation_st { struct _vcs_dpi_voltage_scaling_st { int state; + double dscclk_mhz; double dcfclk_mhz; double socclk_mhz; double dram_speed_mhz; @@ -131,6 +132,9 @@ struct _vcs_dpi_ip_params_st { unsigned int writeback_chroma_line_buffer_width_pixels; unsigned int max_page_table_levels; unsigned int max_num_dpp; + unsigned int max_num_otg; + unsigned int cursor_chunk_size; + unsigned int cursor_buffer_size; unsigned int max_num_wb; unsigned int max_dchub_pscl_bw_pix_per_clk; unsigned int max_pscl_lb_bw_pix_per_clk; @@ -224,6 +228,7 @@ struct writeback_st { }; struct _vcs_dpi_display_output_params_st { + int dp_lanes; int output_bpp; int dsc_enable; int wb_enable; diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c index ada0eeed33011..e1a3182d58b3a 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c +++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c @@ -6,202 +6,220 @@ static const unsigned int NumberOfStates = DC__VOLTAGE_STATES; static void fetch_socbb_params(struct display_mode_lib *mode_lib); static void fetch_ip_params(struct display_mode_lib *mode_lib); static void fetch_pipe_params(struct display_mode_lib *mode_lib); -static void recalculate_params(struct display_mode_lib *mode_lib, - const display_e2e_pipe_params_st *pipes, - unsigned int num_pipes); +static void recalculate_params( + struct display_mode_lib *mode_lib, + const display_e2e_pipe_params_st *pipes, + unsigned int num_pipes); static void recalculate(struct display_mode_lib *mode_lib); -static double adjust_ReturnBW(struct display_mode_lib *mode_lib, double ReturnBW, bool DCCEnabledAnyPlane, double ReturnBandwidthToDCN); +static double adjust_ReturnBW( + struct display_mode_lib *mode_lib, + double ReturnBW, + bool DCCEnabledAnyPlane, + double ReturnBandwidthToDCN); static void ModeSupportAndSystemConfiguration(struct display_mode_lib *mode_lib); static void DisplayPipeConfiguration(struct display_mode_lib *mode_lib); -static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation(struct display_mode_lib *mode_lib); -static unsigned int dscceComputeDelay(unsigned int bpc, - double bpp, - unsigned int sliceWidth, - unsigned int numSlices, - enum output_format_class pixelFormat); +static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation( + struct display_mode_lib *mode_lib); +static unsigned int dscceComputeDelay( + unsigned int bpc, + double bpp, + unsigned int sliceWidth, + unsigned int numSlices, + enum output_format_class pixelFormat); static unsigned int dscComputeDelay(enum output_format_class pixelFormat); // Super monster function with some 45 argument -static bool CalculatePrefetchSchedule(struct display_mode_lib *mode_lib, - double DPPCLK, - double DISPCLK, - double PixelClock, - double DCFClkDeepSleep, - unsigned int DSCDelay, - unsigned int DPPPerPlane, - bool ScalerEnabled, - unsigned int NumberOfCursors, - double DPPCLKDelaySubtotal, - double DPPCLKDelaySCL, - double DPPCLKDelaySCLLBOnly, - double DPPCLKDelayCNVCFormater, - double DPPCLKDelayCNVCCursor, - double DISPCLKDelaySubtotal, - unsigned int ScalerRecoutWidth, - enum output_format_class OutputFormat, - unsigned int VBlank, - unsigned int HTotal, - unsigned int MaxInterDCNTileRepeaters, - unsigned int VStartup, - unsigned int PageTableLevels, - bool VirtualMemoryEnable, - bool DynamicMetadataEnable, - unsigned int DynamicMetadataLinesBeforeActiveRequired, - unsigned int DynamicMetadataTransmittedBytes, - bool DCCEnable, - double UrgentLatency, - double UrgentExtraLatency, - double TCalc, - unsigned int PDEAndMetaPTEBytesFrame, - unsigned int MetaRowByte, - unsigned int PixelPTEBytesPerRow, - double PrefetchSourceLinesY, - unsigned int SwathWidthY, - double BytePerPixelDETY, - double VInitPreFillY, - unsigned int MaxNumSwathY, - double PrefetchSourceLinesC, - double BytePerPixelDETC, - double VInitPreFillC, - unsigned int MaxNumSwathC, - unsigned int SwathHeightY, - unsigned int SwathHeightC, - double TWait, - bool XFCEnabled, - double XFCRemoteSurfaceFlipDelay, - bool InterlaceEnable, - bool ProgressiveToInterlaceUnitInOPP, - double *DSTXAfterScaler, - double *DSTYAfterScaler, - double *DestinationLinesForPrefetch, - double *PrefetchBandwidth, - double *DestinationLinesToRequestVMInVBlank, - double *DestinationLinesToRequestRowInVBlank, - double *VRatioPrefetchY, - double *VRatioPrefetchC, - double *RequiredPrefetchPixDataBW, - unsigned int *VStartupRequiredWhenNotEnoughTimeForDynamicMetadata, - double *Tno_bw); -static double CeilToDFSGranularity(double Clock, double VCOSpeed); -static double FloorToDFSGranularity(double Clock, double VCOSpeed); -static double CalculatePrefetchSourceLines(struct display_mode_lib *mode_lib, - double VRatio, - double vtaps, - bool Interlace, - bool ProgressiveToInterlaceUnitInOPP, - unsigned int SwathHeight, - unsigned int ViewportYStart, - double *VInitPreFill, - unsigned int *MaxNumSwath); -static unsigned int CalculateVMAndRowBytes(struct display_mode_lib *mode_lib, - bool DCCEnable, - unsigned int BlockHeight256Bytes, - unsigned int BlockWidth256Bytes, - enum source_format_class SourcePixelFormat, - unsigned int SurfaceTiling, - unsigned int BytePerPixel, - enum scan_direction_class ScanDirection, - unsigned int ViewportWidth, - unsigned int ViewportHeight, - unsigned int SwathWidthY, - bool VirtualMemoryEnable, - unsigned int VMMPageSize, - unsigned int PTEBufferSizeInRequests, - unsigned int PDEProcessingBufIn64KBReqs, - unsigned int Pitch, - unsigned int DCCMetaPitch, - unsigned int *MacroTileWidth, - unsigned int *MetaRowByte, - unsigned int *PixelPTEBytesPerRow, - bool *PTEBufferSizeNotExceeded, - unsigned int *dpte_row_height, - unsigned int *meta_row_height); -static double CalculateTWait(unsigned int PrefetchMode, - double DRAMClockChangeLatency, - double UrgentLatency, - double SREnterPlusExitTime); -static double CalculateRemoteSurfaceFlipDelay(struct display_mode_lib *mode_lib, - double VRatio, - double SwathWidth, - double Bpp, - double LineTime, - double XFCTSlvVupdateOffset, - double XFCTSlvVupdateWidth, - double XFCTSlvVreadyOffset, - double XFCXBUFLatencyTolerance, - double XFCFillBWOverhead, - double XFCSlvChunkSize, - double XFCBusTransportTime, - double TCalc, - double TWait, - double *SrcActiveDrainRate, - double *TInitXFill, - double *TslvChk); -static double CalculateWriteBackDISPCLK(enum source_format_class WritebackPixelFormat, - double PixelClock, - double WritebackHRatio, - double WritebackVRatio, - unsigned int WritebackLumaHTaps, - unsigned int WritebackLumaVTaps, - unsigned int WritebackChromaHTaps, - unsigned int WritebackChromaVTaps, - double WritebackDestinationWidth, - unsigned int HTotal, - unsigned int WritebackChromaLineBufferWidth); -static void CalculateActiveRowBandwidth(bool VirtualMemoryEnable, - enum source_format_class SourcePixelFormat, - double VRatio, - bool DCCEnable, - double LineTime, - unsigned int MetaRowByteLuma, - unsigned int MetaRowByteChroma, - unsigned int meta_row_height_luma, - unsigned int meta_row_height_chroma, - unsigned int PixelPTEBytesPerRowLuma, - unsigned int PixelPTEBytesPerRowChroma, - unsigned int dpte_row_height_luma, - unsigned int dpte_row_height_chroma, - double *meta_row_bw, - double *dpte_row_bw, - double *qual_row_bw); -static void CalculateFlipSchedule(struct display_mode_lib *mode_lib, - double UrgentExtraLatency, - double UrgentLatency, - unsigned int MaxPageTableLevels, - bool VirtualMemoryEnable, - double BandwidthAvailableForImmediateFlip, - unsigned int TotImmediateFlipBytes, - enum source_format_class SourcePixelFormat, - unsigned int ImmediateFlipBytes, - double LineTime, - double Tno_bw, - double VRatio, - double PDEAndMetaPTEBytesFrame, - unsigned int MetaRowByte, - unsigned int PixelPTEBytesPerRow, - bool DCCEnable, - unsigned int dpte_row_height, - unsigned int meta_row_height, - double qual_row_bw, - double *DestinationLinesToRequestVMInImmediateFlip, - double *DestinationLinesToRequestRowInImmediateFlip, - double *final_flip_bw, - bool *ImmediateFlipSupportedForPipe); -static double CalculateWriteBackDelay(enum source_format_class WritebackPixelFormat, - double WritebackHRatio, - double WritebackVRatio, - unsigned int WritebackLumaHTaps, - unsigned int WritebackLumaVTaps, - unsigned int WritebackChromaHTaps, - unsigned int WritebackChromaVTaps, - unsigned int WritebackDestinationWidth); +static bool CalculatePrefetchSchedule( + struct display_mode_lib *mode_lib, + double DPPCLK, + double DISPCLK, + double PixelClock, + double DCFClkDeepSleep, + unsigned int DSCDelay, + unsigned int DPPPerPlane, + bool ScalerEnabled, + unsigned int NumberOfCursors, + double DPPCLKDelaySubtotal, + double DPPCLKDelaySCL, + double DPPCLKDelaySCLLBOnly, + double DPPCLKDelayCNVCFormater, + double DPPCLKDelayCNVCCursor, + double DISPCLKDelaySubtotal, + unsigned int ScalerRecoutWidth, + enum output_format_class OutputFormat, + unsigned int VBlank, + unsigned int HTotal, + unsigned int MaxInterDCNTileRepeaters, + unsigned int VStartup, + unsigned int PageTableLevels, + bool VirtualMemoryEnable, + bool DynamicMetadataEnable, + unsigned int DynamicMetadataLinesBeforeActiveRequired, + unsigned int DynamicMetadataTransmittedBytes, + bool DCCEnable, + double UrgentLatency, + double UrgentExtraLatency, + double TCalc, + unsigned int PDEAndMetaPTEBytesFrame, + unsigned int MetaRowByte, + unsigned int PixelPTEBytesPerRow, + double PrefetchSourceLinesY, + unsigned int SwathWidthY, + double BytePerPixelDETY, + double VInitPreFillY, + unsigned int MaxNumSwathY, + double PrefetchSourceLinesC, + double BytePerPixelDETC, + double VInitPreFillC, + unsigned int MaxNumSwathC, + unsigned int SwathHeightY, + unsigned int SwathHeightC, + double TWait, + bool XFCEnabled, + double XFCRemoteSurfaceFlipDelay, + bool InterlaceEnable, + bool ProgressiveToInterlaceUnitInOPP, + double *DSTXAfterScaler, + double *DSTYAfterScaler, + double *DestinationLinesForPrefetch, + double *PrefetchBandwidth, + double *DestinationLinesToRequestVMInVBlank, + double *DestinationLinesToRequestRowInVBlank, + double *VRatioPrefetchY, + double *VRatioPrefetchC, + double *RequiredPrefetchPixDataBW, + unsigned int *VStartupRequiredWhenNotEnoughTimeForDynamicMetadata, + double *Tno_bw); +static double RoundToDFSGranularityUp(double Clock, double VCOSpeed); +static double RoundToDFSGranularityDown(double Clock, double VCOSpeed); +static double CalculatePrefetchSourceLines( + struct display_mode_lib *mode_lib, + double VRatio, + double vtaps, + bool Interlace, + bool ProgressiveToInterlaceUnitInOPP, + unsigned int SwathHeight, + unsigned int ViewportYStart, + double *VInitPreFill, + unsigned int *MaxNumSwath); +static unsigned int CalculateVMAndRowBytes( + struct display_mode_lib *mode_lib, + bool DCCEnable, + unsigned int BlockHeight256Bytes, + unsigned int BlockWidth256Bytes, + enum source_format_class SourcePixelFormat, + unsigned int SurfaceTiling, + unsigned int BytePerPixel, + enum scan_direction_class ScanDirection, + unsigned int ViewportWidth, + unsigned int ViewportHeight, + unsigned int SwathWidthY, + bool VirtualMemoryEnable, + unsigned int VMMPageSize, + unsigned int PTEBufferSizeInRequests, + unsigned int PDEProcessingBufIn64KBReqs, + unsigned int Pitch, + unsigned int DCCMetaPitch, + unsigned int *MacroTileWidth, + unsigned int *MetaRowByte, + unsigned int *PixelPTEBytesPerRow, + bool *PTEBufferSizeNotExceeded, + unsigned int *dpte_row_height, + unsigned int *meta_row_height); +static double CalculateTWait( + unsigned int PrefetchMode, + double DRAMClockChangeLatency, + double UrgentLatency, + double SREnterPlusExitTime); +static double CalculateRemoteSurfaceFlipDelay( + struct display_mode_lib *mode_lib, + double VRatio, + double SwathWidth, + double Bpp, + double LineTime, + double XFCTSlvVupdateOffset, + double XFCTSlvVupdateWidth, + double XFCTSlvVreadyOffset, + double XFCXBUFLatencyTolerance, + double XFCFillBWOverhead, + double XFCSlvChunkSize, + double XFCBusTransportTime, + double TCalc, + double TWait, + double *SrcActiveDrainRate, + double *TInitXFill, + double *TslvChk); +static double CalculateWriteBackDISPCLK( + enum source_format_class WritebackPixelFormat, + double PixelClock, + double WritebackHRatio, + double WritebackVRatio, + unsigned int WritebackLumaHTaps, + unsigned int WritebackLumaVTaps, + unsigned int WritebackChromaHTaps, + unsigned int WritebackChromaVTaps, + double WritebackDestinationWidth, + unsigned int HTotal, + unsigned int WritebackChromaLineBufferWidth); +static void CalculateActiveRowBandwidth( + bool VirtualMemoryEnable, + enum source_format_class SourcePixelFormat, + double VRatio, + bool DCCEnable, + double LineTime, + unsigned int MetaRowByteLuma, + unsigned int MetaRowByteChroma, + unsigned int meta_row_height_luma, + unsigned int meta_row_height_chroma, + unsigned int PixelPTEBytesPerRowLuma, + unsigned int PixelPTEBytesPerRowChroma, + unsigned int dpte_row_height_luma, + unsigned int dpte_row_height_chroma, + double *meta_row_bw, + double *dpte_row_bw, + double *qual_row_bw); +static void CalculateFlipSchedule( + struct display_mode_lib *mode_lib, + double UrgentExtraLatency, + double UrgentLatency, + unsigned int MaxPageTableLevels, + bool VirtualMemoryEnable, + double BandwidthAvailableForImmediateFlip, + unsigned int TotImmediateFlipBytes, + enum source_format_class SourcePixelFormat, + unsigned int ImmediateFlipBytes, + double LineTime, + double Tno_bw, + double VRatio, + double PDEAndMetaPTEBytesFrame, + unsigned int MetaRowByte, + unsigned int PixelPTEBytesPerRow, + bool DCCEnable, + unsigned int dpte_row_height, + unsigned int meta_row_height, + double qual_row_bw, + double *DestinationLinesToRequestVMInImmediateFlip, + double *DestinationLinesToRequestRowInImmediateFlip, + double *final_flip_bw, + bool *ImmediateFlipSupportedForPipe); +static double CalculateWriteBackDelay( + enum source_format_class WritebackPixelFormat, + double WritebackHRatio, + double WritebackVRatio, + unsigned int WritebackLumaHTaps, + unsigned int WritebackLumaVTaps, + unsigned int WritebackChromaHTaps, + unsigned int WritebackChromaVTaps, + unsigned int WritebackDestinationWidth); static void PixelClockAdjustmentForProgressiveToInterlaceUnit(struct display_mode_lib *mode_lib); static unsigned int CursorBppEnumToBits(enum cursor_bpp ebpp); - -void set_prefetch_mode(struct display_mode_lib *mode_lib, - bool cstate_en, - bool pstate_en, - bool ignore_viewport_pos, - bool immediate_flip_support) +static void ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_lib); + +void set_prefetch_mode( + struct display_mode_lib *mode_lib, + bool cstate_en, + bool pstate_en, + bool ignore_viewport_pos, + bool immediate_flip_support) { unsigned int prefetch_mode; @@ -211,11 +229,13 @@ void set_prefetch_mode(struct display_mode_lib *mode_lib, prefetch_mode = 1; else prefetch_mode = 2; - if (prefetch_mode != mode_lib->vba.PrefetchMode || ignore_viewport_pos != mode_lib->vba.IgnoreViewportPositioning - || immediate_flip_support != mode_lib->vba.ImmediateFlipSupport) { - DTRACE(" Prefetch mode has changed from %i to %i. Recalculating.", - prefetch_mode, - mode_lib->vba.PrefetchMode); + if (prefetch_mode != mode_lib->vba.PrefetchMode + || ignore_viewport_pos != mode_lib->vba.IgnoreViewportPositioning + || immediate_flip_support != mode_lib->vba.ImmediateFlipSupport) { + DTRACE( + " Prefetch mode has changed from %i to %i. Recalculating.", + prefetch_mode, + mode_lib->vba.PrefetchMode); mode_lib->vba.PrefetchMode = prefetch_mode; mode_lib->vba.IgnoreViewportPositioning = ignore_viewport_pos; mode_lib->vba.ImmediateFlipSupport = immediate_flip_support; @@ -223,6 +243,39 @@ void set_prefetch_mode(struct display_mode_lib *mode_lib, } } +unsigned int dml_get_voltage_level( + struct display_mode_lib *mode_lib, + const display_e2e_pipe_params_st *pipes, + unsigned int num_pipes) +{ + bool need_recalculate = memcmp( + &mode_lib->soc, + &mode_lib->vba.soc, + sizeof(mode_lib->vba.soc)) != 0 + || memcmp(&mode_lib->ip, &mode_lib->vba.ip, sizeof(mode_lib->vba.ip)) != 0 + || memcmp(&mode_lib->me, &mode_lib->vba.me, sizeof(mode_lib->vba.me)) != 0 + || num_pipes != mode_lib->vba.cache_num_pipes + || memcmp(pipes, mode_lib->vba.cache_pipes, + sizeof(display_e2e_pipe_params_st) * num_pipes) != 0; + + mode_lib->vba.soc = mode_lib->soc; + mode_lib->vba.ip = mode_lib->ip; + mode_lib->vba.me = mode_lib->me; + memcpy(mode_lib->vba.cache_pipes, pipes, sizeof(*pipes) * num_pipes); + mode_lib->vba.cache_num_pipes = num_pipes; + + if (need_recalculate) + recalculate(mode_lib); + else { + fetch_socbb_params(mode_lib); + fetch_ip_params(mode_lib); + fetch_pipe_params(mode_lib); + } + ModeSupportAndSystemConfigurationFull(mode_lib); + + return mode_lib->vba.VoltageLevel; +} + #define dml_get_attr_func(attr, var) double get_##attr(struct display_mode_lib *mode_lib, const display_e2e_pipe_params_st *pipes, unsigned int num_pipes) \ { \ recalculate_params(mode_lib, pipes, num_pipes); \ @@ -243,7 +296,9 @@ dml_get_attr_func(stutter_efficiency_no_vblank, mode_lib->vba.StutterEfficiencyN dml_get_attr_func(urgent_latency, mode_lib->vba.MinUrgentLatencySupportUs); dml_get_attr_func(urgent_extra_latency, mode_lib->vba.UrgentExtraLatency); dml_get_attr_func(nonurgent_latency, mode_lib->vba.NonUrgentLatencyTolerance); -dml_get_attr_func(dram_clock_change_latency, mode_lib->vba.MinActiveDRAMClockChangeLatencySupported); +dml_get_attr_func( + dram_clock_change_latency, + mode_lib->vba.MinActiveDRAMClockChangeLatencySupported); dml_get_attr_func(dispclk_calculated, mode_lib->vba.DISPCLK_calculated); dml_get_attr_func(total_data_read_bw, mode_lib->vba.TotalDataReadBandwidth); dml_get_attr_func(return_bw, mode_lib->vba.ReturnBW); @@ -269,17 +324,20 @@ dml_get_pipe_attr_func(dst_y_per_vm_vblank, mode_lib->vba.DestinationLinesToRequ dml_get_pipe_attr_func(dst_y_per_row_vblank, mode_lib->vba.DestinationLinesToRequestRowInVBlank); dml_get_pipe_attr_func(dst_y_prefetch, mode_lib->vba.DestinationLinesForPrefetch); dml_get_pipe_attr_func(dst_y_per_vm_flip, mode_lib->vba.DestinationLinesToRequestVMInImmediateFlip); -dml_get_pipe_attr_func(dst_y_per_row_flip, mode_lib->vba.DestinationLinesToRequestRowInImmediateFlip); +dml_get_pipe_attr_func( + dst_y_per_row_flip, + mode_lib->vba.DestinationLinesToRequestRowInImmediateFlip); dml_get_pipe_attr_func(xfc_transfer_delay, mode_lib->vba.XFCTransferDelay); dml_get_pipe_attr_func(xfc_precharge_delay, mode_lib->vba.XFCPrechargeDelay); dml_get_pipe_attr_func(xfc_remote_surface_flip_latency, mode_lib->vba.XFCRemoteSurfaceFlipLatency); dml_get_pipe_attr_func(xfc_prefetch_margin, mode_lib->vba.XFCPrefetchMargin); -unsigned int get_vstartup_calculated(struct display_mode_lib *mode_lib, - const display_e2e_pipe_params_st *pipes, - unsigned int num_pipes, - unsigned int which_pipe) +unsigned int get_vstartup_calculated( + struct display_mode_lib *mode_lib, + const display_e2e_pipe_params_st *pipes, + unsigned int num_pipes, + unsigned int which_pipe) { unsigned int which_plane; @@ -288,25 +346,28 @@ unsigned int get_vstartup_calculated(struct display_mode_lib *mode_lib, return mode_lib->vba.VStartup[which_plane]; } -double get_total_immediate_flip_bytes(struct display_mode_lib *mode_lib, - const display_e2e_pipe_params_st *pipes, - unsigned int num_pipes) +double get_total_immediate_flip_bytes( + struct display_mode_lib *mode_lib, + const display_e2e_pipe_params_st *pipes, + unsigned int num_pipes) { recalculate_params(mode_lib, pipes, num_pipes); return mode_lib->vba.TotImmediateFlipBytes; } -double get_total_immediate_flip_bw(struct display_mode_lib *mode_lib, - const display_e2e_pipe_params_st *pipes, - unsigned int num_pipes) +double get_total_immediate_flip_bw( + struct display_mode_lib *mode_lib, + const display_e2e_pipe_params_st *pipes, + unsigned int num_pipes) { recalculate_params(mode_lib, pipes, num_pipes); return mode_lib->vba.ImmediateFlipBW; } -double get_total_prefetch_bw(struct display_mode_lib *mode_lib, - const display_e2e_pipe_params_st *pipes, - unsigned int num_pipes) +double get_total_prefetch_bw( + struct display_mode_lib *mode_lib, + const display_e2e_pipe_params_st *pipes, + unsigned int num_pipes) { unsigned int k; double total_prefetch_bw = 0.0; @@ -326,10 +387,11 @@ static void fetch_socbb_params(struct display_mode_lib *mode_lib) mode_lib->vba.ReturnBusWidth = soc->return_bus_width_bytes; mode_lib->vba.NumberOfChannels = soc->num_chans; mode_lib->vba.PercentOfIdealDRAMAndFabricBWReceivedAfterUrgLatency = - soc->ideal_dram_bw_after_urgent_percent; // there's always that one bastard variable that's so long it throws everything out of alignment! + soc->ideal_dram_bw_after_urgent_percent; // there's always that one bastard variable that's so long it throws everything out of alignment! mode_lib->vba.UrgentLatency = soc->urgent_latency_us; mode_lib->vba.RoundTripPingLatencyCycles = soc->round_trip_ping_latency_dcfclk_cycles; - mode_lib->vba.UrgentOutOfOrderReturnPerChannel = soc->urgent_out_of_order_return_per_channel_bytes; + mode_lib->vba.UrgentOutOfOrderReturnPerChannel = + soc->urgent_out_of_order_return_per_channel_bytes; mode_lib->vba.WritebackLatency = soc->writeback_latency_us; mode_lib->vba.SRExitTime = soc->sr_exit_time_us; mode_lib->vba.SREnterPlusExitTime = soc->sr_enter_plus_exit_time_us; @@ -342,7 +404,7 @@ static void fetch_socbb_params(struct display_mode_lib *mode_lib) mode_lib->vba.VMMPageSize = soc->vmm_page_size_bytes; // Set the voltage scaling clocks as the defaults. Most of these will // be set to different values by the test - for (i = 0; i < DC__VOLTAGE_STATES; ++i) + for (i = 0; i < DC__VOLTAGE_STATES; i++) if (soc->clock_limits[i].state == mode_lib->vba.VoltageLevel) break; @@ -353,6 +415,23 @@ static void fetch_socbb_params(struct display_mode_lib *mode_lib) mode_lib->vba.XFCBusTransportTime = soc->xfc_bus_transport_time_us; mode_lib->vba.XFCXBUFLatencyTolerance = soc->xfc_xbuf_latency_tolerance_us; + + mode_lib->vba.SupportGFX7CompatibleTilingIn32bppAnd64bpp = false; + mode_lib->vba.MaxHSCLRatio = 4; + mode_lib->vba.MaxVSCLRatio = 4; + mode_lib->vba.MaxNumWriteback = 0; /*TODO*/ + mode_lib->vba.WritebackLumaAndChromaScalingSupported = true; + mode_lib->vba.Cursor64BppSupport = true; + for (i = 0; i <= DC__VOLTAGE_STATES; i++) { + mode_lib->vba.DCFCLKPerState[i] = soc->clock_limits[i].dcfclk_mhz; + mode_lib->vba.FabricClockPerState[i] = soc->clock_limits[i].fabricclk_mhz; + mode_lib->vba.SOCCLKPerState[i] = soc->clock_limits[i].socclk_mhz; + mode_lib->vba.PHYCLKPerState[i] = soc->clock_limits[i].phyclk_mhz; + mode_lib->vba.MaxDppclk[i] = soc->clock_limits[i].dppclk_mhz; + mode_lib->vba.MaxDSCCLK[i] = soc->clock_limits[i].dscclk_mhz; + mode_lib->vba.DRAMSpeedPerState[i] = soc->clock_limits[i].dram_speed_mhz; + mode_lib->vba.MaxDispclk[i] = soc->clock_limits[i].dispclk_mhz; + } } static void fetch_ip_params(struct display_mode_lib *mode_lib) @@ -360,6 +439,11 @@ static void fetch_ip_params(struct display_mode_lib *mode_lib) ip_params_st *ip = &mode_lib->vba.ip; // IP Parameters + mode_lib->vba.MaxNumDPP = ip->max_num_dpp; + mode_lib->vba.MaxNumOTG = ip->max_num_otg; + mode_lib->vba.CursorChunkSize = ip->cursor_chunk_size; + mode_lib->vba.CursorBufferSize = ip->cursor_buffer_size; + mode_lib->vba.MaxDCHUBToPSCLThroughput = ip->max_dchub_pscl_bw_pix_per_clk; mode_lib->vba.MaxPSCLToLBThroughput = ip->max_pscl_lb_bw_pix_per_clk; mode_lib->vba.ROBBufferSizeInKByte = ip->rob_buffer_size_kbytes; @@ -375,7 +459,8 @@ static void fetch_ip_params(struct display_mode_lib *mode_lib) mode_lib->vba.OPPOutputBufferLines = ip->opp_output_buffer_lines; mode_lib->vba.WritebackInterfaceLumaBufferSize = ip->writeback_luma_buffer_size_kbytes; mode_lib->vba.WritebackInterfaceChromaBufferSize = ip->writeback_chroma_buffer_size_kbytes; - mode_lib->vba.WritebackChromaLineBufferWidth = ip->writeback_chroma_line_buffer_width_pixels; + mode_lib->vba.WritebackChromaLineBufferWidth = + ip->writeback_chroma_line_buffer_width_pixels; mode_lib->vba.MaxPageTableLevels = ip->max_page_table_levels; mode_lib->vba.MaxInterDCNTileRepeaters = ip->max_inter_dcn_tile_repeaters; mode_lib->vba.NumberOfDSC = ip->num_dsc; @@ -402,10 +487,10 @@ static void fetch_pipe_params(struct display_mode_lib *mode_lib) display_e2e_pipe_params_st *pipes = mode_lib->vba.cache_pipes; ip_params_st *ip = &mode_lib->vba.ip; - unsigned int OTGInstPlane[DC__NUM_DPP]; + unsigned int OTGInstPlane[DC__NUM_DPP__MAX]; unsigned int j, k; - bool PlaneVisited[DC__NUM_DPP]; - bool visited[DC__NUM_PIPES__MAX]; + bool PlaneVisited[DC__NUM_DPP__MAX]; + bool visited[DC__NUM_DPP__MAX]; // Convert Pipes to Planes for (k = 0; k < mode_lib->vba.cache_num_pipes; ++k) @@ -427,11 +512,16 @@ static void fetch_pipe_params(struct display_mode_lib *mode_lib) mode_lib->vba.pipe_plane[j] = mode_lib->vba.NumberOfActivePlanes; mode_lib->vba.DPPPerPlane[mode_lib->vba.NumberOfActivePlanes] = 1; - mode_lib->vba.SourceScan[mode_lib->vba.NumberOfActivePlanes] = (enum scan_direction_class)(src->source_scan); - mode_lib->vba.ViewportWidth[mode_lib->vba.NumberOfActivePlanes] = src->viewport_width; - mode_lib->vba.ViewportHeight[mode_lib->vba.NumberOfActivePlanes] = src->viewport_height; - mode_lib->vba.ViewportYStartY[mode_lib->vba.NumberOfActivePlanes] = src->viewport_y_y; - mode_lib->vba.ViewportYStartC[mode_lib->vba.NumberOfActivePlanes] = src->viewport_y_c; + mode_lib->vba.SourceScan[mode_lib->vba.NumberOfActivePlanes] = + (enum scan_direction_class) (src->source_scan); + mode_lib->vba.ViewportWidth[mode_lib->vba.NumberOfActivePlanes] = + src->viewport_width; + mode_lib->vba.ViewportHeight[mode_lib->vba.NumberOfActivePlanes] = + src->viewport_height; + mode_lib->vba.ViewportYStartY[mode_lib->vba.NumberOfActivePlanes] = + src->viewport_y_y; + mode_lib->vba.ViewportYStartC[mode_lib->vba.NumberOfActivePlanes] = + src->viewport_y_c; mode_lib->vba.PitchY[mode_lib->vba.NumberOfActivePlanes] = src->data_pitch; mode_lib->vba.PitchC[mode_lib->vba.NumberOfActivePlanes] = src->data_pitch_c; mode_lib->vba.DCCMetaPitchY[mode_lib->vba.NumberOfActivePlanes] = src->meta_pitch; @@ -448,40 +538,62 @@ static void fetch_pipe_params(struct display_mode_lib *mode_lib) mode_lib->vba.HTotal[mode_lib->vba.NumberOfActivePlanes] = dst->htotal; mode_lib->vba.VTotal[mode_lib->vba.NumberOfActivePlanes] = dst->vtotal; mode_lib->vba.DCCEnable[mode_lib->vba.NumberOfActivePlanes] = - src->dcc_use_global ? ip->dcc_supported : src->dcc & ip->dcc_supported; + src->dcc_use_global ? + ip->dcc_supported : src->dcc && ip->dcc_supported; mode_lib->vba.DCCRate[mode_lib->vba.NumberOfActivePlanes] = src->dcc_rate; - mode_lib->vba.SourcePixelFormat[mode_lib->vba.NumberOfActivePlanes] = (enum source_format_class)(src->source_format); + mode_lib->vba.SourcePixelFormat[mode_lib->vba.NumberOfActivePlanes] = + (enum source_format_class) (src->source_format); mode_lib->vba.HActive[mode_lib->vba.NumberOfActivePlanes] = dst->hactive; mode_lib->vba.VActive[mode_lib->vba.NumberOfActivePlanes] = dst->vactive; - mode_lib->vba.SurfaceTiling[mode_lib->vba.NumberOfActivePlanes] = (enum dm_swizzle_mode)(src->sw_mode); - mode_lib->vba.ScalerRecoutWidth[mode_lib->vba.NumberOfActivePlanes] = dst->recout_width; // TODO: or should this be full_recout_width???...maybe only when in hsplit mode? - mode_lib->vba.ODMCombineEnabled[mode_lib->vba.NumberOfActivePlanes] = dst->odm_combine; - mode_lib->vba.OutputFormat[mode_lib->vba.NumberOfActivePlanes] = (enum output_format_class)(dout->output_format); - mode_lib->vba.Output[mode_lib->vba.NumberOfActivePlanes] = (enum output_encoder_class)(dout->output_type); + mode_lib->vba.SurfaceTiling[mode_lib->vba.NumberOfActivePlanes] = + (enum dm_swizzle_mode) (src->sw_mode); + mode_lib->vba.ScalerRecoutWidth[mode_lib->vba.NumberOfActivePlanes] = + dst->recout_width; // TODO: or should this be full_recout_width???...maybe only when in hsplit mode? + mode_lib->vba.ODMCombineEnabled[mode_lib->vba.NumberOfActivePlanes] = + dst->odm_combine; + mode_lib->vba.OutputFormat[mode_lib->vba.NumberOfActivePlanes] = + (enum output_format_class) (dout->output_format); + mode_lib->vba.Output[mode_lib->vba.NumberOfActivePlanes] = + (enum output_encoder_class) (dout->output_type); mode_lib->vba.OutputBpp[mode_lib->vba.NumberOfActivePlanes] = dout->output_bpp; + mode_lib->vba.OutputLinkDPLanes[mode_lib->vba.NumberOfActivePlanes] = + dout->dp_lanes; mode_lib->vba.DSCEnabled[mode_lib->vba.NumberOfActivePlanes] = dout->dsc_enable; - mode_lib->vba.NumberOfDSCSlices[mode_lib->vba.NumberOfActivePlanes] = dout->dsc_slices; + mode_lib->vba.NumberOfDSCSlices[mode_lib->vba.NumberOfActivePlanes] = + dout->dsc_slices; mode_lib->vba.DSCInputBitPerComponent[mode_lib->vba.NumberOfActivePlanes] = - dout->output_bpc == 0 ? 12 : dout->output_bpc; + dout->output_bpc == 0 ? 12 : dout->output_bpc; mode_lib->vba.WritebackEnable[mode_lib->vba.NumberOfActivePlanes] = dout->wb_enable; - mode_lib->vba.WritebackSourceHeight[mode_lib->vba.NumberOfActivePlanes] = dout->wb.wb_src_height; - mode_lib->vba.WritebackDestinationWidth[mode_lib->vba.NumberOfActivePlanes] = dout->wb.wb_dst_width; - mode_lib->vba.WritebackDestinationHeight[mode_lib->vba.NumberOfActivePlanes] = dout->wb.wb_dst_height; - mode_lib->vba.WritebackPixelFormat[mode_lib->vba.NumberOfActivePlanes] = (enum source_format_class)(dout->wb.wb_pixel_format); - mode_lib->vba.WritebackLumaHTaps[mode_lib->vba.NumberOfActivePlanes] = dout->wb.wb_htaps_luma; - mode_lib->vba.WritebackLumaVTaps[mode_lib->vba.NumberOfActivePlanes] = dout->wb.wb_vtaps_luma; - mode_lib->vba.WritebackChromaHTaps[mode_lib->vba.NumberOfActivePlanes] = dout->wb.wb_htaps_chroma; - mode_lib->vba.WritebackChromaVTaps[mode_lib->vba.NumberOfActivePlanes] = dout->wb.wb_vtaps_chroma; - mode_lib->vba.WritebackHRatio[mode_lib->vba.NumberOfActivePlanes] = dout->wb.wb_hratio; - mode_lib->vba.WritebackVRatio[mode_lib->vba.NumberOfActivePlanes] = dout->wb.wb_vratio; - - mode_lib->vba.DynamicMetadataEnable[mode_lib->vba.NumberOfActivePlanes] = src->dynamic_metadata_enable; + mode_lib->vba.WritebackSourceHeight[mode_lib->vba.NumberOfActivePlanes] = + dout->wb.wb_src_height; + mode_lib->vba.WritebackDestinationWidth[mode_lib->vba.NumberOfActivePlanes] = + dout->wb.wb_dst_width; + mode_lib->vba.WritebackDestinationHeight[mode_lib->vba.NumberOfActivePlanes] = + dout->wb.wb_dst_height; + mode_lib->vba.WritebackPixelFormat[mode_lib->vba.NumberOfActivePlanes] = + (enum source_format_class) (dout->wb.wb_pixel_format); + mode_lib->vba.WritebackLumaHTaps[mode_lib->vba.NumberOfActivePlanes] = + dout->wb.wb_htaps_luma; + mode_lib->vba.WritebackLumaVTaps[mode_lib->vba.NumberOfActivePlanes] = + dout->wb.wb_vtaps_luma; + mode_lib->vba.WritebackChromaHTaps[mode_lib->vba.NumberOfActivePlanes] = + dout->wb.wb_htaps_chroma; + mode_lib->vba.WritebackChromaVTaps[mode_lib->vba.NumberOfActivePlanes] = + dout->wb.wb_vtaps_chroma; + mode_lib->vba.WritebackHRatio[mode_lib->vba.NumberOfActivePlanes] = + dout->wb.wb_hratio; + mode_lib->vba.WritebackVRatio[mode_lib->vba.NumberOfActivePlanes] = + dout->wb.wb_vratio; + + mode_lib->vba.DynamicMetadataEnable[mode_lib->vba.NumberOfActivePlanes] = + src->dynamic_metadata_enable; mode_lib->vba.DynamicMetadataLinesBeforeActiveRequired[mode_lib->vba.NumberOfActivePlanes] = - src->dynamic_metadata_lines_before_active; + src->dynamic_metadata_lines_before_active; mode_lib->vba.DynamicMetadataTransmittedBytes[mode_lib->vba.NumberOfActivePlanes] = - src->dynamic_metadata_xmit_bytes; + src->dynamic_metadata_xmit_bytes; - mode_lib->vba.XFCEnabled[mode_lib->vba.NumberOfActivePlanes] = src->xfc_enable && ip->xfc_supported; + mode_lib->vba.XFCEnabled[mode_lib->vba.NumberOfActivePlanes] = src->xfc_enable + && ip->xfc_supported; mode_lib->vba.XFCSlvChunkSize = src->xfc_params.xfc_slv_chunk_size_bytes; mode_lib->vba.XFCTSlvVupdateOffset = src->xfc_params.xfc_tslv_vupdate_offset_us; mode_lib->vba.XFCTSlvVupdateWidth = src->xfc_params.xfc_tslv_vupdate_width_us; @@ -489,7 +601,8 @@ static void fetch_pipe_params(struct display_mode_lib *mode_lib) mode_lib->vba.PixelClock[mode_lib->vba.NumberOfActivePlanes] = dst->pixel_rate_mhz; mode_lib->vba.DPPCLK[mode_lib->vba.NumberOfActivePlanes] = clks->dppclk_mhz; if (ip->is_line_buffer_bpp_fixed) - mode_lib->vba.LBBitPerPixel[mode_lib->vba.NumberOfActivePlanes] = ip->line_buffer_fixed_bpp; + mode_lib->vba.LBBitPerPixel[mode_lib->vba.NumberOfActivePlanes] = + ip->line_buffer_fixed_bpp; else { unsigned int lb_depth; @@ -520,27 +633,36 @@ static void fetch_pipe_params(struct display_mode_lib *mode_lib) for (k = 0; k < DC__NUM_CURSOR; ++k) { switch (k) { case 0: - mode_lib->vba.CursorBPP[mode_lib->vba.NumberOfActivePlanes][0] = CursorBppEnumToBits((enum cursor_bpp)(src->cur0_bpp)); - mode_lib->vba.CursorWidth[mode_lib->vba.NumberOfActivePlanes][0] = src->cur0_src_width; + mode_lib->vba.CursorBPP[mode_lib->vba.NumberOfActivePlanes][0] = + CursorBppEnumToBits( + (enum cursor_bpp) (src->cur0_bpp)); + mode_lib->vba.CursorWidth[mode_lib->vba.NumberOfActivePlanes][0] = + src->cur0_src_width; if (src->cur0_src_width > 0) mode_lib->vba.NumberOfCursors[mode_lib->vba.NumberOfActivePlanes]++; break; case 1: - mode_lib->vba.CursorBPP[mode_lib->vba.NumberOfActivePlanes][1] = CursorBppEnumToBits((enum cursor_bpp)(src->cur1_bpp)); - mode_lib->vba.CursorWidth[mode_lib->vba.NumberOfActivePlanes][1] = src->cur1_src_width; + mode_lib->vba.CursorBPP[mode_lib->vba.NumberOfActivePlanes][1] = + CursorBppEnumToBits( + (enum cursor_bpp) (src->cur1_bpp)); + mode_lib->vba.CursorWidth[mode_lib->vba.NumberOfActivePlanes][1] = + src->cur1_src_width; if (src->cur1_src_width > 0) mode_lib->vba.NumberOfCursors[mode_lib->vba.NumberOfActivePlanes]++; break; default: - dml_print("ERROR: Number of cursors specified exceeds supported maximum\n"); + dml_print( + "ERROR: Number of cursors specified exceeds supported maximum\n") + ; } } OTGInstPlane[mode_lib->vba.NumberOfActivePlanes] = dst->otg_inst; if (dst->odm_combine && !src->is_hsplit) - dml_print("ERROR: ODM Combine is specified but is_hsplit has not be specified for pipe %i\n", - j); + dml_print( + "ERROR: ODM Combine is specified but is_hsplit has not be specified for pipe %i\n", + j); if (src->is_hsplit) { for (k = j + 1; k < mode_lib->vba.cache_num_pipes; ++k) { @@ -548,18 +670,20 @@ static void fetch_pipe_params(struct display_mode_lib *mode_lib) display_output_params_st *dout_k = &pipes[k].dout; if (src_k->is_hsplit && !visited[k] - && src->hsplit_grp == src_k->hsplit_grp) { - mode_lib->vba.pipe_plane[k] = mode_lib->vba.NumberOfActivePlanes; + && src->hsplit_grp == src_k->hsplit_grp) { + mode_lib->vba.pipe_plane[k] = + mode_lib->vba.NumberOfActivePlanes; mode_lib->vba.DPPPerPlane[mode_lib->vba.NumberOfActivePlanes]++; - if (mode_lib->vba.SourceScan[mode_lib->vba.NumberOfActivePlanes] == dm_horz) + if (mode_lib->vba.SourceScan[mode_lib->vba.NumberOfActivePlanes] + == dm_horz) mode_lib->vba.ViewportWidth[mode_lib->vba.NumberOfActivePlanes] += - src_k->viewport_width; + src_k->viewport_width; else mode_lib->vba.ViewportHeight[mode_lib->vba.NumberOfActivePlanes] += - src_k->viewport_height; + src_k->viewport_height; mode_lib->vba.NumberOfDSCSlices[mode_lib->vba.NumberOfActivePlanes] += - dout_k->dsc_slices; + dout_k->dsc_slices; visited[k] = true; } } @@ -598,26 +722,30 @@ static void fetch_pipe_params(struct display_mode_lib *mode_lib) for (k = 1; k < mode_lib->vba.cache_num_pipes; ++k) ASSERT(mode_lib->vba.SynchronizedVBlank == pipes[k].pipe.dest.synchronized_vblank_all_planes); - mode_lib->vba.VirtualMemoryEnable = 0; + mode_lib->vba.VirtualMemoryEnable = false; mode_lib->vba.OverridePageTableLevels = 0; for (k = 0; k < mode_lib->vba.cache_num_pipes; ++k) { - mode_lib->vba.VirtualMemoryEnable |= pipes[k].pipe.src.vm; + mode_lib->vba.VirtualMemoryEnable = mode_lib->vba.VirtualMemoryEnable + || !!pipes[k].pipe.src.vm; mode_lib->vba.OverridePageTableLevels = - (pipes[k].pipe.src.vm_levels_force_en - && mode_lib->vba.OverridePageTableLevels - < pipes[k].pipe.src.vm_levels_force) ? - pipes[k].pipe.src.vm_levels_force : - mode_lib->vba.OverridePageTableLevels; + (pipes[k].pipe.src.vm_levels_force_en + && mode_lib->vba.OverridePageTableLevels + < pipes[k].pipe.src.vm_levels_force) ? + pipes[k].pipe.src.vm_levels_force : + mode_lib->vba.OverridePageTableLevels; } if (mode_lib->vba.OverridePageTableLevels) mode_lib->vba.MaxPageTableLevels = mode_lib->vba.OverridePageTableLevels; - mode_lib->vba.VirtualMemoryEnable &= ip->pte_enable; + mode_lib->vba.VirtualMemoryEnable = mode_lib->vba.VirtualMemoryEnable && !!ip->pte_enable; - mode_lib->vba.FabricAndDRAMBandwidth = dml_min(mode_lib->vba.DRAMSpeed * mode_lib->vba.NumberOfChannels * mode_lib->vba.DRAMChannelWidth, - mode_lib->vba.FabricClock * mode_lib->vba.FabricDatapathToDCNDataReturn) / 1000.0; + mode_lib->vba.FabricAndDRAMBandwidth = dml_min( + mode_lib->vba.DRAMSpeed * mode_lib->vba.NumberOfChannels + * mode_lib->vba.DRAMChannelWidth, + mode_lib->vba.FabricClock * mode_lib->vba.FabricDatapathToDCNDataReturn) + / 1000.0; // TODO: Must be consistent across all pipes // DCCProgrammingAssumesScanDirectionUnknown = src.dcc_scan_dir_unknown; @@ -633,16 +761,20 @@ static void recalculate(struct display_mode_lib *mode_lib) // in wm mode we pull the parameters needed from the display_e2e_pipe_params_st structs // rather than working them out as in recalculate_ms -static void recalculate_params(struct display_mode_lib *mode_lib, - const display_e2e_pipe_params_st *pipes, - unsigned int num_pipes) +static void recalculate_params( + struct display_mode_lib *mode_lib, + const display_e2e_pipe_params_st *pipes, + unsigned int num_pipes) { // This is only safe to use memcmp because there are non-POD types in struct display_mode_lib if (memcmp(&mode_lib->soc, &mode_lib->vba.soc, sizeof(mode_lib->vba.soc)) != 0 || memcmp(&mode_lib->ip, &mode_lib->vba.ip, sizeof(mode_lib->vba.ip)) != 0 || memcmp(&mode_lib->me, &mode_lib->vba.me, sizeof(mode_lib->vba.me)) != 0 || num_pipes != mode_lib->vba.cache_num_pipes - || memcmp(pipes, mode_lib->vba.cache_pipes, sizeof(display_e2e_pipe_params_st) * num_pipes) != 0) { + || memcmp( + pipes, + mode_lib->vba.cache_pipes, + sizeof(display_e2e_pipe_params_st) * num_pipes) != 0) { mode_lib->vba.soc = mode_lib->soc; mode_lib->vba.ip = mode_lib->ip; mode_lib->vba.me = mode_lib->me; @@ -677,55 +809,70 @@ static void ModeSupportAndSystemConfiguration(struct display_mode_lib *mode_lib) // Total Available Pipes Support Check for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) total_pipes += mode_lib->vba.DPPPerPlane[k]; - ASSERT(total_pipes <= DC__NUM_DPP); + ASSERT(total_pipes <= DC__NUM_DPP__MAX); } -static double adjust_ReturnBW(struct display_mode_lib *mode_lib, double ReturnBW, bool DCCEnabledAnyPlane, double ReturnBandwidthToDCN) +static double adjust_ReturnBW( + struct display_mode_lib *mode_lib, + double ReturnBW, + bool DCCEnabledAnyPlane, + double ReturnBandwidthToDCN) { double CriticalCompression; - if (DCCEnabledAnyPlane && ReturnBandwidthToDCN > mode_lib->vba.DCFCLK * mode_lib->vba.ReturnBusWidth / 4.0) + if (DCCEnabledAnyPlane + && ReturnBandwidthToDCN + > mode_lib->vba.DCFCLK * mode_lib->vba.ReturnBusWidth / 4.0) ReturnBW = - dml_min(ReturnBW, - ReturnBandwidthToDCN * 4 - * (1.0 - - mode_lib->vba.UrgentLatency - / ((mode_lib->vba.ROBBufferSizeInKByte - - mode_lib->vba.PixelChunkSizeInKByte) - * 1024 - / ReturnBandwidthToDCN - - mode_lib->vba.DCFCLK - * mode_lib->vba.ReturnBusWidth - / 4) - + mode_lib->vba.UrgentLatency)); - - CriticalCompression = 2.0 * mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLK * mode_lib->vba.UrgentLatency - / (ReturnBandwidthToDCN * mode_lib->vba.UrgentLatency - + (mode_lib->vba.ROBBufferSizeInKByte - mode_lib->vba.PixelChunkSizeInKByte) * 1024); + dml_min( + ReturnBW, + ReturnBandwidthToDCN * 4 + * (1.0 + - mode_lib->vba.UrgentLatency + / ((mode_lib->vba.ROBBufferSizeInKByte + - mode_lib->vba.PixelChunkSizeInKByte) + * 1024 + / ReturnBandwidthToDCN + - mode_lib->vba.DCFCLK + * mode_lib->vba.ReturnBusWidth + / 4) + + mode_lib->vba.UrgentLatency)); + + CriticalCompression = 2.0 * mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLK + * mode_lib->vba.UrgentLatency + / (ReturnBandwidthToDCN * mode_lib->vba.UrgentLatency + + (mode_lib->vba.ROBBufferSizeInKByte + - mode_lib->vba.PixelChunkSizeInKByte) + * 1024); if (DCCEnabledAnyPlane && CriticalCompression > 1.0 && CriticalCompression < 4.0) ReturnBW = - dml_min(ReturnBW, - 4.0 * ReturnBandwidthToDCN - * (mode_lib->vba.ROBBufferSizeInKByte - - mode_lib->vba.PixelChunkSizeInKByte) - * 1024 * mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLK - * mode_lib->vba.UrgentLatency - / dml_pow((ReturnBandwidthToDCN - * mode_lib->vba.UrgentLatency - + (mode_lib->vba.ROBBufferSizeInKByte - - mode_lib->vba.PixelChunkSizeInKByte) - * 1024), - 2)); + dml_min( + ReturnBW, + 4.0 * ReturnBandwidthToDCN + * (mode_lib->vba.ROBBufferSizeInKByte + - mode_lib->vba.PixelChunkSizeInKByte) + * 1024 + * mode_lib->vba.ReturnBusWidth + * mode_lib->vba.DCFCLK + * mode_lib->vba.UrgentLatency + / dml_pow( + (ReturnBandwidthToDCN + * mode_lib->vba.UrgentLatency + + (mode_lib->vba.ROBBufferSizeInKByte + - mode_lib->vba.PixelChunkSizeInKByte) + * 1024), + 2)); return ReturnBW; } -static unsigned int dscceComputeDelay(unsigned int bpc, - double bpp, - unsigned int sliceWidth, - unsigned int numSlices, - enum output_format_class pixelFormat) +static unsigned int dscceComputeDelay( + unsigned int bpc, + double bpp, + unsigned int sliceWidth, + unsigned int numSlices, + enum output_format_class pixelFormat) { // valid bpc = source bits per component in the set of {8, 10, 12} // valid bpp = increments of 1/16 of a bit @@ -739,12 +886,12 @@ static unsigned int dscceComputeDelay(unsigned int bpc, unsigned int rcModelSize = 8192; // N422/N420 operate at 2 pixels per clock - unsigned int pixelsPerClock, lstall, D, initalXmitDelay, w, s, ix, wx, p, l0, a, ax, l, Delay, - pixels; + unsigned int pixelsPerClock, lstall, D, initalXmitDelay, w, s, ix, wx, p, l0, a, ax, l, + Delay, pixels; if (pixelFormat == dm_n422 || pixelFormat == dm_420) pixelsPerClock = 2; - // #all other modes operate at 1 pixel per clock + // #all other modes operate at 1 pixel per clock else pixelsPerClock = 1; @@ -859,66 +1006,67 @@ static unsigned int dscComputeDelay(enum output_format_class pixelFormat) return Delay; } -static bool CalculatePrefetchSchedule(struct display_mode_lib *mode_lib, - double DPPCLK, - double DISPCLK, - double PixelClock, - double DCFClkDeepSleep, - unsigned int DSCDelay, - unsigned int DPPPerPlane, - bool ScalerEnabled, - unsigned int NumberOfCursors, - double DPPCLKDelaySubtotal, - double DPPCLKDelaySCL, - double DPPCLKDelaySCLLBOnly, - double DPPCLKDelayCNVCFormater, - double DPPCLKDelayCNVCCursor, - double DISPCLKDelaySubtotal, - unsigned int ScalerRecoutWidth, - enum output_format_class OutputFormat, - unsigned int VBlank, - unsigned int HTotal, - unsigned int MaxInterDCNTileRepeaters, - unsigned int VStartup, - unsigned int PageTableLevels, - bool VirtualMemoryEnable, - bool DynamicMetadataEnable, - unsigned int DynamicMetadataLinesBeforeActiveRequired, - unsigned int DynamicMetadataTransmittedBytes, - bool DCCEnable, - double UrgentLatency, - double UrgentExtraLatency, - double TCalc, - unsigned int PDEAndMetaPTEBytesFrame, - unsigned int MetaRowByte, - unsigned int PixelPTEBytesPerRow, - double PrefetchSourceLinesY, - unsigned int SwathWidthY, - double BytePerPixelDETY, - double VInitPreFillY, - unsigned int MaxNumSwathY, - double PrefetchSourceLinesC, - double BytePerPixelDETC, - double VInitPreFillC, - unsigned int MaxNumSwathC, - unsigned int SwathHeightY, - unsigned int SwathHeightC, - double TWait, - bool XFCEnabled, - double XFCRemoteSurfaceFlipDelay, - bool InterlaceEnable, - bool ProgressiveToInterlaceUnitInOPP, - double *DSTXAfterScaler, - double *DSTYAfterScaler, - double *DestinationLinesForPrefetch, - double *PrefetchBandwidth, - double *DestinationLinesToRequestVMInVBlank, - double *DestinationLinesToRequestRowInVBlank, - double *VRatioPrefetchY, - double *VRatioPrefetchC, - double *RequiredPrefetchPixDataBW, - unsigned int *VStartupRequiredWhenNotEnoughTimeForDynamicMetadata, - double *Tno_bw) +static bool CalculatePrefetchSchedule( + struct display_mode_lib *mode_lib, + double DPPCLK, + double DISPCLK, + double PixelClock, + double DCFClkDeepSleep, + unsigned int DSCDelay, + unsigned int DPPPerPlane, + bool ScalerEnabled, + unsigned int NumberOfCursors, + double DPPCLKDelaySubtotal, + double DPPCLKDelaySCL, + double DPPCLKDelaySCLLBOnly, + double DPPCLKDelayCNVCFormater, + double DPPCLKDelayCNVCCursor, + double DISPCLKDelaySubtotal, + unsigned int ScalerRecoutWidth, + enum output_format_class OutputFormat, + unsigned int VBlank, + unsigned int HTotal, + unsigned int MaxInterDCNTileRepeaters, + unsigned int VStartup, + unsigned int PageTableLevels, + bool VirtualMemoryEnable, + bool DynamicMetadataEnable, + unsigned int DynamicMetadataLinesBeforeActiveRequired, + unsigned int DynamicMetadataTransmittedBytes, + bool DCCEnable, + double UrgentLatency, + double UrgentExtraLatency, + double TCalc, + unsigned int PDEAndMetaPTEBytesFrame, + unsigned int MetaRowByte, + unsigned int PixelPTEBytesPerRow, + double PrefetchSourceLinesY, + unsigned int SwathWidthY, + double BytePerPixelDETY, + double VInitPreFillY, + unsigned int MaxNumSwathY, + double PrefetchSourceLinesC, + double BytePerPixelDETC, + double VInitPreFillC, + unsigned int MaxNumSwathC, + unsigned int SwathHeightY, + unsigned int SwathHeightC, + double TWait, + bool XFCEnabled, + double XFCRemoteSurfaceFlipDelay, + bool InterlaceEnable, + bool ProgressiveToInterlaceUnitInOPP, + double *DSTXAfterScaler, + double *DSTYAfterScaler, + double *DestinationLinesForPrefetch, + double *PrefetchBandwidth, + double *DestinationLinesToRequestVMInVBlank, + double *DestinationLinesToRequestRowInVBlank, + double *VRatioPrefetchY, + double *VRatioPrefetchC, + double *RequiredPrefetchPixDataBW, + unsigned int *VStartupRequiredWhenNotEnoughTimeForDynamicMetadata, + double *Tno_bw) { bool MyError = false; unsigned int DPPCycles, DISPCLKCycles, VUpdateOffsetPix, VUpdateWidthPix, VReadyOffsetPix; @@ -948,7 +1096,7 @@ static bool CalculatePrefetchSchedule(struct display_mode_lib *mode_lib, return true; *DSTXAfterScaler = DPPCycles * PixelClock / DPPCLK + DISPCLKCycles * PixelClock / DISPCLK - + DSCDelay; + + DSCDelay; if (DPPPerPlane > 1) *DSTXAfterScaler = *DSTXAfterScaler + ScalerRecoutWidth; @@ -958,22 +1106,23 @@ static bool CalculatePrefetchSchedule(struct display_mode_lib *mode_lib, else *DSTYAfterScaler = 0; - DSTTotalPixelsAfterScaler = ((double)(*DSTYAfterScaler * HTotal)) + *DSTXAfterScaler; + DSTTotalPixelsAfterScaler = ((double) (*DSTYAfterScaler * HTotal)) + *DSTXAfterScaler; *DSTYAfterScaler = dml_floor(DSTTotalPixelsAfterScaler / HTotal, 1); - *DSTXAfterScaler = DSTTotalPixelsAfterScaler - ((double)(*DSTYAfterScaler * HTotal)); + *DSTXAfterScaler = DSTTotalPixelsAfterScaler - ((double) (*DSTYAfterScaler * HTotal)); VUpdateOffsetPix = dml_ceil(HTotal / 4.0, 1); TotalRepeaterDelayTime = MaxInterDCNTileRepeaters * (2.0 / DPPCLK + 3.0 / DISPCLK); VUpdateWidthPix = (14.0 / DCFClkDeepSleep + 12.0 / DPPCLK + TotalRepeaterDelayTime) - * PixelClock; + * PixelClock; - VReadyOffsetPix = dml_max(150.0 / DPPCLK, - TotalRepeaterDelayTime + 20.0 / DCFClkDeepSleep + 10.0 / DPPCLK) - * PixelClock; + VReadyOffsetPix = dml_max( + 150.0 / DPPCLK, + TotalRepeaterDelayTime + 20.0 / DCFClkDeepSleep + 10.0 / DPPCLK) + * PixelClock; - Tsetup = (double)(VUpdateOffsetPix + VUpdateWidthPix + VReadyOffsetPix) / PixelClock; + Tsetup = (double) (VUpdateOffsetPix + VUpdateWidthPix + VReadyOffsetPix) / PixelClock; - LineTime = (double)HTotal / PixelClock; + LineTime = (double) HTotal / PixelClock; if (DynamicMetadataEnable) { double Tdmbf, Tdmec, Tdmsks; @@ -988,10 +1137,10 @@ static bool CalculatePrefetchSchedule(struct display_mode_lib *mode_lib, if (InterlaceEnable && !ProgressiveToInterlaceUnitInOPP) Tdmsks = Tdmsks / 2; if (VStartup * LineTime - < Tsetup + TWait + UrgentExtraLatency + Tdmbf + Tdmec + Tdmsks) { + < Tsetup + TWait + UrgentExtraLatency + Tdmbf + Tdmec + Tdmsks) { MyError = true; *VStartupRequiredWhenNotEnoughTimeForDynamicMetadata = (Tsetup + TWait - + UrgentExtraLatency + Tdmbf + Tdmec + Tdmsks) / LineTime; + + UrgentExtraLatency + Tdmbf + Tdmec + Tdmsks) / LineTime; } else *VStartupRequiredWhenNotEnoughTimeForDynamicMetadata = 0.0; } else @@ -1010,30 +1159,33 @@ static bool CalculatePrefetchSchedule(struct display_mode_lib *mode_lib, *Tno_bw = LineTime / 4; dst_y_prefetch_equ = VStartup - dml_max(TCalc + TWait, XFCRemoteSurfaceFlipDelay) / LineTime - - (Tsetup + Tdm) / LineTime - - (*DSTYAfterScaler + *DSTXAfterScaler / HTotal); + - (Tsetup + Tdm) / LineTime + - (*DSTYAfterScaler + *DSTXAfterScaler / HTotal); Tsw_oto = dml_max(PrefetchSourceLinesY, PrefetchSourceLinesC) * LineTime; prefetch_bw_oto = (MetaRowByte + PixelPTEBytesPerRow - + PrefetchSourceLinesY * SwathWidthY * dml_ceil(BytePerPixelDETY, 1) - + PrefetchSourceLinesC * SwathWidthY / 2 * dml_ceil(BytePerPixelDETC, 2)) - / Tsw_oto; + + PrefetchSourceLinesY * SwathWidthY * dml_ceil(BytePerPixelDETY, 1) + + PrefetchSourceLinesC * SwathWidthY / 2 * dml_ceil(BytePerPixelDETC, 2)) + / Tsw_oto; if (VirtualMemoryEnable == true) { Tvm_oto = - dml_max(*Tno_bw + PDEAndMetaPTEBytesFrame / prefetch_bw_oto, - dml_max(UrgentExtraLatency - + UrgentLatency - * (PageTableLevels - - 1), - LineTime / 4.0)); + dml_max( + *Tno_bw + PDEAndMetaPTEBytesFrame / prefetch_bw_oto, + dml_max( + UrgentExtraLatency + + UrgentLatency + * (PageTableLevels + - 1), + LineTime / 4.0)); } else Tvm_oto = LineTime / 4.0; if ((VirtualMemoryEnable == true || DCCEnable == true)) { - Tr0_oto = dml_max((MetaRowByte + PixelPTEBytesPerRow) / prefetch_bw_oto, - dml_max(UrgentLatency, dml_max(LineTime - Tvm_oto, LineTime / 4))); + Tr0_oto = dml_max( + (MetaRowByte + PixelPTEBytesPerRow) / prefetch_bw_oto, + dml_max(UrgentLatency, dml_max(LineTime - Tvm_oto, LineTime / 4))); } else Tr0_oto = LineTime - Tvm_oto; @@ -1046,7 +1198,8 @@ static bool CalculatePrefetchSchedule(struct display_mode_lib *mode_lib, else *DestinationLinesForPrefetch = dst_y_prefetch_equ; - *DestinationLinesForPrefetch = dml_floor(4.0 * (*DestinationLinesForPrefetch + 0.125), 1) / 4; + *DestinationLinesForPrefetch = dml_floor(4.0 * (*DestinationLinesForPrefetch + 0.125), 1) + / 4; dml_print("DML: VStartup: %d\n", VStartup); dml_print("DML: TCalc: %f\n", TCalc); @@ -1067,21 +1220,23 @@ static bool CalculatePrefetchSchedule(struct display_mode_lib *mode_lib, *RequiredPrefetchPixDataBW = 0; if (*DestinationLinesForPrefetch > 1) { *PrefetchBandwidth = (PDEAndMetaPTEBytesFrame + 2 * MetaRowByte - + 2 * PixelPTEBytesPerRow - + PrefetchSourceLinesY * SwathWidthY * dml_ceil(BytePerPixelDETY, 1) - + PrefetchSourceLinesC * SwathWidthY / 2 - * dml_ceil(BytePerPixelDETC, 2)) - / (*DestinationLinesForPrefetch * LineTime - *Tno_bw); + + 2 * PixelPTEBytesPerRow + + PrefetchSourceLinesY * SwathWidthY * dml_ceil(BytePerPixelDETY, 1) + + PrefetchSourceLinesC * SwathWidthY / 2 + * dml_ceil(BytePerPixelDETC, 2)) + / (*DestinationLinesForPrefetch * LineTime - *Tno_bw); if (VirtualMemoryEnable) { TimeForFetchingMetaPTE = - dml_max(*Tno_bw - + (double)PDEAndMetaPTEBytesFrame - / *PrefetchBandwidth, - dml_max(UrgentExtraLatency - + UrgentLatency - * (PageTableLevels - - 1), - LineTime / 4)); + dml_max( + *Tno_bw + + (double) PDEAndMetaPTEBytesFrame + / *PrefetchBandwidth, + dml_max( + UrgentExtraLatency + + UrgentLatency + * (PageTableLevels + - 1), + LineTime / 4)); } else { if (NumberOfCursors > 0 || XFCEnabled) TimeForFetchingMetaPTE = LineTime / 4; @@ -1091,13 +1246,16 @@ static bool CalculatePrefetchSchedule(struct display_mode_lib *mode_lib, if ((VirtualMemoryEnable == true || DCCEnable == true)) { TimeForFetchingRowInVBlank = - dml_max((MetaRowByte + PixelPTEBytesPerRow) - / *PrefetchBandwidth, - dml_max(UrgentLatency, - dml_max(LineTime - - TimeForFetchingMetaPTE, - LineTime - / 4.0))); + dml_max( + (MetaRowByte + PixelPTEBytesPerRow) + / *PrefetchBandwidth, + dml_max( + UrgentLatency, + dml_max( + LineTime + - TimeForFetchingMetaPTE, + LineTime + / 4.0))); } else { if (NumberOfCursors > 0 || XFCEnabled) TimeForFetchingRowInVBlank = LineTime - TimeForFetchingMetaPTE; @@ -1105,36 +1263,39 @@ static bool CalculatePrefetchSchedule(struct display_mode_lib *mode_lib, TimeForFetchingRowInVBlank = 0.0; } - *DestinationLinesToRequestVMInVBlank = dml_floor(4.0 * (TimeForFetchingMetaPTE / LineTime + 0.125), - 1) / 4.0; + *DestinationLinesToRequestVMInVBlank = dml_floor( + 4.0 * (TimeForFetchingMetaPTE / LineTime + 0.125), + 1) / 4.0; - *DestinationLinesToRequestRowInVBlank = dml_floor(4.0 * (TimeForFetchingRowInVBlank / LineTime + 0.125), - 1) / 4.0; + *DestinationLinesToRequestRowInVBlank = dml_floor( + 4.0 * (TimeForFetchingRowInVBlank / LineTime + 0.125), + 1) / 4.0; LinesToRequestPrefetchPixelData = - *DestinationLinesForPrefetch - - ((NumberOfCursors > 0 || VirtualMemoryEnable - || DCCEnable) ? - (*DestinationLinesToRequestVMInVBlank - + *DestinationLinesToRequestRowInVBlank) : - 0.0); + *DestinationLinesForPrefetch + - ((NumberOfCursors > 0 || VirtualMemoryEnable + || DCCEnable) ? + (*DestinationLinesToRequestVMInVBlank + + *DestinationLinesToRequestRowInVBlank) : + 0.0); if (LinesToRequestPrefetchPixelData > 0) { - *VRatioPrefetchY = (double)PrefetchSourceLinesY - / LinesToRequestPrefetchPixelData; + *VRatioPrefetchY = (double) PrefetchSourceLinesY + / LinesToRequestPrefetchPixelData; *VRatioPrefetchY = dml_max(*VRatioPrefetchY, 1.0); if ((SwathHeightY > 4) && (VInitPreFillY > 3)) { if (LinesToRequestPrefetchPixelData > (VInitPreFillY - 3.0) / 2.0) { *VRatioPrefetchY = - dml_max((double)PrefetchSourceLinesY - / LinesToRequestPrefetchPixelData, - (double)MaxNumSwathY - * SwathHeightY - / (LinesToRequestPrefetchPixelData - - (VInitPreFillY - - 3.0) - / 2.0)); + dml_max( + (double) PrefetchSourceLinesY + / LinesToRequestPrefetchPixelData, + (double) MaxNumSwathY + * SwathHeightY + / (LinesToRequestPrefetchPixelData + - (VInitPreFillY + - 3.0) + / 2.0)); *VRatioPrefetchY = dml_max(*VRatioPrefetchY, 1.0); } else { MyError = true; @@ -1142,20 +1303,21 @@ static bool CalculatePrefetchSchedule(struct display_mode_lib *mode_lib, } } - *VRatioPrefetchC = (double)PrefetchSourceLinesC - / LinesToRequestPrefetchPixelData; + *VRatioPrefetchC = (double) PrefetchSourceLinesC + / LinesToRequestPrefetchPixelData; *VRatioPrefetchC = dml_max(*VRatioPrefetchC, 1.0); if ((SwathHeightC > 4)) { if (LinesToRequestPrefetchPixelData > (VInitPreFillC - 3.0) / 2.0) { *VRatioPrefetchC = - dml_max(*VRatioPrefetchC, - (double)MaxNumSwathC - * SwathHeightC - / (LinesToRequestPrefetchPixelData - - (VInitPreFillC - - 3.0) - / 2.0)); + dml_max( + *VRatioPrefetchC, + (double) MaxNumSwathC + * SwathHeightC + / (LinesToRequestPrefetchPixelData + - (VInitPreFillC + - 3.0) + / 2.0)); *VRatioPrefetchC = dml_max(*VRatioPrefetchC, 1.0); } else { MyError = true; @@ -1164,17 +1326,19 @@ static bool CalculatePrefetchSchedule(struct display_mode_lib *mode_lib, } *RequiredPrefetchPixDataBW = - DPPPerPlane - * ((double)PrefetchSourceLinesY - / LinesToRequestPrefetchPixelData - * dml_ceil(BytePerPixelDETY, - 1) - + (double)PrefetchSourceLinesC - / LinesToRequestPrefetchPixelData - * dml_ceil(BytePerPixelDETC, - 2) - / 2) - * SwathWidthY / LineTime; + DPPPerPlane + * ((double) PrefetchSourceLinesY + / LinesToRequestPrefetchPixelData + * dml_ceil( + BytePerPixelDETY, + 1) + + (double) PrefetchSourceLinesC + / LinesToRequestPrefetchPixelData + * dml_ceil( + BytePerPixelDETC, + 2) + / 2) + * SwathWidthY / LineTime; } else { MyError = true; *VRatioPrefetchY = 0; @@ -1202,25 +1366,26 @@ static bool CalculatePrefetchSchedule(struct display_mode_lib *mode_lib, return MyError; } -static double CeilToDFSGranularity(double Clock, double VCOSpeed) +static double RoundToDFSGranularityUp(double Clock, double VCOSpeed) { return VCOSpeed * 4 / dml_floor(VCOSpeed * 4 / Clock, 1); } -static double FloorToDFSGranularity(double Clock, double VCOSpeed) +static double RoundToDFSGranularityDown(double Clock, double VCOSpeed) { return VCOSpeed * 4 / dml_ceil(VCOSpeed * 4 / Clock, 1); } -static double CalculatePrefetchSourceLines(struct display_mode_lib *mode_lib, - double VRatio, - double vtaps, - bool Interlace, - bool ProgressiveToInterlaceUnitInOPP, - unsigned int SwathHeight, - unsigned int ViewportYStart, - double *VInitPreFill, - unsigned int *MaxNumSwath) +static double CalculatePrefetchSourceLines( + struct display_mode_lib *mode_lib, + double VRatio, + double vtaps, + bool Interlace, + bool ProgressiveToInterlaceUnitInOPP, + unsigned int SwathHeight, + unsigned int ViewportYStart, + double *VInitPreFill, + unsigned int *MaxNumSwath) { unsigned int MaxPartialSwath; @@ -1234,50 +1399,54 @@ static double CalculatePrefetchSourceLines(struct display_mode_lib *mode_lib, *MaxNumSwath = dml_ceil((*VInitPreFill - 1.0) / SwathHeight, 1) + 1.0; if (*VInitPreFill > 1.0) - MaxPartialSwath = (unsigned int)(*VInitPreFill - 2) % SwathHeight; + MaxPartialSwath = (unsigned int) (*VInitPreFill - 2) % SwathHeight; else - MaxPartialSwath = (unsigned int)(*VInitPreFill + SwathHeight - 2) % SwathHeight; + MaxPartialSwath = (unsigned int) (*VInitPreFill + SwathHeight - 2) + % SwathHeight; MaxPartialSwath = dml_max(1U, MaxPartialSwath); } else { if (ViewportYStart != 0) - dml_print("WARNING DML: using viewport y position of 0 even though actual viewport y position is non-zero in prefetch source lines calculation\n"); + dml_print( + "WARNING DML: using viewport y position of 0 even though actual viewport y position is non-zero in prefetch source lines calculation\n"); *MaxNumSwath = dml_ceil(*VInitPreFill / SwathHeight, 1); if (*VInitPreFill > 1.0) - MaxPartialSwath = (unsigned int)(*VInitPreFill - 1) % SwathHeight; + MaxPartialSwath = (unsigned int) (*VInitPreFill - 1) % SwathHeight; else - MaxPartialSwath = (unsigned int)(*VInitPreFill + SwathHeight - 1) % SwathHeight; + MaxPartialSwath = (unsigned int) (*VInitPreFill + SwathHeight - 1) + % SwathHeight; } return *MaxNumSwath * SwathHeight + MaxPartialSwath; } -static unsigned int CalculateVMAndRowBytes(struct display_mode_lib *mode_lib, - bool DCCEnable, - unsigned int BlockHeight256Bytes, - unsigned int BlockWidth256Bytes, - enum source_format_class SourcePixelFormat, - unsigned int SurfaceTiling, - unsigned int BytePerPixel, - enum scan_direction_class ScanDirection, - unsigned int ViewportWidth, - unsigned int ViewportHeight, - unsigned int SwathWidth, - bool VirtualMemoryEnable, - unsigned int VMMPageSize, - unsigned int PTEBufferSizeInRequests, - unsigned int PDEProcessingBufIn64KBReqs, - unsigned int Pitch, - unsigned int DCCMetaPitch, - unsigned int *MacroTileWidth, - unsigned int *MetaRowByte, - unsigned int *PixelPTEBytesPerRow, - bool *PTEBufferSizeNotExceeded, - unsigned int *dpte_row_height, - unsigned int *meta_row_height) +static unsigned int CalculateVMAndRowBytes( + struct display_mode_lib *mode_lib, + bool DCCEnable, + unsigned int BlockHeight256Bytes, + unsigned int BlockWidth256Bytes, + enum source_format_class SourcePixelFormat, + unsigned int SurfaceTiling, + unsigned int BytePerPixel, + enum scan_direction_class ScanDirection, + unsigned int ViewportWidth, + unsigned int ViewportHeight, + unsigned int SwathWidth, + bool VirtualMemoryEnable, + unsigned int VMMPageSize, + unsigned int PTEBufferSizeInRequests, + unsigned int PDEProcessingBufIn64KBReqs, + unsigned int Pitch, + unsigned int DCCMetaPitch, + unsigned int *MacroTileWidth, + unsigned int *MetaRowByte, + unsigned int *PixelPTEBytesPerRow, + bool *PTEBufferSizeNotExceeded, + unsigned int *dpte_row_height, + unsigned int *meta_row_height) { unsigned int MetaRequestHeight; unsigned int MetaRequestWidth; @@ -1298,31 +1467,33 @@ static unsigned int CalculateVMAndRowBytes(struct display_mode_lib *mode_lib, MetaRequestWidth = 8 * BlockWidth256Bytes; if (ScanDirection == dm_horz) { *meta_row_height = MetaRequestHeight; - MetaSurfWidth = dml_ceil((double)SwathWidth - 1, MetaRequestWidth) - + MetaRequestWidth; + MetaSurfWidth = dml_ceil((double) SwathWidth - 1, MetaRequestWidth) + + MetaRequestWidth; *MetaRowByte = MetaSurfWidth * MetaRequestHeight * BytePerPixel / 256.0; } else { *meta_row_height = MetaRequestWidth; - MetaSurfHeight = dml_ceil((double)SwathWidth - 1, MetaRequestHeight) - + MetaRequestHeight; + MetaSurfHeight = dml_ceil((double) SwathWidth - 1, MetaRequestHeight) + + MetaRequestHeight; *MetaRowByte = MetaSurfHeight * MetaRequestWidth * BytePerPixel / 256.0; } if (ScanDirection == dm_horz) { DCCMetaSurfaceBytes = DCCMetaPitch - * (dml_ceil(ViewportHeight - 1, 64 * BlockHeight256Bytes) - + 64 * BlockHeight256Bytes) * BytePerPixel - / 256; + * (dml_ceil(ViewportHeight - 1, 64 * BlockHeight256Bytes) + + 64 * BlockHeight256Bytes) * BytePerPixel + / 256; } else { DCCMetaSurfaceBytes = DCCMetaPitch - * (dml_ceil((double)ViewportHeight - 1, - 64 * BlockHeight256Bytes) - + 64 * BlockHeight256Bytes) * BytePerPixel - / 256; + * (dml_ceil( + (double) ViewportHeight - 1, + 64 * BlockHeight256Bytes) + + 64 * BlockHeight256Bytes) * BytePerPixel + / 256; } if (VirtualMemoryEnable == true) { - MetaPTEBytesFrame = (dml_ceil((double)(DCCMetaSurfaceBytes - VMMPageSize) - / (8 * VMMPageSize), - 1) + 1) * 64; + MetaPTEBytesFrame = (dml_ceil( + (double) (DCCMetaSurfaceBytes - VMMPageSize) + / (8 * VMMPageSize), + 1) + 1) * 64; MPDEBytesFrame = 128 * (mode_lib->vba.MaxPageTableLevels - 1); } else { MetaPTEBytesFrame = 0; @@ -1338,13 +1509,13 @@ static unsigned int CalculateVMAndRowBytes(struct display_mode_lib *mode_lib, MacroTileSizeBytes = 256; MacroTileHeight = 1; } else if (SurfaceTiling == dm_sw_4kb_s || SurfaceTiling == dm_sw_4kb_s_x - || SurfaceTiling == dm_sw_4kb_d || SurfaceTiling == dm_sw_4kb_d_x) { + || SurfaceTiling == dm_sw_4kb_d || SurfaceTiling == dm_sw_4kb_d_x) { MacroTileSizeBytes = 4096; MacroTileHeight = 4 * BlockHeight256Bytes; } else if (SurfaceTiling == dm_sw_64kb_s || SurfaceTiling == dm_sw_64kb_s_t - || SurfaceTiling == dm_sw_64kb_s_x || SurfaceTiling == dm_sw_64kb_d - || SurfaceTiling == dm_sw_64kb_d_t || SurfaceTiling == dm_sw_64kb_d_x - || SurfaceTiling == dm_sw_64kb_r_x) { + || SurfaceTiling == dm_sw_64kb_s_x || SurfaceTiling == dm_sw_64kb_d + || SurfaceTiling == dm_sw_64kb_d_t || SurfaceTiling == dm_sw_64kb_d_x + || SurfaceTiling == dm_sw_64kb_r_x) { MacroTileSizeBytes = 65536; MacroTileHeight = 16 * BlockHeight256Bytes; } else { @@ -1356,30 +1527,34 @@ static unsigned int CalculateVMAndRowBytes(struct display_mode_lib *mode_lib, if (VirtualMemoryEnable == true && mode_lib->vba.MaxPageTableLevels > 1) { if (ScanDirection == dm_horz) { DPDE0BytesFrame = - 64 - * (dml_ceil(((Pitch - * (dml_ceil(ViewportHeight - - 1, - MacroTileHeight) - + MacroTileHeight) - * BytePerPixel) - - MacroTileSizeBytes) - / (8 - * 2097152), - 1) + 1); + 64 + * (dml_ceil( + ((Pitch + * (dml_ceil( + ViewportHeight + - 1, + MacroTileHeight) + + MacroTileHeight) + * BytePerPixel) + - MacroTileSizeBytes) + / (8 + * 2097152), + 1) + 1); } else { DPDE0BytesFrame = - 64 - * (dml_ceil(((Pitch - * (dml_ceil((double)SwathWidth - - 1, - MacroTileHeight) - + MacroTileHeight) - * BytePerPixel) - - MacroTileSizeBytes) - / (8 - * 2097152), - 1) + 1); + 64 + * (dml_ceil( + ((Pitch + * (dml_ceil( + (double) SwathWidth + - 1, + MacroTileHeight) + + MacroTileHeight) + * BytePerPixel) + - MacroTileSizeBytes) + / (8 + * 2097152), + 1) + 1); } ExtraDPDEBytesFrame = 128 * (mode_lib->vba.MaxPageTableLevels - 2); } else { @@ -1388,7 +1563,7 @@ static unsigned int CalculateVMAndRowBytes(struct display_mode_lib *mode_lib, } PDEAndMetaPTEBytesFrame = MetaPTEBytesFrame + MPDEBytesFrame + DPDE0BytesFrame - + ExtraDPDEBytesFrame; + + ExtraDPDEBytesFrame; if (VirtualMemoryEnable == true) { unsigned int PTERequestSize; @@ -1429,33 +1604,39 @@ static unsigned int CalculateVMAndRowBytes(struct display_mode_lib *mode_lib, if (SurfaceTiling == dm_sw_linear) { *dpte_row_height = - dml_min(128, - 1 - << (unsigned int)dml_floor(dml_log2(dml_min((double)PTEBufferSizeInRequests - * PixelPTEReqWidth, - EffectivePDEProcessingBufIn64KBReqs - * 65536.0 - / BytePerPixel) - / Pitch), - 1)); + dml_min( + 128, + 1 + << (unsigned int) dml_floor( + dml_log2( + dml_min( + (double) PTEBufferSizeInRequests + * PixelPTEReqWidth, + EffectivePDEProcessingBufIn64KBReqs + * 65536.0 + / BytePerPixel) + / Pitch), + 1)); *PixelPTEBytesPerRow = PTERequestSize - * (dml_ceil((double)(Pitch * *dpte_row_height - 1) - / PixelPTEReqWidth, - 1) + 1); + * (dml_ceil( + (double) (Pitch * *dpte_row_height - 1) + / PixelPTEReqWidth, + 1) + 1); } else if (ScanDirection == dm_horz) { *dpte_row_height = PixelPTEReqHeight; *PixelPTEBytesPerRow = PTERequestSize - * (dml_ceil(((double)SwathWidth - 1) / PixelPTEReqWidth, 1) - + 1); + * (dml_ceil(((double) SwathWidth - 1) / PixelPTEReqWidth, 1) + + 1); } else { *dpte_row_height = dml_min(PixelPTEReqWidth, *MacroTileWidth); *PixelPTEBytesPerRow = PTERequestSize - * (dml_ceil(((double)SwathWidth - 1) - / PixelPTEReqHeight, - 1) + 1); + * (dml_ceil( + ((double) SwathWidth - 1) + / PixelPTEReqHeight, + 1) + 1); } if (*PixelPTEBytesPerRow * (1 - FractionOfPTEReturnDrop) - <= 64 * PTEBufferSizeInRequests) { + <= 64 * PTEBufferSizeInRequests) { *PTEBufferSizeNotExceeded = true; } else { *PTEBufferSizeNotExceeded = false; @@ -1468,7 +1649,8 @@ static unsigned int CalculateVMAndRowBytes(struct display_mode_lib *mode_lib, return PDEAndMetaPTEBytesFrame; } -static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation(struct display_mode_lib *mode_lib) +static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation( + struct display_mode_lib *mode_lib) { unsigned int j, k; @@ -1481,81 +1663,107 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman // for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { if (mode_lib->vba.WritebackEnable[k]) { - mode_lib->vba.WritebackDISPCLK = dml_max(mode_lib->vba.WritebackDISPCLK, - CalculateWriteBackDISPCLK(mode_lib->vba.WritebackPixelFormat[k], - mode_lib->vba.PixelClock[k], - mode_lib->vba.WritebackHRatio[k], - mode_lib->vba.WritebackVRatio[k], - mode_lib->vba.WritebackLumaHTaps[k], - mode_lib->vba.WritebackLumaVTaps[k], - mode_lib->vba.WritebackChromaHTaps[k], - mode_lib->vba.WritebackChromaVTaps[k], - mode_lib->vba.WritebackDestinationWidth[k], - mode_lib->vba.HTotal[k], - mode_lib->vba.WritebackChromaLineBufferWidth)); + mode_lib->vba.WritebackDISPCLK = + dml_max( + mode_lib->vba.WritebackDISPCLK, + CalculateWriteBackDISPCLK( + mode_lib->vba.WritebackPixelFormat[k], + mode_lib->vba.PixelClock[k], + mode_lib->vba.WritebackHRatio[k], + mode_lib->vba.WritebackVRatio[k], + mode_lib->vba.WritebackLumaHTaps[k], + mode_lib->vba.WritebackLumaVTaps[k], + mode_lib->vba.WritebackChromaHTaps[k], + mode_lib->vba.WritebackChromaVTaps[k], + mode_lib->vba.WritebackDestinationWidth[k], + mode_lib->vba.HTotal[k], + mode_lib->vba.WritebackChromaLineBufferWidth)); } } for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { if (mode_lib->vba.HRatio[k] > 1) { - mode_lib->vba.PSCL_THROUGHPUT_LUMA[k] = dml_min(mode_lib->vba.MaxDCHUBToPSCLThroughput, - mode_lib->vba.MaxPSCLToLBThroughput * mode_lib->vba.HRatio[k] - / dml_ceil(mode_lib->vba.htaps[k] / 6.0, 1)); + mode_lib->vba.PSCL_THROUGHPUT_LUMA[k] = dml_min( + mode_lib->vba.MaxDCHUBToPSCLThroughput, + mode_lib->vba.MaxPSCLToLBThroughput + * mode_lib->vba.HRatio[k] + / dml_ceil( + mode_lib->vba.htaps[k] + / 6.0, + 1)); } else { - mode_lib->vba.PSCL_THROUGHPUT_LUMA[k] = dml_min(mode_lib->vba.MaxDCHUBToPSCLThroughput, - mode_lib->vba.MaxPSCLToLBThroughput); + mode_lib->vba.PSCL_THROUGHPUT_LUMA[k] = dml_min( + mode_lib->vba.MaxDCHUBToPSCLThroughput, + mode_lib->vba.MaxPSCLToLBThroughput); } mode_lib->vba.DPPCLKUsingSingleDPPLuma = - mode_lib->vba.PixelClock[k] - * dml_max(mode_lib->vba.vtaps[k] / 6.0 - * dml_min(1.0, - mode_lib->vba.HRatio[k]), - dml_max(mode_lib->vba.HRatio[k] - * mode_lib->vba.VRatio[k] - / mode_lib->vba.PSCL_THROUGHPUT_LUMA[k], - 1.0)); + mode_lib->vba.PixelClock[k] + * dml_max( + mode_lib->vba.vtaps[k] / 6.0 + * dml_min( + 1.0, + mode_lib->vba.HRatio[k]), + dml_max( + mode_lib->vba.HRatio[k] + * mode_lib->vba.VRatio[k] + / mode_lib->vba.PSCL_THROUGHPUT_LUMA[k], + 1.0)); if ((mode_lib->vba.htaps[k] > 6 || mode_lib->vba.vtaps[k] > 6) - && mode_lib->vba.DPPCLKUsingSingleDPPLuma < 2 * mode_lib->vba.PixelClock[k]) { + && mode_lib->vba.DPPCLKUsingSingleDPPLuma + < 2 * mode_lib->vba.PixelClock[k]) { mode_lib->vba.DPPCLKUsingSingleDPPLuma = 2 * mode_lib->vba.PixelClock[k]; } - if ((mode_lib->vba.SourcePixelFormat[k] != dm_420_8 && mode_lib->vba.SourcePixelFormat[k] != dm_420_10)) { + if ((mode_lib->vba.SourcePixelFormat[k] != dm_420_8 + && mode_lib->vba.SourcePixelFormat[k] != dm_420_10)) { mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k] = 0.0; - mode_lib->vba.DPPCLKUsingSingleDPP[k] = mode_lib->vba.DPPCLKUsingSingleDPPLuma; + mode_lib->vba.DPPCLKUsingSingleDPP[k] = + mode_lib->vba.DPPCLKUsingSingleDPPLuma; } else { if (mode_lib->vba.HRatio[k] > 1) { mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k] = - dml_min(mode_lib->vba.MaxDCHUBToPSCLThroughput, - mode_lib->vba.MaxPSCLToLBThroughput * mode_lib->vba.HRatio[k] - / 2 - / dml_ceil(mode_lib->vba.HTAPsChroma[k] - / 6.0, - 1.0)); + dml_min( + mode_lib->vba.MaxDCHUBToPSCLThroughput, + mode_lib->vba.MaxPSCLToLBThroughput + * mode_lib->vba.HRatio[k] + / 2 + / dml_ceil( + mode_lib->vba.HTAPsChroma[k] + / 6.0, + 1.0)); } else { - mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k] = dml_min(mode_lib->vba.MaxDCHUBToPSCLThroughput, - mode_lib->vba.MaxPSCLToLBThroughput); + mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k] = dml_min( + mode_lib->vba.MaxDCHUBToPSCLThroughput, + mode_lib->vba.MaxPSCLToLBThroughput); } mode_lib->vba.DPPCLKUsingSingleDPPChroma = - mode_lib->vba.PixelClock[k] - * dml_max(mode_lib->vba.VTAPsChroma[k] / 6.0 - * dml_min(1.0, - mode_lib->vba.HRatio[k] - / 2), - dml_max(mode_lib->vba.HRatio[k] - * mode_lib->vba.VRatio[k] - / 4 - / mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k], - 1.0)); + mode_lib->vba.PixelClock[k] + * dml_max( + mode_lib->vba.VTAPsChroma[k] + / 6.0 + * dml_min( + 1.0, + mode_lib->vba.HRatio[k] + / 2), + dml_max( + mode_lib->vba.HRatio[k] + * mode_lib->vba.VRatio[k] + / 4 + / mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k], + 1.0)); if ((mode_lib->vba.HTAPsChroma[k] > 6 || mode_lib->vba.VTAPsChroma[k] > 6) - && mode_lib->vba.DPPCLKUsingSingleDPPChroma < 2 * mode_lib->vba.PixelClock[k]) { - mode_lib->vba.DPPCLKUsingSingleDPPChroma = 2 * mode_lib->vba.PixelClock[k]; + && mode_lib->vba.DPPCLKUsingSingleDPPChroma + < 2 * mode_lib->vba.PixelClock[k]) { + mode_lib->vba.DPPCLKUsingSingleDPPChroma = 2 + * mode_lib->vba.PixelClock[k]; } - mode_lib->vba.DPPCLKUsingSingleDPP[k] = dml_max(mode_lib->vba.DPPCLKUsingSingleDPPLuma, - mode_lib->vba.DPPCLKUsingSingleDPPChroma); + mode_lib->vba.DPPCLKUsingSingleDPP[k] = dml_max( + mode_lib->vba.DPPCLKUsingSingleDPPLuma, + mode_lib->vba.DPPCLKUsingSingleDPPChroma); } } @@ -1564,67 +1772,90 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman continue; if (mode_lib->vba.ODMCombineEnabled[k]) { mode_lib->vba.DISPCLKWithRamping = - dml_max(mode_lib->vba.DISPCLKWithRamping, - mode_lib->vba.PixelClock[k] / 2 - * (1 - + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading - / 100) - * (1 - + mode_lib->vba.DISPCLKRampingMargin - / 100)); + dml_max( + mode_lib->vba.DISPCLKWithRamping, + mode_lib->vba.PixelClock[k] / 2 + * (1 + + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading + / 100) + * (1 + + mode_lib->vba.DISPCLKRampingMargin + / 100)); mode_lib->vba.DISPCLKWithoutRamping = - dml_max(mode_lib->vba.DISPCLKWithoutRamping, - mode_lib->vba.PixelClock[k] / 2 - * (1 - + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading - / 100)); + dml_max( + mode_lib->vba.DISPCLKWithoutRamping, + mode_lib->vba.PixelClock[k] / 2 + * (1 + + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading + / 100)); } else if (!mode_lib->vba.ODMCombineEnabled[k]) { - mode_lib->vba.DISPCLKWithRamping = dml_max(mode_lib->vba.DISPCLKWithRamping, - mode_lib->vba.PixelClock[k] * (1 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100) - * (1 + mode_lib->vba.DISPCLKRampingMargin / 100)); + mode_lib->vba.DISPCLKWithRamping = + dml_max( + mode_lib->vba.DISPCLKWithRamping, + mode_lib->vba.PixelClock[k] + * (1 + + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading + / 100) + * (1 + + mode_lib->vba.DISPCLKRampingMargin + / 100)); mode_lib->vba.DISPCLKWithoutRamping = - dml_max(mode_lib->vba.DISPCLKWithoutRamping, - mode_lib->vba.PixelClock[k] - * (1 - + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading - / 100)); + dml_max( + mode_lib->vba.DISPCLKWithoutRamping, + mode_lib->vba.PixelClock[k] + * (1 + + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading + / 100)); } } - mode_lib->vba.DISPCLKWithRamping = dml_max(mode_lib->vba.DISPCLKWithRamping, mode_lib->vba.WritebackDISPCLK); - mode_lib->vba.DISPCLKWithoutRamping = dml_max(mode_lib->vba.DISPCLKWithoutRamping, mode_lib->vba.WritebackDISPCLK); + mode_lib->vba.DISPCLKWithRamping = dml_max( + mode_lib->vba.DISPCLKWithRamping, + mode_lib->vba.WritebackDISPCLK); + mode_lib->vba.DISPCLKWithoutRamping = dml_max( + mode_lib->vba.DISPCLKWithoutRamping, + mode_lib->vba.WritebackDISPCLK); - mode_lib->vba.MaxDispclk = mode_lib->vba.soc.clock_limits[NumberOfStates - 1].dispclk_mhz; ASSERT(mode_lib->vba.DISPCLKDPPCLKVCOSpeed != 0); - mode_lib->vba.DISPCLKWithRampingRoundedToDFSGranularity = CeilToDFSGranularity( + mode_lib->vba.DISPCLKWithRampingRoundedToDFSGranularity = RoundToDFSGranularityUp( mode_lib->vba.DISPCLKWithRamping, mode_lib->vba.DISPCLKDPPCLKVCOSpeed); - mode_lib->vba.DISPCLKWithoutRampingRoundedToDFSGranularity = CeilToDFSGranularity( + mode_lib->vba.DISPCLKWithoutRampingRoundedToDFSGranularity = RoundToDFSGranularityUp( mode_lib->vba.DISPCLKWithoutRamping, mode_lib->vba.DISPCLKDPPCLKVCOSpeed); - mode_lib->vba.MaxDispclkRoundedToDFSGranularity = FloorToDFSGranularity( - mode_lib->vba.MaxDispclk, + mode_lib->vba.MaxDispclkRoundedToDFSGranularity = RoundToDFSGranularityDown( + mode_lib->vba.soc.clock_limits[NumberOfStates - 1].dispclk_mhz, mode_lib->vba.DISPCLKDPPCLKVCOSpeed); if (mode_lib->vba.DISPCLKWithoutRampingRoundedToDFSGranularity - > mode_lib->vba.MaxDispclkRoundedToDFSGranularity) { - mode_lib->vba.DISPCLK_calculated = mode_lib->vba.DISPCLKWithoutRampingRoundedToDFSGranularity; + > mode_lib->vba.MaxDispclkRoundedToDFSGranularity) { + mode_lib->vba.DISPCLK_calculated = + mode_lib->vba.DISPCLKWithoutRampingRoundedToDFSGranularity; } else if (mode_lib->vba.DISPCLKWithRampingRoundedToDFSGranularity - > mode_lib->vba.MaxDispclkRoundedToDFSGranularity) { + > mode_lib->vba.MaxDispclkRoundedToDFSGranularity) { mode_lib->vba.DISPCLK_calculated = mode_lib->vba.MaxDispclkRoundedToDFSGranularity; } else { - mode_lib->vba.DISPCLK_calculated = mode_lib->vba.DISPCLKWithRampingRoundedToDFSGranularity; + mode_lib->vba.DISPCLK_calculated = + mode_lib->vba.DISPCLKWithRampingRoundedToDFSGranularity; } DTRACE(" dispclk_mhz (calculated) = %f", mode_lib->vba.DISPCLK_calculated); for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { - mode_lib->vba.DPPCLK_calculated[k] = mode_lib->vba.DPPCLKUsingSingleDPP[k] / mode_lib->vba.DPPPerPlane[k] - * (1 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100); - mode_lib->vba.GlobalDPPCLK = dml_max(mode_lib->vba.GlobalDPPCLK, mode_lib->vba.DPPCLK_calculated[k]); + mode_lib->vba.DPPCLK_calculated[k] = mode_lib->vba.DPPCLKUsingSingleDPP[k] + / mode_lib->vba.DPPPerPlane[k] + * (1 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100); + mode_lib->vba.GlobalDPPCLK = dml_max( + mode_lib->vba.GlobalDPPCLK, + mode_lib->vba.DPPCLK_calculated[k]); } - mode_lib->vba.GlobalDPPCLK = CeilToDFSGranularity(mode_lib->vba.GlobalDPPCLK, mode_lib->vba.DISPCLKDPPCLKVCOSpeed); + mode_lib->vba.GlobalDPPCLK = RoundToDFSGranularityUp( + mode_lib->vba.GlobalDPPCLK, + mode_lib->vba.DISPCLKDPPCLKVCOSpeed); for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { mode_lib->vba.DPPCLK_calculated[k] = mode_lib->vba.GlobalDPPCLK / 255 - * dml_ceil(mode_lib->vba.DPPCLK_calculated[k] * 255 / mode_lib->vba.GlobalDPPCLK, 1); + * dml_ceil( + mode_lib->vba.DPPCLK_calculated[k] * 255 + / mode_lib->vba.GlobalDPPCLK, + 1); DTRACE(" dppclk_mhz[%i] (calculated) = %f", k, mode_lib->vba.DPPCLK_calculated[k]); } @@ -1634,15 +1865,27 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman if (mode_lib->vba.DCCEnable[k]) mode_lib->vba.DCCEnabledAnyPlane = true; - mode_lib->vba.ReturnBandwidthToDCN = dml_min(mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLK, mode_lib->vba.FabricAndDRAMBandwidth * 1000) - * mode_lib->vba.PercentOfIdealDRAMAndFabricBWReceivedAfterUrgLatency / 100; + mode_lib->vba.ReturnBandwidthToDCN = dml_min( + mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLK, + mode_lib->vba.FabricAndDRAMBandwidth * 1000) + * mode_lib->vba.PercentOfIdealDRAMAndFabricBWReceivedAfterUrgLatency / 100; mode_lib->vba.ReturnBW = mode_lib->vba.ReturnBandwidthToDCN; - mode_lib->vba.ReturnBW = adjust_ReturnBW(mode_lib, mode_lib->vba.ReturnBW, mode_lib->vba.DCCEnabledAnyPlane, mode_lib->vba.ReturnBandwidthToDCN); + mode_lib->vba.ReturnBW = adjust_ReturnBW( + mode_lib, + mode_lib->vba.ReturnBW, + mode_lib->vba.DCCEnabledAnyPlane, + mode_lib->vba.ReturnBandwidthToDCN); // Let's do this calculation again?? - mode_lib->vba.ReturnBandwidthToDCN = dml_min(mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLK, mode_lib->vba.FabricAndDRAMBandwidth * 1000); - mode_lib->vba.ReturnBW = adjust_ReturnBW(mode_lib, mode_lib->vba.ReturnBW, mode_lib->vba.DCCEnabledAnyPlane, mode_lib->vba.ReturnBandwidthToDCN); + mode_lib->vba.ReturnBandwidthToDCN = dml_min( + mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLK, + mode_lib->vba.FabricAndDRAMBandwidth * 1000); + mode_lib->vba.ReturnBW = adjust_ReturnBW( + mode_lib, + mode_lib->vba.ReturnBW, + mode_lib->vba.DCCEnabledAnyPlane, + mode_lib->vba.ReturnBandwidthToDCN); DTRACE(" dcfclk_mhz = %f", mode_lib->vba.DCFCLK); DTRACE(" return_bw_to_dcn = %f", mode_lib->vba.ReturnBandwidthToDCN); @@ -1659,14 +1902,19 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman if (mode_lib->vba.ODMCombineEnabled[k] == true) MainPlaneDoesODMCombine = true; for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) - if (mode_lib->vba.BlendingAndTiming[k] == j && mode_lib->vba.ODMCombineEnabled[j] == true) + if (mode_lib->vba.BlendingAndTiming[k] == j + && mode_lib->vba.ODMCombineEnabled[j] == true) MainPlaneDoesODMCombine = true; if (MainPlaneDoesODMCombine == true) - mode_lib->vba.SwathWidthY[k] = dml_min((double)mode_lib->vba.SwathWidthSingleDPPY[k], - dml_round(mode_lib->vba.HActive[k] / 2.0 * mode_lib->vba.HRatio[k])); + mode_lib->vba.SwathWidthY[k] = dml_min( + (double) mode_lib->vba.SwathWidthSingleDPPY[k], + dml_round( + mode_lib->vba.HActive[k] / 2.0 + * mode_lib->vba.HRatio[k])); else - mode_lib->vba.SwathWidthY[k] = mode_lib->vba.SwathWidthSingleDPPY[k] / mode_lib->vba.DPPPerPlane[k]; + mode_lib->vba.SwathWidthY[k] = mode_lib->vba.SwathWidthSingleDPPY[k] + / mode_lib->vba.DPPPerPlane[k]; } for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { @@ -1694,76 +1942,104 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman mode_lib->vba.TotalDataReadBandwidth = 0.0; for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { mode_lib->vba.ReadBandwidthPlaneLuma[k] = mode_lib->vba.SwathWidthSingleDPPY[k] - * dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1) / (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]) - * mode_lib->vba.VRatio[k]; - mode_lib->vba.ReadBandwidthPlaneChroma[k] = mode_lib->vba.SwathWidthSingleDPPY[k] / 2 - * dml_ceil(mode_lib->vba.BytePerPixelDETC[k], 2) / (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]) - * mode_lib->vba.VRatio[k] / 2; - DTRACE(" read_bw[%i] = %fBps", - k, - mode_lib->vba.ReadBandwidthPlaneLuma[k] + mode_lib->vba.ReadBandwidthPlaneChroma[k]); + * dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1) + / (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]) + * mode_lib->vba.VRatio[k]; + mode_lib->vba.ReadBandwidthPlaneChroma[k] = mode_lib->vba.SwathWidthSingleDPPY[k] + / 2 * dml_ceil(mode_lib->vba.BytePerPixelDETC[k], 2) + / (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]) + * mode_lib->vba.VRatio[k] / 2; + DTRACE( + " read_bw[%i] = %fBps", + k, + mode_lib->vba.ReadBandwidthPlaneLuma[k] + + mode_lib->vba.ReadBandwidthPlaneChroma[k]); mode_lib->vba.TotalDataReadBandwidth += mode_lib->vba.ReadBandwidthPlaneLuma[k] - + mode_lib->vba.ReadBandwidthPlaneChroma[k]; + + mode_lib->vba.ReadBandwidthPlaneChroma[k]; } mode_lib->vba.TotalDCCActiveDPP = 0; mode_lib->vba.TotalActiveDPP = 0; for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { - mode_lib->vba.TotalActiveDPP = mode_lib->vba.TotalActiveDPP + mode_lib->vba.DPPPerPlane[k]; + mode_lib->vba.TotalActiveDPP = mode_lib->vba.TotalActiveDPP + + mode_lib->vba.DPPPerPlane[k]; if (mode_lib->vba.DCCEnable[k]) - mode_lib->vba.TotalDCCActiveDPP = mode_lib->vba.TotalDCCActiveDPP + mode_lib->vba.DPPPerPlane[k]; + mode_lib->vba.TotalDCCActiveDPP = mode_lib->vba.TotalDCCActiveDPP + + mode_lib->vba.DPPPerPlane[k]; } - mode_lib->vba.UrgentRoundTripAndOutOfOrderLatency = (mode_lib->vba.RoundTripPingLatencyCycles + 32) / mode_lib->vba.DCFCLK - + mode_lib->vba.UrgentOutOfOrderReturnPerChannel * mode_lib->vba.NumberOfChannels / mode_lib->vba.ReturnBW; + mode_lib->vba.UrgentRoundTripAndOutOfOrderLatency = + (mode_lib->vba.RoundTripPingLatencyCycles + 32) / mode_lib->vba.DCFCLK + + mode_lib->vba.UrgentOutOfOrderReturnPerChannel + * mode_lib->vba.NumberOfChannels + / mode_lib->vba.ReturnBW; mode_lib->vba.LastPixelOfLineExtraWatermark = 0; for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { double DataFabricLineDeliveryTimeLuma, DataFabricLineDeliveryTimeChroma; if (mode_lib->vba.VRatio[k] <= 1.0) - mode_lib->vba.DisplayPipeLineDeliveryTimeLuma[k] = (double)mode_lib->vba.SwathWidthY[k] - * mode_lib->vba.DPPPerPlane[k] / mode_lib->vba.HRatio[k] / mode_lib->vba.PixelClock[k]; + mode_lib->vba.DisplayPipeLineDeliveryTimeLuma[k] = + (double) mode_lib->vba.SwathWidthY[k] + * mode_lib->vba.DPPPerPlane[k] + / mode_lib->vba.HRatio[k] + / mode_lib->vba.PixelClock[k]; else - mode_lib->vba.DisplayPipeLineDeliveryTimeLuma[k] = (double)mode_lib->vba.SwathWidthY[k] - / mode_lib->vba.PSCL_THROUGHPUT_LUMA[k] / mode_lib->vba.DPPCLK[k]; - - DataFabricLineDeliveryTimeLuma = - mode_lib->vba.SwathWidthSingleDPPY[k] * mode_lib->vba.SwathHeightY[k] - * dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1) - / (mode_lib->vba.ReturnBW * mode_lib->vba.ReadBandwidthPlaneLuma[k] - / mode_lib->vba.TotalDataReadBandwidth); - mode_lib->vba.LastPixelOfLineExtraWatermark = dml_max(mode_lib->vba.LastPixelOfLineExtraWatermark, - DataFabricLineDeliveryTimeLuma - - mode_lib->vba.DisplayPipeLineDeliveryTimeLuma[k]); + mode_lib->vba.DisplayPipeLineDeliveryTimeLuma[k] = + (double) mode_lib->vba.SwathWidthY[k] + / mode_lib->vba.PSCL_THROUGHPUT_LUMA[k] + / mode_lib->vba.DPPCLK[k]; + + DataFabricLineDeliveryTimeLuma = mode_lib->vba.SwathWidthSingleDPPY[k] + * mode_lib->vba.SwathHeightY[k] + * dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1) + / (mode_lib->vba.ReturnBW * mode_lib->vba.ReadBandwidthPlaneLuma[k] + / mode_lib->vba.TotalDataReadBandwidth); + mode_lib->vba.LastPixelOfLineExtraWatermark = dml_max( + mode_lib->vba.LastPixelOfLineExtraWatermark, + DataFabricLineDeliveryTimeLuma + - mode_lib->vba.DisplayPipeLineDeliveryTimeLuma[k]); if (mode_lib->vba.BytePerPixelDETC[k] == 0) mode_lib->vba.DisplayPipeLineDeliveryTimeChroma[k] = 0.0; else if (mode_lib->vba.VRatio[k] / 2.0 <= 1.0) - mode_lib->vba.DisplayPipeLineDeliveryTimeChroma[k] = mode_lib->vba.SwathWidthY[k] / 2.0 - * mode_lib->vba.DPPPerPlane[k] / (mode_lib->vba.HRatio[k] / 2.0) / mode_lib->vba.PixelClock[k]; + mode_lib->vba.DisplayPipeLineDeliveryTimeChroma[k] = + mode_lib->vba.SwathWidthY[k] / 2.0 + * mode_lib->vba.DPPPerPlane[k] + / (mode_lib->vba.HRatio[k] / 2.0) + / mode_lib->vba.PixelClock[k]; else - mode_lib->vba.DisplayPipeLineDeliveryTimeChroma[k] = mode_lib->vba.SwathWidthY[k] / 2.0 - / mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k] / mode_lib->vba.DPPCLK[k]; + mode_lib->vba.DisplayPipeLineDeliveryTimeChroma[k] = + mode_lib->vba.SwathWidthY[k] / 2.0 + / mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k] + / mode_lib->vba.DPPCLK[k]; DataFabricLineDeliveryTimeChroma = mode_lib->vba.SwathWidthSingleDPPY[k] / 2.0 - * mode_lib->vba.SwathHeightC[k] * dml_ceil(mode_lib->vba.BytePerPixelDETC[k], 2) - / (mode_lib->vba.ReturnBW * mode_lib->vba.ReadBandwidthPlaneChroma[k] - / mode_lib->vba.TotalDataReadBandwidth); - mode_lib->vba.LastPixelOfLineExtraWatermark = dml_max(mode_lib->vba.LastPixelOfLineExtraWatermark, - DataFabricLineDeliveryTimeChroma - - mode_lib->vba.DisplayPipeLineDeliveryTimeChroma[k]); + * mode_lib->vba.SwathHeightC[k] + * dml_ceil(mode_lib->vba.BytePerPixelDETC[k], 2) + / (mode_lib->vba.ReturnBW + * mode_lib->vba.ReadBandwidthPlaneChroma[k] + / mode_lib->vba.TotalDataReadBandwidth); + mode_lib->vba.LastPixelOfLineExtraWatermark = + dml_max( + mode_lib->vba.LastPixelOfLineExtraWatermark, + DataFabricLineDeliveryTimeChroma + - mode_lib->vba.DisplayPipeLineDeliveryTimeChroma[k]); } mode_lib->vba.UrgentExtraLatency = mode_lib->vba.UrgentRoundTripAndOutOfOrderLatency - + (mode_lib->vba.TotalActiveDPP * mode_lib->vba.PixelChunkSizeInKByte - + mode_lib->vba.TotalDCCActiveDPP * mode_lib->vba.MetaChunkSize) * 1024.0 - / mode_lib->vba.ReturnBW; + + (mode_lib->vba.TotalActiveDPP * mode_lib->vba.PixelChunkSizeInKByte + + mode_lib->vba.TotalDCCActiveDPP + * mode_lib->vba.MetaChunkSize) * 1024.0 + / mode_lib->vba.ReturnBW; if (mode_lib->vba.VirtualMemoryEnable) - mode_lib->vba.UrgentExtraLatency += mode_lib->vba.TotalActiveDPP * mode_lib->vba.PTEChunkSize * 1024.0 / mode_lib->vba.ReturnBW; + mode_lib->vba.UrgentExtraLatency += mode_lib->vba.TotalActiveDPP + * mode_lib->vba.PTEChunkSize * 1024.0 / mode_lib->vba.ReturnBW; - mode_lib->vba.UrgentWatermark = mode_lib->vba.UrgentLatency + mode_lib->vba.LastPixelOfLineExtraWatermark + mode_lib->vba.UrgentExtraLatency; + mode_lib->vba.UrgentWatermark = mode_lib->vba.UrgentLatency + + mode_lib->vba.LastPixelOfLineExtraWatermark + + mode_lib->vba.UrgentExtraLatency; DTRACE(" urgent_extra_latency = %fus", mode_lib->vba.UrgentExtraLatency); DTRACE(" wm_urgent = %fus", mode_lib->vba.UrgentWatermark); @@ -1780,12 +2056,14 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman mode_lib->vba.WritebackUrgentWatermark = mode_lib->vba.WritebackLatency; else mode_lib->vba.WritebackUrgentWatermark = mode_lib->vba.WritebackLatency - + mode_lib->vba.WritebackChunkSize * 1024.0 / 32 / mode_lib->vba.SOCCLK; + + mode_lib->vba.WritebackChunkSize * 1024.0 / 32 + / mode_lib->vba.SOCCLK; DTRACE(" wm_wb_urgent = %fus", mode_lib->vba.WritebackUrgentWatermark); // NB P-State/DRAM Clock Change Watermark - mode_lib->vba.DRAMClockChangeWatermark = mode_lib->vba.DRAMClockChangeLatency + mode_lib->vba.UrgentWatermark; + mode_lib->vba.DRAMClockChangeWatermark = mode_lib->vba.DRAMClockChangeLatency + + mode_lib->vba.UrgentWatermark; DTRACE(" wm_pstate_change = %fus", mode_lib->vba.DRAMClockChangeWatermark); @@ -1794,28 +2072,42 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman DTRACE(" socclk frequency %f Mhz", mode_lib->vba.SOCCLK); if (mode_lib->vba.TotalActiveWriteback <= 1) - mode_lib->vba.WritebackDRAMClockChangeWatermark = mode_lib->vba.DRAMClockChangeLatency + mode_lib->vba.WritebackLatency; + mode_lib->vba.WritebackDRAMClockChangeWatermark = + mode_lib->vba.DRAMClockChangeLatency + + mode_lib->vba.WritebackLatency; else - mode_lib->vba.WritebackDRAMClockChangeWatermark = mode_lib->vba.DRAMClockChangeLatency + mode_lib->vba.WritebackLatency - + mode_lib->vba.WritebackChunkSize * 1024.0 / 32 / mode_lib->vba.SOCCLK; + mode_lib->vba.WritebackDRAMClockChangeWatermark = + mode_lib->vba.DRAMClockChangeLatency + + mode_lib->vba.WritebackLatency + + mode_lib->vba.WritebackChunkSize * 1024.0 / 32 + / mode_lib->vba.SOCCLK; DTRACE(" wm_wb_pstate %fus", mode_lib->vba.WritebackDRAMClockChangeWatermark); // Stutter Efficiency for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { - mode_lib->vba.LinesInDETY[k] = mode_lib->vba.DETBufferSizeY[k] / mode_lib->vba.BytePerPixelDETY[k] - / mode_lib->vba.SwathWidthY[k]; - mode_lib->vba.LinesInDETYRoundedDownToSwath[k] = dml_floor(mode_lib->vba.LinesInDETY[k], - mode_lib->vba.SwathHeightY[k]); - mode_lib->vba.FullDETBufferingTimeY[k] = mode_lib->vba.LinesInDETYRoundedDownToSwath[k] - * (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]) / mode_lib->vba.VRatio[k]; + mode_lib->vba.LinesInDETY[k] = mode_lib->vba.DETBufferSizeY[k] + / mode_lib->vba.BytePerPixelDETY[k] / mode_lib->vba.SwathWidthY[k]; + mode_lib->vba.LinesInDETYRoundedDownToSwath[k] = dml_floor( + mode_lib->vba.LinesInDETY[k], + mode_lib->vba.SwathHeightY[k]); + mode_lib->vba.FullDETBufferingTimeY[k] = + mode_lib->vba.LinesInDETYRoundedDownToSwath[k] + * (mode_lib->vba.HTotal[k] + / mode_lib->vba.PixelClock[k]) + / mode_lib->vba.VRatio[k]; if (mode_lib->vba.BytePerPixelDETC[k] > 0) { - mode_lib->vba.LinesInDETC[k] = mode_lib->vba.DETBufferSizeC[k] / mode_lib->vba.BytePerPixelDETC[k] - / (mode_lib->vba.SwathWidthY[k] / 2); - mode_lib->vba.LinesInDETCRoundedDownToSwath[k] = dml_floor(mode_lib->vba.LinesInDETC[k], - mode_lib->vba.SwathHeightC[k]); - mode_lib->vba.FullDETBufferingTimeC[k] = mode_lib->vba.LinesInDETCRoundedDownToSwath[k] - * (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]) / (mode_lib->vba.VRatio[k] / 2); + mode_lib->vba.LinesInDETC[k] = mode_lib->vba.DETBufferSizeC[k] + / mode_lib->vba.BytePerPixelDETC[k] + / (mode_lib->vba.SwathWidthY[k] / 2); + mode_lib->vba.LinesInDETCRoundedDownToSwath[k] = dml_floor( + mode_lib->vba.LinesInDETC[k], + mode_lib->vba.SwathHeightC[k]); + mode_lib->vba.FullDETBufferingTimeC[k] = + mode_lib->vba.LinesInDETCRoundedDownToSwath[k] + * (mode_lib->vba.HTotal[k] + / mode_lib->vba.PixelClock[k]) + / (mode_lib->vba.VRatio[k] / 2); } else { mode_lib->vba.LinesInDETC[k] = 0; mode_lib->vba.LinesInDETCRoundedDownToSwath[k] = 0; @@ -1825,15 +2117,21 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman mode_lib->vba.MinFullDETBufferingTime = 999999.0; for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { - if (mode_lib->vba.FullDETBufferingTimeY[k] < mode_lib->vba.MinFullDETBufferingTime) { - mode_lib->vba.MinFullDETBufferingTime = mode_lib->vba.FullDETBufferingTimeY[k]; - mode_lib->vba.FrameTimeForMinFullDETBufferingTime = (double)mode_lib->vba.VTotal[k] * mode_lib->vba.HTotal[k] - / mode_lib->vba.PixelClock[k]; + if (mode_lib->vba.FullDETBufferingTimeY[k] + < mode_lib->vba.MinFullDETBufferingTime) { + mode_lib->vba.MinFullDETBufferingTime = + mode_lib->vba.FullDETBufferingTimeY[k]; + mode_lib->vba.FrameTimeForMinFullDETBufferingTime = + (double) mode_lib->vba.VTotal[k] * mode_lib->vba.HTotal[k] + / mode_lib->vba.PixelClock[k]; } - if (mode_lib->vba.FullDETBufferingTimeC[k] < mode_lib->vba.MinFullDETBufferingTime) { - mode_lib->vba.MinFullDETBufferingTime = mode_lib->vba.FullDETBufferingTimeC[k]; - mode_lib->vba.FrameTimeForMinFullDETBufferingTime = (double)mode_lib->vba.VTotal[k] * mode_lib->vba.HTotal[k] - / mode_lib->vba.PixelClock[k]; + if (mode_lib->vba.FullDETBufferingTimeC[k] + < mode_lib->vba.MinFullDETBufferingTime) { + mode_lib->vba.MinFullDETBufferingTime = + mode_lib->vba.FullDETBufferingTimeC[k]; + mode_lib->vba.FrameTimeForMinFullDETBufferingTime = + (double) mode_lib->vba.VTotal[k] * mode_lib->vba.HTotal[k] + / mode_lib->vba.PixelClock[k]; } } @@ -1841,45 +2139,58 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { if (mode_lib->vba.DCCEnable[k]) { mode_lib->vba.AverageReadBandwidthGBytePerSecond = - mode_lib->vba.AverageReadBandwidthGBytePerSecond - + mode_lib->vba.ReadBandwidthPlaneLuma[k] / mode_lib->vba.DCCRate[k] - / 1000 - + mode_lib->vba.ReadBandwidthPlaneChroma[k] - / mode_lib->vba.DCCRate[k] / 1000; + mode_lib->vba.AverageReadBandwidthGBytePerSecond + + mode_lib->vba.ReadBandwidthPlaneLuma[k] + / mode_lib->vba.DCCRate[k] + / 1000 + + mode_lib->vba.ReadBandwidthPlaneChroma[k] + / mode_lib->vba.DCCRate[k] + / 1000; } else { mode_lib->vba.AverageReadBandwidthGBytePerSecond = - mode_lib->vba.AverageReadBandwidthGBytePerSecond - + mode_lib->vba.ReadBandwidthPlaneLuma[k] / 1000 - + mode_lib->vba.ReadBandwidthPlaneChroma[k] / 1000; + mode_lib->vba.AverageReadBandwidthGBytePerSecond + + mode_lib->vba.ReadBandwidthPlaneLuma[k] + / 1000 + + mode_lib->vba.ReadBandwidthPlaneChroma[k] + / 1000; } if (mode_lib->vba.DCCEnable[k]) { mode_lib->vba.AverageReadBandwidthGBytePerSecond = - mode_lib->vba.AverageReadBandwidthGBytePerSecond - + mode_lib->vba.ReadBandwidthPlaneLuma[k] / 1000 / 256 - + mode_lib->vba.ReadBandwidthPlaneChroma[k] / 1000 - / 256; + mode_lib->vba.AverageReadBandwidthGBytePerSecond + + mode_lib->vba.ReadBandwidthPlaneLuma[k] + / 1000 / 256 + + mode_lib->vba.ReadBandwidthPlaneChroma[k] + / 1000 / 256; } if (mode_lib->vba.VirtualMemoryEnable) { mode_lib->vba.AverageReadBandwidthGBytePerSecond = - mode_lib->vba.AverageReadBandwidthGBytePerSecond - + mode_lib->vba.ReadBandwidthPlaneLuma[k] / 1000 / 512 - + mode_lib->vba.ReadBandwidthPlaneChroma[k] / 1000 - / 512; + mode_lib->vba.AverageReadBandwidthGBytePerSecond + + mode_lib->vba.ReadBandwidthPlaneLuma[k] + / 1000 / 512 + + mode_lib->vba.ReadBandwidthPlaneChroma[k] + / 1000 / 512; } } - mode_lib->vba.PartOfBurstThatFitsInROB = dml_min(mode_lib->vba.MinFullDETBufferingTime * mode_lib->vba.TotalDataReadBandwidth, - mode_lib->vba.ROBBufferSizeInKByte * 1024 * mode_lib->vba.TotalDataReadBandwidth - / (mode_lib->vba.AverageReadBandwidthGBytePerSecond * 1000)); + mode_lib->vba.PartOfBurstThatFitsInROB = + dml_min( + mode_lib->vba.MinFullDETBufferingTime + * mode_lib->vba.TotalDataReadBandwidth, + mode_lib->vba.ROBBufferSizeInKByte * 1024 + * mode_lib->vba.TotalDataReadBandwidth + / (mode_lib->vba.AverageReadBandwidthGBytePerSecond + * 1000)); mode_lib->vba.StutterBurstTime = mode_lib->vba.PartOfBurstThatFitsInROB - * (mode_lib->vba.AverageReadBandwidthGBytePerSecond * 1000) / mode_lib->vba.TotalDataReadBandwidth - / mode_lib->vba.ReturnBW - + (mode_lib->vba.MinFullDETBufferingTime * mode_lib->vba.TotalDataReadBandwidth - - mode_lib->vba.PartOfBurstThatFitsInROB) / (mode_lib->vba.DCFCLK * 64); + * (mode_lib->vba.AverageReadBandwidthGBytePerSecond * 1000) + / mode_lib->vba.TotalDataReadBandwidth / mode_lib->vba.ReturnBW + + (mode_lib->vba.MinFullDETBufferingTime + * mode_lib->vba.TotalDataReadBandwidth + - mode_lib->vba.PartOfBurstThatFitsInROB) + / (mode_lib->vba.DCFCLK * 64); if (mode_lib->vba.TotalActiveWriteback == 0) { mode_lib->vba.StutterEfficiencyNotIncludingVBlank = (1 - - (mode_lib->vba.SRExitTime + mode_lib->vba.StutterBurstTime) / mode_lib->vba.MinFullDETBufferingTime) - * 100; + - (mode_lib->vba.SRExitTime + mode_lib->vba.StutterBurstTime) + / mode_lib->vba.MinFullDETBufferingTime) * 100; } else { mode_lib->vba.StutterEfficiencyNotIncludingVBlank = 0; } @@ -1887,47 +2198,66 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman mode_lib->vba.SmallestVBlank = 999999; for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { if (mode_lib->vba.SynchronizedVBlank || mode_lib->vba.NumberOfActivePlanes == 1) { - mode_lib->vba.VBlankTime = (double)(mode_lib->vba.VTotal[k] - mode_lib->vba.VActive[k]) * mode_lib->vba.HTotal[k] - / mode_lib->vba.PixelClock[k]; + mode_lib->vba.VBlankTime = (double) (mode_lib->vba.VTotal[k] + - mode_lib->vba.VActive[k]) * mode_lib->vba.HTotal[k] + / mode_lib->vba.PixelClock[k]; } else { mode_lib->vba.VBlankTime = 0; } - mode_lib->vba.SmallestVBlank = dml_min(mode_lib->vba.SmallestVBlank, mode_lib->vba.VBlankTime); + mode_lib->vba.SmallestVBlank = dml_min( + mode_lib->vba.SmallestVBlank, + mode_lib->vba.VBlankTime); } mode_lib->vba.StutterEfficiency = (mode_lib->vba.StutterEfficiencyNotIncludingVBlank / 100 - * (mode_lib->vba.FrameTimeForMinFullDETBufferingTime - mode_lib->vba.SmallestVBlank) - + mode_lib->vba.SmallestVBlank) / mode_lib->vba.FrameTimeForMinFullDETBufferingTime * 100; + * (mode_lib->vba.FrameTimeForMinFullDETBufferingTime + - mode_lib->vba.SmallestVBlank) + + mode_lib->vba.SmallestVBlank) + / mode_lib->vba.FrameTimeForMinFullDETBufferingTime * 100; // dml_ml->vba.DCFCLK Deep Sleep mode_lib->vba.DCFClkDeepSleep = 8.0; for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; k++) { if (mode_lib->vba.BytePerPixelDETC[k] > 0) { - mode_lib->vba.DCFCLKDeepSleepPerPlane = dml_max(1.1 * mode_lib->vba.SwathWidthY[k] - * dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1) / 32 - / mode_lib->vba.DisplayPipeLineDeliveryTimeLuma[k], - 1.1 * mode_lib->vba.SwathWidthY[k] / 2.0 - * dml_ceil(mode_lib->vba.BytePerPixelDETC[k], 2) / 32 - / mode_lib->vba.DisplayPipeLineDeliveryTimeChroma[k]); + mode_lib->vba.DCFCLKDeepSleepPerPlane = + dml_max( + 1.1 * mode_lib->vba.SwathWidthY[k] + * dml_ceil( + mode_lib->vba.BytePerPixelDETY[k], + 1) / 32 + / mode_lib->vba.DisplayPipeLineDeliveryTimeLuma[k], + 1.1 * mode_lib->vba.SwathWidthY[k] / 2.0 + * dml_ceil( + mode_lib->vba.BytePerPixelDETC[k], + 2) / 32 + / mode_lib->vba.DisplayPipeLineDeliveryTimeChroma[k]); } else mode_lib->vba.DCFCLKDeepSleepPerPlane = 1.1 * mode_lib->vba.SwathWidthY[k] - * dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1) / 64.0 - / mode_lib->vba.DisplayPipeLineDeliveryTimeLuma[k]; - mode_lib->vba.DCFCLKDeepSleepPerPlane = dml_max(mode_lib->vba.DCFCLKDeepSleepPerPlane, - mode_lib->vba.PixelClock[k] / 16.0); - mode_lib->vba.DCFClkDeepSleep = dml_max(mode_lib->vba.DCFClkDeepSleep, mode_lib->vba.DCFCLKDeepSleepPerPlane); + * dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1) / 64.0 + / mode_lib->vba.DisplayPipeLineDeliveryTimeLuma[k]; + mode_lib->vba.DCFCLKDeepSleepPerPlane = dml_max( + mode_lib->vba.DCFCLKDeepSleepPerPlane, + mode_lib->vba.PixelClock[k] / 16.0); + mode_lib->vba.DCFClkDeepSleep = dml_max( + mode_lib->vba.DCFClkDeepSleep, + mode_lib->vba.DCFCLKDeepSleepPerPlane); - DTRACE(" dcfclk_deepsleep_per_plane[%i] = %fMHz", k, mode_lib->vba.DCFCLKDeepSleepPerPlane); + DTRACE( + " dcfclk_deepsleep_per_plane[%i] = %fMHz", + k, + mode_lib->vba.DCFCLKDeepSleepPerPlane); } DTRACE(" dcfclk_deepsleep_mhz = %fMHz", mode_lib->vba.DCFClkDeepSleep); // Stutter Watermark - mode_lib->vba.StutterExitWatermark = mode_lib->vba.SRExitTime + mode_lib->vba.LastPixelOfLineExtraWatermark + mode_lib->vba.UrgentExtraLatency - + 10 / mode_lib->vba.DCFClkDeepSleep; - mode_lib->vba.StutterEnterPlusExitWatermark = mode_lib->vba.SREnterPlusExitTime + mode_lib->vba.LastPixelOfLineExtraWatermark - + mode_lib->vba.UrgentExtraLatency; + mode_lib->vba.StutterExitWatermark = mode_lib->vba.SRExitTime + + mode_lib->vba.LastPixelOfLineExtraWatermark + + mode_lib->vba.UrgentExtraLatency + 10 / mode_lib->vba.DCFClkDeepSleep; + mode_lib->vba.StutterEnterPlusExitWatermark = mode_lib->vba.SREnterPlusExitTime + + mode_lib->vba.LastPixelOfLineExtraWatermark + + mode_lib->vba.UrgentExtraLatency; DTRACE(" wm_cstate_exit = %fus", mode_lib->vba.StutterExitWatermark); DTRACE(" wm_cstate_enter_exit = %fus", mode_lib->vba.StutterEnterPlusExitWatermark); @@ -1935,72 +2265,95 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman // Urgent Latency Supported for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { mode_lib->vba.EffectiveDETPlusLBLinesLuma = - dml_floor(mode_lib->vba.LinesInDETY[k] - + dml_min(mode_lib->vba.LinesInDETY[k] - * mode_lib->vba.DPPCLK[k] - * mode_lib->vba.BytePerPixelDETY[k] - * mode_lib->vba.PSCL_THROUGHPUT_LUMA[k] - / (mode_lib->vba.ReturnBW - / mode_lib->vba.DPPPerPlane[k]), - (double)mode_lib->vba.EffectiveLBLatencyHidingSourceLinesLuma), - mode_lib->vba.SwathHeightY[k]); + dml_floor( + mode_lib->vba.LinesInDETY[k] + + dml_min( + mode_lib->vba.LinesInDETY[k] + * mode_lib->vba.DPPCLK[k] + * mode_lib->vba.BytePerPixelDETY[k] + * mode_lib->vba.PSCL_THROUGHPUT_LUMA[k] + / (mode_lib->vba.ReturnBW + / mode_lib->vba.DPPPerPlane[k]), + (double) mode_lib->vba.EffectiveLBLatencyHidingSourceLinesLuma), + mode_lib->vba.SwathHeightY[k]); mode_lib->vba.UrgentLatencySupportUsLuma = mode_lib->vba.EffectiveDETPlusLBLinesLuma - * (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]) / mode_lib->vba.VRatio[k] - - mode_lib->vba.EffectiveDETPlusLBLinesLuma * mode_lib->vba.SwathWidthY[k] - * mode_lib->vba.BytePerPixelDETY[k] - / (mode_lib->vba.ReturnBW / mode_lib->vba.DPPPerPlane[k]); + * (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]) + / mode_lib->vba.VRatio[k] + - mode_lib->vba.EffectiveDETPlusLBLinesLuma + * mode_lib->vba.SwathWidthY[k] + * mode_lib->vba.BytePerPixelDETY[k] + / (mode_lib->vba.ReturnBW + / mode_lib->vba.DPPPerPlane[k]); if (mode_lib->vba.BytePerPixelDETC[k] > 0) { mode_lib->vba.EffectiveDETPlusLBLinesChroma = - dml_floor(mode_lib->vba.LinesInDETC[k] - + dml_min(mode_lib->vba.LinesInDETC[k] - * mode_lib->vba.DPPCLK[k] - * mode_lib->vba.BytePerPixelDETC[k] - * mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k] - / (mode_lib->vba.ReturnBW - / mode_lib->vba.DPPPerPlane[k]), - (double)mode_lib->vba.EffectiveLBLatencyHidingSourceLinesChroma), - mode_lib->vba.SwathHeightC[k]); - mode_lib->vba.UrgentLatencySupportUsChroma = mode_lib->vba.EffectiveDETPlusLBLinesChroma - * (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]) / (mode_lib->vba.VRatio[k] / 2) - - mode_lib->vba.EffectiveDETPlusLBLinesChroma - * (mode_lib->vba.SwathWidthY[k] / 2) - * mode_lib->vba.BytePerPixelDETC[k] - / (mode_lib->vba.ReturnBW / mode_lib->vba.DPPPerPlane[k]); - mode_lib->vba.UrgentLatencySupportUs[k] = dml_min(mode_lib->vba.UrgentLatencySupportUsLuma, - mode_lib->vba.UrgentLatencySupportUsChroma); + dml_floor( + mode_lib->vba.LinesInDETC[k] + + dml_min( + mode_lib->vba.LinesInDETC[k] + * mode_lib->vba.DPPCLK[k] + * mode_lib->vba.BytePerPixelDETC[k] + * mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k] + / (mode_lib->vba.ReturnBW + / mode_lib->vba.DPPPerPlane[k]), + (double) mode_lib->vba.EffectiveLBLatencyHidingSourceLinesChroma), + mode_lib->vba.SwathHeightC[k]); + mode_lib->vba.UrgentLatencySupportUsChroma = + mode_lib->vba.EffectiveDETPlusLBLinesChroma + * (mode_lib->vba.HTotal[k] + / mode_lib->vba.PixelClock[k]) + / (mode_lib->vba.VRatio[k] / 2) + - mode_lib->vba.EffectiveDETPlusLBLinesChroma + * (mode_lib->vba.SwathWidthY[k] + / 2) + * mode_lib->vba.BytePerPixelDETC[k] + / (mode_lib->vba.ReturnBW + / mode_lib->vba.DPPPerPlane[k]); + mode_lib->vba.UrgentLatencySupportUs[k] = dml_min( + mode_lib->vba.UrgentLatencySupportUsLuma, + mode_lib->vba.UrgentLatencySupportUsChroma); } else { - mode_lib->vba.UrgentLatencySupportUs[k] = mode_lib->vba.UrgentLatencySupportUsLuma; + mode_lib->vba.UrgentLatencySupportUs[k] = + mode_lib->vba.UrgentLatencySupportUsLuma; } } mode_lib->vba.MinUrgentLatencySupportUs = 999999; for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { - mode_lib->vba.MinUrgentLatencySupportUs = dml_min(mode_lib->vba.MinUrgentLatencySupportUs, - mode_lib->vba.UrgentLatencySupportUs[k]); + mode_lib->vba.MinUrgentLatencySupportUs = dml_min( + mode_lib->vba.MinUrgentLatencySupportUs, + mode_lib->vba.UrgentLatencySupportUs[k]); } // Non-Urgent Latency Tolerance - mode_lib->vba.NonUrgentLatencyTolerance = mode_lib->vba.MinUrgentLatencySupportUs - mode_lib->vba.UrgentWatermark; + mode_lib->vba.NonUrgentLatencyTolerance = mode_lib->vba.MinUrgentLatencySupportUs + - mode_lib->vba.UrgentWatermark; // DSCCLK for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { if ((mode_lib->vba.BlendingAndTiming[k] != k) || !mode_lib->vba.DSCEnabled[k]) { mode_lib->vba.DSCCLK_calculated[k] = 0.0; } else { - if (mode_lib->vba.OutputFormat[k] == dm_420 || mode_lib->vba.OutputFormat[k] == dm_n422) + if (mode_lib->vba.OutputFormat[k] == dm_420 + || mode_lib->vba.OutputFormat[k] == dm_n422) mode_lib->vba.DSCFormatFactor = 2; else mode_lib->vba.DSCFormatFactor = 1; if (mode_lib->vba.ODMCombineEnabled[k]) - mode_lib->vba.DSCCLK_calculated[k] = mode_lib->vba.PixelClockBackEnd[k] / 6 - / mode_lib->vba.DSCFormatFactor - / (1 - mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100); + mode_lib->vba.DSCCLK_calculated[k] = + mode_lib->vba.PixelClockBackEnd[k] / 6 + / mode_lib->vba.DSCFormatFactor + / (1 + - mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading + / 100); else - mode_lib->vba.DSCCLK_calculated[k] = mode_lib->vba.PixelClockBackEnd[k] / 3 - / mode_lib->vba.DSCFormatFactor - / (1 - mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100); + mode_lib->vba.DSCCLK_calculated[k] = + mode_lib->vba.PixelClockBackEnd[k] / 3 + / mode_lib->vba.DSCFormatFactor + / (1 + - mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading + / 100); } } @@ -2013,27 +2366,35 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman if (mode_lib->vba.DSCEnabled[k] && bpp != 0) { if (!mode_lib->vba.ODMCombineEnabled[k]) { mode_lib->vba.DSCDelay[k] = - dscceComputeDelay(mode_lib->vba.DSCInputBitPerComponent[k], - bpp, - dml_ceil((double)mode_lib->vba.HActive[k] - / mode_lib->vba.NumberOfDSCSlices[k], - 1), - slices, - mode_lib->vba.OutputFormat[k]) - + dscComputeDelay(mode_lib->vba.OutputFormat[k]); + dscceComputeDelay( + mode_lib->vba.DSCInputBitPerComponent[k], + bpp, + dml_ceil( + (double) mode_lib->vba.HActive[k] + / mode_lib->vba.NumberOfDSCSlices[k], + 1), + slices, + mode_lib->vba.OutputFormat[k]) + + dscComputeDelay( + mode_lib->vba.OutputFormat[k]); } else { mode_lib->vba.DSCDelay[k] = - 2 - * (dscceComputeDelay(mode_lib->vba.DSCInputBitPerComponent[k], - bpp, - dml_ceil((double)mode_lib->vba.HActive[k] - / mode_lib->vba.NumberOfDSCSlices[k], - 1), - slices / 2.0, - mode_lib->vba.OutputFormat[k]) - + dscComputeDelay(mode_lib->vba.OutputFormat[k])); - } - mode_lib->vba.DSCDelay[k] = mode_lib->vba.DSCDelay[k] * mode_lib->vba.PixelClock[k] / mode_lib->vba.PixelClockBackEnd[k]; + 2 + * (dscceComputeDelay( + mode_lib->vba.DSCInputBitPerComponent[k], + bpp, + dml_ceil( + (double) mode_lib->vba.HActive[k] + / mode_lib->vba.NumberOfDSCSlices[k], + 1), + slices / 2.0, + mode_lib->vba.OutputFormat[k]) + + dscComputeDelay( + mode_lib->vba.OutputFormat[k])); + } + mode_lib->vba.DSCDelay[k] = mode_lib->vba.DSCDelay[k] + * mode_lib->vba.PixelClock[k] + / mode_lib->vba.PixelClockBackEnd[k]; } else { mode_lib->vba.DSCDelay[k] = 0; } @@ -2041,7 +2402,8 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) // NumberOfPlanes - if (j != k && mode_lib->vba.BlendingAndTiming[k] == j && mode_lib->vba.DSCEnabled[j]) + if (j != k && mode_lib->vba.BlendingAndTiming[k] == j + && mode_lib->vba.DSCEnabled[j]) mode_lib->vba.DSCDelay[k] = mode_lib->vba.DSCDelay[j]; // Prefetch @@ -2053,82 +2415,91 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman unsigned int PDEAndMetaPTEBytesFrameC; unsigned int PixelPTEBytesPerRowC; - Calculate256BBlockSizes(mode_lib->vba.SourcePixelFormat[k], - mode_lib->vba.SurfaceTiling[k], - dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1), - dml_ceil(mode_lib->vba.BytePerPixelDETC[k], 2), - &mode_lib->vba.BlockHeight256BytesY[k], - &mode_lib->vba.BlockHeight256BytesC[k], - &mode_lib->vba.BlockWidth256BytesY[k], - &mode_lib->vba.BlockWidth256BytesC[k]); - PDEAndMetaPTEBytesFrameY = CalculateVMAndRowBytes(mode_lib, - mode_lib->vba.DCCEnable[k], - mode_lib->vba.BlockHeight256BytesY[k], - mode_lib->vba.BlockWidth256BytesY[k], - mode_lib->vba.SourcePixelFormat[k], - mode_lib->vba.SurfaceTiling[k], - dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1), - mode_lib->vba.SourceScan[k], - mode_lib->vba.ViewportWidth[k], - mode_lib->vba.ViewportHeight[k], - mode_lib->vba.SwathWidthY[k], - mode_lib->vba.VirtualMemoryEnable, - mode_lib->vba.VMMPageSize, - mode_lib->vba.PTEBufferSizeInRequests, - mode_lib->vba.PDEProcessingBufIn64KBReqs, - mode_lib->vba.PitchY[k], - mode_lib->vba.DCCMetaPitchY[k], - &mode_lib->vba.MacroTileWidthY, - &MetaRowByteY, - &PixelPTEBytesPerRowY, - &mode_lib->vba.PTEBufferSizeNotExceeded, - &mode_lib->vba.dpte_row_height[k], - &mode_lib->vba.meta_row_height[k]); - mode_lib->vba.PrefetchSourceLinesY[k] = CalculatePrefetchSourceLines(mode_lib, - mode_lib->vba.VRatio[k], - mode_lib->vba.vtaps[k], - mode_lib->vba.Interlace[k], - mode_lib->vba.ProgressiveToInterlaceUnitInOPP, - mode_lib->vba.SwathHeightY[k], - mode_lib->vba.ViewportYStartY[k], - &mode_lib->vba.VInitPreFillY[k], - &mode_lib->vba.MaxNumSwathY[k]); - - if ((mode_lib->vba.SourcePixelFormat[k] != dm_444_64 && mode_lib->vba.SourcePixelFormat[k] != dm_444_32 - && mode_lib->vba.SourcePixelFormat[k] != dm_444_16 - && mode_lib->vba.SourcePixelFormat[k] != dm_444_8)) { - PDEAndMetaPTEBytesFrameC = CalculateVMAndRowBytes(mode_lib, - mode_lib->vba.DCCEnable[k], - mode_lib->vba.BlockHeight256BytesC[k], - mode_lib->vba.BlockWidth256BytesC[k], + Calculate256BBlockSizes( mode_lib->vba.SourcePixelFormat[k], mode_lib->vba.SurfaceTiling[k], + dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1), dml_ceil(mode_lib->vba.BytePerPixelDETC[k], 2), + &mode_lib->vba.BlockHeight256BytesY[k], + &mode_lib->vba.BlockHeight256BytesC[k], + &mode_lib->vba.BlockWidth256BytesY[k], + &mode_lib->vba.BlockWidth256BytesC[k]); + PDEAndMetaPTEBytesFrameY = CalculateVMAndRowBytes( + mode_lib, + mode_lib->vba.DCCEnable[k], + mode_lib->vba.BlockHeight256BytesY[k], + mode_lib->vba.BlockWidth256BytesY[k], + mode_lib->vba.SourcePixelFormat[k], + mode_lib->vba.SurfaceTiling[k], + dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1), mode_lib->vba.SourceScan[k], - mode_lib->vba.ViewportWidth[k] / 2, - mode_lib->vba.ViewportHeight[k] / 2, - mode_lib->vba.SwathWidthY[k] / 2, + mode_lib->vba.ViewportWidth[k], + mode_lib->vba.ViewportHeight[k], + mode_lib->vba.SwathWidthY[k], mode_lib->vba.VirtualMemoryEnable, mode_lib->vba.VMMPageSize, mode_lib->vba.PTEBufferSizeInRequests, mode_lib->vba.PDEProcessingBufIn64KBReqs, - mode_lib->vba.PitchC[k], - 0, - &mode_lib->vba.MacroTileWidthC, - &MetaRowByteC, - &PixelPTEBytesPerRowC, - &mode_lib->vba.PTEBufferSizeNotExceeded, - &mode_lib->vba.dpte_row_height_chroma[k], - &mode_lib->vba.meta_row_height_chroma[k]); - mode_lib->vba.PrefetchSourceLinesC[k] = CalculatePrefetchSourceLines(mode_lib, - mode_lib->vba.VRatio[k] / 2, - mode_lib->vba.VTAPsChroma[k], + mode_lib->vba.PitchY[k], + mode_lib->vba.DCCMetaPitchY[k], + &mode_lib->vba.MacroTileWidthY[k], + &MetaRowByteY, + &PixelPTEBytesPerRowY, + &mode_lib->vba.PTEBufferSizeNotExceeded[mode_lib->vba.VoltageLevel], + &mode_lib->vba.dpte_row_height[k], + &mode_lib->vba.meta_row_height[k]); + mode_lib->vba.PrefetchSourceLinesY[k] = CalculatePrefetchSourceLines( + mode_lib, + mode_lib->vba.VRatio[k], + mode_lib->vba.vtaps[k], mode_lib->vba.Interlace[k], mode_lib->vba.ProgressiveToInterlaceUnitInOPP, - mode_lib->vba.SwathHeightC[k], - mode_lib->vba.ViewportYStartC[k], - &mode_lib->vba.VInitPreFillC[k], - &mode_lib->vba.MaxNumSwathC[k]); + mode_lib->vba.SwathHeightY[k], + mode_lib->vba.ViewportYStartY[k], + &mode_lib->vba.VInitPreFillY[k], + &mode_lib->vba.MaxNumSwathY[k]); + + if ((mode_lib->vba.SourcePixelFormat[k] != dm_444_64 + && mode_lib->vba.SourcePixelFormat[k] != dm_444_32 + && mode_lib->vba.SourcePixelFormat[k] != dm_444_16 + && mode_lib->vba.SourcePixelFormat[k] != dm_444_8)) { + PDEAndMetaPTEBytesFrameC = + CalculateVMAndRowBytes( + mode_lib, + mode_lib->vba.DCCEnable[k], + mode_lib->vba.BlockHeight256BytesC[k], + mode_lib->vba.BlockWidth256BytesC[k], + mode_lib->vba.SourcePixelFormat[k], + mode_lib->vba.SurfaceTiling[k], + dml_ceil( + mode_lib->vba.BytePerPixelDETC[k], + 2), + mode_lib->vba.SourceScan[k], + mode_lib->vba.ViewportWidth[k] / 2, + mode_lib->vba.ViewportHeight[k] / 2, + mode_lib->vba.SwathWidthY[k] / 2, + mode_lib->vba.VirtualMemoryEnable, + mode_lib->vba.VMMPageSize, + mode_lib->vba.PTEBufferSizeInRequests, + mode_lib->vba.PDEProcessingBufIn64KBReqs, + mode_lib->vba.PitchC[k], + 0, + &mode_lib->vba.MacroTileWidthC[k], + &MetaRowByteC, + &PixelPTEBytesPerRowC, + &mode_lib->vba.PTEBufferSizeNotExceeded[mode_lib->vba.VoltageLevel], + &mode_lib->vba.dpte_row_height_chroma[k], + &mode_lib->vba.meta_row_height_chroma[k]); + mode_lib->vba.PrefetchSourceLinesC[k] = CalculatePrefetchSourceLines( + mode_lib, + mode_lib->vba.VRatio[k] / 2, + mode_lib->vba.VTAPsChroma[k], + mode_lib->vba.Interlace[k], + mode_lib->vba.ProgressiveToInterlaceUnitInOPP, + mode_lib->vba.SwathHeightC[k], + mode_lib->vba.ViewportYStartC[k], + &mode_lib->vba.VInitPreFillC[k], + &mode_lib->vba.MaxNumSwathC[k]); } else { PixelPTEBytesPerRowC = 0; PDEAndMetaPTEBytesFrameC = 0; @@ -2138,25 +2509,27 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman } mode_lib->vba.PixelPTEBytesPerRow[k] = PixelPTEBytesPerRowY + PixelPTEBytesPerRowC; - mode_lib->vba.PDEAndMetaPTEBytesFrame[k] = PDEAndMetaPTEBytesFrameY + PDEAndMetaPTEBytesFrameC; + mode_lib->vba.PDEAndMetaPTEBytesFrame[k] = PDEAndMetaPTEBytesFrameY + + PDEAndMetaPTEBytesFrameC; mode_lib->vba.MetaRowByte[k] = MetaRowByteY + MetaRowByteC; - CalculateActiveRowBandwidth(mode_lib->vba.VirtualMemoryEnable, - mode_lib->vba.SourcePixelFormat[k], - mode_lib->vba.VRatio[k], - mode_lib->vba.DCCEnable[k], - mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k], - MetaRowByteY, - MetaRowByteC, - mode_lib->vba.meta_row_height[k], - mode_lib->vba.meta_row_height_chroma[k], - PixelPTEBytesPerRowY, - PixelPTEBytesPerRowC, - mode_lib->vba.dpte_row_height[k], - mode_lib->vba.dpte_row_height_chroma[k], - &mode_lib->vba.meta_row_bw[k], - &mode_lib->vba.dpte_row_bw[k], - &mode_lib->vba.qual_row_bw[k]); + CalculateActiveRowBandwidth( + mode_lib->vba.VirtualMemoryEnable, + mode_lib->vba.SourcePixelFormat[k], + mode_lib->vba.VRatio[k], + mode_lib->vba.DCCEnable[k], + mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k], + MetaRowByteY, + MetaRowByteC, + mode_lib->vba.meta_row_height[k], + mode_lib->vba.meta_row_height_chroma[k], + PixelPTEBytesPerRowY, + PixelPTEBytesPerRowC, + mode_lib->vba.dpte_row_height[k], + mode_lib->vba.dpte_row_height_chroma[k], + &mode_lib->vba.meta_row_bw[k], + &mode_lib->vba.dpte_row_bw[k], + &mode_lib->vba.qual_row_bw[k]); } mode_lib->vba.TCalc = 24.0 / mode_lib->vba.DCFClkDeepSleep; @@ -2164,32 +2537,37 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { if (mode_lib->vba.BlendingAndTiming[k] == k) { if (mode_lib->vba.WritebackEnable[k] == true) { - mode_lib->vba.WritebackDelay[k] = mode_lib->vba.WritebackLatency - + CalculateWriteBackDelay(mode_lib->vba.WritebackPixelFormat[k], - mode_lib->vba.WritebackHRatio[k], - mode_lib->vba.WritebackVRatio[k], - mode_lib->vba.WritebackLumaHTaps[k], - mode_lib->vba.WritebackLumaVTaps[k], - mode_lib->vba.WritebackChromaHTaps[k], - mode_lib->vba.WritebackChromaVTaps[k], - mode_lib->vba.WritebackDestinationWidth[k]) - / mode_lib->vba.DISPCLK; + mode_lib->vba.WritebackDelay[mode_lib->vba.VoltageLevel][k] = + mode_lib->vba.WritebackLatency + + CalculateWriteBackDelay( + mode_lib->vba.WritebackPixelFormat[k], + mode_lib->vba.WritebackHRatio[k], + mode_lib->vba.WritebackVRatio[k], + mode_lib->vba.WritebackLumaHTaps[k], + mode_lib->vba.WritebackLumaVTaps[k], + mode_lib->vba.WritebackChromaHTaps[k], + mode_lib->vba.WritebackChromaVTaps[k], + mode_lib->vba.WritebackDestinationWidth[k]) + / mode_lib->vba.DISPCLK; } else - mode_lib->vba.WritebackDelay[k] = 0; + mode_lib->vba.WritebackDelay[mode_lib->vba.VoltageLevel][k] = 0; for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) { - if (mode_lib->vba.BlendingAndTiming[j] == k && mode_lib->vba.WritebackEnable[j] == true) { - mode_lib->vba.WritebackDelay[k] = - dml_max(mode_lib->vba.WritebackDelay[k], - mode_lib->vba.WritebackLatency - + CalculateWriteBackDelay(mode_lib->vba.WritebackPixelFormat[j], - mode_lib->vba.WritebackHRatio[j], - mode_lib->vba.WritebackVRatio[j], - mode_lib->vba.WritebackLumaHTaps[j], - mode_lib->vba.WritebackLumaVTaps[j], - mode_lib->vba.WritebackChromaHTaps[j], - mode_lib->vba.WritebackChromaVTaps[j], - mode_lib->vba.WritebackDestinationWidth[j]) - / mode_lib->vba.DISPCLK); + if (mode_lib->vba.BlendingAndTiming[j] == k + && mode_lib->vba.WritebackEnable[j] == true) { + mode_lib->vba.WritebackDelay[mode_lib->vba.VoltageLevel][k] = + dml_max( + mode_lib->vba.WritebackDelay[mode_lib->vba.VoltageLevel][k], + mode_lib->vba.WritebackLatency + + CalculateWriteBackDelay( + mode_lib->vba.WritebackPixelFormat[j], + mode_lib->vba.WritebackHRatio[j], + mode_lib->vba.WritebackVRatio[j], + mode_lib->vba.WritebackLumaHTaps[j], + mode_lib->vba.WritebackLumaVTaps[j], + mode_lib->vba.WritebackChromaHTaps[j], + mode_lib->vba.WritebackChromaVTaps[j], + mode_lib->vba.WritebackDestinationWidth[j]) + / mode_lib->vba.DISPCLK); } } } @@ -2198,27 +2576,34 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) if (mode_lib->vba.BlendingAndTiming[k] == j) - mode_lib->vba.WritebackDelay[k] = mode_lib->vba.WritebackDelay[j]; + mode_lib->vba.WritebackDelay[mode_lib->vba.VoltageLevel][k] = + mode_lib->vba.WritebackDelay[mode_lib->vba.VoltageLevel][j]; mode_lib->vba.VStartupLines = 13; for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { mode_lib->vba.MaxVStartupLines[k] = - mode_lib->vba.VTotal[k] - mode_lib->vba.VActive[k] - - dml_max(1.0, - dml_ceil(mode_lib->vba.WritebackDelay[k] - / (mode_lib->vba.HTotal[k] - / mode_lib->vba.PixelClock[k]), - 1)); + mode_lib->vba.VTotal[k] - mode_lib->vba.VActive[k] + - dml_max( + 1.0, + dml_ceil( + mode_lib->vba.WritebackDelay[mode_lib->vba.VoltageLevel][k] + / (mode_lib->vba.HTotal[k] + / mode_lib->vba.PixelClock[k]), + 1)); } for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) - mode_lib->vba.MaximumMaxVStartupLines = dml_max(mode_lib->vba.MaximumMaxVStartupLines, mode_lib->vba.MaxVStartupLines[k]); + mode_lib->vba.MaximumMaxVStartupLines = dml_max( + mode_lib->vba.MaximumMaxVStartupLines, + mode_lib->vba.MaxVStartupLines[k]); for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { mode_lib->vba.cursor_bw[k] = 0.0; for (j = 0; j < mode_lib->vba.NumberOfCursors[k]; ++j) - mode_lib->vba.cursor_bw[k] += mode_lib->vba.CursorWidth[k][j] * mode_lib->vba.CursorBPP[k][j] / 8.0 - / (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]) * mode_lib->vba.VRatio[k]; + mode_lib->vba.cursor_bw[k] += mode_lib->vba.CursorWidth[k][j] + * mode_lib->vba.CursorBPP[k][j] / 8.0 + / (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]) + * mode_lib->vba.VRatio[k]; } do { @@ -2227,102 +2612,119 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman bool VRatioPrefetchMoreThan4 = false; bool prefetch_vm_bw_valid = true; bool prefetch_row_bw_valid = true; - double TWait = CalculateTWait(mode_lib->vba.PrefetchMode, - mode_lib->vba.DRAMClockChangeLatency, - mode_lib->vba.UrgentLatency, - mode_lib->vba.SREnterPlusExitTime); + double TWait = CalculateTWait( + mode_lib->vba.PrefetchMode, + mode_lib->vba.DRAMClockChangeLatency, + mode_lib->vba.UrgentLatency, + mode_lib->vba.SREnterPlusExitTime); for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { if (mode_lib->vba.XFCEnabled[k] == true) { - mode_lib->vba.XFCRemoteSurfaceFlipDelay = CalculateRemoteSurfaceFlipDelay(mode_lib, - mode_lib->vba.VRatio[k], - mode_lib->vba.SwathWidthY[k], - dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1), - mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k], - mode_lib->vba.XFCTSlvVupdateOffset, - mode_lib->vba.XFCTSlvVupdateWidth, - mode_lib->vba.XFCTSlvVreadyOffset, - mode_lib->vba.XFCXBUFLatencyTolerance, - mode_lib->vba.XFCFillBWOverhead, - mode_lib->vba.XFCSlvChunkSize, - mode_lib->vba.XFCBusTransportTime, - mode_lib->vba.TCalc, - TWait, - &mode_lib->vba.SrcActiveDrainRate, - &mode_lib->vba.TInitXFill, - &mode_lib->vba.TslvChk); + mode_lib->vba.XFCRemoteSurfaceFlipDelay = + CalculateRemoteSurfaceFlipDelay( + mode_lib, + mode_lib->vba.VRatio[k], + mode_lib->vba.SwathWidthY[k], + dml_ceil( + mode_lib->vba.BytePerPixelDETY[k], + 1), + mode_lib->vba.HTotal[k] + / mode_lib->vba.PixelClock[k], + mode_lib->vba.XFCTSlvVupdateOffset, + mode_lib->vba.XFCTSlvVupdateWidth, + mode_lib->vba.XFCTSlvVreadyOffset, + mode_lib->vba.XFCXBUFLatencyTolerance, + mode_lib->vba.XFCFillBWOverhead, + mode_lib->vba.XFCSlvChunkSize, + mode_lib->vba.XFCBusTransportTime, + mode_lib->vba.TCalc, + TWait, + &mode_lib->vba.SrcActiveDrainRate, + &mode_lib->vba.TInitXFill, + &mode_lib->vba.TslvChk); } else { mode_lib->vba.XFCRemoteSurfaceFlipDelay = 0; } - mode_lib->vba.ErrorResult[k] = CalculatePrefetchSchedule(mode_lib, - mode_lib->vba.DPPCLK[k], - mode_lib->vba.DISPCLK, - mode_lib->vba.PixelClock[k], - mode_lib->vba.DCFClkDeepSleep, - mode_lib->vba.DSCDelay[k], - mode_lib->vba.DPPPerPlane[k], - mode_lib->vba.ScalerEnabled[k], - mode_lib->vba.NumberOfCursors[k], - mode_lib->vba.DPPCLKDelaySubtotal, - mode_lib->vba.DPPCLKDelaySCL, - mode_lib->vba.DPPCLKDelaySCLLBOnly, - mode_lib->vba.DPPCLKDelayCNVCFormater, - mode_lib->vba.DPPCLKDelayCNVCCursor, - mode_lib->vba.DISPCLKDelaySubtotal, - (unsigned int)(mode_lib->vba.SwathWidthY[k] / mode_lib->vba.HRatio[k]), - mode_lib->vba.OutputFormat[k], - mode_lib->vba.VTotal[k] - mode_lib->vba.VActive[k], - mode_lib->vba.HTotal[k], - mode_lib->vba.MaxInterDCNTileRepeaters, - dml_min(mode_lib->vba.VStartupLines, mode_lib->vba.MaxVStartupLines[k]), - mode_lib->vba.MaxPageTableLevels, - mode_lib->vba.VirtualMemoryEnable, - mode_lib->vba.DynamicMetadataEnable[k], - mode_lib->vba.DynamicMetadataLinesBeforeActiveRequired[k], - mode_lib->vba.DynamicMetadataTransmittedBytes[k], - mode_lib->vba.DCCEnable[k], - mode_lib->vba.UrgentLatency, - mode_lib->vba.UrgentExtraLatency, - mode_lib->vba.TCalc, - mode_lib->vba.PDEAndMetaPTEBytesFrame[k], - mode_lib->vba.MetaRowByte[k], - mode_lib->vba.PixelPTEBytesPerRow[k], - mode_lib->vba.PrefetchSourceLinesY[k], - mode_lib->vba.SwathWidthY[k], - mode_lib->vba.BytePerPixelDETY[k], - mode_lib->vba.VInitPreFillY[k], - mode_lib->vba.MaxNumSwathY[k], - mode_lib->vba.PrefetchSourceLinesC[k], - mode_lib->vba.BytePerPixelDETC[k], - mode_lib->vba.VInitPreFillC[k], - mode_lib->vba.MaxNumSwathC[k], - mode_lib->vba.SwathHeightY[k], - mode_lib->vba.SwathHeightC[k], - TWait, - mode_lib->vba.XFCEnabled[k], - mode_lib->vba.XFCRemoteSurfaceFlipDelay, - mode_lib->vba.Interlace[k], - mode_lib->vba.ProgressiveToInterlaceUnitInOPP, - &mode_lib->vba.DSTXAfterScaler[k], - &mode_lib->vba.DSTYAfterScaler[k], - &mode_lib->vba.DestinationLinesForPrefetch[k], - &mode_lib->vba.PrefetchBandwidth[k], - &mode_lib->vba.DestinationLinesToRequestVMInVBlank[k], - &mode_lib->vba.DestinationLinesToRequestRowInVBlank[k], - &mode_lib->vba.VRatioPrefetchY[k], - &mode_lib->vba.VRatioPrefetchC[k], - &mode_lib->vba.RequiredPrefetchPixDataBW[k], - &mode_lib->vba.VStartupRequiredWhenNotEnoughTimeForDynamicMetadata, - &mode_lib->vba.Tno_bw[k]); + mode_lib->vba.ErrorResult[k] = + CalculatePrefetchSchedule( + mode_lib, + mode_lib->vba.DPPCLK[k], + mode_lib->vba.DISPCLK, + mode_lib->vba.PixelClock[k], + mode_lib->vba.DCFClkDeepSleep, + mode_lib->vba.DSCDelay[k], + mode_lib->vba.DPPPerPlane[k], + mode_lib->vba.ScalerEnabled[k], + mode_lib->vba.NumberOfCursors[k], + mode_lib->vba.DPPCLKDelaySubtotal, + mode_lib->vba.DPPCLKDelaySCL, + mode_lib->vba.DPPCLKDelaySCLLBOnly, + mode_lib->vba.DPPCLKDelayCNVCFormater, + mode_lib->vba.DPPCLKDelayCNVCCursor, + mode_lib->vba.DISPCLKDelaySubtotal, + (unsigned int) (mode_lib->vba.SwathWidthY[k] + / mode_lib->vba.HRatio[k]), + mode_lib->vba.OutputFormat[k], + mode_lib->vba.VTotal[k] + - mode_lib->vba.VActive[k], + mode_lib->vba.HTotal[k], + mode_lib->vba.MaxInterDCNTileRepeaters, + dml_min( + mode_lib->vba.VStartupLines, + mode_lib->vba.MaxVStartupLines[k]), + mode_lib->vba.MaxPageTableLevels, + mode_lib->vba.VirtualMemoryEnable, + mode_lib->vba.DynamicMetadataEnable[k], + mode_lib->vba.DynamicMetadataLinesBeforeActiveRequired[k], + mode_lib->vba.DynamicMetadataTransmittedBytes[k], + mode_lib->vba.DCCEnable[k], + mode_lib->vba.UrgentLatency, + mode_lib->vba.UrgentExtraLatency, + mode_lib->vba.TCalc, + mode_lib->vba.PDEAndMetaPTEBytesFrame[k], + mode_lib->vba.MetaRowByte[k], + mode_lib->vba.PixelPTEBytesPerRow[k], + mode_lib->vba.PrefetchSourceLinesY[k], + mode_lib->vba.SwathWidthY[k], + mode_lib->vba.BytePerPixelDETY[k], + mode_lib->vba.VInitPreFillY[k], + mode_lib->vba.MaxNumSwathY[k], + mode_lib->vba.PrefetchSourceLinesC[k], + mode_lib->vba.BytePerPixelDETC[k], + mode_lib->vba.VInitPreFillC[k], + mode_lib->vba.MaxNumSwathC[k], + mode_lib->vba.SwathHeightY[k], + mode_lib->vba.SwathHeightC[k], + TWait, + mode_lib->vba.XFCEnabled[k], + mode_lib->vba.XFCRemoteSurfaceFlipDelay, + mode_lib->vba.Interlace[k], + mode_lib->vba.ProgressiveToInterlaceUnitInOPP, + &mode_lib->vba.DSTXAfterScaler[k], + &mode_lib->vba.DSTYAfterScaler[k], + &mode_lib->vba.DestinationLinesForPrefetch[k], + &mode_lib->vba.PrefetchBandwidth[k], + &mode_lib->vba.DestinationLinesToRequestVMInVBlank[k], + &mode_lib->vba.DestinationLinesToRequestRowInVBlank[k], + &mode_lib->vba.VRatioPrefetchY[k], + &mode_lib->vba.VRatioPrefetchC[k], + &mode_lib->vba.RequiredPrefetchPixDataBW[k], + &mode_lib->vba.VStartupRequiredWhenNotEnoughTimeForDynamicMetadata, + &mode_lib->vba.Tno_bw[k]); if (mode_lib->vba.BlendingAndTiming[k] == k) { - mode_lib->vba.VStartup[k] = dml_min(mode_lib->vba.VStartupLines, mode_lib->vba.MaxVStartupLines[k]); - if (mode_lib->vba.VStartupRequiredWhenNotEnoughTimeForDynamicMetadata != 0) { + mode_lib->vba.VStartup[k] = dml_min( + mode_lib->vba.VStartupLines, + mode_lib->vba.MaxVStartupLines[k]); + if (mode_lib->vba.VStartupRequiredWhenNotEnoughTimeForDynamicMetadata + != 0) { mode_lib->vba.VStartup[k] = - mode_lib->vba.VStartupRequiredWhenNotEnoughTimeForDynamicMetadata; + mode_lib->vba.VStartupRequiredWhenNotEnoughTimeForDynamicMetadata; } } else { - mode_lib->vba.VStartup[k] = dml_min(mode_lib->vba.VStartupLines, - mode_lib->vba.MaxVStartupLines[mode_lib->vba.BlendingAndTiming[k]]); + mode_lib->vba.VStartup[k] = + dml_min( + mode_lib->vba.VStartupLines, + mode_lib->vba.MaxVStartupLines[mode_lib->vba.BlendingAndTiming[k]]); } } @@ -2331,116 +2733,136 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman if (mode_lib->vba.PDEAndMetaPTEBytesFrame[k] == 0) mode_lib->vba.prefetch_vm_bw[k] = 0; else if (mode_lib->vba.DestinationLinesToRequestVMInVBlank[k] > 0) { - mode_lib->vba.prefetch_vm_bw[k] = (double)mode_lib->vba.PDEAndMetaPTEBytesFrame[k] - / (mode_lib->vba.DestinationLinesToRequestVMInVBlank[k] - * mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]); + mode_lib->vba.prefetch_vm_bw[k] = + (double) mode_lib->vba.PDEAndMetaPTEBytesFrame[k] + / (mode_lib->vba.DestinationLinesToRequestVMInVBlank[k] + * mode_lib->vba.HTotal[k] + / mode_lib->vba.PixelClock[k]); } else { mode_lib->vba.prefetch_vm_bw[k] = 0; prefetch_vm_bw_valid = false; } - if (mode_lib->vba.MetaRowByte[k] + mode_lib->vba.PixelPTEBytesPerRow[k] == 0) + if (mode_lib->vba.MetaRowByte[k] + mode_lib->vba.PixelPTEBytesPerRow[k] + == 0) mode_lib->vba.prefetch_row_bw[k] = 0; else if (mode_lib->vba.DestinationLinesToRequestRowInVBlank[k] > 0) { - mode_lib->vba.prefetch_row_bw[k] = (double)(mode_lib->vba.MetaRowByte[k] - + mode_lib->vba.PixelPTEBytesPerRow[k]) - / (mode_lib->vba.DestinationLinesToRequestRowInVBlank[k] - * mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]); + mode_lib->vba.prefetch_row_bw[k] = + (double) (mode_lib->vba.MetaRowByte[k] + + mode_lib->vba.PixelPTEBytesPerRow[k]) + / (mode_lib->vba.DestinationLinesToRequestRowInVBlank[k] + * mode_lib->vba.HTotal[k] + / mode_lib->vba.PixelClock[k]); } else { mode_lib->vba.prefetch_row_bw[k] = 0; prefetch_row_bw_valid = false; } MaxTotalRDBandwidth = - MaxTotalRDBandwidth + mode_lib->vba.cursor_bw[k] - + dml_max(mode_lib->vba.prefetch_vm_bw[k], - dml_max(mode_lib->vba.prefetch_row_bw[k], - dml_max(mode_lib->vba.ReadBandwidthPlaneLuma[k] - + mode_lib->vba.ReadBandwidthPlaneChroma[k], - mode_lib->vba.RequiredPrefetchPixDataBW[k]) - + mode_lib->vba.meta_row_bw[k] - + mode_lib->vba.dpte_row_bw[k])); + MaxTotalRDBandwidth + mode_lib->vba.cursor_bw[k] + + dml_max( + mode_lib->vba.prefetch_vm_bw[k], + dml_max( + mode_lib->vba.prefetch_row_bw[k], + dml_max( + mode_lib->vba.ReadBandwidthPlaneLuma[k] + + mode_lib->vba.ReadBandwidthPlaneChroma[k], + mode_lib->vba.RequiredPrefetchPixDataBW[k]) + + mode_lib->vba.meta_row_bw[k] + + mode_lib->vba.dpte_row_bw[k])); if (mode_lib->vba.DestinationLinesForPrefetch[k] < 2) DestinationLineTimesForPrefetchLessThan2 = true; - if (mode_lib->vba.VRatioPrefetchY[k] > 4 || mode_lib->vba.VRatioPrefetchC[k] > 4) + if (mode_lib->vba.VRatioPrefetchY[k] > 4 + || mode_lib->vba.VRatioPrefetchC[k] > 4) VRatioPrefetchMoreThan4 = true; } - if (MaxTotalRDBandwidth <= mode_lib->vba.ReturnBW && prefetch_vm_bw_valid && prefetch_row_bw_valid - && !VRatioPrefetchMoreThan4 + if (MaxTotalRDBandwidth <= mode_lib->vba.ReturnBW && prefetch_vm_bw_valid + && prefetch_row_bw_valid && !VRatioPrefetchMoreThan4 && !DestinationLineTimesForPrefetchLessThan2) mode_lib->vba.PrefetchModeSupported = true; else { mode_lib->vba.PrefetchModeSupported = false; - dml_print("DML: CalculatePrefetchSchedule ***failed***. Bandwidth violation. Results are NOT valid\n"); + dml_print( + "DML: CalculatePrefetchSchedule ***failed***. Bandwidth violation. Results are NOT valid\n"); } if (mode_lib->vba.PrefetchModeSupported == true) { - double final_flip_bw[DC__NUM_PIPES__MAX]; - unsigned int ImmediateFlipBytes[DC__NUM_PIPES__MAX]; + double final_flip_bw[DC__NUM_DPP__MAX]; + unsigned int ImmediateFlipBytes[DC__NUM_DPP__MAX]; double total_dcn_read_bw_with_flip = 0; mode_lib->vba.BandwidthAvailableForImmediateFlip = mode_lib->vba.ReturnBW; for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { mode_lib->vba.BandwidthAvailableForImmediateFlip = - mode_lib->vba.BandwidthAvailableForImmediateFlip - mode_lib->vba.cursor_bw[k] - - dml_max(mode_lib->vba.ReadBandwidthPlaneLuma[k] - + mode_lib->vba.ReadBandwidthPlaneChroma[k] - + mode_lib->vba.qual_row_bw[k], - mode_lib->vba.PrefetchBandwidth[k]); + mode_lib->vba.BandwidthAvailableForImmediateFlip + - mode_lib->vba.cursor_bw[k] + - dml_max( + mode_lib->vba.ReadBandwidthPlaneLuma[k] + + mode_lib->vba.ReadBandwidthPlaneChroma[k] + + mode_lib->vba.qual_row_bw[k], + mode_lib->vba.PrefetchBandwidth[k]); } for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { ImmediateFlipBytes[k] = 0; if ((mode_lib->vba.SourcePixelFormat[k] != dm_420_8 - && mode_lib->vba.SourcePixelFormat[k] != dm_420_10)) { - ImmediateFlipBytes[k] = mode_lib->vba.PDEAndMetaPTEBytesFrame[k] - + mode_lib->vba.MetaRowByte[k] - + mode_lib->vba.PixelPTEBytesPerRow[k]; + && mode_lib->vba.SourcePixelFormat[k] != dm_420_10)) { + ImmediateFlipBytes[k] = + mode_lib->vba.PDEAndMetaPTEBytesFrame[k] + + mode_lib->vba.MetaRowByte[k] + + mode_lib->vba.PixelPTEBytesPerRow[k]; } } mode_lib->vba.TotImmediateFlipBytes = 0; for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { if ((mode_lib->vba.SourcePixelFormat[k] != dm_420_8 - && mode_lib->vba.SourcePixelFormat[k] != dm_420_10)) { - mode_lib->vba.TotImmediateFlipBytes = mode_lib->vba.TotImmediateFlipBytes - + ImmediateFlipBytes[k]; + && mode_lib->vba.SourcePixelFormat[k] != dm_420_10)) { + mode_lib->vba.TotImmediateFlipBytes = + mode_lib->vba.TotImmediateFlipBytes + + ImmediateFlipBytes[k]; } } for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { - CalculateFlipSchedule(mode_lib, - mode_lib->vba.UrgentExtraLatency, - mode_lib->vba.UrgentLatency, - mode_lib->vba.MaxPageTableLevels, - mode_lib->vba.VirtualMemoryEnable, - mode_lib->vba.BandwidthAvailableForImmediateFlip, - mode_lib->vba.TotImmediateFlipBytes, - mode_lib->vba.SourcePixelFormat[k], - ImmediateFlipBytes[k], - mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k], - mode_lib->vba.VRatio[k], - mode_lib->vba.Tno_bw[k], - mode_lib->vba.PDEAndMetaPTEBytesFrame[k], - mode_lib->vba.MetaRowByte[k], - mode_lib->vba.PixelPTEBytesPerRow[k], - mode_lib->vba.DCCEnable[k], - mode_lib->vba.dpte_row_height[k], - mode_lib->vba.meta_row_height[k], - mode_lib->vba.qual_row_bw[k], - &mode_lib->vba.DestinationLinesToRequestVMInImmediateFlip[k], - &mode_lib->vba.DestinationLinesToRequestRowInImmediateFlip[k], - &final_flip_bw[k], - &mode_lib->vba.ImmediateFlipSupportedForPipe[k]); + CalculateFlipSchedule( + mode_lib, + mode_lib->vba.UrgentExtraLatency, + mode_lib->vba.UrgentLatency, + mode_lib->vba.MaxPageTableLevels, + mode_lib->vba.VirtualMemoryEnable, + mode_lib->vba.BandwidthAvailableForImmediateFlip, + mode_lib->vba.TotImmediateFlipBytes, + mode_lib->vba.SourcePixelFormat[k], + ImmediateFlipBytes[k], + mode_lib->vba.HTotal[k] + / mode_lib->vba.PixelClock[k], + mode_lib->vba.VRatio[k], + mode_lib->vba.Tno_bw[k], + mode_lib->vba.PDEAndMetaPTEBytesFrame[k], + mode_lib->vba.MetaRowByte[k], + mode_lib->vba.PixelPTEBytesPerRow[k], + mode_lib->vba.DCCEnable[k], + mode_lib->vba.dpte_row_height[k], + mode_lib->vba.meta_row_height[k], + mode_lib->vba.qual_row_bw[k], + &mode_lib->vba.DestinationLinesToRequestVMInImmediateFlip[k], + &mode_lib->vba.DestinationLinesToRequestRowInImmediateFlip[k], + &final_flip_bw[k], + &mode_lib->vba.ImmediateFlipSupportedForPipe[k]); } for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { total_dcn_read_bw_with_flip = - total_dcn_read_bw_with_flip + mode_lib->vba.cursor_bw[k] - + dml_max(mode_lib->vba.prefetch_vm_bw[k], - dml_max(mode_lib->vba.prefetch_row_bw[k], - final_flip_bw[k] - + dml_max(mode_lib->vba.ReadBandwidthPlaneLuma[k] - + mode_lib->vba.ReadBandwidthPlaneChroma[k], - mode_lib->vba.RequiredPrefetchPixDataBW[k]))); + total_dcn_read_bw_with_flip + + mode_lib->vba.cursor_bw[k] + + dml_max( + mode_lib->vba.prefetch_vm_bw[k], + dml_max( + mode_lib->vba.prefetch_row_bw[k], + final_flip_bw[k] + + dml_max( + mode_lib->vba.ReadBandwidthPlaneLuma[k] + + mode_lib->vba.ReadBandwidthPlaneChroma[k], + mode_lib->vba.RequiredPrefetchPixDataBW[k]))); } mode_lib->vba.ImmediateFlipSupported = true; if (total_dcn_read_bw_with_flip > mode_lib->vba.ReturnBW) { @@ -2458,35 +2880,44 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { if (mode_lib->vba.ErrorResult[k]) { mode_lib->vba.PrefetchModeSupported = false; - dml_print("DML: CalculatePrefetchSchedule ***failed***. Prefetch schedule violation. Results are NOT valid\n"); + dml_print( + "DML: CalculatePrefetchSchedule ***failed***. Prefetch schedule violation. Results are NOT valid\n"); } } mode_lib->vba.VStartupLines = mode_lib->vba.VStartupLines + 1; } while (!((mode_lib->vba.PrefetchModeSupported - && (!mode_lib->vba.ImmediateFlipSupport || mode_lib->vba.ImmediateFlipSupported)) - || mode_lib->vba.MaximumMaxVStartupLines < mode_lib->vba.VStartupLines)); + && (!mode_lib->vba.ImmediateFlipSupport + || mode_lib->vba.ImmediateFlipSupported)) + || mode_lib->vba.MaximumMaxVStartupLines < mode_lib->vba.VStartupLines)); //Display Pipeline Delivery Time in Prefetch for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { if (mode_lib->vba.VRatioPrefetchY[k] <= 1) { - mode_lib->vba.DisplayPipeLineDeliveryTimeLumaPrefetch[k] = mode_lib->vba.SwathWidthY[k] - * mode_lib->vba.DPPPerPlane[k] / mode_lib->vba.HRatio[k] / mode_lib->vba.PixelClock[k]; + mode_lib->vba.DisplayPipeLineDeliveryTimeLumaPrefetch[k] = + mode_lib->vba.SwathWidthY[k] * mode_lib->vba.DPPPerPlane[k] + / mode_lib->vba.HRatio[k] + / mode_lib->vba.PixelClock[k]; } else { - mode_lib->vba.DisplayPipeLineDeliveryTimeLumaPrefetch[k] = mode_lib->vba.SwathWidthY[k] - / mode_lib->vba.PSCL_THROUGHPUT_LUMA[k] / mode_lib->vba.DPPCLK[k]; + mode_lib->vba.DisplayPipeLineDeliveryTimeLumaPrefetch[k] = + mode_lib->vba.SwathWidthY[k] + / mode_lib->vba.PSCL_THROUGHPUT_LUMA[k] + / mode_lib->vba.DPPCLK[k]; } if (mode_lib->vba.BytePerPixelDETC[k] == 0) { mode_lib->vba.DisplayPipeLineDeliveryTimeChromaPrefetch[k] = 0; } else { if (mode_lib->vba.VRatioPrefetchC[k] <= 1) { mode_lib->vba.DisplayPipeLineDeliveryTimeChromaPrefetch[k] = - mode_lib->vba.SwathWidthY[k] * mode_lib->vba.DPPPerPlane[k] / mode_lib->vba.HRatio[k] - / mode_lib->vba.PixelClock[k]; + mode_lib->vba.SwathWidthY[k] + * mode_lib->vba.DPPPerPlane[k] + / mode_lib->vba.HRatio[k] + / mode_lib->vba.PixelClock[k]; } else { mode_lib->vba.DisplayPipeLineDeliveryTimeChromaPrefetch[k] = - mode_lib->vba.SwathWidthY[k] / mode_lib->vba.PSCL_THROUGHPUT_LUMA[k] - / mode_lib->vba.DPPCLK[k]; + mode_lib->vba.SwathWidthY[k] + / mode_lib->vba.PSCL_THROUGHPUT_LUMA[k] + / mode_lib->vba.DPPCLK[k]; } } } @@ -2496,19 +2927,25 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman if (mode_lib->vba.PrefetchMode == 0) { mode_lib->vba.AllowDRAMClockChangeDuringVBlank[k] = true; mode_lib->vba.AllowDRAMSelfRefreshDuringVBlank[k] = true; - mode_lib->vba.MinTTUVBlank[k] = dml_max(mode_lib->vba.DRAMClockChangeWatermark, - dml_max(mode_lib->vba.StutterEnterPlusExitWatermark, mode_lib->vba.UrgentWatermark)); + mode_lib->vba.MinTTUVBlank[k] = dml_max( + mode_lib->vba.DRAMClockChangeWatermark, + dml_max( + mode_lib->vba.StutterEnterPlusExitWatermark, + mode_lib->vba.UrgentWatermark)); } else if (mode_lib->vba.PrefetchMode == 1) { mode_lib->vba.AllowDRAMClockChangeDuringVBlank[k] = false; mode_lib->vba.AllowDRAMSelfRefreshDuringVBlank[k] = true; - mode_lib->vba.MinTTUVBlank[k] = dml_max(mode_lib->vba.StutterEnterPlusExitWatermark, mode_lib->vba.UrgentWatermark); + mode_lib->vba.MinTTUVBlank[k] = dml_max( + mode_lib->vba.StutterEnterPlusExitWatermark, + mode_lib->vba.UrgentWatermark); } else { mode_lib->vba.AllowDRAMClockChangeDuringVBlank[k] = false; mode_lib->vba.AllowDRAMSelfRefreshDuringVBlank[k] = false; mode_lib->vba.MinTTUVBlank[k] = mode_lib->vba.UrgentWatermark; } if (!mode_lib->vba.DynamicMetadataEnable[k]) - mode_lib->vba.MinTTUVBlank[k] = mode_lib->vba.TCalc + mode_lib->vba.MinTTUVBlank[k]; + mode_lib->vba.MinTTUVBlank[k] = mode_lib->vba.TCalc + + mode_lib->vba.MinTTUVBlank[k]; } // DCC Configuration @@ -2528,33 +2965,43 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman double ActiveDRAMClockChangeLatencyMarginY; mode_lib->vba.LBLatencyHidingSourceLinesY = - dml_min(mode_lib->vba.MaxLineBufferLines, - (unsigned int)dml_floor((double)mode_lib->vba.LineBufferSize - / mode_lib->vba.LBBitPerPixel[k] - / (mode_lib->vba.SwathWidthY[k] - / dml_max(mode_lib->vba.HRatio[k], - 1.0)), - 1)) - (mode_lib->vba.vtaps[k] - 1); + dml_min( + mode_lib->vba.MaxLineBufferLines, + (unsigned int) dml_floor( + (double) mode_lib->vba.LineBufferSize + / mode_lib->vba.LBBitPerPixel[k] + / (mode_lib->vba.SwathWidthY[k] + / dml_max( + mode_lib->vba.HRatio[k], + 1.0)), + 1)) - (mode_lib->vba.vtaps[k] - 1); mode_lib->vba.LBLatencyHidingSourceLinesC = - dml_min(mode_lib->vba.MaxLineBufferLines, - (unsigned int)dml_floor((double)mode_lib->vba.LineBufferSize - / mode_lib->vba.LBBitPerPixel[k] - / (mode_lib->vba.SwathWidthY[k] - / 2.0 - / dml_max(mode_lib->vba.HRatio[k] - / 2, - 1.0)), - 1)) - (mode_lib->vba.VTAPsChroma[k] - 1); - - EffectiveLBLatencyHidingY = mode_lib->vba.LBLatencyHidingSourceLinesY / mode_lib->vba.VRatio[k] - * (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]); - - EffectiveLBLatencyHidingC = mode_lib->vba.LBLatencyHidingSourceLinesC / (mode_lib->vba.VRatio[k] / 2) - * (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]); + dml_min( + mode_lib->vba.MaxLineBufferLines, + (unsigned int) dml_floor( + (double) mode_lib->vba.LineBufferSize + / mode_lib->vba.LBBitPerPixel[k] + / (mode_lib->vba.SwathWidthY[k] + / 2.0 + / dml_max( + mode_lib->vba.HRatio[k] + / 2, + 1.0)), + 1)) + - (mode_lib->vba.VTAPsChroma[k] - 1); + + EffectiveLBLatencyHidingY = mode_lib->vba.LBLatencyHidingSourceLinesY + / mode_lib->vba.VRatio[k] + * (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]); + + EffectiveLBLatencyHidingC = mode_lib->vba.LBLatencyHidingSourceLinesC + / (mode_lib->vba.VRatio[k] / 2) + * (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]); if (mode_lib->vba.SwathWidthY[k] > 2 * mode_lib->vba.DPPOutputBufferPixels) { - DPPOutputBufferLinesY = mode_lib->vba.DPPOutputBufferPixels / mode_lib->vba.SwathWidthY[k]; + DPPOutputBufferLinesY = mode_lib->vba.DPPOutputBufferPixels + / mode_lib->vba.SwathWidthY[k]; } else if (mode_lib->vba.SwathWidthY[k] > mode_lib->vba.DPPOutputBufferPixels) { DPPOutputBufferLinesY = 0.5; } else { @@ -2562,7 +3009,8 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman } if (mode_lib->vba.SwathWidthY[k] / 2 > 2 * mode_lib->vba.DPPOutputBufferPixels) { - DPPOutputBufferLinesC = mode_lib->vba.DPPOutputBufferPixels / (mode_lib->vba.SwathWidthY[k] / 2); + DPPOutputBufferLinesC = mode_lib->vba.DPPOutputBufferPixels + / (mode_lib->vba.SwathWidthY[k] / 2); } else if (mode_lib->vba.SwathWidthY[k] / 2 > mode_lib->vba.DPPOutputBufferPixels) { DPPOutputBufferLinesC = 0.5; } else { @@ -2570,46 +3018,59 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman } DPPOPPBufferingY = (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]) - * (DPPOutputBufferLinesY + mode_lib->vba.OPPOutputBufferLines); + * (DPPOutputBufferLinesY + mode_lib->vba.OPPOutputBufferLines); MaxDETBufferingTimeY = mode_lib->vba.FullDETBufferingTimeY[k] - + (mode_lib->vba.LinesInDETY[k] - mode_lib->vba.LinesInDETYRoundedDownToSwath[k]) - / mode_lib->vba.SwathHeightY[k] * (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]); + + (mode_lib->vba.LinesInDETY[k] + - mode_lib->vba.LinesInDETYRoundedDownToSwath[k]) + / mode_lib->vba.SwathHeightY[k] + * (mode_lib->vba.HTotal[k] + / mode_lib->vba.PixelClock[k]); ActiveDRAMClockChangeLatencyMarginY = DPPOPPBufferingY + EffectiveLBLatencyHidingY - + MaxDETBufferingTimeY - mode_lib->vba.DRAMClockChangeWatermark; + + MaxDETBufferingTimeY - mode_lib->vba.DRAMClockChangeWatermark; if (mode_lib->vba.ActiveDPPs > 1) { - ActiveDRAMClockChangeLatencyMarginY = ActiveDRAMClockChangeLatencyMarginY - - (1 - 1 / (mode_lib->vba.ActiveDPPs - 1)) * mode_lib->vba.SwathHeightY[k] - * (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]); + ActiveDRAMClockChangeLatencyMarginY = + ActiveDRAMClockChangeLatencyMarginY + - (1 - 1 / (mode_lib->vba.ActiveDPPs - 1)) + * mode_lib->vba.SwathHeightY[k] + * (mode_lib->vba.HTotal[k] + / mode_lib->vba.PixelClock[k]); } if (mode_lib->vba.BytePerPixelDETC[k] > 0) { - double DPPOPPBufferingC = (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]) - * (DPPOutputBufferLinesC + mode_lib->vba.OPPOutputBufferLines); + double DPPOPPBufferingC = (mode_lib->vba.HTotal[k] + / mode_lib->vba.PixelClock[k]) + * (DPPOutputBufferLinesC + + mode_lib->vba.OPPOutputBufferLines); double MaxDETBufferingTimeC = - mode_lib->vba.FullDETBufferingTimeC[k] - + (mode_lib->vba.LinesInDETC[k] - - mode_lib->vba.LinesInDETCRoundedDownToSwath[k]) - / mode_lib->vba.SwathHeightC[k] - * (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]); + mode_lib->vba.FullDETBufferingTimeC[k] + + (mode_lib->vba.LinesInDETC[k] + - mode_lib->vba.LinesInDETCRoundedDownToSwath[k]) + / mode_lib->vba.SwathHeightC[k] + * (mode_lib->vba.HTotal[k] + / mode_lib->vba.PixelClock[k]); double ActiveDRAMClockChangeLatencyMarginC = DPPOPPBufferingC - + EffectiveLBLatencyHidingC + MaxDETBufferingTimeC - - mode_lib->vba.DRAMClockChangeWatermark; + + EffectiveLBLatencyHidingC + MaxDETBufferingTimeC + - mode_lib->vba.DRAMClockChangeWatermark; if (mode_lib->vba.ActiveDPPs > 1) { ActiveDRAMClockChangeLatencyMarginC = - ActiveDRAMClockChangeLatencyMarginC - - (1 - 1 / (mode_lib->vba.ActiveDPPs - 1)) - * mode_lib->vba.SwathHeightC[k] - * (mode_lib->vba.HTotal[k] - / mode_lib->vba.PixelClock[k]); - } - mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k] = dml_min(ActiveDRAMClockChangeLatencyMarginY, - ActiveDRAMClockChangeLatencyMarginC); + ActiveDRAMClockChangeLatencyMarginC + - (1 + - 1 + / (mode_lib->vba.ActiveDPPs + - 1)) + * mode_lib->vba.SwathHeightC[k] + * (mode_lib->vba.HTotal[k] + / mode_lib->vba.PixelClock[k]); + } + mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k] = dml_min( + ActiveDRAMClockChangeLatencyMarginY, + ActiveDRAMClockChangeLatencyMarginC); } else { mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k] = - ActiveDRAMClockChangeLatencyMarginY; + ActiveDRAMClockChangeLatencyMarginY; } if (mode_lib->vba.WritebackEnable[k]) { @@ -2617,51 +3078,60 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman if (mode_lib->vba.WritebackPixelFormat[k] == dm_444_32) { WritebackDRAMClockChangeLatencyMargin = - (double)(mode_lib->vba.WritebackInterfaceLumaBufferSize - + mode_lib->vba.WritebackInterfaceChromaBufferSize) - / (mode_lib->vba.WritebackDestinationWidth[k] - * mode_lib->vba.WritebackDestinationHeight[k] - / (mode_lib->vba.WritebackSourceHeight[k] - * mode_lib->vba.HTotal[k] - / mode_lib->vba.PixelClock[k]) - * 4) - - mode_lib->vba.WritebackDRAMClockChangeWatermark; + (double) (mode_lib->vba.WritebackInterfaceLumaBufferSize + + mode_lib->vba.WritebackInterfaceChromaBufferSize) + / (mode_lib->vba.WritebackDestinationWidth[k] + * mode_lib->vba.WritebackDestinationHeight[k] + / (mode_lib->vba.WritebackSourceHeight[k] + * mode_lib->vba.HTotal[k] + / mode_lib->vba.PixelClock[k]) + * 4) + - mode_lib->vba.WritebackDRAMClockChangeWatermark; } else if (mode_lib->vba.WritebackPixelFormat[k] == dm_420_10) { - WritebackDRAMClockChangeLatencyMargin = dml_min((double)mode_lib->vba.WritebackInterfaceLumaBufferSize * 8.0 - / 10, - 2.0 * mode_lib->vba.WritebackInterfaceChromaBufferSize * 8 / 10) - / (mode_lib->vba.WritebackDestinationWidth[k] - * mode_lib->vba.WritebackDestinationHeight[k] - / (mode_lib->vba.WritebackSourceHeight[k] - * mode_lib->vba.HTotal[k] - / mode_lib->vba.PixelClock[k])) - - mode_lib->vba.WritebackDRAMClockChangeWatermark; + WritebackDRAMClockChangeLatencyMargin = + dml_min( + (double) mode_lib->vba.WritebackInterfaceLumaBufferSize + * 8.0 / 10, + 2.0 + * mode_lib->vba.WritebackInterfaceChromaBufferSize + * 8 / 10) + / (mode_lib->vba.WritebackDestinationWidth[k] + * mode_lib->vba.WritebackDestinationHeight[k] + / (mode_lib->vba.WritebackSourceHeight[k] + * mode_lib->vba.HTotal[k] + / mode_lib->vba.PixelClock[k])) + - mode_lib->vba.WritebackDRAMClockChangeWatermark; } else { - WritebackDRAMClockChangeLatencyMargin = dml_min((double)mode_lib->vba.WritebackInterfaceLumaBufferSize, - 2.0 * mode_lib->vba.WritebackInterfaceChromaBufferSize) - / (mode_lib->vba.WritebackDestinationWidth[k] - * mode_lib->vba.WritebackDestinationHeight[k] - / (mode_lib->vba.WritebackSourceHeight[k] - * mode_lib->vba.HTotal[k] - / mode_lib->vba.PixelClock[k])) - - mode_lib->vba.WritebackDRAMClockChangeWatermark; + WritebackDRAMClockChangeLatencyMargin = + dml_min( + (double) mode_lib->vba.WritebackInterfaceLumaBufferSize, + 2.0 + * mode_lib->vba.WritebackInterfaceChromaBufferSize) + / (mode_lib->vba.WritebackDestinationWidth[k] + * mode_lib->vba.WritebackDestinationHeight[k] + / (mode_lib->vba.WritebackSourceHeight[k] + * mode_lib->vba.HTotal[k] + / mode_lib->vba.PixelClock[k])) + - mode_lib->vba.WritebackDRAMClockChangeWatermark; } - mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k] = dml_min(mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k], - WritebackDRAMClockChangeLatencyMargin); + mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k] = dml_min( + mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k], + WritebackDRAMClockChangeLatencyMargin); } } mode_lib->vba.MinActiveDRAMClockChangeMargin = 999999; for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { if (mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k] - < mode_lib->vba.MinActiveDRAMClockChangeMargin) { + < mode_lib->vba.MinActiveDRAMClockChangeMargin) { mode_lib->vba.MinActiveDRAMClockChangeMargin = - mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k]; + mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k]; } } - mode_lib->vba.MinActiveDRAMClockChangeLatencySupported = mode_lib->vba.MinActiveDRAMClockChangeMargin - + mode_lib->vba.DRAMClockChangeLatency; + mode_lib->vba.MinActiveDRAMClockChangeLatencySupported = + mode_lib->vba.MinActiveDRAMClockChangeMargin + + mode_lib->vba.DRAMClockChangeLatency; if (mode_lib->vba.MinActiveDRAMClockChangeMargin > 0) { mode_lib->vba.DRAMClockChangeSupport = dm_dram_clock_change_vactive; @@ -2670,7 +3140,8 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman mode_lib->vba.DRAMClockChangeSupport = dm_dram_clock_change_vblank; for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { if (!mode_lib->vba.AllowDRAMClockChangeDuringVBlank[k]) { - mode_lib->vba.DRAMClockChangeSupport = dm_dram_clock_change_unsupported; + mode_lib->vba.DRAMClockChangeSupport = + dm_dram_clock_change_unsupported; } } } else { @@ -2686,48 +3157,74 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman mode_lib->vba.XFCSlaveVUpdateOffset[k] = mode_lib->vba.XFCTSlvVupdateOffset; mode_lib->vba.XFCSlaveVupdateWidth[k] = mode_lib->vba.XFCTSlvVupdateWidth; mode_lib->vba.XFCSlaveVReadyOffset[k] = mode_lib->vba.XFCTSlvVreadyOffset; - TWait = CalculateTWait(mode_lib->vba.PrefetchMode, - mode_lib->vba.DRAMClockChangeLatency, - mode_lib->vba.UrgentLatency, - mode_lib->vba.SREnterPlusExitTime); - mode_lib->vba.XFCRemoteSurfaceFlipDelay = CalculateRemoteSurfaceFlipDelay(mode_lib, - mode_lib->vba.VRatio[k], - mode_lib->vba.SwathWidthY[k], - dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1), - mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k], - mode_lib->vba.XFCTSlvVupdateOffset, - mode_lib->vba.XFCTSlvVupdateWidth, - mode_lib->vba.XFCTSlvVreadyOffset, - mode_lib->vba.XFCXBUFLatencyTolerance, - mode_lib->vba.XFCFillBWOverhead, - mode_lib->vba.XFCSlvChunkSize, - mode_lib->vba.XFCBusTransportTime, - mode_lib->vba.TCalc, - TWait, - &mode_lib->vba.SrcActiveDrainRate, - &mode_lib->vba.TInitXFill, - &mode_lib->vba.TslvChk); - mode_lib->vba.XFCRemoteSurfaceFlipLatency[k] = dml_floor(mode_lib->vba.XFCRemoteSurfaceFlipDelay / (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]), - 1); - mode_lib->vba.XFCTransferDelay[k] = dml_ceil(mode_lib->vba.XFCBusTransportTime / (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]), - 1); - mode_lib->vba.XFCPrechargeDelay[k] = dml_ceil((mode_lib->vba.XFCBusTransportTime + mode_lib->vba.TInitXFill + mode_lib->vba.TslvChk) - / (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]), - 1); - mode_lib->vba.InitFillLevel = mode_lib->vba.XFCXBUFLatencyTolerance * mode_lib->vba.SrcActiveDrainRate; - mode_lib->vba.FinalFillMargin = (mode_lib->vba.DestinationLinesToRequestVMInVBlank[k] - + mode_lib->vba.DestinationLinesToRequestRowInVBlank[k]) * mode_lib->vba.HTotal[k] - / mode_lib->vba.PixelClock[k] * mode_lib->vba.SrcActiveDrainRate + mode_lib->vba.XFCFillConstant; - mode_lib->vba.FinalFillLevel = mode_lib->vba.XFCRemoteSurfaceFlipDelay * mode_lib->vba.SrcActiveDrainRate - + mode_lib->vba.FinalFillMargin; - mode_lib->vba.RemainingFillLevel = dml_max(0.0, - mode_lib->vba.FinalFillLevel - mode_lib->vba.InitFillLevel); + TWait = CalculateTWait( + mode_lib->vba.PrefetchMode, + mode_lib->vba.DRAMClockChangeLatency, + mode_lib->vba.UrgentLatency, + mode_lib->vba.SREnterPlusExitTime); + mode_lib->vba.XFCRemoteSurfaceFlipDelay = CalculateRemoteSurfaceFlipDelay( + mode_lib, + mode_lib->vba.VRatio[k], + mode_lib->vba.SwathWidthY[k], + dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1), + mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k], + mode_lib->vba.XFCTSlvVupdateOffset, + mode_lib->vba.XFCTSlvVupdateWidth, + mode_lib->vba.XFCTSlvVreadyOffset, + mode_lib->vba.XFCXBUFLatencyTolerance, + mode_lib->vba.XFCFillBWOverhead, + mode_lib->vba.XFCSlvChunkSize, + mode_lib->vba.XFCBusTransportTime, + mode_lib->vba.TCalc, + TWait, + &mode_lib->vba.SrcActiveDrainRate, + &mode_lib->vba.TInitXFill, + &mode_lib->vba.TslvChk); + mode_lib->vba.XFCRemoteSurfaceFlipLatency[k] = + dml_floor( + mode_lib->vba.XFCRemoteSurfaceFlipDelay + / (mode_lib->vba.HTotal[k] + / mode_lib->vba.PixelClock[k]), + 1); + mode_lib->vba.XFCTransferDelay[k] = + dml_ceil( + mode_lib->vba.XFCBusTransportTime + / (mode_lib->vba.HTotal[k] + / mode_lib->vba.PixelClock[k]), + 1); + mode_lib->vba.XFCPrechargeDelay[k] = + dml_ceil( + (mode_lib->vba.XFCBusTransportTime + + mode_lib->vba.TInitXFill + + mode_lib->vba.TslvChk) + / (mode_lib->vba.HTotal[k] + / mode_lib->vba.PixelClock[k]), + 1); + mode_lib->vba.InitFillLevel = mode_lib->vba.XFCXBUFLatencyTolerance + * mode_lib->vba.SrcActiveDrainRate; + mode_lib->vba.FinalFillMargin = + (mode_lib->vba.DestinationLinesToRequestVMInVBlank[k] + + mode_lib->vba.DestinationLinesToRequestRowInVBlank[k]) + * mode_lib->vba.HTotal[k] + / mode_lib->vba.PixelClock[k] + * mode_lib->vba.SrcActiveDrainRate + + mode_lib->vba.XFCFillConstant; + mode_lib->vba.FinalFillLevel = mode_lib->vba.XFCRemoteSurfaceFlipDelay + * mode_lib->vba.SrcActiveDrainRate + + mode_lib->vba.FinalFillMargin; + mode_lib->vba.RemainingFillLevel = dml_max( + 0.0, + mode_lib->vba.FinalFillLevel - mode_lib->vba.InitFillLevel); mode_lib->vba.TFinalxFill = mode_lib->vba.RemainingFillLevel - / (mode_lib->vba.SrcActiveDrainRate * mode_lib->vba.XFCFillBWOverhead / 100); - mode_lib->vba.XFCPrefetchMargin[k] = mode_lib->vba.XFCRemoteSurfaceFlipDelay + mode_lib->vba.TFinalxFill - + (mode_lib->vba.DestinationLinesToRequestVMInVBlank[k] - + mode_lib->vba.DestinationLinesToRequestRowInVBlank[k]) - * mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]; + / (mode_lib->vba.SrcActiveDrainRate + * mode_lib->vba.XFCFillBWOverhead / 100); + mode_lib->vba.XFCPrefetchMargin[k] = + mode_lib->vba.XFCRemoteSurfaceFlipDelay + + mode_lib->vba.TFinalxFill + + (mode_lib->vba.DestinationLinesToRequestVMInVBlank[k] + + mode_lib->vba.DestinationLinesToRequestRowInVBlank[k]) + * mode_lib->vba.HTotal[k] + / mode_lib->vba.PixelClock[k]; } else { mode_lib->vba.XFCSlaveVUpdateOffset[k] = 0; mode_lib->vba.XFCSlaveVupdateWidth[k] = 0; @@ -2782,21 +3279,22 @@ static void DisplayPipeConfiguration(struct display_mode_lib *mode_lib) BytePerPixDETC = 8.0 / 3.0; } - if ((mode_lib->vba.SourcePixelFormat[k] == dm_444_64 || mode_lib->vba.SourcePixelFormat[k] == dm_444_32 - || mode_lib->vba.SourcePixelFormat[k] == dm_444_16 - || mode_lib->vba.SourcePixelFormat[k] == dm_444_8)) { + if ((mode_lib->vba.SourcePixelFormat[k] == dm_444_64 + || mode_lib->vba.SourcePixelFormat[k] == dm_444_32 + || mode_lib->vba.SourcePixelFormat[k] == dm_444_16 + || mode_lib->vba.SourcePixelFormat[k] == dm_444_8)) { if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear) { Read256BytesBlockHeightY = 1; } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_64) { Read256BytesBlockHeightY = 4; } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_32 - || mode_lib->vba.SourcePixelFormat[k] == dm_444_16) { + || mode_lib->vba.SourcePixelFormat[k] == dm_444_16) { Read256BytesBlockHeightY = 8; } else { Read256BytesBlockHeightY = 16; } Read256BytesBlockWidthY = 256 / dml_ceil(BytePerPixDETY, 1) - / Read256BytesBlockHeightY; + / Read256BytesBlockHeightY; Read256BytesBlockHeightC = 0; Read256BytesBlockWidthC = 0; } else { @@ -2811,9 +3309,9 @@ static void DisplayPipeConfiguration(struct display_mode_lib *mode_lib) Read256BytesBlockHeightC = 8; } Read256BytesBlockWidthY = 256 / dml_ceil(BytePerPixDETY, 1) - / Read256BytesBlockHeightY; + / Read256BytesBlockHeightY; Read256BytesBlockWidthC = 256 / dml_ceil(BytePerPixDETC, 2) - / Read256BytesBlockHeightC; + / Read256BytesBlockHeightC; } if (mode_lib->vba.SourceScan[k] == dm_horz) { @@ -2824,27 +3322,30 @@ static void DisplayPipeConfiguration(struct display_mode_lib *mode_lib) MaximumSwathHeightC = Read256BytesBlockWidthC; } - if ((mode_lib->vba.SourcePixelFormat[k] == dm_444_64 || mode_lib->vba.SourcePixelFormat[k] == dm_444_32 - || mode_lib->vba.SourcePixelFormat[k] == dm_444_16 - || mode_lib->vba.SourcePixelFormat[k] == dm_444_8)) { + if ((mode_lib->vba.SourcePixelFormat[k] == dm_444_64 + || mode_lib->vba.SourcePixelFormat[k] == dm_444_32 + || mode_lib->vba.SourcePixelFormat[k] == dm_444_16 + || mode_lib->vba.SourcePixelFormat[k] == dm_444_8)) { if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear - || (mode_lib->vba.SourcePixelFormat[k] == dm_444_64 - && (mode_lib->vba.SurfaceTiling[k] == dm_sw_4kb_s - || mode_lib->vba.SurfaceTiling[k] - == dm_sw_4kb_s_x - || mode_lib->vba.SurfaceTiling[k] - == dm_sw_64kb_s - || mode_lib->vba.SurfaceTiling[k] - == dm_sw_64kb_s_t - || mode_lib->vba.SurfaceTiling[k] - == dm_sw_64kb_s_x - || mode_lib->vba.SurfaceTiling[k] - == dm_sw_var_s - || mode_lib->vba.SurfaceTiling[k] - == dm_sw_var_s_x) - && mode_lib->vba.SourceScan[k] == dm_horz)) { + || (mode_lib->vba.SourcePixelFormat[k] == dm_444_64 + && (mode_lib->vba.SurfaceTiling[k] + == dm_sw_4kb_s + || mode_lib->vba.SurfaceTiling[k] + == dm_sw_4kb_s_x + || mode_lib->vba.SurfaceTiling[k] + == dm_sw_64kb_s + || mode_lib->vba.SurfaceTiling[k] + == dm_sw_64kb_s_t + || mode_lib->vba.SurfaceTiling[k] + == dm_sw_64kb_s_x + || mode_lib->vba.SurfaceTiling[k] + == dm_sw_var_s + || mode_lib->vba.SurfaceTiling[k] + == dm_sw_var_s_x) + && mode_lib->vba.SourceScan[k] == dm_horz)) { MinimumSwathHeightY = MaximumSwathHeightY; - } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_8 && mode_lib->vba.SourceScan[k] != dm_horz) { + } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_8 + && mode_lib->vba.SourceScan[k] != dm_horz) { MinimumSwathHeightY = MaximumSwathHeightY; } else { MinimumSwathHeightY = MaximumSwathHeightY / 2.0; @@ -2854,10 +3355,12 @@ static void DisplayPipeConfiguration(struct display_mode_lib *mode_lib) if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear) { MinimumSwathHeightY = MaximumSwathHeightY; MinimumSwathHeightC = MaximumSwathHeightC; - } else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8 && mode_lib->vba.SourceScan[k] == dm_horz) { + } else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8 + && mode_lib->vba.SourceScan[k] == dm_horz) { MinimumSwathHeightY = MaximumSwathHeightY / 2.0; MinimumSwathHeightC = MaximumSwathHeightC; - } else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10 && mode_lib->vba.SourceScan[k] == dm_horz) { + } else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10 + && mode_lib->vba.SourceScan[k] == dm_horz) { MinimumSwathHeightC = MaximumSwathHeightC / 2.0; MinimumSwathHeightY = MaximumSwathHeightY; } else { @@ -2876,40 +3379,46 @@ static void DisplayPipeConfiguration(struct display_mode_lib *mode_lib) MainPlaneDoesODMCombine = true; } for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) { - if (mode_lib->vba.BlendingAndTiming[k] == j && mode_lib->vba.ODMCombineEnabled[j] == true) { + if (mode_lib->vba.BlendingAndTiming[k] == j + && mode_lib->vba.ODMCombineEnabled[j] == true) { MainPlaneDoesODMCombine = true; } } if (MainPlaneDoesODMCombine == true) { - SwathWidth = dml_min(SwathWidth, mode_lib->vba.HActive[k] / 2.0 * mode_lib->vba.HRatio[k]); + SwathWidth = dml_min( + SwathWidth, + mode_lib->vba.HActive[k] / 2.0 * mode_lib->vba.HRatio[k]); } else { SwathWidth = SwathWidth / mode_lib->vba.DPPPerPlane[k]; } SwathWidthGranularityY = 256 / dml_ceil(BytePerPixDETY, 1) / MaximumSwathHeightY; - RoundedUpMaxSwathSizeBytesY = (dml_ceil((double)(SwathWidth - 1), - SwathWidthGranularityY) + SwathWidthGranularityY) * BytePerPixDETY - * MaximumSwathHeightY; + RoundedUpMaxSwathSizeBytesY = (dml_ceil( + (double) (SwathWidth - 1), + SwathWidthGranularityY) + SwathWidthGranularityY) * BytePerPixDETY + * MaximumSwathHeightY; if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10) { RoundedUpMaxSwathSizeBytesY = dml_ceil(RoundedUpMaxSwathSizeBytesY, 256) - + 256; + + 256; } if (MaximumSwathHeightC > 0) { SwathWidthGranularityC = 256.0 / dml_ceil(BytePerPixDETC, 2) - / MaximumSwathHeightC; - RoundedUpMaxSwathSizeBytesC = (dml_ceil((double)(SwathWidth / 2.0 - 1), - SwathWidthGranularityC) + SwathWidthGranularityC) - * BytePerPixDETC * MaximumSwathHeightC; + / MaximumSwathHeightC; + RoundedUpMaxSwathSizeBytesC = (dml_ceil( + (double) (SwathWidth / 2.0 - 1), + SwathWidthGranularityC) + SwathWidthGranularityC) + * BytePerPixDETC * MaximumSwathHeightC; if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10) { - RoundedUpMaxSwathSizeBytesC = dml_ceil(RoundedUpMaxSwathSizeBytesC, - 256) + 256; + RoundedUpMaxSwathSizeBytesC = dml_ceil( + RoundedUpMaxSwathSizeBytesC, + 256) + 256; } } else RoundedUpMaxSwathSizeBytesC = 0.0; if (RoundedUpMaxSwathSizeBytesY + RoundedUpMaxSwathSizeBytesC - <= mode_lib->vba.DETBufferSizeInKByte * 1024.0 / 2.0) { + <= mode_lib->vba.DETBufferSizeInKByte * 1024.0 / 2.0) { mode_lib->vba.SwathHeightY[k] = MaximumSwathHeightY; mode_lib->vba.SwathHeightC[k] = MaximumSwathHeightC; } else { @@ -2921,27 +3430,32 @@ static void DisplayPipeConfiguration(struct display_mode_lib *mode_lib) mode_lib->vba.DETBufferSizeY[k] = mode_lib->vba.DETBufferSizeInKByte * 1024; mode_lib->vba.DETBufferSizeC[k] = 0; } else if (mode_lib->vba.SwathHeightY[k] <= mode_lib->vba.SwathHeightC[k]) { - mode_lib->vba.DETBufferSizeY[k] = mode_lib->vba.DETBufferSizeInKByte * 1024.0 / 2; - mode_lib->vba.DETBufferSizeC[k] = mode_lib->vba.DETBufferSizeInKByte * 1024.0 / 2; + mode_lib->vba.DETBufferSizeY[k] = mode_lib->vba.DETBufferSizeInKByte + * 1024.0 / 2; + mode_lib->vba.DETBufferSizeC[k] = mode_lib->vba.DETBufferSizeInKByte + * 1024.0 / 2; } else { - mode_lib->vba.DETBufferSizeY[k] = mode_lib->vba.DETBufferSizeInKByte * 1024.0 * 2 / 3; - mode_lib->vba.DETBufferSizeC[k] = mode_lib->vba.DETBufferSizeInKByte * 1024.0 / 3; + mode_lib->vba.DETBufferSizeY[k] = mode_lib->vba.DETBufferSizeInKByte + * 1024.0 * 2 / 3; + mode_lib->vba.DETBufferSizeC[k] = mode_lib->vba.DETBufferSizeInKByte + * 1024.0 / 3; } } } -bool Calculate256BBlockSizes(enum source_format_class SourcePixelFormat, - enum dm_swizzle_mode SurfaceTiling, - unsigned int BytePerPixelY, - unsigned int BytePerPixelC, - unsigned int *BlockHeight256BytesY, - unsigned int *BlockHeight256BytesC, - unsigned int *BlockWidth256BytesY, - unsigned int *BlockWidth256BytesC) +bool Calculate256BBlockSizes( + enum source_format_class SourcePixelFormat, + enum dm_swizzle_mode SurfaceTiling, + unsigned int BytePerPixelY, + unsigned int BytePerPixelC, + unsigned int *BlockHeight256BytesY, + unsigned int *BlockHeight256BytesC, + unsigned int *BlockWidth256BytesY, + unsigned int *BlockWidth256BytesC) { if ((SourcePixelFormat == dm_444_64 || SourcePixelFormat == dm_444_32 - || SourcePixelFormat == dm_444_16 || SourcePixelFormat == dm_444_16 - || SourcePixelFormat == dm_444_8)) { + || SourcePixelFormat == dm_444_16 || SourcePixelFormat == dm_444_16 + || SourcePixelFormat == dm_444_8)) { if (SurfaceTiling == dm_sw_linear) { *BlockHeight256BytesY = 1; } else if (SourcePixelFormat == dm_444_64) { @@ -2971,14 +3485,16 @@ bool Calculate256BBlockSizes(enum source_format_class SourcePixelFormat, return true; } -static double CalculateTWait(unsigned int PrefetchMode, - double DRAMClockChangeLatency, - double UrgentLatency, - double SREnterPlusExitTime) +static double CalculateTWait( + unsigned int PrefetchMode, + double DRAMClockChangeLatency, + double UrgentLatency, + double SREnterPlusExitTime) { if (PrefetchMode == 0) { - return dml_max(DRAMClockChangeLatency + UrgentLatency, - dml_max(SREnterPlusExitTime, UrgentLatency)); + return dml_max( + DRAMClockChangeLatency + UrgentLatency, + dml_max(SREnterPlusExitTime, UrgentLatency)); } else if (PrefetchMode == 1) { return dml_max(SREnterPlusExitTime, UrgentLatency); } else { @@ -2986,23 +3502,24 @@ static double CalculateTWait(unsigned int PrefetchMode, } } -static double CalculateRemoteSurfaceFlipDelay(struct display_mode_lib *mode_lib, - double VRatio, - double SwathWidth, - double Bpp, - double LineTime, - double XFCTSlvVupdateOffset, - double XFCTSlvVupdateWidth, - double XFCTSlvVreadyOffset, - double XFCXBUFLatencyTolerance, - double XFCFillBWOverhead, - double XFCSlvChunkSize, - double XFCBusTransportTime, - double TCalc, - double TWait, - double *SrcActiveDrainRate, - double *TInitXFill, - double *TslvChk) +static double CalculateRemoteSurfaceFlipDelay( + struct display_mode_lib *mode_lib, + double VRatio, + double SwathWidth, + double Bpp, + double LineTime, + double XFCTSlvVupdateOffset, + double XFCTSlvVupdateWidth, + double XFCTSlvVreadyOffset, + double XFCXBUFLatencyTolerance, + double XFCFillBWOverhead, + double XFCSlvChunkSize, + double XFCBusTransportTime, + double TCalc, + double TWait, + double *SrcActiveDrainRate, + double *TInitXFill, + double *TslvChk) { double TSlvSetup, AvgfillRate, result; @@ -3011,8 +3528,9 @@ static double CalculateRemoteSurfaceFlipDelay(struct display_mode_lib *mode_lib, *TInitXFill = XFCXBUFLatencyTolerance / (1 + XFCFillBWOverhead / 100); AvgfillRate = *SrcActiveDrainRate * (1 + XFCFillBWOverhead / 100); *TslvChk = XFCSlvChunkSize / AvgfillRate; - dml_print("DML::CalculateRemoteSurfaceFlipDelay: SrcActiveDrainRate: %f\n", - *SrcActiveDrainRate); + dml_print( + "DML::CalculateRemoteSurfaceFlipDelay: SrcActiveDrainRate: %f\n", + *SrcActiveDrainRate); dml_print("DML::CalculateRemoteSurfaceFlipDelay: TSlvSetup: %f\n", TSlvSetup); dml_print("DML::CalculateRemoteSurfaceFlipDelay: TInitXFill: %f\n", *TInitXFill); dml_print("DML::CalculateRemoteSurfaceFlipDelay: AvgfillRate: %f\n", AvgfillRate); @@ -3022,99 +3540,192 @@ static double CalculateRemoteSurfaceFlipDelay(struct display_mode_lib *mode_lib, return result; } -static double CalculateWriteBackDISPCLK(enum source_format_class WritebackPixelFormat, - double PixelClock, - double WritebackHRatio, - double WritebackVRatio, - unsigned int WritebackLumaHTaps, - unsigned int WritebackLumaVTaps, - unsigned int WritebackChromaHTaps, - unsigned int WritebackChromaVTaps, - double WritebackDestinationWidth, - unsigned int HTotal, - unsigned int WritebackChromaLineBufferWidth) +static double CalculateWriteBackDISPCLK( + enum source_format_class WritebackPixelFormat, + double PixelClock, + double WritebackHRatio, + double WritebackVRatio, + unsigned int WritebackLumaHTaps, + unsigned int WritebackLumaVTaps, + unsigned int WritebackChromaHTaps, + unsigned int WritebackChromaVTaps, + double WritebackDestinationWidth, + unsigned int HTotal, + unsigned int WritebackChromaLineBufferWidth) { - double CalculateWriteBackDISPCLK = 1.01 * PixelClock - * dml_max( - dml_ceil(WritebackLumaHTaps / 4.0, 1) / WritebackHRatio, - dml_max( - (WritebackLumaVTaps * dml_ceil(1.0 / WritebackVRatio, 1) - * dml_ceil(WritebackDestinationWidth / 4.0, 1) - + dml_ceil(WritebackDestinationWidth / 4.0, 1)) / (double)HTotal - + dml_ceil(1.0 / WritebackVRatio, 1) * (dml_ceil(WritebackLumaVTaps / 4.0, 1) + 4.0) - / (double)HTotal, - dml_ceil(1.0 / WritebackVRatio, 1) * WritebackDestinationWidth / (double)HTotal)); - if (WritebackPixelFormat != dm_444_32) { - CalculateWriteBackDISPCLK = dml_max( - CalculateWriteBackDISPCLK, + double CalculateWriteBackDISPCLK = 1.01 * PixelClock - * dml_max( - dml_ceil(WritebackChromaHTaps / 2.0, 1) / (2 * WritebackHRatio), + * dml_max( + dml_ceil(WritebackLumaHTaps / 4.0, 1) + / WritebackHRatio, + dml_max( + (WritebackLumaVTaps + * dml_ceil( + 1.0 + / WritebackVRatio, + 1) + * dml_ceil( + WritebackDestinationWidth + / 4.0, + 1) + + dml_ceil( + WritebackDestinationWidth + / 4.0, + 1)) + / (double) HTotal + + dml_ceil( + 1.0 + / WritebackVRatio, + 1) + * (dml_ceil( + WritebackLumaVTaps + / 4.0, + 1) + + 4.0) + / (double) HTotal, + dml_ceil( + 1.0 + / WritebackVRatio, + 1) + * WritebackDestinationWidth + / (double) HTotal)); + if (WritebackPixelFormat != dm_444_32) { + CalculateWriteBackDISPCLK = dml_max( - (WritebackChromaVTaps * dml_ceil(1 / (2 * WritebackVRatio), 1) - * dml_ceil(WritebackDestinationWidth / 2.0 / 2.0, 1) - + dml_ceil(WritebackDestinationWidth / 2.0 / WritebackChromaLineBufferWidth, 1)) - / HTotal - + dml_ceil(1 / (2 * WritebackVRatio), 1) - * (dml_ceil(WritebackChromaVTaps / 4.0, 1) + 4) / HTotal, - dml_ceil(1.0 / (2 * WritebackVRatio), 1) * WritebackDestinationWidth / 2.0 - / HTotal))); + CalculateWriteBackDISPCLK, + 1.01 * PixelClock + * dml_max( + dml_ceil( + WritebackChromaHTaps + / 2.0, + 1) + / (2 + * WritebackHRatio), + dml_max( + (WritebackChromaVTaps + * dml_ceil( + 1 + / (2 + * WritebackVRatio), + 1) + * dml_ceil( + WritebackDestinationWidth + / 2.0 + / 2.0, + 1) + + dml_ceil( + WritebackDestinationWidth + / 2.0 + / WritebackChromaLineBufferWidth, + 1)) + / HTotal + + dml_ceil( + 1 + / (2 + * WritebackVRatio), + 1) + * (dml_ceil( + WritebackChromaVTaps + / 4.0, + 1) + + 4) + / HTotal, + dml_ceil( + 1.0 + / (2 + * WritebackVRatio), + 1) + * WritebackDestinationWidth + / 2.0 + / HTotal))); } return CalculateWriteBackDISPCLK; } static double CalculateWriteBackDelay( -enum source_format_class WritebackPixelFormat, - double WritebackHRatio, - double WritebackVRatio, - unsigned int WritebackLumaHTaps, - unsigned int WritebackLumaVTaps, - unsigned int WritebackChromaHTaps, - unsigned int WritebackChromaVTaps, - unsigned int WritebackDestinationWidth) + enum source_format_class WritebackPixelFormat, + double WritebackHRatio, + double WritebackVRatio, + unsigned int WritebackLumaHTaps, + unsigned int WritebackLumaVTaps, + unsigned int WritebackChromaHTaps, + unsigned int WritebackChromaVTaps, + unsigned int WritebackDestinationWidth) { - double CalculateWriteBackDelay = dml_max( - dml_ceil(WritebackLumaHTaps / 4.0, 1) / WritebackHRatio, - WritebackLumaVTaps * dml_ceil(1.0 / WritebackVRatio, 1) - * dml_ceil(WritebackDestinationWidth / 4.0, 1) - + dml_ceil(1.0 / WritebackVRatio, 1) * (dml_ceil(WritebackLumaVTaps / 4.0, 1) + 4)); + double CalculateWriteBackDelay = + dml_max( + dml_ceil(WritebackLumaHTaps / 4.0, 1) / WritebackHRatio, + WritebackLumaVTaps * dml_ceil(1.0 / WritebackVRatio, 1) + * dml_ceil( + WritebackDestinationWidth + / 4.0, + 1) + + dml_ceil(1.0 / WritebackVRatio, 1) + * (dml_ceil( + WritebackLumaVTaps + / 4.0, + 1) + 4)); if (WritebackPixelFormat != dm_444_32) { - CalculateWriteBackDelay = dml_max( - CalculateWriteBackDelay, - dml_max( - dml_ceil(WritebackChromaHTaps / 2.0, 1) / (2 * WritebackHRatio), - WritebackChromaVTaps * dml_ceil(1 / (2 * WritebackVRatio), 1) - * dml_ceil(WritebackDestinationWidth / 2.0 / 2.0, 1) - + dml_ceil(1 / (2 * WritebackVRatio), 1) - * (dml_ceil(WritebackChromaVTaps / 4.0, 1) + 4))); + CalculateWriteBackDelay = + dml_max( + CalculateWriteBackDelay, + dml_max( + dml_ceil( + WritebackChromaHTaps + / 2.0, + 1) + / (2 + * WritebackHRatio), + WritebackChromaVTaps + * dml_ceil( + 1 + / (2 + * WritebackVRatio), + 1) + * dml_ceil( + WritebackDestinationWidth + / 2.0 + / 2.0, + 1) + + dml_ceil( + 1 + / (2 + * WritebackVRatio), + 1) + * (dml_ceil( + WritebackChromaVTaps + / 4.0, + 1) + + 4))); } return CalculateWriteBackDelay; } -static void CalculateActiveRowBandwidth(bool VirtualMemoryEnable, - enum source_format_class SourcePixelFormat, - double VRatio, - bool DCCEnable, - double LineTime, - unsigned int MetaRowByteLuma, - unsigned int MetaRowByteChroma, - unsigned int meta_row_height_luma, - unsigned int meta_row_height_chroma, - unsigned int PixelPTEBytesPerRowLuma, - unsigned int PixelPTEBytesPerRowChroma, - unsigned int dpte_row_height_luma, - unsigned int dpte_row_height_chroma, - double *meta_row_bw, - double *dpte_row_bw, - double *qual_row_bw) +static void CalculateActiveRowBandwidth( + bool VirtualMemoryEnable, + enum source_format_class SourcePixelFormat, + double VRatio, + bool DCCEnable, + double LineTime, + unsigned int MetaRowByteLuma, + unsigned int MetaRowByteChroma, + unsigned int meta_row_height_luma, + unsigned int meta_row_height_chroma, + unsigned int PixelPTEBytesPerRowLuma, + unsigned int PixelPTEBytesPerRowChroma, + unsigned int dpte_row_height_luma, + unsigned int dpte_row_height_chroma, + double *meta_row_bw, + double *dpte_row_bw, + double *qual_row_bw) { if (DCCEnable != true) { *meta_row_bw = 0; } else if (SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10) { *meta_row_bw = VRatio * MetaRowByteLuma / (meta_row_height_luma * LineTime) - + VRatio / 2 * MetaRowByteChroma - / (meta_row_height_chroma * LineTime); + + VRatio / 2 * MetaRowByteChroma + / (meta_row_height_chroma * LineTime); } else { *meta_row_bw = VRatio * MetaRowByteLuma / (meta_row_height_luma * LineTime); } @@ -3123,8 +3734,8 @@ static void CalculateActiveRowBandwidth(bool VirtualMemoryEnable, *dpte_row_bw = 0; } else if (SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10) { *dpte_row_bw = VRatio * PixelPTEBytesPerRowLuma / (dpte_row_height_luma * LineTime) - + VRatio / 2 * PixelPTEBytesPerRowChroma - / (dpte_row_height_chroma * LineTime); + + VRatio / 2 * PixelPTEBytesPerRowChroma + / (dpte_row_height_chroma * LineTime); } else { *dpte_row_bw = VRatio * PixelPTEBytesPerRowLuma / (dpte_row_height_luma * LineTime); } @@ -3136,29 +3747,30 @@ static void CalculateActiveRowBandwidth(bool VirtualMemoryEnable, } } -static void CalculateFlipSchedule(struct display_mode_lib *mode_lib, - double UrgentExtraLatency, - double UrgentLatency, - unsigned int MaxPageTableLevels, - bool VirtualMemoryEnable, - double BandwidthAvailableForImmediateFlip, - unsigned int TotImmediateFlipBytes, - enum source_format_class SourcePixelFormat, - unsigned int ImmediateFlipBytes, - double LineTime, - double Tno_bw, - double VRatio, - double PDEAndMetaPTEBytesFrame, - unsigned int MetaRowByte, - unsigned int PixelPTEBytesPerRow, - bool DCCEnable, - unsigned int dpte_row_height, - unsigned int meta_row_height, - double qual_row_bw, - double *DestinationLinesToRequestVMInImmediateFlip, - double *DestinationLinesToRequestRowInImmediateFlip, - double *final_flip_bw, - bool *ImmediateFlipSupportedForPipe) +static void CalculateFlipSchedule( + struct display_mode_lib *mode_lib, + double UrgentExtraLatency, + double UrgentLatency, + unsigned int MaxPageTableLevels, + bool VirtualMemoryEnable, + double BandwidthAvailableForImmediateFlip, + unsigned int TotImmediateFlipBytes, + enum source_format_class SourcePixelFormat, + unsigned int ImmediateFlipBytes, + double LineTime, + double Tno_bw, + double VRatio, + double PDEAndMetaPTEBytesFrame, + unsigned int MetaRowByte, + unsigned int PixelPTEBytesPerRow, + bool DCCEnable, + unsigned int dpte_row_height, + unsigned int meta_row_height, + double qual_row_bw, + double *DestinationLinesToRequestVMInImmediateFlip, + double *DestinationLinesToRequestRowInImmediateFlip, + double *final_flip_bw, + bool *ImmediateFlipSupportedForPipe) { double min_row_time = 0.0; @@ -3172,47 +3784,54 @@ static void CalculateFlipSchedule(struct display_mode_lib *mode_lib, double TimeForFetchingRowInVBlankImmediateFlip; if (VirtualMemoryEnable == true) { - mode_lib->vba.ImmediateFlipBW = BandwidthAvailableForImmediateFlip * ImmediateFlipBytes - / TotImmediateFlipBytes; + mode_lib->vba.ImmediateFlipBW = BandwidthAvailableForImmediateFlip + * ImmediateFlipBytes / TotImmediateFlipBytes; TimeForFetchingMetaPTEImmediateFlip = - dml_max(Tno_bw - + PDEAndMetaPTEBytesFrame - / mode_lib->vba.ImmediateFlipBW, - dml_max(UrgentExtraLatency - + UrgentLatency - * (MaxPageTableLevels - - 1), - LineTime / 4.0)); + dml_max( + Tno_bw + + PDEAndMetaPTEBytesFrame + / mode_lib->vba.ImmediateFlipBW, + dml_max( + UrgentExtraLatency + + UrgentLatency + * (MaxPageTableLevels + - 1), + LineTime / 4.0)); } else { TimeForFetchingMetaPTEImmediateFlip = 0; } - *DestinationLinesToRequestVMInImmediateFlip = dml_floor(4.0 * (TimeForFetchingMetaPTEImmediateFlip / LineTime + 0.125), - 1) / 4.0; + *DestinationLinesToRequestVMInImmediateFlip = dml_floor( + 4.0 * (TimeForFetchingMetaPTEImmediateFlip / LineTime + 0.125), + 1) / 4.0; if ((VirtualMemoryEnable == true || DCCEnable == true)) { - mode_lib->vba.ImmediateFlipBW = BandwidthAvailableForImmediateFlip * ImmediateFlipBytes - / TotImmediateFlipBytes; - TimeForFetchingRowInVBlankImmediateFlip = dml_max((MetaRowByte + PixelPTEBytesPerRow) / mode_lib->vba.ImmediateFlipBW, - dml_max(UrgentLatency, LineTime / 4.0)); + mode_lib->vba.ImmediateFlipBW = BandwidthAvailableForImmediateFlip + * ImmediateFlipBytes / TotImmediateFlipBytes; + TimeForFetchingRowInVBlankImmediateFlip = dml_max( + (MetaRowByte + PixelPTEBytesPerRow) + / mode_lib->vba.ImmediateFlipBW, + dml_max(UrgentLatency, LineTime / 4.0)); } else { TimeForFetchingRowInVBlankImmediateFlip = 0; } - *DestinationLinesToRequestRowInImmediateFlip = dml_floor(4.0 * (TimeForFetchingRowInVBlankImmediateFlip / LineTime + 0.125), - 1) / 4.0; + *DestinationLinesToRequestRowInImmediateFlip = dml_floor( + 4.0 * (TimeForFetchingRowInVBlankImmediateFlip / LineTime + 0.125), + 1) / 4.0; if (VirtualMemoryEnable == true) { *final_flip_bw = - dml_max(PDEAndMetaPTEBytesFrame - / (*DestinationLinesToRequestVMInImmediateFlip - * LineTime), - (MetaRowByte + PixelPTEBytesPerRow) - / (TimeForFetchingRowInVBlankImmediateFlip - * LineTime)); + dml_max( + PDEAndMetaPTEBytesFrame + / (*DestinationLinesToRequestVMInImmediateFlip + * LineTime), + (MetaRowByte + PixelPTEBytesPerRow) + / (TimeForFetchingRowInVBlankImmediateFlip + * LineTime)); } else if (MetaRowByte + PixelPTEBytesPerRow > 0) { *final_flip_bw = (MetaRowByte + PixelPTEBytesPerRow) - / (TimeForFetchingRowInVBlankImmediateFlip * LineTime); + / (TimeForFetchingRowInVBlankImmediateFlip * LineTime); } else { *final_flip_bw = 0; } @@ -3223,12 +3842,13 @@ static void CalculateFlipSchedule(struct display_mode_lib *mode_lib, min_row_time = meta_row_height * LineTime / VRatio; else min_row_time = dml_min(dpte_row_height, meta_row_height) * LineTime - / VRatio; + / VRatio; if (*DestinationLinesToRequestVMInImmediateFlip >= 8 || *DestinationLinesToRequestRowInImmediateFlip >= 16 || TimeForFetchingMetaPTEImmediateFlip - + 2 * TimeForFetchingRowInVBlankImmediateFlip > min_row_time) + + 2 * TimeForFetchingRowInVBlankImmediateFlip + > min_row_time) *ImmediateFlipSupportedForPipe = false; else *ImmediateFlipSupportedForPipe = true; @@ -3242,7 +3862,8 @@ static void PixelClockAdjustmentForProgressiveToInterlaceUnit(struct display_mod //Progressive To dml_ml->vba.Interlace Unit Effect for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { mode_lib->vba.PixelClockBackEnd[k] = mode_lib->vba.PixelClock[k]; - if (mode_lib->vba.Interlace[k] == 1 && mode_lib->vba.ProgressiveToInterlaceUnitInOPP == true) { + if (mode_lib->vba.Interlace[k] == 1 + && mode_lib->vba.ProgressiveToInterlaceUnitInOPP == true) { mode_lib->vba.PixelClock[k] = 2 * mode_lib->vba.PixelClock[k]; } } @@ -3261,3 +3882,2211 @@ static unsigned int CursorBppEnumToBits(enum cursor_bpp ebpp) return 0; } } + +static unsigned int TruncToValidBPP( + double DecimalBPP, + bool DSCEnabled, + enum output_encoder_class Output, + enum output_format_class Format, + unsigned int DSCInputBitPerComponent) +{ + if (Output == dm_hdmi) { + if (Format == dm_420) { + if (DecimalBPP >= 18) + return 18; + else if (DecimalBPP >= 15) + return 15; + else if (DecimalBPP >= 12) + return 12; + else + return 0; + } else if (Format == dm_444) { + if (DecimalBPP >= 36) + return 36; + else if (DecimalBPP >= 30) + return 30; + else if (DecimalBPP >= 24) + return 24; + else + return 0; + } else { + if (DecimalBPP / 1.5 >= 24) + return 24; + else if (DecimalBPP / 1.5 >= 20) + return 20; + else if (DecimalBPP / 1.5 >= 16) + return 16; + else + return 0; + } + } else { + if (DSCEnabled) { + if (Format == dm_420) { + if (DecimalBPP < 6) + return 0; + else if (DecimalBPP >= 1.5 * DSCInputBitPerComponent - 1 / 16) + return 1.5 * DSCInputBitPerComponent - 1 / 16; + else + return dml_floor(16 * DecimalBPP, 1) / 16; + } else if (Format == dm_n422) { + if (DecimalBPP < 7) + return 0; + else if (DecimalBPP >= 2 * DSCInputBitPerComponent - 1 / 16) + return 2 * DSCInputBitPerComponent - 1 / 16; + else + return dml_floor(16 * DecimalBPP, 1) / 16; + } else { + if (DecimalBPP < 8) + return 0; + else if (DecimalBPP >= 3 * DSCInputBitPerComponent - 1 / 16) + return 3 * DSCInputBitPerComponent - 1 / 16; + else + return dml_floor(16 * DecimalBPP, 1) / 16; + } + } else if (Format == dm_420) { + if (DecimalBPP >= 18) + return 18; + else if (DecimalBPP >= 15) + return 15; + else if (DecimalBPP >= 12) + return 12; + else + return 0; + } else if (Format == dm_s422 || Format == dm_n422) { + if (DecimalBPP >= 24) + return 24; + else if (DecimalBPP >= 20) + return 20; + else if (DecimalBPP >= 16) + return 16; + else + return 0; + } else { + if (DecimalBPP >= 36) + return 36; + else if (DecimalBPP >= 30) + return 30; + else if (DecimalBPP >= 24) + return 24; + else + return 0; + } + } +} + +static void ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_lib) +{ + int i; + unsigned int j, k; + /*MODE SUPPORT, VOLTAGE STATE AND SOC CONFIGURATION*/ + + /*Scale Ratio, taps Support Check*/ + + mode_lib->vba.ScaleRatioAndTapsSupport = true; + for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { + if (mode_lib->vba.ScalerEnabled[k] == false + && ((mode_lib->vba.SourcePixelFormat[k] != dm_444_64 + && mode_lib->vba.SourcePixelFormat[k] != dm_444_32 + && mode_lib->vba.SourcePixelFormat[k] != dm_444_16 + && mode_lib->vba.SourcePixelFormat[k] != dm_mono_16 + && mode_lib->vba.SourcePixelFormat[k] != dm_mono_8) + || mode_lib->vba.HRatio[k] != 1.0 + || mode_lib->vba.htaps[k] != 1.0 + || mode_lib->vba.VRatio[k] != 1.0 + || mode_lib->vba.vtaps[k] != 1.0)) { + mode_lib->vba.ScaleRatioAndTapsSupport = false; + } else if (mode_lib->vba.vtaps[k] < 1.0 || mode_lib->vba.vtaps[k] > 8.0 + || mode_lib->vba.htaps[k] < 1.0 || mode_lib->vba.htaps[k] > 8.0 + || (mode_lib->vba.htaps[k] > 1.0 + && (mode_lib->vba.htaps[k] % 2) == 1) + || mode_lib->vba.HRatio[k] > mode_lib->vba.MaxHSCLRatio + || mode_lib->vba.VRatio[k] > mode_lib->vba.MaxVSCLRatio + || mode_lib->vba.HRatio[k] > mode_lib->vba.htaps[k] + || mode_lib->vba.VRatio[k] > mode_lib->vba.vtaps[k] + || (mode_lib->vba.SourcePixelFormat[k] != dm_444_64 + && mode_lib->vba.SourcePixelFormat[k] != dm_444_32 + && mode_lib->vba.SourcePixelFormat[k] != dm_444_16 + && mode_lib->vba.SourcePixelFormat[k] != dm_mono_16 + && mode_lib->vba.SourcePixelFormat[k] != dm_mono_8 + && (mode_lib->vba.HRatio[k] / 2.0 + > mode_lib->vba.HTAPsChroma[k] + || mode_lib->vba.VRatio[k] / 2.0 + > mode_lib->vba.VTAPsChroma[k]))) { + mode_lib->vba.ScaleRatioAndTapsSupport = false; + } + } + /*Source Format, Pixel Format and Scan Support Check*/ + + mode_lib->vba.SourceFormatPixelAndScanSupport = true; + for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { + if ((mode_lib->vba.SurfaceTiling[k] == dm_sw_linear + && mode_lib->vba.SourceScan[k] != dm_horz) + || ((mode_lib->vba.SurfaceTiling[k] == dm_sw_4kb_d + || mode_lib->vba.SurfaceTiling[k] == dm_sw_4kb_d_x + || mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_d + || mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_d_t + || mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_d_x + || mode_lib->vba.SurfaceTiling[k] == dm_sw_var_d + || mode_lib->vba.SurfaceTiling[k] == dm_sw_var_d_x) + && mode_lib->vba.SourcePixelFormat[k] != dm_444_64) + || (mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_r_x + && (mode_lib->vba.SourcePixelFormat[k] == dm_mono_8 + || mode_lib->vba.SourcePixelFormat[k] + == dm_420_8 + || mode_lib->vba.SourcePixelFormat[k] + == dm_420_10)) + || (((mode_lib->vba.SurfaceTiling[k] + == dm_sw_gfx7_2d_thin_gl + || mode_lib->vba.SurfaceTiling[k] + == dm_sw_gfx7_2d_thin_lvp) + && !((mode_lib->vba.SourcePixelFormat[k] + == dm_444_64 + || mode_lib->vba.SourcePixelFormat[k] + == dm_444_32) + && mode_lib->vba.SourceScan[k] + == dm_horz + && mode_lib->vba.SupportGFX7CompatibleTilingIn32bppAnd64bpp + == true + && mode_lib->vba.DCCEnable[k] + == false)) + || (mode_lib->vba.DCCEnable[k] == true + && (mode_lib->vba.SurfaceTiling[k] + == dm_sw_linear + || mode_lib->vba.SourcePixelFormat[k] + == dm_420_8 + || mode_lib->vba.SourcePixelFormat[k] + == dm_420_10)))) { + mode_lib->vba.SourceFormatPixelAndScanSupport = false; + } + } + /*Bandwidth Support Check*/ + + for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { + if (mode_lib->vba.SourceScan[k] == dm_horz) { + mode_lib->vba.SwathWidthYSingleDPP[k] = mode_lib->vba.ViewportWidth[k]; + } else { + mode_lib->vba.SwathWidthYSingleDPP[k] = mode_lib->vba.ViewportHeight[k]; + } + if (mode_lib->vba.SourcePixelFormat[k] == dm_444_64) { + mode_lib->vba.BytePerPixelInDETY[k] = 8.0; + mode_lib->vba.BytePerPixelInDETC[k] = 0.0; + } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_32) { + mode_lib->vba.BytePerPixelInDETY[k] = 4.0; + mode_lib->vba.BytePerPixelInDETC[k] = 0.0; + } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_16 + || mode_lib->vba.SourcePixelFormat[k] == dm_mono_16) { + mode_lib->vba.BytePerPixelInDETY[k] = 2.0; + mode_lib->vba.BytePerPixelInDETC[k] = 0.0; + } else if (mode_lib->vba.SourcePixelFormat[k] == dm_mono_8) { + mode_lib->vba.BytePerPixelInDETY[k] = 1.0; + mode_lib->vba.BytePerPixelInDETC[k] = 0.0; + } else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8) { + mode_lib->vba.BytePerPixelInDETY[k] = 1.0; + mode_lib->vba.BytePerPixelInDETC[k] = 2.0; + } else { + mode_lib->vba.BytePerPixelInDETY[k] = 4.0 / 3; + mode_lib->vba.BytePerPixelInDETC[k] = 8.0 / 3; + } + } + mode_lib->vba.TotalReadBandwidthConsumedGBytePerSecond = 0.0; + for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { + mode_lib->vba.ReadBandwidth[k] = mode_lib->vba.SwathWidthYSingleDPP[k] + * (dml_ceil(mode_lib->vba.BytePerPixelInDETY[k], 1.0) + * mode_lib->vba.VRatio[k] + + dml_ceil(mode_lib->vba.BytePerPixelInDETC[k], 2.0) + / 2.0 * mode_lib->vba.VRatio[k] / 2) + / (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]); + if (mode_lib->vba.DCCEnable[k] == true) { + mode_lib->vba.ReadBandwidth[k] = mode_lib->vba.ReadBandwidth[k] + * (1 + 1 / 256); + } + if (mode_lib->vba.VirtualMemoryEnable == true + && mode_lib->vba.SourceScan[k] != dm_horz + && (mode_lib->vba.SurfaceTiling[k] == dm_sw_4kb_s + || mode_lib->vba.SurfaceTiling[k] == dm_sw_4kb_s_x + || mode_lib->vba.SurfaceTiling[k] == dm_sw_4kb_d + || mode_lib->vba.SurfaceTiling[k] == dm_sw_4kb_d_x)) { + mode_lib->vba.ReadBandwidth[k] = mode_lib->vba.ReadBandwidth[k] + * (1 + 1 / 64); + } else if (mode_lib->vba.VirtualMemoryEnable == true + && mode_lib->vba.SourceScan[k] == dm_horz + && (mode_lib->vba.SourcePixelFormat[k] == dm_444_64 + || mode_lib->vba.SourcePixelFormat[k] == dm_444_32) + && (mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_s + || mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_s_t + || mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_s_x + || mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_d + || mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_d_t + || mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_d_x + || mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_r_x)) { + mode_lib->vba.ReadBandwidth[k] = mode_lib->vba.ReadBandwidth[k] + * (1 + 1 / 256); + } else if (mode_lib->vba.VirtualMemoryEnable == true) { + mode_lib->vba.ReadBandwidth[k] = mode_lib->vba.ReadBandwidth[k] + * (1 + 1 / 512); + } + mode_lib->vba.TotalReadBandwidthConsumedGBytePerSecond = + mode_lib->vba.TotalReadBandwidthConsumedGBytePerSecond + + mode_lib->vba.ReadBandwidth[k] / 1000.0; + } + mode_lib->vba.TotalWriteBandwidthConsumedGBytePerSecond = 0.0; + for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { + if (mode_lib->vba.WritebackEnable[k] == true + && mode_lib->vba.WritebackPixelFormat[k] == dm_444_32) { + mode_lib->vba.WriteBandwidth[k] = mode_lib->vba.WritebackDestinationWidth[k] + * mode_lib->vba.WritebackDestinationHeight[k] + / (mode_lib->vba.WritebackSourceHeight[k] + * mode_lib->vba.HTotal[k] + / mode_lib->vba.PixelClock[k]) * 4.0; + } else if (mode_lib->vba.WritebackEnable[k] == true + && mode_lib->vba.WritebackPixelFormat[k] == dm_420_10) { + mode_lib->vba.WriteBandwidth[k] = mode_lib->vba.WritebackDestinationWidth[k] + * mode_lib->vba.WritebackDestinationHeight[k] + / (mode_lib->vba.WritebackSourceHeight[k] + * mode_lib->vba.HTotal[k] + / mode_lib->vba.PixelClock[k]) * 3.0; + } else if (mode_lib->vba.WritebackEnable[k] == true) { + mode_lib->vba.WriteBandwidth[k] = mode_lib->vba.WritebackDestinationWidth[k] + * mode_lib->vba.WritebackDestinationHeight[k] + / (mode_lib->vba.WritebackSourceHeight[k] + * mode_lib->vba.HTotal[k] + / mode_lib->vba.PixelClock[k]) * 1.5; + } else { + mode_lib->vba.WriteBandwidth[k] = 0.0; + } + mode_lib->vba.TotalWriteBandwidthConsumedGBytePerSecond = + mode_lib->vba.TotalWriteBandwidthConsumedGBytePerSecond + + mode_lib->vba.WriteBandwidth[k] / 1000.0; + } + mode_lib->vba.TotalBandwidthConsumedGBytePerSecond = + mode_lib->vba.TotalReadBandwidthConsumedGBytePerSecond + + mode_lib->vba.TotalWriteBandwidthConsumedGBytePerSecond; + mode_lib->vba.DCCEnabledInAnyPlane = false; + for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { + if (mode_lib->vba.DCCEnable[k] == true) { + mode_lib->vba.DCCEnabledInAnyPlane = true; + } + } + for (i = 0; i <= DC__VOLTAGE_STATES; i++) { + mode_lib->vba.FabricAndDRAMBandwidthPerState[i] = dml_min( + mode_lib->vba.DRAMSpeedPerState[i] * mode_lib->vba.NumberOfChannels + * mode_lib->vba.DRAMChannelWidth, + mode_lib->vba.FabricClockPerState[i] + * mode_lib->vba.FabricDatapathToDCNDataReturn) + / 1000; + mode_lib->vba.ReturnBWToDCNPerState = dml_min( + mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLKPerState[i], + mode_lib->vba.FabricAndDRAMBandwidthPerState[i] * 1000.0) + * mode_lib->vba.PercentOfIdealDRAMAndFabricBWReceivedAfterUrgLatency + / 100; + mode_lib->vba.ReturnBWPerState[i] = mode_lib->vba.ReturnBWToDCNPerState; + if (mode_lib->vba.DCCEnabledInAnyPlane == true + && mode_lib->vba.ReturnBWToDCNPerState + > mode_lib->vba.DCFCLKPerState[i] + * mode_lib->vba.ReturnBusWidth + / 4.0) { + mode_lib->vba.ReturnBWPerState[i] = + dml_min( + mode_lib->vba.ReturnBWPerState[i], + mode_lib->vba.ReturnBWToDCNPerState * 4.0 + * (1.0 + - mode_lib->vba.UrgentLatency + / ((mode_lib->vba.ROBBufferSizeInKByte + - mode_lib->vba.PixelChunkSizeInKByte) + * 1024.0 + / (mode_lib->vba.ReturnBWToDCNPerState + - mode_lib->vba.DCFCLKPerState[i] + * mode_lib->vba.ReturnBusWidth + / 4.0) + + mode_lib->vba.UrgentLatency))); + } + mode_lib->vba.CriticalPoint = + 2.0 * mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLKPerState[i] + * mode_lib->vba.UrgentLatency + / (mode_lib->vba.ReturnBWToDCNPerState + * mode_lib->vba.UrgentLatency + + (mode_lib->vba.ROBBufferSizeInKByte + - mode_lib->vba.PixelChunkSizeInKByte) + * 1024.0); + if (mode_lib->vba.DCCEnabledInAnyPlane == true && mode_lib->vba.CriticalPoint > 1.0 + && mode_lib->vba.CriticalPoint < 4.0) { + mode_lib->vba.ReturnBWPerState[i] = + dml_min( + mode_lib->vba.ReturnBWPerState[i], + dml_pow( + 4.0 + * mode_lib->vba.ReturnBWToDCNPerState + * (mode_lib->vba.ROBBufferSizeInKByte + - mode_lib->vba.PixelChunkSizeInKByte) + * 1024.0 + * mode_lib->vba.ReturnBusWidth + * mode_lib->vba.DCFCLKPerState[i] + * mode_lib->vba.UrgentLatency + / (mode_lib->vba.ReturnBWToDCNPerState + * mode_lib->vba.UrgentLatency + + (mode_lib->vba.ROBBufferSizeInKByte + - mode_lib->vba.PixelChunkSizeInKByte) + * 1024.0), + 2)); + } + mode_lib->vba.ReturnBWToDCNPerState = dml_min( + mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLKPerState[i], + mode_lib->vba.FabricAndDRAMBandwidthPerState[i] * 1000.0); + if (mode_lib->vba.DCCEnabledInAnyPlane == true + && mode_lib->vba.ReturnBWToDCNPerState + > mode_lib->vba.DCFCLKPerState[i] + * mode_lib->vba.ReturnBusWidth + / 4.0) { + mode_lib->vba.ReturnBWPerState[i] = + dml_min( + mode_lib->vba.ReturnBWPerState[i], + mode_lib->vba.ReturnBWToDCNPerState * 4.0 + * (1.0 + - mode_lib->vba.UrgentLatency + / ((mode_lib->vba.ROBBufferSizeInKByte + - mode_lib->vba.PixelChunkSizeInKByte) + * 1024.0 + / (mode_lib->vba.ReturnBWToDCNPerState + - mode_lib->vba.DCFCLKPerState[i] + * mode_lib->vba.ReturnBusWidth + / 4.0) + + mode_lib->vba.UrgentLatency))); + } + mode_lib->vba.CriticalPoint = + 2.0 * mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLKPerState[i] + * mode_lib->vba.UrgentLatency + / (mode_lib->vba.ReturnBWToDCNPerState + * mode_lib->vba.UrgentLatency + + (mode_lib->vba.ROBBufferSizeInKByte + - mode_lib->vba.PixelChunkSizeInKByte) + * 1024.0); + if (mode_lib->vba.DCCEnabledInAnyPlane == true && mode_lib->vba.CriticalPoint > 1.0 + && mode_lib->vba.CriticalPoint < 4.0) { + mode_lib->vba.ReturnBWPerState[i] = + dml_min( + mode_lib->vba.ReturnBWPerState[i], + dml_pow( + 4.0 + * mode_lib->vba.ReturnBWToDCNPerState + * (mode_lib->vba.ROBBufferSizeInKByte + - mode_lib->vba.PixelChunkSizeInKByte) + * 1024.0 + * mode_lib->vba.ReturnBusWidth + * mode_lib->vba.DCFCLKPerState[i] + * mode_lib->vba.UrgentLatency + / (mode_lib->vba.ReturnBWToDCNPerState + * mode_lib->vba.UrgentLatency + + (mode_lib->vba.ROBBufferSizeInKByte + - mode_lib->vba.PixelChunkSizeInKByte) + * 1024.0), + 2)); + } + } + for (i = 0; i <= DC__VOLTAGE_STATES; i++) { + if ((mode_lib->vba.TotalReadBandwidthConsumedGBytePerSecond * 1000.0 + <= mode_lib->vba.ReturnBWPerState[i]) + && (mode_lib->vba.TotalBandwidthConsumedGBytePerSecond * 1000.0 + <= mode_lib->vba.FabricAndDRAMBandwidthPerState[i] + * 1000.0 + * mode_lib->vba.PercentOfIdealDRAMAndFabricBWReceivedAfterUrgLatency + / 100.0)) { + mode_lib->vba.BandwidthSupport[i] = true; + } else { + mode_lib->vba.BandwidthSupport[i] = false; + } + } + /*Writeback Latency support check*/ + + mode_lib->vba.WritebackLatencySupport = true; + for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { + if (mode_lib->vba.WritebackEnable[k] == true) { + if (mode_lib->vba.WritebackPixelFormat[k] == dm_444_32) { + if (mode_lib->vba.WriteBandwidth[k] + > (mode_lib->vba.WritebackInterfaceLumaBufferSize + + mode_lib->vba.WritebackInterfaceChromaBufferSize) + / mode_lib->vba.WritebackLatency) { + mode_lib->vba.WritebackLatencySupport = false; + } + } else { + if (mode_lib->vba.WriteBandwidth[k] + > 1.5 + * dml_min( + mode_lib->vba.WritebackInterfaceLumaBufferSize, + 2.0 + * mode_lib->vba.WritebackInterfaceChromaBufferSize) + / mode_lib->vba.WritebackLatency) { + mode_lib->vba.WritebackLatencySupport = false; + } + } + } + } + /*Re-ordering Buffer Support Check*/ + + for (i = 0; i <= DC__VOLTAGE_STATES; i++) { + mode_lib->vba.UrgentRoundTripAndOutOfOrderLatencyPerState[i] = + (mode_lib->vba.RoundTripPingLatencyCycles + 32.0) + / mode_lib->vba.DCFCLKPerState[i] + + mode_lib->vba.UrgentOutOfOrderReturnPerChannel + * mode_lib->vba.NumberOfChannels + / mode_lib->vba.ReturnBWPerState[i]; + if ((mode_lib->vba.ROBBufferSizeInKByte - mode_lib->vba.PixelChunkSizeInKByte) + * 1024.0 / mode_lib->vba.ReturnBWPerState[i] + > mode_lib->vba.UrgentRoundTripAndOutOfOrderLatencyPerState[i]) { + mode_lib->vba.ROBSupport[i] = true; + } else { + mode_lib->vba.ROBSupport[i] = false; + } + } + /*Writeback Mode Support Check*/ + + mode_lib->vba.TotalNumberOfActiveWriteback = 0; + for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { + if (mode_lib->vba.WritebackEnable[k] == true) { + mode_lib->vba.TotalNumberOfActiveWriteback = + mode_lib->vba.TotalNumberOfActiveWriteback + 1; + } + } + mode_lib->vba.WritebackModeSupport = true; + if (mode_lib->vba.TotalNumberOfActiveWriteback > mode_lib->vba.MaxNumWriteback) { + mode_lib->vba.WritebackModeSupport = false; + } + for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { + if (mode_lib->vba.WritebackEnable[k] == true + && mode_lib->vba.Writeback10bpc420Supported != true + && mode_lib->vba.WritebackPixelFormat[k] == dm_420_10) { + mode_lib->vba.WritebackModeSupport = false; + } + } + /*Writeback Scale Ratio and Taps Support Check*/ + + mode_lib->vba.WritebackScaleRatioAndTapsSupport = true; + for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { + if (mode_lib->vba.WritebackEnable[k] == true) { + if (mode_lib->vba.WritebackLumaAndChromaScalingSupported == false + && (mode_lib->vba.WritebackHRatio[k] != 1.0 + || mode_lib->vba.WritebackVRatio[k] != 1.0)) { + mode_lib->vba.WritebackScaleRatioAndTapsSupport = false; + } + if (mode_lib->vba.WritebackHRatio[k] > mode_lib->vba.WritebackMaxHSCLRatio + || mode_lib->vba.WritebackVRatio[k] + > mode_lib->vba.WritebackMaxVSCLRatio + || mode_lib->vba.WritebackHRatio[k] + < mode_lib->vba.WritebackMinHSCLRatio + || mode_lib->vba.WritebackVRatio[k] + < mode_lib->vba.WritebackMinVSCLRatio + || mode_lib->vba.WritebackLumaHTaps[k] + > mode_lib->vba.WritebackMaxHSCLTaps + || mode_lib->vba.WritebackLumaVTaps[k] + > mode_lib->vba.WritebackMaxVSCLTaps + || mode_lib->vba.WritebackHRatio[k] + > mode_lib->vba.WritebackLumaHTaps[k] + || mode_lib->vba.WritebackVRatio[k] + > mode_lib->vba.WritebackLumaVTaps[k] + || (mode_lib->vba.WritebackLumaHTaps[k] > 2.0 + && ((mode_lib->vba.WritebackLumaHTaps[k] % 2) + == 1)) + || (mode_lib->vba.WritebackPixelFormat[k] != dm_444_32 + && (mode_lib->vba.WritebackChromaHTaps[k] + > mode_lib->vba.WritebackMaxHSCLTaps + || mode_lib->vba.WritebackChromaVTaps[k] + > mode_lib->vba.WritebackMaxVSCLTaps + || 2.0 + * mode_lib->vba.WritebackHRatio[k] + > mode_lib->vba.WritebackChromaHTaps[k] + || 2.0 + * mode_lib->vba.WritebackVRatio[k] + > mode_lib->vba.WritebackChromaVTaps[k] + || (mode_lib->vba.WritebackChromaHTaps[k] > 2.0 + && ((mode_lib->vba.WritebackChromaHTaps[k] % 2) == 1))))) { + mode_lib->vba.WritebackScaleRatioAndTapsSupport = false; + } + if (mode_lib->vba.WritebackVRatio[k] < 1.0) { + mode_lib->vba.WritebackLumaVExtra = + dml_max(1.0 - 2.0 / dml_ceil(1.0 / mode_lib->vba.WritebackVRatio[k], 1.0), 0.0); + } else { + mode_lib->vba.WritebackLumaVExtra = -1; + } + if ((mode_lib->vba.WritebackPixelFormat[k] == dm_444_32 + && mode_lib->vba.WritebackLumaVTaps[k] + > (mode_lib->vba.WritebackLineBufferLumaBufferSize + + mode_lib->vba.WritebackLineBufferChromaBufferSize) + / 3.0 + / mode_lib->vba.WritebackDestinationWidth[k] + - mode_lib->vba.WritebackLumaVExtra) + || (mode_lib->vba.WritebackPixelFormat[k] == dm_420_8 + && mode_lib->vba.WritebackLumaVTaps[k] + > mode_lib->vba.WritebackLineBufferLumaBufferSize + / mode_lib->vba.WritebackDestinationWidth[k] + - mode_lib->vba.WritebackLumaVExtra) + || (mode_lib->vba.WritebackPixelFormat[k] == dm_420_10 + && mode_lib->vba.WritebackLumaVTaps[k] + > mode_lib->vba.WritebackLineBufferLumaBufferSize + * 8.0 / 10.0 + / mode_lib->vba.WritebackDestinationWidth[k] + - mode_lib->vba.WritebackLumaVExtra)) { + mode_lib->vba.WritebackScaleRatioAndTapsSupport = false; + } + if (2.0 * mode_lib->vba.WritebackVRatio[k] < 1) { + mode_lib->vba.WritebackChromaVExtra = 0.0; + } else { + mode_lib->vba.WritebackChromaVExtra = -1; + } + if ((mode_lib->vba.WritebackPixelFormat[k] == dm_420_8 + && mode_lib->vba.WritebackChromaVTaps[k] + > mode_lib->vba.WritebackLineBufferChromaBufferSize + / mode_lib->vba.WritebackDestinationWidth[k] + - mode_lib->vba.WritebackChromaVExtra) + || (mode_lib->vba.WritebackPixelFormat[k] == dm_420_10 + && mode_lib->vba.WritebackChromaVTaps[k] + > mode_lib->vba.WritebackLineBufferChromaBufferSize + * 8.0 / 10.0 + / mode_lib->vba.WritebackDestinationWidth[k] + - mode_lib->vba.WritebackChromaVExtra)) { + mode_lib->vba.WritebackScaleRatioAndTapsSupport = false; + } + } + } + /*Maximum DISPCLK/DPPCLK Support check*/ + + mode_lib->vba.WritebackRequiredDISPCLK = 0.0; + for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { + if (mode_lib->vba.WritebackEnable[k] == true) { + mode_lib->vba.WritebackRequiredDISPCLK = + dml_max( + mode_lib->vba.WritebackRequiredDISPCLK, + CalculateWriteBackDISPCLK( + mode_lib->vba.WritebackPixelFormat[k], + mode_lib->vba.PixelClock[k], + mode_lib->vba.WritebackHRatio[k], + mode_lib->vba.WritebackVRatio[k], + mode_lib->vba.WritebackLumaHTaps[k], + mode_lib->vba.WritebackLumaVTaps[k], + mode_lib->vba.WritebackChromaHTaps[k], + mode_lib->vba.WritebackChromaVTaps[k], + mode_lib->vba.WritebackDestinationWidth[k], + mode_lib->vba.HTotal[k], + mode_lib->vba.WritebackChromaLineBufferWidth)); + } + } + for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { + if (mode_lib->vba.HRatio[k] > 1.0) { + mode_lib->vba.PSCL_FACTOR[k] = dml_min( + mode_lib->vba.MaxDCHUBToPSCLThroughput, + mode_lib->vba.MaxPSCLToLBThroughput + * mode_lib->vba.HRatio[k] + / dml_ceil( + mode_lib->vba.htaps[k] + / 6.0, + 1.0)); + } else { + mode_lib->vba.PSCL_FACTOR[k] = dml_min( + mode_lib->vba.MaxDCHUBToPSCLThroughput, + mode_lib->vba.MaxPSCLToLBThroughput); + } + if (mode_lib->vba.BytePerPixelInDETC[k] == 0.0) { + mode_lib->vba.PSCL_FACTOR_CHROMA[k] = 0.0; + mode_lib->vba.MinDPPCLKUsingSingleDPP[k] = + mode_lib->vba.PixelClock[k] + * dml_max3( + mode_lib->vba.vtaps[k] / 6.0 + * dml_min( + 1.0, + mode_lib->vba.HRatio[k]), + mode_lib->vba.HRatio[k] + * mode_lib->vba.VRatio[k] + / mode_lib->vba.PSCL_FACTOR[k], + 1.0); + if ((mode_lib->vba.htaps[k] > 6.0 || mode_lib->vba.vtaps[k] > 6.0) + && mode_lib->vba.MinDPPCLKUsingSingleDPP[k] + < 2.0 * mode_lib->vba.PixelClock[k]) { + mode_lib->vba.MinDPPCLKUsingSingleDPP[k] = 2.0 + * mode_lib->vba.PixelClock[k]; + } + } else { + if (mode_lib->vba.HRatio[k] / 2.0 > 1.0) { + mode_lib->vba.PSCL_FACTOR_CHROMA[k] = + dml_min( + mode_lib->vba.MaxDCHUBToPSCLThroughput, + mode_lib->vba.MaxPSCLToLBThroughput + * mode_lib->vba.HRatio[k] + / 2.0 + / dml_ceil( + mode_lib->vba.HTAPsChroma[k] + / 6.0, + 1.0)); + } else { + mode_lib->vba.PSCL_FACTOR_CHROMA[k] = dml_min( + mode_lib->vba.MaxDCHUBToPSCLThroughput, + mode_lib->vba.MaxPSCLToLBThroughput); + } + mode_lib->vba.MinDPPCLKUsingSingleDPP[k] = + mode_lib->vba.PixelClock[k] + * dml_max5( + mode_lib->vba.vtaps[k] / 6.0 + * dml_min( + 1.0, + mode_lib->vba.HRatio[k]), + mode_lib->vba.HRatio[k] + * mode_lib->vba.VRatio[k] + / mode_lib->vba.PSCL_FACTOR[k], + mode_lib->vba.VTAPsChroma[k] + / 6.0 + * dml_min( + 1.0, + mode_lib->vba.HRatio[k] + / 2.0), + mode_lib->vba.HRatio[k] + * mode_lib->vba.VRatio[k] + / 4.0 + / mode_lib->vba.PSCL_FACTOR_CHROMA[k], + 1.0); + if ((mode_lib->vba.htaps[k] > 6.0 || mode_lib->vba.vtaps[k] > 6.0 + || mode_lib->vba.HTAPsChroma[k] > 6.0 + || mode_lib->vba.VTAPsChroma[k] > 6.0) + && mode_lib->vba.MinDPPCLKUsingSingleDPP[k] + < 2.0 * mode_lib->vba.PixelClock[k]) { + mode_lib->vba.MinDPPCLKUsingSingleDPP[k] = 2.0 + * mode_lib->vba.PixelClock[k]; + } + } + } + for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { + Calculate256BBlockSizes( + mode_lib->vba.SourcePixelFormat[k], + mode_lib->vba.SurfaceTiling[k], + dml_ceil(mode_lib->vba.BytePerPixelInDETY[k], 1.0), + dml_ceil(mode_lib->vba.BytePerPixelInDETC[k], 2.0), + &mode_lib->vba.Read256BlockHeightY[k], + &mode_lib->vba.Read256BlockHeightC[k], + &mode_lib->vba.Read256BlockWidthY[k], + &mode_lib->vba.Read256BlockWidthC[k]); + if (mode_lib->vba.SourceScan[k] == dm_horz) { + mode_lib->vba.MaxSwathHeightY[k] = mode_lib->vba.Read256BlockHeightY[k]; + mode_lib->vba.MaxSwathHeightC[k] = mode_lib->vba.Read256BlockHeightC[k]; + } else { + mode_lib->vba.MaxSwathHeightY[k] = mode_lib->vba.Read256BlockWidthY[k]; + mode_lib->vba.MaxSwathHeightC[k] = mode_lib->vba.Read256BlockWidthC[k]; + } + if ((mode_lib->vba.SourcePixelFormat[k] == dm_444_64 + || mode_lib->vba.SourcePixelFormat[k] == dm_444_32 + || mode_lib->vba.SourcePixelFormat[k] == dm_444_16 + || mode_lib->vba.SourcePixelFormat[k] == dm_mono_16 + || mode_lib->vba.SourcePixelFormat[k] == dm_mono_8)) { + if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear + || (mode_lib->vba.SourcePixelFormat[k] == dm_444_64 + && (mode_lib->vba.SurfaceTiling[k] + == dm_sw_4kb_s + || mode_lib->vba.SurfaceTiling[k] + == dm_sw_4kb_s_x + || mode_lib->vba.SurfaceTiling[k] + == dm_sw_64kb_s + || mode_lib->vba.SurfaceTiling[k] + == dm_sw_64kb_s_t + || mode_lib->vba.SurfaceTiling[k] + == dm_sw_64kb_s_x + || mode_lib->vba.SurfaceTiling[k] + == dm_sw_var_s + || mode_lib->vba.SurfaceTiling[k] + == dm_sw_var_s_x) + && mode_lib->vba.SourceScan[k] == dm_horz)) { + mode_lib->vba.MinSwathHeightY[k] = mode_lib->vba.MaxSwathHeightY[k]; + } else { + mode_lib->vba.MinSwathHeightY[k] = mode_lib->vba.MaxSwathHeightY[k] + / 2.0; + } + mode_lib->vba.MinSwathHeightC[k] = mode_lib->vba.MaxSwathHeightC[k]; + } else { + if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear) { + mode_lib->vba.MinSwathHeightY[k] = mode_lib->vba.MaxSwathHeightY[k]; + mode_lib->vba.MinSwathHeightC[k] = mode_lib->vba.MaxSwathHeightC[k]; + } else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8 + && mode_lib->vba.SourceScan[k] == dm_horz) { + mode_lib->vba.MinSwathHeightY[k] = mode_lib->vba.MaxSwathHeightY[k] + / 2.0; + mode_lib->vba.MinSwathHeightC[k] = mode_lib->vba.MaxSwathHeightC[k]; + } else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10 + && mode_lib->vba.SourceScan[k] == dm_horz) { + mode_lib->vba.MinSwathHeightC[k] = mode_lib->vba.MaxSwathHeightC[k] + / 2.0; + mode_lib->vba.MinSwathHeightY[k] = mode_lib->vba.MaxSwathHeightY[k]; + } else { + mode_lib->vba.MinSwathHeightY[k] = mode_lib->vba.MaxSwathHeightY[k]; + mode_lib->vba.MinSwathHeightC[k] = mode_lib->vba.MaxSwathHeightC[k]; + } + } + if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear) { + mode_lib->vba.MaximumSwathWidthSupport = 8192.0; + } else { + mode_lib->vba.MaximumSwathWidthSupport = 5120.0; + } + mode_lib->vba.MaximumSwathWidthInDETBuffer = + dml_min( + mode_lib->vba.MaximumSwathWidthSupport, + mode_lib->vba.DETBufferSizeInKByte * 1024.0 / 2.0 + / (mode_lib->vba.BytePerPixelInDETY[k] + * mode_lib->vba.MinSwathHeightY[k] + + mode_lib->vba.BytePerPixelInDETC[k] + / 2.0 + * mode_lib->vba.MinSwathHeightC[k])); + if (mode_lib->vba.BytePerPixelInDETC[k] == 0.0) { + mode_lib->vba.MaximumSwathWidthInLineBuffer = + mode_lib->vba.LineBufferSize + * dml_max(mode_lib->vba.HRatio[k], 1.0) + / mode_lib->vba.LBBitPerPixel[k] + / (mode_lib->vba.vtaps[k] + + dml_max( + dml_ceil( + mode_lib->vba.VRatio[k], + 1.0) + - 2, + 0.0)); + } else { + mode_lib->vba.MaximumSwathWidthInLineBuffer = + dml_min( + mode_lib->vba.LineBufferSize + * dml_max( + mode_lib->vba.HRatio[k], + 1.0) + / mode_lib->vba.LBBitPerPixel[k] + / (mode_lib->vba.vtaps[k] + + dml_max( + dml_ceil( + mode_lib->vba.VRatio[k], + 1.0) + - 2, + 0.0)), + 2.0 * mode_lib->vba.LineBufferSize + * dml_max( + mode_lib->vba.HRatio[k] + / 2.0, + 1.0) + / mode_lib->vba.LBBitPerPixel[k] + / (mode_lib->vba.VTAPsChroma[k] + + dml_max( + dml_ceil( + mode_lib->vba.VRatio[k] + / 2.0, + 1.0) + - 2, + 0.0))); + } + mode_lib->vba.MaximumSwathWidth[k] = dml_min( + mode_lib->vba.MaximumSwathWidthInDETBuffer, + mode_lib->vba.MaximumSwathWidthInLineBuffer); + } + for (i = 0; i <= DC__VOLTAGE_STATES; i++) { + mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity = RoundToDFSGranularityDown( + mode_lib->vba.MaxDispclk[i], + mode_lib->vba.DISPCLKDPPCLKVCOSpeed); + mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity = RoundToDFSGranularityDown( + mode_lib->vba.MaxDppclk[i], + mode_lib->vba.DISPCLKDPPCLKVCOSpeed); + mode_lib->vba.RequiredDISPCLK[i] = 0.0; + mode_lib->vba.DISPCLK_DPPCLK_Support[i] = true; + for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { + mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine = + mode_lib->vba.PixelClock[k] + * (1.0 + + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading + / 100.0) + * (1.0 + + mode_lib->vba.DISPCLKRampingMargin + / 100.0); + if (mode_lib->vba.ODMCapability == true + && mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine + > mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity) { + mode_lib->vba.ODMCombineEnablePerState[i][k] = true; + mode_lib->vba.PlaneRequiredDISPCLK = + mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine + / 2.0; + } else { + mode_lib->vba.ODMCombineEnablePerState[i][k] = false; + mode_lib->vba.PlaneRequiredDISPCLK = + mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine; + } + if (mode_lib->vba.MinDPPCLKUsingSingleDPP[k] + * (1.0 + + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading + / 100.0) + <= mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity + && mode_lib->vba.SwathWidthYSingleDPP[k] + <= mode_lib->vba.MaximumSwathWidth[k] + && mode_lib->vba.ODMCombineEnablePerState[i][k] == false) { + mode_lib->vba.NoOfDPP[i][k] = 1.0; + mode_lib->vba.RequiredDPPCLK[i][k] = + mode_lib->vba.MinDPPCLKUsingSingleDPP[k] + * (1.0 + + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading + / 100.0); + } else { + mode_lib->vba.NoOfDPP[i][k] = 2.0; + mode_lib->vba.RequiredDPPCLK[i][k] = + mode_lib->vba.MinDPPCLKUsingSingleDPP[k] + * (1.0 + + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading + / 100.0) + / 2.0; + } + mode_lib->vba.RequiredDISPCLK[i] = dml_max( + mode_lib->vba.RequiredDISPCLK[i], + mode_lib->vba.PlaneRequiredDISPCLK); + if ((mode_lib->vba.MinDPPCLKUsingSingleDPP[k] / mode_lib->vba.NoOfDPP[i][k] + * (1.0 + + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading + / 100.0) + > mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity) + || (mode_lib->vba.PlaneRequiredDISPCLK + > mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity)) { + mode_lib->vba.DISPCLK_DPPCLK_Support[i] = false; + } + } + mode_lib->vba.TotalNumberOfActiveDPP[i] = 0.0; + for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { + mode_lib->vba.TotalNumberOfActiveDPP[i] = + mode_lib->vba.TotalNumberOfActiveDPP[i] + + mode_lib->vba.NoOfDPP[i][k]; + } + if ((mode_lib->vba.MaxDispclk[i] == mode_lib->vba.MaxDispclk[DC__VOLTAGE_STATES] + && mode_lib->vba.MaxDppclk[i] + == mode_lib->vba.MaxDppclk[DC__VOLTAGE_STATES]) + && (mode_lib->vba.TotalNumberOfActiveDPP[i] + > mode_lib->vba.MaxNumDPP + || mode_lib->vba.DISPCLK_DPPCLK_Support[i] == false)) { + mode_lib->vba.RequiredDISPCLK[i] = 0.0; + mode_lib->vba.DISPCLK_DPPCLK_Support[i] = true; + for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { + mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine = + mode_lib->vba.PixelClock[k] + * (1.0 + + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading + / 100.0); + if (mode_lib->vba.ODMCapability == true + && mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine + > mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity) { + mode_lib->vba.ODMCombineEnablePerState[i][k] = true; + mode_lib->vba.PlaneRequiredDISPCLK = + mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine + / 2.0; + } else { + mode_lib->vba.ODMCombineEnablePerState[i][k] = false; + mode_lib->vba.PlaneRequiredDISPCLK = + mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine; + } + if (mode_lib->vba.MinDPPCLKUsingSingleDPP[k] + * (1.0 + + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading + / 100.0) + <= mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity + && mode_lib->vba.SwathWidthYSingleDPP[k] + <= mode_lib->vba.MaximumSwathWidth[k] + && mode_lib->vba.ODMCombineEnablePerState[i][k] + == false) { + mode_lib->vba.NoOfDPP[i][k] = 1.0; + mode_lib->vba.RequiredDPPCLK[i][k] = + mode_lib->vba.MinDPPCLKUsingSingleDPP[k] + * (1.0 + + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading + / 100.0); + } else { + mode_lib->vba.NoOfDPP[i][k] = 2.0; + mode_lib->vba.RequiredDPPCLK[i][k] = + mode_lib->vba.MinDPPCLKUsingSingleDPP[k] + * (1.0 + + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading + / 100.0) + / 2.0; + } + mode_lib->vba.RequiredDISPCLK[i] = dml_max( + mode_lib->vba.RequiredDISPCLK[i], + mode_lib->vba.PlaneRequiredDISPCLK); + if ((mode_lib->vba.MinDPPCLKUsingSingleDPP[k] + / mode_lib->vba.NoOfDPP[i][k] + * (1.0 + + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading + / 100.0) + > mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity) + || (mode_lib->vba.PlaneRequiredDISPCLK + > mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity)) { + mode_lib->vba.DISPCLK_DPPCLK_Support[i] = false; + } + } + mode_lib->vba.TotalNumberOfActiveDPP[i] = 0.0; + for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { + mode_lib->vba.TotalNumberOfActiveDPP[i] = + mode_lib->vba.TotalNumberOfActiveDPP[i] + + mode_lib->vba.NoOfDPP[i][k]; + } + } + if (mode_lib->vba.TotalNumberOfActiveDPP[i] > mode_lib->vba.MaxNumDPP) { + mode_lib->vba.RequiredDISPCLK[i] = 0.0; + mode_lib->vba.DISPCLK_DPPCLK_Support[i] = true; + for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { + mode_lib->vba.ODMCombineEnablePerState[i][k] = false; + if (mode_lib->vba.SwathWidthYSingleDPP[k] + <= mode_lib->vba.MaximumSwathWidth[k]) { + mode_lib->vba.NoOfDPP[i][k] = 1.0; + mode_lib->vba.RequiredDPPCLK[i][k] = + mode_lib->vba.MinDPPCLKUsingSingleDPP[k] + * (1.0 + + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading + / 100.0); + } else { + mode_lib->vba.NoOfDPP[i][k] = 2.0; + mode_lib->vba.RequiredDPPCLK[i][k] = + mode_lib->vba.MinDPPCLKUsingSingleDPP[k] + * (1.0 + + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading + / 100.0) + / 2.0; + } + if (!(mode_lib->vba.MaxDispclk[i] + == mode_lib->vba.MaxDispclk[DC__VOLTAGE_STATES] + && mode_lib->vba.MaxDppclk[i] + == mode_lib->vba.MaxDppclk[DC__VOLTAGE_STATES])) { + mode_lib->vba.PlaneRequiredDISPCLK = + mode_lib->vba.PixelClock[k] + * (1.0 + + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading + / 100.0) + * (1.0 + + mode_lib->vba.DISPCLKRampingMargin + / 100.0); + } else { + mode_lib->vba.PlaneRequiredDISPCLK = + mode_lib->vba.PixelClock[k] + * (1.0 + + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading + / 100.0); + } + mode_lib->vba.RequiredDISPCLK[i] = dml_max( + mode_lib->vba.RequiredDISPCLK[i], + mode_lib->vba.PlaneRequiredDISPCLK); + if ((mode_lib->vba.MinDPPCLKUsingSingleDPP[k] + / mode_lib->vba.NoOfDPP[i][k] + * (1.0 + + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading + / 100.0) + > mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity) + || (mode_lib->vba.PlaneRequiredDISPCLK + > mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity)) { + mode_lib->vba.DISPCLK_DPPCLK_Support[i] = false; + } + } + mode_lib->vba.TotalNumberOfActiveDPP[i] = 0.0; + for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { + mode_lib->vba.TotalNumberOfActiveDPP[i] = + mode_lib->vba.TotalNumberOfActiveDPP[i] + + mode_lib->vba.NoOfDPP[i][k]; + } + } + mode_lib->vba.RequiredDISPCLK[i] = dml_max( + mode_lib->vba.RequiredDISPCLK[i], + mode_lib->vba.WritebackRequiredDISPCLK); + if (mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity + < mode_lib->vba.WritebackRequiredDISPCLK) { + mode_lib->vba.DISPCLK_DPPCLK_Support[i] = false; + } + } + /*Viewport Size Check*/ + + for (i = 0; i <= DC__VOLTAGE_STATES; i++) { + mode_lib->vba.ViewportSizeSupport[i] = true; + for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { + if (mode_lib->vba.ODMCombineEnablePerState[i][k] == true) { + if (dml_min( + mode_lib->vba.SwathWidthYSingleDPP[k], + dml_round( + mode_lib->vba.HActive[k] / 2.0 + * mode_lib->vba.HRatio[k])) + > mode_lib->vba.MaximumSwathWidth[k]) { + mode_lib->vba.ViewportSizeSupport[i] = false; + } + } else { + if (mode_lib->vba.SwathWidthYSingleDPP[k] / 2.0 + > mode_lib->vba.MaximumSwathWidth[k]) { + mode_lib->vba.ViewportSizeSupport[i] = false; + } + } + } + } + /*Total Available Pipes Support Check*/ + + for (i = 0; i <= DC__VOLTAGE_STATES; i++) { + if (mode_lib->vba.TotalNumberOfActiveDPP[i] <= mode_lib->vba.MaxNumDPP) { + mode_lib->vba.TotalAvailablePipesSupport[i] = true; + } else { + mode_lib->vba.TotalAvailablePipesSupport[i] = false; + } + } + /*Total Available OTG Support Check*/ + + mode_lib->vba.TotalNumberOfActiveOTG = 0.0; + for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { + if (mode_lib->vba.BlendingAndTiming[k] == k) { + mode_lib->vba.TotalNumberOfActiveOTG = mode_lib->vba.TotalNumberOfActiveOTG + + 1.0; + } + } + if (mode_lib->vba.TotalNumberOfActiveOTG <= mode_lib->vba.MaxNumOTG) { + mode_lib->vba.NumberOfOTGSupport = true; + } else { + mode_lib->vba.NumberOfOTGSupport = false; + } + /*Display IO and DSC Support Check*/ + + mode_lib->vba.NonsupportedDSCInputBPC = false; + for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { + if (!(mode_lib->vba.DSCInputBitPerComponent[k] == 12.0 + || mode_lib->vba.DSCInputBitPerComponent[k] == 10.0 + || mode_lib->vba.DSCInputBitPerComponent[k] == 8.0)) { + mode_lib->vba.NonsupportedDSCInputBPC = true; + } + } + for (i = 0; i <= DC__VOLTAGE_STATES; i++) { + for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { + mode_lib->vba.RequiresDSC[i][k] = 0; + mode_lib->vba.RequiresFEC[i][k] = 0; + if (mode_lib->vba.BlendingAndTiming[k] == k) { + if (mode_lib->vba.Output[k] == dm_hdmi) { + mode_lib->vba.RequiresDSC[i][k] = 0; + mode_lib->vba.RequiresFEC[i][k] = 0; + mode_lib->vba.OutputBppPerState[i][k] = + TruncToValidBPP( + dml_min( + 600.0, + mode_lib->vba.PHYCLKPerState[i]) + / mode_lib->vba.PixelClockBackEnd[k] + * 24, + false, + mode_lib->vba.Output[k], + mode_lib->vba.OutputFormat[k], + mode_lib->vba.DSCInputBitPerComponent[k]); + } else if (mode_lib->vba.Output[k] == dm_dp + || mode_lib->vba.Output[k] == dm_edp) { + if (mode_lib->vba.Output[k] == dm_edp) { + mode_lib->vba.EffectiveFECOverhead = 0.0; + } else { + mode_lib->vba.EffectiveFECOverhead = + mode_lib->vba.FECOverhead; + } + if (mode_lib->vba.PHYCLKPerState[i] >= 270.0) { + mode_lib->vba.Outbpp = + TruncToValidBPP( + (1.0 + - mode_lib->vba.Downspreading + / 100.0) + * 270.0 + * mode_lib->vba.OutputLinkDPLanes[k] + / mode_lib->vba.PixelClockBackEnd[k] + * 8.0, + false, + mode_lib->vba.Output[k], + mode_lib->vba.OutputFormat[k], + mode_lib->vba.DSCInputBitPerComponent[k]); + mode_lib->vba.OutbppDSC = + TruncToValidBPP( + (1.0 + - mode_lib->vba.Downspreading + / 100.0) + * (1.0 + - mode_lib->vba.EffectiveFECOverhead + / 100.0) + * 270.0 + * mode_lib->vba.OutputLinkDPLanes[k] + / mode_lib->vba.PixelClockBackEnd[k] + * 8.0, + true, + mode_lib->vba.Output[k], + mode_lib->vba.OutputFormat[k], + mode_lib->vba.DSCInputBitPerComponent[k]); + if (mode_lib->vba.DSCEnabled[k] == true) { + mode_lib->vba.RequiresDSC[i][k] = true; + if (mode_lib->vba.Output[k] == dm_dp) { + mode_lib->vba.RequiresFEC[i][k] = + true; + } else { + mode_lib->vba.RequiresFEC[i][k] = + false; + } + mode_lib->vba.Outbpp = + mode_lib->vba.OutbppDSC; + } else { + mode_lib->vba.RequiresDSC[i][k] = false; + mode_lib->vba.RequiresFEC[i][k] = false; + } + mode_lib->vba.OutputBppPerState[i][k] = + mode_lib->vba.Outbpp; + } + if (mode_lib->vba.Outbpp == 0) { + mode_lib->vba.Outbpp = + TruncToValidBPP( + (1.0 + - mode_lib->vba.Downspreading + / 100.0) + * 540.0 + * mode_lib->vba.OutputLinkDPLanes[k] + / mode_lib->vba.PixelClockBackEnd[k] + * 8.0, + false, + mode_lib->vba.Output[k], + mode_lib->vba.OutputFormat[k], + mode_lib->vba.DSCInputBitPerComponent[k]); + mode_lib->vba.OutbppDSC = + TruncToValidBPP( + (1.0 + - mode_lib->vba.Downspreading + / 100.0) + * (1.0 + - mode_lib->vba.EffectiveFECOverhead + / 100.0) + * 540.0 + * mode_lib->vba.OutputLinkDPLanes[k] + / mode_lib->vba.PixelClockBackEnd[k] + * 8.0, + true, + mode_lib->vba.Output[k], + mode_lib->vba.OutputFormat[k], + mode_lib->vba.DSCInputBitPerComponent[k]); + if (mode_lib->vba.DSCEnabled[k] == true) { + mode_lib->vba.RequiresDSC[i][k] = true; + if (mode_lib->vba.Output[k] == dm_dp) { + mode_lib->vba.RequiresFEC[i][k] = + true; + } else { + mode_lib->vba.RequiresFEC[i][k] = + false; + } + mode_lib->vba.Outbpp = + mode_lib->vba.OutbppDSC; + } else { + mode_lib->vba.RequiresDSC[i][k] = false; + mode_lib->vba.RequiresFEC[i][k] = false; + } + mode_lib->vba.OutputBppPerState[i][k] = + mode_lib->vba.Outbpp; + } + if (mode_lib->vba.Outbpp == 0 + && mode_lib->vba.PHYCLKPerState[i] + >= 810.0) { + mode_lib->vba.Outbpp = + TruncToValidBPP( + (1.0 + - mode_lib->vba.Downspreading + / 100.0) + * 810.0 + * mode_lib->vba.OutputLinkDPLanes[k] + / mode_lib->vba.PixelClockBackEnd[k] + * 8.0, + false, + mode_lib->vba.Output[k], + mode_lib->vba.OutputFormat[k], + mode_lib->vba.DSCInputBitPerComponent[k]); + mode_lib->vba.OutbppDSC = + TruncToValidBPP( + (1.0 + - mode_lib->vba.Downspreading + / 100.0) + * (1.0 + - mode_lib->vba.EffectiveFECOverhead + / 100.0) + * 810.0 + * mode_lib->vba.OutputLinkDPLanes[k] + / mode_lib->vba.PixelClockBackEnd[k] + * 8.0, + true, + mode_lib->vba.Output[k], + mode_lib->vba.OutputFormat[k], + mode_lib->vba.DSCInputBitPerComponent[k]); + if (mode_lib->vba.DSCEnabled[k] == true + || mode_lib->vba.Outbpp == 0) { + mode_lib->vba.RequiresDSC[i][k] = true; + if (mode_lib->vba.Output[k] == dm_dp) { + mode_lib->vba.RequiresFEC[i][k] = + true; + } else { + mode_lib->vba.RequiresFEC[i][k] = + false; + } + mode_lib->vba.Outbpp = + mode_lib->vba.OutbppDSC; + } else { + mode_lib->vba.RequiresDSC[i][k] = false; + mode_lib->vba.RequiresFEC[i][k] = false; + } + mode_lib->vba.OutputBppPerState[i][k] = + mode_lib->vba.Outbpp; + } + } + } else { + mode_lib->vba.OutputBppPerState[i][k] = 0; + } + } + } + for (i = 0; i <= DC__VOLTAGE_STATES; i++) { + mode_lib->vba.DIOSupport[i] = true; + for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { + if (mode_lib->vba.OutputBppPerState[i][k] == 0 + || (mode_lib->vba.OutputFormat[k] == dm_420 + && mode_lib->vba.ProgressiveToInterlaceUnitInOPP + == true)) { + mode_lib->vba.DIOSupport[i] = false; + } + } + } + for (i = 0; i <= DC__VOLTAGE_STATES; i++) { + for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { + mode_lib->vba.DSCCLKRequiredMoreThanSupported[i] = false; + if (mode_lib->vba.BlendingAndTiming[k] == k) { + if ((mode_lib->vba.Output[k] == dm_dp + || mode_lib->vba.Output[k] == dm_edp)) { + if (mode_lib->vba.OutputFormat[k] == dm_420 + || mode_lib->vba.OutputFormat[k] + == dm_n422) { + mode_lib->vba.DSCFormatFactor = 2; + } else { + mode_lib->vba.DSCFormatFactor = 1; + } + if (mode_lib->vba.RequiresDSC[i][k] == true) { + if (mode_lib->vba.ODMCombineEnablePerState[i][k] + == true) { + if (mode_lib->vba.PixelClockBackEnd[k] / 6.0 + / mode_lib->vba.DSCFormatFactor + > (1.0 + - mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading + / 100.0) + * mode_lib->vba.MaxDSCCLK[i]) { + mode_lib->vba.DSCCLKRequiredMoreThanSupported[i] = + true; + } + } else { + if (mode_lib->vba.PixelClockBackEnd[k] / 3.0 + / mode_lib->vba.DSCFormatFactor + > (1.0 + - mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading + / 100.0) + * mode_lib->vba.MaxDSCCLK[i]) { + mode_lib->vba.DSCCLKRequiredMoreThanSupported[i] = + true; + } + } + } + } + } + } + } + for (i = 0; i <= DC__VOLTAGE_STATES; i++) { + mode_lib->vba.NotEnoughDSCUnits[i] = false; + mode_lib->vba.TotalDSCUnitsRequired = 0.0; + for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { + if (mode_lib->vba.RequiresDSC[i][k] == true) { + if (mode_lib->vba.ODMCombineEnablePerState[i][k] == true) { + mode_lib->vba.TotalDSCUnitsRequired = + mode_lib->vba.TotalDSCUnitsRequired + 2.0; + } else { + mode_lib->vba.TotalDSCUnitsRequired = + mode_lib->vba.TotalDSCUnitsRequired + 1.0; + } + } + } + if (mode_lib->vba.TotalDSCUnitsRequired > mode_lib->vba.NumberOfDSC) { + mode_lib->vba.NotEnoughDSCUnits[i] = true; + } + } + /*DSC Delay per state*/ + + for (i = 0; i <= DC__VOLTAGE_STATES; i++) { + for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { + if (mode_lib->vba.BlendingAndTiming[k] != k) { + mode_lib->vba.slices = 0; + } else if (mode_lib->vba.RequiresDSC[i][k] == 0 + || mode_lib->vba.RequiresDSC[i][k] == false) { + mode_lib->vba.slices = 0; + } else if (mode_lib->vba.PixelClockBackEnd[k] > 3200.0) { + mode_lib->vba.slices = dml_ceil( + mode_lib->vba.PixelClockBackEnd[k] / 400.0, + 4.0); + } else if (mode_lib->vba.PixelClockBackEnd[k] > 1360.0) { + mode_lib->vba.slices = 8.0; + } else if (mode_lib->vba.PixelClockBackEnd[k] > 680.0) { + mode_lib->vba.slices = 4.0; + } else if (mode_lib->vba.PixelClockBackEnd[k] > 340.0) { + mode_lib->vba.slices = 2.0; + } else { + mode_lib->vba.slices = 1.0; + } + if (mode_lib->vba.OutputBppPerState[i][k] == 0 + || mode_lib->vba.OutputBppPerState[i][k] == 0) { + mode_lib->vba.bpp = 0.0; + } else { + mode_lib->vba.bpp = mode_lib->vba.OutputBppPerState[i][k]; + } + if (mode_lib->vba.RequiresDSC[i][k] == true && mode_lib->vba.bpp != 0.0) { + if (mode_lib->vba.ODMCombineEnablePerState[i][k] == false) { + mode_lib->vba.DSCDelayPerState[i][k] = + dscceComputeDelay( + mode_lib->vba.DSCInputBitPerComponent[k], + mode_lib->vba.bpp, + dml_ceil( + mode_lib->vba.HActive[k] + / mode_lib->vba.slices, + 1.0), + mode_lib->vba.slices, + mode_lib->vba.OutputFormat[k]) + + dscComputeDelay( + mode_lib->vba.OutputFormat[k]); + } else { + mode_lib->vba.DSCDelayPerState[i][k] = + 2.0 + * (dscceComputeDelay( + mode_lib->vba.DSCInputBitPerComponent[k], + mode_lib->vba.bpp, + dml_ceil( + mode_lib->vba.HActive[k] + / mode_lib->vba.slices, + 1.0), + mode_lib->vba.slices + / 2, + mode_lib->vba.OutputFormat[k]) + + dscComputeDelay( + mode_lib->vba.OutputFormat[k])); + } + mode_lib->vba.DSCDelayPerState[i][k] = + mode_lib->vba.DSCDelayPerState[i][k] + * mode_lib->vba.PixelClock[k] + / mode_lib->vba.PixelClockBackEnd[k]; + } else { + mode_lib->vba.DSCDelayPerState[i][k] = 0.0; + } + } + for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { + for (j = 0; j <= mode_lib->vba.NumberOfActivePlanes - 1; j++) { + if (mode_lib->vba.BlendingAndTiming[k] == j + && mode_lib->vba.RequiresDSC[i][j] == true) { + mode_lib->vba.DSCDelayPerState[i][k] = + mode_lib->vba.DSCDelayPerState[i][j]; + } + } + } + } + /*Urgent Latency Support Check*/ + + for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { + for (i = 0; i <= DC__VOLTAGE_STATES; i++) { + if (mode_lib->vba.ODMCombineEnablePerState[i][k] == true) { + mode_lib->vba.SwathWidthYPerState[i][k] = + dml_min( + mode_lib->vba.SwathWidthYSingleDPP[k], + dml_round( + mode_lib->vba.HActive[k] + / 2.0 + * mode_lib->vba.HRatio[k])); + } else { + mode_lib->vba.SwathWidthYPerState[i][k] = + mode_lib->vba.SwathWidthYSingleDPP[k] + / mode_lib->vba.NoOfDPP[i][k]; + } + mode_lib->vba.SwathWidthGranularityY = 256.0 + / dml_ceil(mode_lib->vba.BytePerPixelInDETY[k], 1.0) + / mode_lib->vba.MaxSwathHeightY[k]; + mode_lib->vba.RoundedUpMaxSwathSizeBytesY = (dml_ceil( + mode_lib->vba.SwathWidthYPerState[i][k] - 1.0, + mode_lib->vba.SwathWidthGranularityY) + + mode_lib->vba.SwathWidthGranularityY) + * mode_lib->vba.BytePerPixelInDETY[k] + * mode_lib->vba.MaxSwathHeightY[k]; + if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10) { + mode_lib->vba.RoundedUpMaxSwathSizeBytesY = dml_ceil( + mode_lib->vba.RoundedUpMaxSwathSizeBytesY, + 256.0) + 256; + } + if (mode_lib->vba.MaxSwathHeightC[k] > 0.0) { + mode_lib->vba.SwathWidthGranularityC = 256.0 + / dml_ceil(mode_lib->vba.BytePerPixelInDETC[k], 2.0) + / mode_lib->vba.MaxSwathHeightC[k]; + mode_lib->vba.RoundedUpMaxSwathSizeBytesC = (dml_ceil( + mode_lib->vba.SwathWidthYPerState[i][k] / 2.0 - 1.0, + mode_lib->vba.SwathWidthGranularityC) + + mode_lib->vba.SwathWidthGranularityC) + * mode_lib->vba.BytePerPixelInDETC[k] + * mode_lib->vba.MaxSwathHeightC[k]; + if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10) { + mode_lib->vba.RoundedUpMaxSwathSizeBytesC = dml_ceil( + mode_lib->vba.RoundedUpMaxSwathSizeBytesC, + 256.0) + 256; + } + } else { + mode_lib->vba.RoundedUpMaxSwathSizeBytesC = 0.0; + } + if (mode_lib->vba.RoundedUpMaxSwathSizeBytesY + + mode_lib->vba.RoundedUpMaxSwathSizeBytesC + <= mode_lib->vba.DETBufferSizeInKByte * 1024.0 / 2.0) { + mode_lib->vba.SwathHeightYPerState[i][k] = + mode_lib->vba.MaxSwathHeightY[k]; + mode_lib->vba.SwathHeightCPerState[i][k] = + mode_lib->vba.MaxSwathHeightC[k]; + } else { + mode_lib->vba.SwathHeightYPerState[i][k] = + mode_lib->vba.MinSwathHeightY[k]; + mode_lib->vba.SwathHeightCPerState[i][k] = + mode_lib->vba.MinSwathHeightC[k]; + } + if (mode_lib->vba.BytePerPixelInDETC[k] == 0.0) { + mode_lib->vba.LinesInDETLuma = mode_lib->vba.DETBufferSizeInKByte + * 1024.0 / mode_lib->vba.BytePerPixelInDETY[k] + / mode_lib->vba.SwathWidthYPerState[i][k]; + mode_lib->vba.LinesInDETChroma = 0.0; + } else if (mode_lib->vba.SwathHeightYPerState[i][k] + <= mode_lib->vba.SwathHeightCPerState[i][k]) { + mode_lib->vba.LinesInDETLuma = mode_lib->vba.DETBufferSizeInKByte + * 1024.0 / 2.0 / mode_lib->vba.BytePerPixelInDETY[k] + / mode_lib->vba.SwathWidthYPerState[i][k]; + mode_lib->vba.LinesInDETChroma = mode_lib->vba.DETBufferSizeInKByte + * 1024.0 / 2.0 / mode_lib->vba.BytePerPixelInDETC[k] + / (mode_lib->vba.SwathWidthYPerState[i][k] / 2.0); + } else { + mode_lib->vba.LinesInDETLuma = mode_lib->vba.DETBufferSizeInKByte + * 1024.0 * 2.0 / 3.0 + / mode_lib->vba.BytePerPixelInDETY[k] + / mode_lib->vba.SwathWidthYPerState[i][k]; + mode_lib->vba.LinesInDETChroma = mode_lib->vba.DETBufferSizeInKByte + * 1024.0 / 3.0 / mode_lib->vba.BytePerPixelInDETY[k] + / (mode_lib->vba.SwathWidthYPerState[i][k] / 2.0); + } + mode_lib->vba.EffectiveLBLatencyHidingSourceLinesLuma = + dml_min( + mode_lib->vba.MaxLineBufferLines, + dml_floor( + mode_lib->vba.LineBufferSize + / mode_lib->vba.LBBitPerPixel[k] + / (mode_lib->vba.SwathWidthYPerState[i][k] + / dml_max( + mode_lib->vba.HRatio[k], + 1.0)), + 1.0)) + - (mode_lib->vba.vtaps[k] - 1.0); + mode_lib->vba.EffectiveLBLatencyHidingSourceLinesChroma = + dml_min( + mode_lib->vba.MaxLineBufferLines, + dml_floor( + mode_lib->vba.LineBufferSize + / mode_lib->vba.LBBitPerPixel[k] + / (mode_lib->vba.SwathWidthYPerState[i][k] + / 2.0 + / dml_max( + mode_lib->vba.HRatio[k] + / 2.0, + 1.0)), + 1.0)) + - (mode_lib->vba.VTAPsChroma[k] - 1.0); + mode_lib->vba.EffectiveDETLBLinesLuma = + dml_floor( + mode_lib->vba.LinesInDETLuma + + dml_min( + mode_lib->vba.LinesInDETLuma + * mode_lib->vba.RequiredDISPCLK[i] + * mode_lib->vba.BytePerPixelInDETY[k] + * mode_lib->vba.PSCL_FACTOR[k] + / mode_lib->vba.ReturnBWPerState[i], + mode_lib->vba.EffectiveLBLatencyHidingSourceLinesLuma), + mode_lib->vba.SwathHeightYPerState[i][k]); + mode_lib->vba.EffectiveDETLBLinesChroma = + dml_floor( + mode_lib->vba.LinesInDETChroma + + dml_min( + mode_lib->vba.LinesInDETChroma + * mode_lib->vba.RequiredDISPCLK[i] + * mode_lib->vba.BytePerPixelInDETC[k] + * mode_lib->vba.PSCL_FACTOR_CHROMA[k] + / mode_lib->vba.ReturnBWPerState[i], + mode_lib->vba.EffectiveLBLatencyHidingSourceLinesChroma), + mode_lib->vba.SwathHeightCPerState[i][k]); + if (mode_lib->vba.BytePerPixelInDETC[k] == 0.0) { + mode_lib->vba.UrgentLatencySupportUsPerState[i][k] = + mode_lib->vba.EffectiveDETLBLinesLuma + * (mode_lib->vba.HTotal[k] + / mode_lib->vba.PixelClock[k]) + / mode_lib->vba.VRatio[k] + - mode_lib->vba.EffectiveDETLBLinesLuma + * mode_lib->vba.SwathWidthYPerState[i][k] + * dml_ceil( + mode_lib->vba.BytePerPixelInDETY[k], + 1.0) + / (mode_lib->vba.ReturnBWPerState[i] + / mode_lib->vba.NoOfDPP[i][k]); + } else { + mode_lib->vba.UrgentLatencySupportUsPerState[i][k] = + dml_min( + mode_lib->vba.EffectiveDETLBLinesLuma + * (mode_lib->vba.HTotal[k] + / mode_lib->vba.PixelClock[k]) + / mode_lib->vba.VRatio[k] + - mode_lib->vba.EffectiveDETLBLinesLuma + * mode_lib->vba.SwathWidthYPerState[i][k] + * dml_ceil( + mode_lib->vba.BytePerPixelInDETY[k], + 1.0) + / (mode_lib->vba.ReturnBWPerState[i] + / mode_lib->vba.NoOfDPP[i][k]), + mode_lib->vba.EffectiveDETLBLinesChroma + * (mode_lib->vba.HTotal[k] + / mode_lib->vba.PixelClock[k]) + / (mode_lib->vba.VRatio[k] + / 2.0) + - mode_lib->vba.EffectiveDETLBLinesChroma + * mode_lib->vba.SwathWidthYPerState[i][k] + / 2.0 + * dml_ceil( + mode_lib->vba.BytePerPixelInDETC[k], + 2.0) + / (mode_lib->vba.ReturnBWPerState[i] + / mode_lib->vba.NoOfDPP[i][k])); + } + } + } + for (i = 0; i <= DC__VOLTAGE_STATES; i++) { + mode_lib->vba.UrgentLatencySupport[i] = true; + for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { + if (mode_lib->vba.UrgentLatencySupportUsPerState[i][k] + < mode_lib->vba.UrgentLatency / 1.0) { + mode_lib->vba.UrgentLatencySupport[i] = false; + } + } + } + /*Prefetch Check*/ + + for (i = 0; i <= DC__VOLTAGE_STATES; i++) { + mode_lib->vba.TotalNumberOfDCCActiveDPP[i] = 0.0; + for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { + if (mode_lib->vba.DCCEnable[k] == true) { + mode_lib->vba.TotalNumberOfDCCActiveDPP[i] = + mode_lib->vba.TotalNumberOfDCCActiveDPP[i] + + mode_lib->vba.NoOfDPP[i][k]; + } + } + } + for (i = 0; i <= DC__VOLTAGE_STATES; i++) { + mode_lib->vba.ProjectedDCFCLKDeepSleep = 8.0; + for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { + mode_lib->vba.ProjectedDCFCLKDeepSleep = dml_max( + mode_lib->vba.ProjectedDCFCLKDeepSleep, + mode_lib->vba.PixelClock[k] / 16.0); + if (mode_lib->vba.BytePerPixelInDETC[k] == 0.0) { + if (mode_lib->vba.VRatio[k] <= 1.0) { + mode_lib->vba.ProjectedDCFCLKDeepSleep = + dml_max( + mode_lib->vba.ProjectedDCFCLKDeepSleep, + 1.1 + * dml_ceil( + mode_lib->vba.BytePerPixelInDETY[k], + 1.0) + / 64.0 + * mode_lib->vba.HRatio[k] + * mode_lib->vba.PixelClock[k] + / mode_lib->vba.NoOfDPP[i][k]); + } else { + mode_lib->vba.ProjectedDCFCLKDeepSleep = + dml_max( + mode_lib->vba.ProjectedDCFCLKDeepSleep, + 1.1 + * dml_ceil( + mode_lib->vba.BytePerPixelInDETY[k], + 1.0) + / 64.0 + * mode_lib->vba.PSCL_FACTOR[k] + * mode_lib->vba.RequiredDPPCLK[i][k]); + } + } else { + if (mode_lib->vba.VRatio[k] <= 1.0) { + mode_lib->vba.ProjectedDCFCLKDeepSleep = + dml_max( + mode_lib->vba.ProjectedDCFCLKDeepSleep, + 1.1 + * dml_ceil( + mode_lib->vba.BytePerPixelInDETY[k], + 1.0) + / 32.0 + * mode_lib->vba.HRatio[k] + * mode_lib->vba.PixelClock[k] + / mode_lib->vba.NoOfDPP[i][k]); + } else { + mode_lib->vba.ProjectedDCFCLKDeepSleep = + dml_max( + mode_lib->vba.ProjectedDCFCLKDeepSleep, + 1.1 + * dml_ceil( + mode_lib->vba.BytePerPixelInDETY[k], + 1.0) + / 32.0 + * mode_lib->vba.PSCL_FACTOR[k] + * mode_lib->vba.RequiredDPPCLK[i][k]); + } + if (mode_lib->vba.VRatio[k] / 2.0 <= 1.0) { + mode_lib->vba.ProjectedDCFCLKDeepSleep = + dml_max( + mode_lib->vba.ProjectedDCFCLKDeepSleep, + 1.1 + * dml_ceil( + mode_lib->vba.BytePerPixelInDETC[k], + 2.0) + / 32.0 + * mode_lib->vba.HRatio[k] + / 2.0 + * mode_lib->vba.PixelClock[k] + / mode_lib->vba.NoOfDPP[i][k]); + } else { + mode_lib->vba.ProjectedDCFCLKDeepSleep = + dml_max( + mode_lib->vba.ProjectedDCFCLKDeepSleep, + 1.1 + * dml_ceil( + mode_lib->vba.BytePerPixelInDETC[k], + 2.0) + / 32.0 + * mode_lib->vba.PSCL_FACTOR_CHROMA[k] + * mode_lib->vba.RequiredDPPCLK[i][k]); + } + } + } + for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { + mode_lib->vba.PDEAndMetaPTEBytesPerFrameY = CalculateVMAndRowBytes( + mode_lib, + mode_lib->vba.DCCEnable[k], + mode_lib->vba.Read256BlockHeightY[k], + mode_lib->vba.Read256BlockWidthY[k], + mode_lib->vba.SourcePixelFormat[k], + mode_lib->vba.SurfaceTiling[k], + dml_ceil(mode_lib->vba.BytePerPixelInDETY[k], 1.0), + mode_lib->vba.SourceScan[k], + mode_lib->vba.ViewportWidth[k], + mode_lib->vba.ViewportHeight[k], + mode_lib->vba.SwathWidthYPerState[i][k], + mode_lib->vba.VirtualMemoryEnable, + mode_lib->vba.VMMPageSize, + mode_lib->vba.PTEBufferSizeInRequests, + mode_lib->vba.PDEProcessingBufIn64KBReqs, + mode_lib->vba.PitchY[k], + mode_lib->vba.DCCMetaPitchY[k], + &mode_lib->vba.MacroTileWidthY[k], + &mode_lib->vba.MetaRowBytesY, + &mode_lib->vba.DPTEBytesPerRowY, + &mode_lib->vba.PTEBufferSizeNotExceededY[i][k], + &mode_lib->vba.dpte_row_height[k], + &mode_lib->vba.meta_row_height[k]); + mode_lib->vba.PrefetchLinesY[k] = CalculatePrefetchSourceLines( + mode_lib, + mode_lib->vba.VRatio[k], + mode_lib->vba.vtaps[k], + mode_lib->vba.Interlace[k], + mode_lib->vba.ProgressiveToInterlaceUnitInOPP, + mode_lib->vba.SwathHeightYPerState[i][k], + mode_lib->vba.ViewportYStartY[k], + &mode_lib->vba.PrefillY[k], + &mode_lib->vba.MaxNumSwY[k]); + if ((mode_lib->vba.SourcePixelFormat[k] != dm_444_64 + && mode_lib->vba.SourcePixelFormat[k] != dm_444_32 + && mode_lib->vba.SourcePixelFormat[k] != dm_444_16 + && mode_lib->vba.SourcePixelFormat[k] != dm_mono_16 + && mode_lib->vba.SourcePixelFormat[k] != dm_mono_8)) { + mode_lib->vba.PDEAndMetaPTEBytesPerFrameC = CalculateVMAndRowBytes( + mode_lib, + mode_lib->vba.DCCEnable[k], + mode_lib->vba.Read256BlockHeightY[k], + mode_lib->vba.Read256BlockWidthY[k], + mode_lib->vba.SourcePixelFormat[k], + mode_lib->vba.SurfaceTiling[k], + dml_ceil(mode_lib->vba.BytePerPixelInDETC[k], 2.0), + mode_lib->vba.SourceScan[k], + mode_lib->vba.ViewportWidth[k] / 2.0, + mode_lib->vba.ViewportHeight[k] / 2.0, + mode_lib->vba.SwathWidthYPerState[i][k] / 2.0, + mode_lib->vba.VirtualMemoryEnable, + mode_lib->vba.VMMPageSize, + mode_lib->vba.PTEBufferSizeInRequests, + mode_lib->vba.PDEProcessingBufIn64KBReqs, + mode_lib->vba.PitchC[k], + 0.0, + &mode_lib->vba.MacroTileWidthC[k], + &mode_lib->vba.MetaRowBytesC, + &mode_lib->vba.DPTEBytesPerRowC, + &mode_lib->vba.PTEBufferSizeNotExceededC[i][k], + &mode_lib->vba.dpte_row_height_chroma[k], + &mode_lib->vba.meta_row_height_chroma[k]); + mode_lib->vba.PrefetchLinesC[k] = CalculatePrefetchSourceLines( + mode_lib, + mode_lib->vba.VRatio[k] / 2.0, + mode_lib->vba.VTAPsChroma[k], + mode_lib->vba.Interlace[k], + mode_lib->vba.ProgressiveToInterlaceUnitInOPP, + mode_lib->vba.SwathHeightCPerState[i][k], + mode_lib->vba.ViewportYStartC[k], + &mode_lib->vba.PrefillC[k], + &mode_lib->vba.MaxNumSwC[k]); + } else { + mode_lib->vba.PDEAndMetaPTEBytesPerFrameC = 0.0; + mode_lib->vba.MetaRowBytesC = 0.0; + mode_lib->vba.DPTEBytesPerRowC = 0.0; + mode_lib->vba.PrefetchLinesC[k] = 0.0; + mode_lib->vba.PTEBufferSizeNotExceededC[i][k] = true; + } + mode_lib->vba.PDEAndMetaPTEBytesPerFrame[k] = + mode_lib->vba.PDEAndMetaPTEBytesPerFrameY + + mode_lib->vba.PDEAndMetaPTEBytesPerFrameC; + mode_lib->vba.MetaRowBytes[k] = mode_lib->vba.MetaRowBytesY + + mode_lib->vba.MetaRowBytesC; + mode_lib->vba.DPTEBytesPerRow[k] = mode_lib->vba.DPTEBytesPerRowY + + mode_lib->vba.DPTEBytesPerRowC; + } + mode_lib->vba.ExtraLatency = + mode_lib->vba.UrgentRoundTripAndOutOfOrderLatencyPerState[i] + + (mode_lib->vba.TotalNumberOfActiveDPP[i] + * mode_lib->vba.PixelChunkSizeInKByte + + mode_lib->vba.TotalNumberOfDCCActiveDPP[i] + * mode_lib->vba.MetaChunkSize) + * 1024.0 + / mode_lib->vba.ReturnBWPerState[i]; + if (mode_lib->vba.VirtualMemoryEnable == true) { + mode_lib->vba.ExtraLatency = mode_lib->vba.ExtraLatency + + mode_lib->vba.TotalNumberOfActiveDPP[i] + * mode_lib->vba.PTEChunkSize * 1024.0 + / mode_lib->vba.ReturnBWPerState[i]; + } + mode_lib->vba.TimeCalc = 24.0 / mode_lib->vba.ProjectedDCFCLKDeepSleep; + for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { + if (mode_lib->vba.BlendingAndTiming[k] == k) { + if (mode_lib->vba.WritebackEnable[k] == true) { + mode_lib->vba.WritebackDelay[i][k] = + mode_lib->vba.WritebackLatency + + CalculateWriteBackDelay( + mode_lib->vba.WritebackPixelFormat[k], + mode_lib->vba.WritebackHRatio[k], + mode_lib->vba.WritebackVRatio[k], + mode_lib->vba.WritebackLumaHTaps[k], + mode_lib->vba.WritebackLumaVTaps[k], + mode_lib->vba.WritebackChromaHTaps[k], + mode_lib->vba.WritebackChromaVTaps[k], + mode_lib->vba.WritebackDestinationWidth[k]) + / mode_lib->vba.RequiredDISPCLK[i]; + } else { + mode_lib->vba.WritebackDelay[i][k] = 0.0; + } + for (j = 0; j <= mode_lib->vba.NumberOfActivePlanes - 1; j++) { + if (mode_lib->vba.BlendingAndTiming[j] == k + && mode_lib->vba.WritebackEnable[j] + == true) { + mode_lib->vba.WritebackDelay[i][k] = + dml_max( + mode_lib->vba.WritebackDelay[i][k], + mode_lib->vba.WritebackLatency + + CalculateWriteBackDelay( + mode_lib->vba.WritebackPixelFormat[j], + mode_lib->vba.WritebackHRatio[j], + mode_lib->vba.WritebackVRatio[j], + mode_lib->vba.WritebackLumaHTaps[j], + mode_lib->vba.WritebackLumaVTaps[j], + mode_lib->vba.WritebackChromaHTaps[j], + mode_lib->vba.WritebackChromaVTaps[j], + mode_lib->vba.WritebackDestinationWidth[j]) + / mode_lib->vba.RequiredDISPCLK[i]); + } + } + } + } + for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { + for (j = 0; j <= mode_lib->vba.NumberOfActivePlanes - 1; j++) { + if (mode_lib->vba.BlendingAndTiming[k] == j) { + mode_lib->vba.WritebackDelay[i][k] = + mode_lib->vba.WritebackDelay[i][j]; + } + } + } + for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { + mode_lib->vba.MaximumVStartup[k] = + mode_lib->vba.VTotal[k] - mode_lib->vba.VActive[k] + - dml_max( + 1.0, + dml_ceil( + mode_lib->vba.WritebackDelay[i][k] + / (mode_lib->vba.HTotal[k] + / mode_lib->vba.PixelClock[k]), + 1.0)); + } + mode_lib->vba.TWait = CalculateTWait( + mode_lib->vba.PrefetchMode, + mode_lib->vba.DRAMClockChangeLatency, + mode_lib->vba.UrgentLatency, + mode_lib->vba.SREnterPlusExitTime); + for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { + if (mode_lib->vba.XFCEnabled[k] == true) { + mode_lib->vba.XFCRemoteSurfaceFlipDelay = + CalculateRemoteSurfaceFlipDelay( + mode_lib, + mode_lib->vba.VRatio[k], + mode_lib->vba.SwathWidthYPerState[i][k], + dml_ceil( + mode_lib->vba.BytePerPixelInDETY[k], + 1.0), + mode_lib->vba.HTotal[k] + / mode_lib->vba.PixelClock[k], + mode_lib->vba.XFCTSlvVupdateOffset, + mode_lib->vba.XFCTSlvVupdateWidth, + mode_lib->vba.XFCTSlvVreadyOffset, + mode_lib->vba.XFCXBUFLatencyTolerance, + mode_lib->vba.XFCFillBWOverhead, + mode_lib->vba.XFCSlvChunkSize, + mode_lib->vba.XFCBusTransportTime, + mode_lib->vba.TimeCalc, + mode_lib->vba.TWait, + &mode_lib->vba.SrcActiveDrainRate, + &mode_lib->vba.TInitXFill, + &mode_lib->vba.TslvChk); + } else { + mode_lib->vba.XFCRemoteSurfaceFlipDelay = 0.0; + } + mode_lib->vba.IsErrorResult[i][k] = + CalculatePrefetchSchedule( + mode_lib, + mode_lib->vba.RequiredDPPCLK[i][k], + mode_lib->vba.RequiredDISPCLK[i], + mode_lib->vba.PixelClock[k], + mode_lib->vba.ProjectedDCFCLKDeepSleep, + mode_lib->vba.DSCDelayPerState[i][k], + mode_lib->vba.NoOfDPP[i][k], + mode_lib->vba.ScalerEnabled[k], + mode_lib->vba.NumberOfCursors[k], + mode_lib->vba.DPPCLKDelaySubtotal, + mode_lib->vba.DPPCLKDelaySCL, + mode_lib->vba.DPPCLKDelaySCLLBOnly, + mode_lib->vba.DPPCLKDelayCNVCFormater, + mode_lib->vba.DPPCLKDelayCNVCCursor, + mode_lib->vba.DISPCLKDelaySubtotal, + mode_lib->vba.SwathWidthYPerState[i][k] + / mode_lib->vba.HRatio[k], + mode_lib->vba.OutputFormat[k], + mode_lib->vba.VTotal[k] + - mode_lib->vba.VActive[k], + mode_lib->vba.HTotal[k], + mode_lib->vba.MaxInterDCNTileRepeaters, + mode_lib->vba.MaximumVStartup[k], + mode_lib->vba.MaxPageTableLevels, + mode_lib->vba.VirtualMemoryEnable, + mode_lib->vba.DynamicMetadataEnable[k], + mode_lib->vba.DynamicMetadataLinesBeforeActiveRequired[k], + mode_lib->vba.DynamicMetadataTransmittedBytes[k], + mode_lib->vba.DCCEnable[k], + mode_lib->vba.UrgentLatency, + mode_lib->vba.ExtraLatency, + mode_lib->vba.TimeCalc, + mode_lib->vba.PDEAndMetaPTEBytesPerFrame[k], + mode_lib->vba.MetaRowBytes[k], + mode_lib->vba.DPTEBytesPerRow[k], + mode_lib->vba.PrefetchLinesY[k], + mode_lib->vba.SwathWidthYPerState[i][k], + mode_lib->vba.BytePerPixelInDETY[k], + mode_lib->vba.PrefillY[k], + mode_lib->vba.MaxNumSwY[k], + mode_lib->vba.PrefetchLinesC[k], + mode_lib->vba.BytePerPixelInDETC[k], + mode_lib->vba.PrefillC[k], + mode_lib->vba.MaxNumSwC[k], + mode_lib->vba.SwathHeightYPerState[i][k], + mode_lib->vba.SwathHeightCPerState[i][k], + mode_lib->vba.TWait, + mode_lib->vba.XFCEnabled[k], + mode_lib->vba.XFCRemoteSurfaceFlipDelay, + mode_lib->vba.Interlace[k], + mode_lib->vba.ProgressiveToInterlaceUnitInOPP, + mode_lib->vba.DSTXAfterScaler, + mode_lib->vba.DSTYAfterScaler, + &mode_lib->vba.LineTimesForPrefetch[k], + &mode_lib->vba.PrefetchBW[k], + &mode_lib->vba.LinesForMetaPTE[k], + &mode_lib->vba.LinesForMetaAndDPTERow[k], + &mode_lib->vba.VRatioPreY[i][k], + &mode_lib->vba.VRatioPreC[i][k], + &mode_lib->vba.RequiredPrefetchPixelDataBW[i][k], + &mode_lib->vba.VStartupRequiredWhenNotEnoughTimeForDynamicMetadata, + &mode_lib->vba.Tno_bw[k]); + } + for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { + mode_lib->vba.cursor_bw[k] = mode_lib->vba.NumberOfCursors[k] + * mode_lib->vba.CursorWidth[k][0] + * mode_lib->vba.CursorBPP[k][0] / 8.0 + / (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]) + * mode_lib->vba.VRatio[k]; + } + mode_lib->vba.MaximumReadBandwidthWithPrefetch = 0.0; + mode_lib->vba.prefetch_vm_bw_valid = true; + mode_lib->vba.prefetch_row_bw_valid = true; + for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { + if (mode_lib->vba.PDEAndMetaPTEBytesPerFrame[k] == 0.0) { + mode_lib->vba.prefetch_vm_bw[k] = 0.0; + } else if (mode_lib->vba.LinesForMetaPTE[k] > 0.0) { + mode_lib->vba.prefetch_vm_bw[k] = + mode_lib->vba.PDEAndMetaPTEBytesPerFrame[k] + / (mode_lib->vba.LinesForMetaPTE[k] + * mode_lib->vba.HTotal[k] + / mode_lib->vba.PixelClock[k]); + } else { + mode_lib->vba.prefetch_vm_bw[k] = 0.0; + mode_lib->vba.prefetch_vm_bw_valid = false; + } + if (mode_lib->vba.MetaRowBytes[k] + mode_lib->vba.DPTEBytesPerRow[k] + == 0.0) { + mode_lib->vba.prefetch_row_bw[k] = 0.0; + } else if (mode_lib->vba.LinesForMetaAndDPTERow[k] > 0.0) { + mode_lib->vba.prefetch_row_bw[k] = (mode_lib->vba.MetaRowBytes[k] + + mode_lib->vba.DPTEBytesPerRow[k]) + / (mode_lib->vba.LinesForMetaAndDPTERow[k] + * mode_lib->vba.HTotal[k] + / mode_lib->vba.PixelClock[k]); + } else { + mode_lib->vba.prefetch_row_bw[k] = 0.0; + mode_lib->vba.prefetch_row_bw_valid = false; + } + mode_lib->vba.MaximumReadBandwidthWithPrefetch = + mode_lib->vba.MaximumReadBandwidthWithPrefetch + + mode_lib->vba.cursor_bw[k] + + dml_max4( + mode_lib->vba.prefetch_vm_bw[k], + mode_lib->vba.prefetch_row_bw[k], + mode_lib->vba.ReadBandwidth[k], + mode_lib->vba.RequiredPrefetchPixelDataBW[i][k]); + } + mode_lib->vba.PrefetchSupported[i] = true; + if (mode_lib->vba.MaximumReadBandwidthWithPrefetch + > mode_lib->vba.ReturnBWPerState[i] + || mode_lib->vba.prefetch_vm_bw_valid == false + || mode_lib->vba.prefetch_row_bw_valid == false) { + mode_lib->vba.PrefetchSupported[i] = false; + } + for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { + if (mode_lib->vba.LineTimesForPrefetch[k] < 2.0 + || mode_lib->vba.LinesForMetaPTE[k] >= 8.0 + || mode_lib->vba.LinesForMetaAndDPTERow[k] >= 16.0 + || mode_lib->vba.IsErrorResult[i][k] == true) { + mode_lib->vba.PrefetchSupported[i] = false; + } + } + mode_lib->vba.VRatioInPrefetchSupported[i] = true; + for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { + if (mode_lib->vba.VRatioPreY[i][k] > 4.0 + || mode_lib->vba.VRatioPreC[i][k] > 4.0 + || mode_lib->vba.IsErrorResult[i][k] == true) { + mode_lib->vba.VRatioInPrefetchSupported[i] = false; + } + } + if (mode_lib->vba.PrefetchSupported[i] == true + && mode_lib->vba.VRatioInPrefetchSupported[i] == true) { + mode_lib->vba.BandwidthAvailableForImmediateFlip = + mode_lib->vba.ReturnBWPerState[i]; + for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { + mode_lib->vba.BandwidthAvailableForImmediateFlip = + mode_lib->vba.BandwidthAvailableForImmediateFlip + - mode_lib->vba.cursor_bw[k] + - dml_max( + mode_lib->vba.ReadBandwidth[k], + mode_lib->vba.PrefetchBW[k]); + } + for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { + mode_lib->vba.ImmediateFlipBytes[k] = 0.0; + if ((mode_lib->vba.SourcePixelFormat[k] != dm_420_8 + && mode_lib->vba.SourcePixelFormat[k] != dm_420_10)) { + mode_lib->vba.ImmediateFlipBytes[k] = + mode_lib->vba.PDEAndMetaPTEBytesPerFrame[k] + + mode_lib->vba.MetaRowBytes[k] + + mode_lib->vba.DPTEBytesPerRow[k]; + } + } + mode_lib->vba.TotImmediateFlipBytes = 0.0; + for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { + if ((mode_lib->vba.SourcePixelFormat[k] != dm_420_8 + && mode_lib->vba.SourcePixelFormat[k] != dm_420_10)) { + mode_lib->vba.TotImmediateFlipBytes = + mode_lib->vba.TotImmediateFlipBytes + + mode_lib->vba.ImmediateFlipBytes[k]; + } + } + for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { + CalculateFlipSchedule( + mode_lib, + mode_lib->vba.ExtraLatency, + mode_lib->vba.UrgentLatency, + mode_lib->vba.MaxPageTableLevels, + mode_lib->vba.VirtualMemoryEnable, + mode_lib->vba.BandwidthAvailableForImmediateFlip, + mode_lib->vba.TotImmediateFlipBytes, + mode_lib->vba.SourcePixelFormat[k], + mode_lib->vba.ImmediateFlipBytes[k], + mode_lib->vba.HTotal[k] + / mode_lib->vba.PixelClock[k], + mode_lib->vba.VRatio[k], + mode_lib->vba.Tno_bw[k], + mode_lib->vba.PDEAndMetaPTEBytesPerFrame[k], + mode_lib->vba.MetaRowBytes[k], + mode_lib->vba.DPTEBytesPerRow[k], + mode_lib->vba.DCCEnable[k], + mode_lib->vba.dpte_row_height[k], + mode_lib->vba.meta_row_height[k], + mode_lib->vba.qual_row_bw[k], + &mode_lib->vba.DestinationLinesToRequestVMInImmediateFlip[k], + &mode_lib->vba.DestinationLinesToRequestRowInImmediateFlip[k], + &mode_lib->vba.final_flip_bw[k], + &mode_lib->vba.ImmediateFlipSupportedForPipe[k]); + } + mode_lib->vba.total_dcn_read_bw_with_flip = 0.0; + for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { + mode_lib->vba.total_dcn_read_bw_with_flip = + mode_lib->vba.total_dcn_read_bw_with_flip + + mode_lib->vba.cursor_bw[k] + + dml_max3( + mode_lib->vba.prefetch_vm_bw[k], + mode_lib->vba.prefetch_row_bw[k], + mode_lib->vba.final_flip_bw[k] + + dml_max( + mode_lib->vba.ReadBandwidth[k], + mode_lib->vba.RequiredPrefetchPixelDataBW[i][k])); + } + mode_lib->vba.ImmediateFlipSupportedForState[i] = true; + if (mode_lib->vba.total_dcn_read_bw_with_flip + > mode_lib->vba.ReturnBWPerState[i]) { + mode_lib->vba.ImmediateFlipSupportedForState[i] = false; + } + for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { + if (mode_lib->vba.ImmediateFlipSupportedForPipe[k] == false) { + mode_lib->vba.ImmediateFlipSupportedForState[i] = false; + } + } + } else { + mode_lib->vba.ImmediateFlipSupportedForState[i] = false; + } + } + /*PTE Buffer Size Check*/ + + for (i = 0; i <= DC__VOLTAGE_STATES; i++) { + mode_lib->vba.PTEBufferSizeNotExceeded[i] = true; + for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { + if (mode_lib->vba.PTEBufferSizeNotExceededY[i][k] == false + || mode_lib->vba.PTEBufferSizeNotExceededC[i][k] == false) { + mode_lib->vba.PTEBufferSizeNotExceeded[i] = false; + } + } + } + /*Cursor Support Check*/ + + mode_lib->vba.CursorSupport = true; + for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { + if (mode_lib->vba.CursorWidth[k][0] > 0.0) { + if (dml_floor( + dml_floor( + mode_lib->vba.CursorBufferSize + - mode_lib->vba.CursorChunkSize, + mode_lib->vba.CursorChunkSize) * 1024.0 + / (mode_lib->vba.CursorWidth[k][0] + * mode_lib->vba.CursorBPP[k][0] + / 8.0), + 1.0) + * (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]) + / mode_lib->vba.VRatio[k] < mode_lib->vba.UrgentLatency + || (mode_lib->vba.CursorBPP[k][0] == 64.0 + && mode_lib->vba.Cursor64BppSupport == false)) { + mode_lib->vba.CursorSupport = false; + } + } + } + /*Valid Pitch Check*/ + + mode_lib->vba.PitchSupport = true; + for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { + mode_lib->vba.AlignedYPitch[k] = dml_ceil( + dml_max(mode_lib->vba.PitchY[k], mode_lib->vba.ViewportWidth[k]), + mode_lib->vba.MacroTileWidthY[k]); + if (mode_lib->vba.AlignedYPitch[k] > mode_lib->vba.PitchY[k]) { + mode_lib->vba.PitchSupport = false; + } + if (mode_lib->vba.DCCEnable[k] == true) { + mode_lib->vba.AlignedDCCMetaPitch[k] = dml_ceil( + dml_max( + mode_lib->vba.DCCMetaPitchY[k], + mode_lib->vba.ViewportWidth[k]), + 64.0 * mode_lib->vba.Read256BlockWidthY[k]); + } else { + mode_lib->vba.AlignedDCCMetaPitch[k] = mode_lib->vba.DCCMetaPitchY[k]; + } + if (mode_lib->vba.AlignedDCCMetaPitch[k] > mode_lib->vba.DCCMetaPitchY[k]) { + mode_lib->vba.PitchSupport = false; + } + if (mode_lib->vba.SourcePixelFormat[k] != dm_444_64 + && mode_lib->vba.SourcePixelFormat[k] != dm_444_32 + && mode_lib->vba.SourcePixelFormat[k] != dm_444_16 + && mode_lib->vba.SourcePixelFormat[k] != dm_mono_16 + && mode_lib->vba.SourcePixelFormat[k] != dm_mono_8) { + mode_lib->vba.AlignedCPitch[k] = dml_ceil( + dml_max( + mode_lib->vba.PitchC[k], + mode_lib->vba.ViewportWidth[k] / 2.0), + mode_lib->vba.MacroTileWidthC[k]); + } else { + mode_lib->vba.AlignedCPitch[k] = mode_lib->vba.PitchC[k]; + } + if (mode_lib->vba.AlignedCPitch[k] > mode_lib->vba.PitchC[k]) { + mode_lib->vba.PitchSupport = false; + } + } + /*Mode Support, Voltage State and SOC Configuration*/ + + for (i = DC__VOLTAGE_STATES; i >= 0; i--) { + if (mode_lib->vba.ScaleRatioAndTapsSupport == true + && mode_lib->vba.SourceFormatPixelAndScanSupport == true + && mode_lib->vba.ViewportSizeSupport[i] == true + && mode_lib->vba.BandwidthSupport[i] == true + && mode_lib->vba.DIOSupport[i] == true + && mode_lib->vba.NotEnoughDSCUnits[i] == false + && mode_lib->vba.DSCCLKRequiredMoreThanSupported[i] == false + && mode_lib->vba.UrgentLatencySupport[i] == true + && mode_lib->vba.ROBSupport[i] == true + && mode_lib->vba.DISPCLK_DPPCLK_Support[i] == true + && mode_lib->vba.TotalAvailablePipesSupport[i] == true + && mode_lib->vba.NumberOfOTGSupport == true + && mode_lib->vba.WritebackModeSupport == true + && mode_lib->vba.WritebackLatencySupport == true + && mode_lib->vba.WritebackScaleRatioAndTapsSupport == true + && mode_lib->vba.CursorSupport == true + && mode_lib->vba.PitchSupport == true + && mode_lib->vba.PrefetchSupported[i] == true + && mode_lib->vba.VRatioInPrefetchSupported[i] == true + && mode_lib->vba.PTEBufferSizeNotExceeded[i] == true + && mode_lib->vba.NonsupportedDSCInputBPC == false) { + mode_lib->vba.ModeSupport[i] = true; + } else { + mode_lib->vba.ModeSupport[i] = false; + } + } + for (i = DC__VOLTAGE_STATES; i >= 0; i--) { + if (i == DC__VOLTAGE_STATES || mode_lib->vba.ModeSupport[i] == true) { + mode_lib->vba.VoltageLevel = i; + } + } + mode_lib->vba.DCFCLK = mode_lib->vba.DCFCLKPerState[mode_lib->vba.VoltageLevel]; + mode_lib->vba.DRAMSpeed = mode_lib->vba.DRAMSpeedPerState[mode_lib->vba.VoltageLevel]; + mode_lib->vba.FabricClock = mode_lib->vba.FabricClockPerState[mode_lib->vba.VoltageLevel]; + mode_lib->vba.SOCCLK = mode_lib->vba.SOCCLKPerState[mode_lib->vba.VoltageLevel]; + mode_lib->vba.FabricAndDRAMBandwidth = + mode_lib->vba.FabricAndDRAMBandwidthPerState[mode_lib->vba.VoltageLevel]; + mode_lib->vba.ImmediateFlipSupport = + mode_lib->vba.ImmediateFlipSupportedForState[mode_lib->vba.VoltageLevel]; + for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { + mode_lib->vba.DPPPerPlane[k] = mode_lib->vba.NoOfDPP[mode_lib->vba.VoltageLevel][k]; + } + for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { + if (mode_lib->vba.BlendingAndTiming[k] == k) { + mode_lib->vba.ODMCombineEnabled[k] = + mode_lib->vba.ODMCombineEnablePerState[mode_lib->vba.VoltageLevel][k]; + } else { + mode_lib->vba.ODMCombineEnabled[k] = 0; + } + mode_lib->vba.DSCEnabled[k] = + mode_lib->vba.RequiresDSC[mode_lib->vba.VoltageLevel][k]; + mode_lib->vba.OutputBpp[k] = + mode_lib->vba.OutputBppPerState[mode_lib->vba.VoltageLevel][k]; + } +} diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h index a24fe9a0383db..346ffea843c99 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h +++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h @@ -79,6 +79,11 @@ double get_total_prefetch_bw( const display_e2e_pipe_params_st *pipes, unsigned int num_pipes); +unsigned int dml_get_voltage_level( + struct display_mode_lib *mode_lib, + const display_e2e_pipe_params_st *pipes, + unsigned int num_pipes); + bool Calculate256BBlockSizes( enum source_format_class SourcePixelFormat, enum dm_swizzle_mode SurfaceTiling, @@ -96,42 +101,41 @@ struct vba_vars_st { mode_evaluation_st me; unsigned int MaximumMaxVStartupLines; - double cursor_bw[DC__NUM_PIPES__MAX]; - double meta_row_bw[DC__NUM_PIPES__MAX]; - double dpte_row_bw[DC__NUM_PIPES__MAX]; - double qual_row_bw[DC__NUM_PIPES__MAX]; + double cursor_bw[DC__NUM_DPP__MAX]; + double meta_row_bw[DC__NUM_DPP__MAX]; + double dpte_row_bw[DC__NUM_DPP__MAX]; + double qual_row_bw[DC__NUM_DPP__MAX]; double WritebackDISPCLK; - double PSCL_THROUGHPUT_LUMA[DC__NUM_PIPES__MAX]; - double PSCL_THROUGHPUT_CHROMA[DC__NUM_PIPES__MAX]; + double PSCL_THROUGHPUT_LUMA[DC__NUM_DPP__MAX]; + double PSCL_THROUGHPUT_CHROMA[DC__NUM_DPP__MAX]; double DPPCLKUsingSingleDPPLuma; double DPPCLKUsingSingleDPPChroma; - double DPPCLKUsingSingleDPP[DC__NUM_PIPES__MAX]; + double DPPCLKUsingSingleDPP[DC__NUM_DPP__MAX]; double DISPCLKWithRamping; double DISPCLKWithoutRamping; double GlobalDPPCLK; - double MaxDispclk; double DISPCLKWithRampingRoundedToDFSGranularity; double DISPCLKWithoutRampingRoundedToDFSGranularity; double MaxDispclkRoundedToDFSGranularity; bool DCCEnabledAnyPlane; double ReturnBandwidthToDCN; - unsigned int SwathWidthY[DC__NUM_PIPES__MAX]; - unsigned int SwathWidthSingleDPPY[DC__NUM_PIPES__MAX]; - double BytePerPixelDETY[DC__NUM_PIPES__MAX]; - double BytePerPixelDETC[DC__NUM_PIPES__MAX]; - double ReadBandwidthPlaneLuma[DC__NUM_PIPES__MAX]; - double ReadBandwidthPlaneChroma[DC__NUM_PIPES__MAX]; + unsigned int SwathWidthY[DC__NUM_DPP__MAX]; + unsigned int SwathWidthSingleDPPY[DC__NUM_DPP__MAX]; + double BytePerPixelDETY[DC__NUM_DPP__MAX]; + double BytePerPixelDETC[DC__NUM_DPP__MAX]; + double ReadBandwidthPlaneLuma[DC__NUM_DPP__MAX]; + double ReadBandwidthPlaneChroma[DC__NUM_DPP__MAX]; unsigned int TotalActiveDPP; unsigned int TotalDCCActiveDPP; double UrgentRoundTripAndOutOfOrderLatency; - double DisplayPipeLineDeliveryTimeLuma[DC__NUM_PIPES__MAX]; // WM - double DisplayPipeLineDeliveryTimeChroma[DC__NUM_PIPES__MAX]; // WM - double LinesInDETY[DC__NUM_PIPES__MAX]; // WM - double LinesInDETC[DC__NUM_PIPES__MAX]; // WM - unsigned int LinesInDETYRoundedDownToSwath[DC__NUM_PIPES__MAX]; // WM - unsigned int LinesInDETCRoundedDownToSwath[DC__NUM_PIPES__MAX]; // WM - double FullDETBufferingTimeY[DC__NUM_PIPES__MAX]; // WM - double FullDETBufferingTimeC[DC__NUM_PIPES__MAX]; // WM + double DisplayPipeLineDeliveryTimeLuma[DC__NUM_DPP__MAX]; // WM + double DisplayPipeLineDeliveryTimeChroma[DC__NUM_DPP__MAX]; // WM + double LinesInDETY[DC__NUM_DPP__MAX]; // WM + double LinesInDETC[DC__NUM_DPP__MAX]; // WM + unsigned int LinesInDETYRoundedDownToSwath[DC__NUM_DPP__MAX]; // WM + unsigned int LinesInDETCRoundedDownToSwath[DC__NUM_DPP__MAX]; // WM + double FullDETBufferingTimeY[DC__NUM_DPP__MAX]; // WM + double FullDETBufferingTimeC[DC__NUM_DPP__MAX]; // WM double MinFullDETBufferingTime; double FrameTimeForMinFullDETBufferingTime; double AverageReadBandwidthGBytePerSecond; @@ -145,55 +149,54 @@ struct vba_vars_st { double EffectiveDETPlusLBLinesChroma; double UrgentLatencySupportUsLuma; double UrgentLatencySupportUsChroma; - double UrgentLatencySupportUs[DC__NUM_PIPES__MAX]; + double UrgentLatencySupportUs[DC__NUM_DPP__MAX]; unsigned int DSCFormatFactor; - unsigned int BlockHeight256BytesY[DC__NUM_PIPES__MAX]; - unsigned int BlockHeight256BytesC[DC__NUM_PIPES__MAX]; - unsigned int BlockWidth256BytesY[DC__NUM_PIPES__MAX]; - unsigned int BlockWidth256BytesC[DC__NUM_PIPES__MAX]; - double VInitPreFillY[DC__NUM_PIPES__MAX]; - double VInitPreFillC[DC__NUM_PIPES__MAX]; - unsigned int MaxNumSwathY[DC__NUM_PIPES__MAX]; - unsigned int MaxNumSwathC[DC__NUM_PIPES__MAX]; - double PrefetchSourceLinesY[DC__NUM_PIPES__MAX]; - double PrefetchSourceLinesC[DC__NUM_PIPES__MAX]; - double PixelPTEBytesPerRow[DC__NUM_PIPES__MAX]; - double MetaRowByte[DC__NUM_PIPES__MAX]; - bool PTEBufferSizeNotExceeded; // not used - unsigned int dpte_row_height[DC__NUM_PIPES__MAX]; - unsigned int dpte_row_height_chroma[DC__NUM_PIPES__MAX]; - unsigned int meta_row_height[DC__NUM_PIPES__MAX]; - unsigned int meta_row_height_chroma[DC__NUM_PIPES__MAX]; - - unsigned int MacroTileWidthY; - unsigned int MacroTileWidthC; - unsigned int MaxVStartupLines[DC__NUM_PIPES__MAX]; - double WritebackDelay[DC__NUM_PIPES__MAX]; + unsigned int BlockHeight256BytesY[DC__NUM_DPP__MAX]; + unsigned int BlockHeight256BytesC[DC__NUM_DPP__MAX]; + unsigned int BlockWidth256BytesY[DC__NUM_DPP__MAX]; + unsigned int BlockWidth256BytesC[DC__NUM_DPP__MAX]; + double VInitPreFillY[DC__NUM_DPP__MAX]; + double VInitPreFillC[DC__NUM_DPP__MAX]; + unsigned int MaxNumSwathY[DC__NUM_DPP__MAX]; + unsigned int MaxNumSwathC[DC__NUM_DPP__MAX]; + double PrefetchSourceLinesY[DC__NUM_DPP__MAX]; + double PrefetchSourceLinesC[DC__NUM_DPP__MAX]; + double PixelPTEBytesPerRow[DC__NUM_DPP__MAX]; + double MetaRowByte[DC__NUM_DPP__MAX]; + unsigned int dpte_row_height[DC__NUM_DPP__MAX]; + unsigned int dpte_row_height_chroma[DC__NUM_DPP__MAX]; + unsigned int meta_row_height[DC__NUM_DPP__MAX]; + unsigned int meta_row_height_chroma[DC__NUM_DPP__MAX]; + + unsigned int MacroTileWidthY[DC__NUM_DPP__MAX]; + unsigned int MacroTileWidthC[DC__NUM_DPP__MAX]; + unsigned int MaxVStartupLines[DC__NUM_DPP__MAX]; + double WritebackDelay[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX]; bool PrefetchModeSupported; - bool AllowDRAMClockChangeDuringVBlank[DC__NUM_PIPES__MAX]; - bool AllowDRAMSelfRefreshDuringVBlank[DC__NUM_PIPES__MAX]; - double RequiredPrefetchPixDataBW[DC__NUM_PIPES__MAX]; + bool AllowDRAMClockChangeDuringVBlank[DC__NUM_DPP__MAX]; + bool AllowDRAMSelfRefreshDuringVBlank[DC__NUM_DPP__MAX]; + double RequiredPrefetchPixDataBW[DC__NUM_DPP__MAX]; double XFCRemoteSurfaceFlipDelay; double TInitXFill; double TslvChk; double SrcActiveDrainRate; - double Tno_bw[DC__NUM_PIPES__MAX]; + double Tno_bw[DC__NUM_DPP__MAX]; bool ImmediateFlipSupported; - double prefetch_vm_bw[DC__NUM_PIPES__MAX]; - double prefetch_row_bw[DC__NUM_PIPES__MAX]; - bool ImmediateFlipSupportedForPipe[DC__NUM_PIPES__MAX]; + double prefetch_vm_bw[DC__NUM_DPP__MAX]; + double prefetch_row_bw[DC__NUM_DPP__MAX]; + bool ImmediateFlipSupportedForPipe[DC__NUM_DPP__MAX]; unsigned int VStartupLines; - double DisplayPipeLineDeliveryTimeLumaPrefetch[DC__NUM_PIPES__MAX]; - double DisplayPipeLineDeliveryTimeChromaPrefetch[DC__NUM_PIPES__MAX]; + double DisplayPipeLineDeliveryTimeLumaPrefetch[DC__NUM_DPP__MAX]; + double DisplayPipeLineDeliveryTimeChromaPrefetch[DC__NUM_DPP__MAX]; unsigned int ActiveDPPs; unsigned int LBLatencyHidingSourceLinesY; unsigned int LBLatencyHidingSourceLinesC; - double ActiveDRAMClockChangeLatencyMargin[DC__NUM_PIPES__MAX]; + double ActiveDRAMClockChangeLatencyMargin[DC__NUM_DPP__MAX]; double MinActiveDRAMClockChangeMargin; - double XFCSlaveVUpdateOffset[DC__NUM_PIPES__MAX]; - double XFCSlaveVupdateWidth[DC__NUM_PIPES__MAX]; - double XFCSlaveVReadyOffset[DC__NUM_PIPES__MAX]; + double XFCSlaveVUpdateOffset[DC__NUM_DPP__MAX]; + double XFCSlaveVupdateWidth[DC__NUM_DPP__MAX]; + double XFCSlaveVReadyOffset[DC__NUM_DPP__MAX]; double InitFillLevel; double FinalFillMargin; double FinalFillLevel; @@ -276,71 +279,71 @@ struct vba_vars_st { double DCFCLK; unsigned int NumberOfActivePlanes; - unsigned int ViewportWidth[DC__NUM_DPP]; - unsigned int ViewportHeight[DC__NUM_DPP]; - unsigned int ViewportYStartY[DC__NUM_DPP]; - unsigned int ViewportYStartC[DC__NUM_DPP]; - unsigned int PitchY[DC__NUM_DPP]; - unsigned int PitchC[DC__NUM_DPP]; - double HRatio[DC__NUM_DPP]; - double VRatio[DC__NUM_DPP]; - unsigned int htaps[DC__NUM_DPP]; - unsigned int vtaps[DC__NUM_DPP]; - unsigned int HTAPsChroma[DC__NUM_DPP]; - unsigned int VTAPsChroma[DC__NUM_DPP]; - unsigned int HTotal[DC__NUM_DPP]; - unsigned int VTotal[DC__NUM_DPP]; - unsigned int DPPPerPlane[DC__NUM_DPP]; - double PixelClock[DC__NUM_DPP]; - double PixelClockBackEnd[DC__NUM_DPP]; - double DPPCLK[DC__NUM_DPP]; - bool DCCEnable[DC__NUM_DPP]; - unsigned int DCCMetaPitchY[DC__NUM_DPP]; - enum scan_direction_class SourceScan[DC__NUM_DPP]; - enum source_format_class SourcePixelFormat[DC__NUM_DPP]; - bool WritebackEnable[DC__NUM_DPP]; - double WritebackDestinationWidth[DC__NUM_DPP]; - double WritebackDestinationHeight[DC__NUM_DPP]; - double WritebackSourceHeight[DC__NUM_DPP]; - enum source_format_class WritebackPixelFormat[DC__NUM_DPP]; - unsigned int WritebackLumaHTaps[DC__NUM_DPP]; - unsigned int WritebackLumaVTaps[DC__NUM_DPP]; - unsigned int WritebackChromaHTaps[DC__NUM_DPP]; - unsigned int WritebackChromaVTaps[DC__NUM_DPP]; - double WritebackHRatio[DC__NUM_DPP]; - double WritebackVRatio[DC__NUM_DPP]; - unsigned int HActive[DC__NUM_DPP]; - unsigned int VActive[DC__NUM_DPP]; - bool Interlace[DC__NUM_DPP]; - enum dm_swizzle_mode SurfaceTiling[DC__NUM_DPP]; - unsigned int ScalerRecoutWidth[DC__NUM_DPP]; - bool DynamicMetadataEnable[DC__NUM_DPP]; - unsigned int DynamicMetadataLinesBeforeActiveRequired[DC__NUM_DPP]; - unsigned int DynamicMetadataTransmittedBytes[DC__NUM_DPP]; - double DCCRate[DC__NUM_DPP]; - bool ODMCombineEnabled[DC__NUM_DPP]; - double OutputBpp[DC__NUM_DPP]; - unsigned int NumberOfDSCSlices[DC__NUM_DPP]; - bool DSCEnabled[DC__NUM_DPP]; - unsigned int DSCDelay[DC__NUM_DPP]; - unsigned int DSCInputBitPerComponent[DC__NUM_DPP]; - enum output_format_class OutputFormat[DC__NUM_DPP]; - enum output_encoder_class Output[DC__NUM_DPP]; - unsigned int BlendingAndTiming[DC__NUM_DPP]; + unsigned int ViewportWidth[DC__NUM_DPP__MAX]; + unsigned int ViewportHeight[DC__NUM_DPP__MAX]; + unsigned int ViewportYStartY[DC__NUM_DPP__MAX]; + unsigned int ViewportYStartC[DC__NUM_DPP__MAX]; + unsigned int PitchY[DC__NUM_DPP__MAX]; + unsigned int PitchC[DC__NUM_DPP__MAX]; + double HRatio[DC__NUM_DPP__MAX]; + double VRatio[DC__NUM_DPP__MAX]; + unsigned int htaps[DC__NUM_DPP__MAX]; + unsigned int vtaps[DC__NUM_DPP__MAX]; + unsigned int HTAPsChroma[DC__NUM_DPP__MAX]; + unsigned int VTAPsChroma[DC__NUM_DPP__MAX]; + unsigned int HTotal[DC__NUM_DPP__MAX]; + unsigned int VTotal[DC__NUM_DPP__MAX]; + unsigned int DPPPerPlane[DC__NUM_DPP__MAX]; + double PixelClock[DC__NUM_DPP__MAX]; + double PixelClockBackEnd[DC__NUM_DPP__MAX]; + double DPPCLK[DC__NUM_DPP__MAX]; + bool DCCEnable[DC__NUM_DPP__MAX]; + unsigned int DCCMetaPitchY[DC__NUM_DPP__MAX]; + enum scan_direction_class SourceScan[DC__NUM_DPP__MAX]; + enum source_format_class SourcePixelFormat[DC__NUM_DPP__MAX]; + bool WritebackEnable[DC__NUM_DPP__MAX]; + double WritebackDestinationWidth[DC__NUM_DPP__MAX]; + double WritebackDestinationHeight[DC__NUM_DPP__MAX]; + double WritebackSourceHeight[DC__NUM_DPP__MAX]; + enum source_format_class WritebackPixelFormat[DC__NUM_DPP__MAX]; + unsigned int WritebackLumaHTaps[DC__NUM_DPP__MAX]; + unsigned int WritebackLumaVTaps[DC__NUM_DPP__MAX]; + unsigned int WritebackChromaHTaps[DC__NUM_DPP__MAX]; + unsigned int WritebackChromaVTaps[DC__NUM_DPP__MAX]; + double WritebackHRatio[DC__NUM_DPP__MAX]; + double WritebackVRatio[DC__NUM_DPP__MAX]; + unsigned int HActive[DC__NUM_DPP__MAX]; + unsigned int VActive[DC__NUM_DPP__MAX]; + bool Interlace[DC__NUM_DPP__MAX]; + enum dm_swizzle_mode SurfaceTiling[DC__NUM_DPP__MAX]; + unsigned int ScalerRecoutWidth[DC__NUM_DPP__MAX]; + bool DynamicMetadataEnable[DC__NUM_DPP__MAX]; + unsigned int DynamicMetadataLinesBeforeActiveRequired[DC__NUM_DPP__MAX]; + unsigned int DynamicMetadataTransmittedBytes[DC__NUM_DPP__MAX]; + double DCCRate[DC__NUM_DPP__MAX]; + bool ODMCombineEnabled[DC__NUM_DPP__MAX]; + double OutputBpp[DC__NUM_DPP__MAX]; + unsigned int NumberOfDSCSlices[DC__NUM_DPP__MAX]; + bool DSCEnabled[DC__NUM_DPP__MAX]; + unsigned int DSCDelay[DC__NUM_DPP__MAX]; + unsigned int DSCInputBitPerComponent[DC__NUM_DPP__MAX]; + enum output_format_class OutputFormat[DC__NUM_DPP__MAX]; + enum output_encoder_class Output[DC__NUM_DPP__MAX]; + unsigned int BlendingAndTiming[DC__NUM_DPP__MAX]; bool SynchronizedVBlank; - unsigned int NumberOfCursors[DC__NUM_DPP]; - unsigned int CursorWidth[DC__NUM_DPP][DC__NUM_CURSOR]; - unsigned int CursorBPP[DC__NUM_DPP][DC__NUM_CURSOR]; - bool XFCEnabled[DC__NUM_DPP]; - bool ScalerEnabled[DC__NUM_DPP]; + unsigned int NumberOfCursors[DC__NUM_DPP__MAX]; + unsigned int CursorWidth[DC__NUM_DPP__MAX][DC__NUM_CURSOR]; + unsigned int CursorBPP[DC__NUM_DPP__MAX][DC__NUM_CURSOR]; + bool XFCEnabled[DC__NUM_DPP__MAX]; + bool ScalerEnabled[DC__NUM_DPP__MAX]; // Intermediates/Informational bool ImmediateFlipSupport; - unsigned int SwathHeightY[DC__NUM_DPP]; - unsigned int SwathHeightC[DC__NUM_DPP]; - unsigned int DETBufferSizeY[DC__NUM_DPP]; - unsigned int DETBufferSizeC[DC__NUM_DPP]; - unsigned int LBBitPerPixel[DC__NUM_DPP]; + unsigned int SwathHeightY[DC__NUM_DPP__MAX]; + unsigned int SwathHeightC[DC__NUM_DPP__MAX]; + unsigned int DETBufferSizeY[DC__NUM_DPP__MAX]; + unsigned int DETBufferSizeC[DC__NUM_DPP__MAX]; + unsigned int LBBitPerPixel[DC__NUM_DPP__MAX]; double LastPixelOfLineExtraWatermark; double TotalDataReadBandwidth; unsigned int TotalActiveWriteback; @@ -349,9 +352,9 @@ struct vba_vars_st { double BandwidthAvailableForImmediateFlip; unsigned int PrefetchMode; bool IgnoreViewportPositioning; - double PrefetchBandwidth[DC__NUM_DPP]; - bool ErrorResult[DC__NUM_DPP]; - double PDEAndMetaPTEBytesFrame[DC__NUM_DPP]; + double PrefetchBandwidth[DC__NUM_DPP__MAX]; + bool ErrorResult[DC__NUM_DPP__MAX]; + double PDEAndMetaPTEBytesFrame[DC__NUM_DPP__MAX]; // // Calculated dml_ml->vba.Outputs @@ -376,35 +379,200 @@ struct vba_vars_st { // used explicitly. They are fetched by tests and then possibly used. The // ultimate values to use are the ones specified by the parameters to DML double DISPCLK_calculated; - double DSCCLK_calculated[DC__NUM_DPP]; - double DPPCLK_calculated[DC__NUM_DPP]; + double DSCCLK_calculated[DC__NUM_DPP__MAX]; + double DPPCLK_calculated[DC__NUM_DPP__MAX]; - unsigned int VStartup[DC__NUM_DPP]; + unsigned int VStartup[DC__NUM_DPP__MAX]; unsigned int VStartupRequiredWhenNotEnoughTimeForDynamicMetadata; double ImmediateFlipBW; unsigned int TotImmediateFlipBytes; double TCalc; - double MinTTUVBlank[DC__NUM_DPP]; - double VRatioPrefetchY[DC__NUM_DPP]; - double VRatioPrefetchC[DC__NUM_DPP]; - double DSTXAfterScaler[DC__NUM_DPP]; - double DSTYAfterScaler[DC__NUM_DPP]; - - double DestinationLinesToRequestVMInVBlank[DC__NUM_DPP]; - double DestinationLinesToRequestRowInVBlank[DC__NUM_DPP]; - double DestinationLinesForPrefetch[DC__NUM_DPP]; - double DestinationLinesToRequestRowInImmediateFlip[DC__NUM_DPP]; - double DestinationLinesToRequestVMInImmediateFlip[DC__NUM_DPP]; - - double XFCTransferDelay[DC__NUM_DPP]; - double XFCPrechargeDelay[DC__NUM_DPP]; - double XFCRemoteSurfaceFlipLatency[DC__NUM_DPP]; - double XFCPrefetchMargin[DC__NUM_DPP]; - - display_e2e_pipe_params_st cache_pipes[DC__NUM_DPP]; + double MinTTUVBlank[DC__NUM_DPP__MAX]; + double VRatioPrefetchY[DC__NUM_DPP__MAX]; + double VRatioPrefetchC[DC__NUM_DPP__MAX]; + double DSTXAfterScaler[DC__NUM_DPP__MAX]; + double DSTYAfterScaler[DC__NUM_DPP__MAX]; + + double DestinationLinesToRequestVMInVBlank[DC__NUM_DPP__MAX]; + double DestinationLinesToRequestRowInVBlank[DC__NUM_DPP__MAX]; + double DestinationLinesForPrefetch[DC__NUM_DPP__MAX]; + double DestinationLinesToRequestRowInImmediateFlip[DC__NUM_DPP__MAX]; + double DestinationLinesToRequestVMInImmediateFlip[DC__NUM_DPP__MAX]; + + double XFCTransferDelay[DC__NUM_DPP__MAX]; + double XFCPrechargeDelay[DC__NUM_DPP__MAX]; + double XFCRemoteSurfaceFlipLatency[DC__NUM_DPP__MAX]; + double XFCPrefetchMargin[DC__NUM_DPP__MAX]; + + display_e2e_pipe_params_st cache_pipes[DC__NUM_DPP__MAX]; unsigned int cache_num_pipes; - unsigned int pipe_plane[DC__NUM_PIPES__MAX]; + unsigned int pipe_plane[DC__NUM_DPP__MAX]; + + /* vba mode support */ + /*inputs*/ + bool SupportGFX7CompatibleTilingIn32bppAnd64bpp; + double MaxHSCLRatio; + double MaxVSCLRatio; + unsigned int MaxNumWriteback; + bool WritebackLumaAndChromaScalingSupported; + bool Cursor64BppSupport; + double DCFCLKPerState[DC__VOLTAGE_STATES + 1]; + double FabricClockPerState[DC__VOLTAGE_STATES + 1]; + double SOCCLKPerState[DC__VOLTAGE_STATES + 1]; + double PHYCLKPerState[DC__VOLTAGE_STATES + 1]; + double MaxDppclk[DC__VOLTAGE_STATES + 1]; + double MaxDSCCLK[DC__VOLTAGE_STATES + 1]; + double DRAMSpeedPerState[DC__VOLTAGE_STATES + 1]; + double MaxDispclk[DC__VOLTAGE_STATES + 1]; + + /*outputs*/ + bool ScaleRatioAndTapsSupport; + bool SourceFormatPixelAndScanSupport; + unsigned int SwathWidthYSingleDPP[DC__NUM_DPP__MAX]; + double BytePerPixelInDETY[DC__NUM_DPP__MAX]; + double BytePerPixelInDETC[DC__NUM_DPP__MAX]; + double TotalReadBandwidthConsumedGBytePerSecond; + double ReadBandwidth[DC__NUM_DPP__MAX]; + double TotalWriteBandwidthConsumedGBytePerSecond; + double WriteBandwidth[DC__NUM_DPP__MAX]; + double TotalBandwidthConsumedGBytePerSecond; + bool DCCEnabledInAnyPlane; + bool WritebackLatencySupport; + bool WritebackModeSupport; + bool Writeback10bpc420Supported; + bool BandwidthSupport[DC__VOLTAGE_STATES + 1]; + unsigned int TotalNumberOfActiveWriteback; + double CriticalPoint; + double ReturnBWToDCNPerState; + double FabricAndDRAMBandwidthPerState[DC__VOLTAGE_STATES + 1]; + double ReturnBWPerState[DC__VOLTAGE_STATES + 1]; + double UrgentRoundTripAndOutOfOrderLatencyPerState[DC__VOLTAGE_STATES + 1]; + bool ODMCombineEnablePerState[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX]; + bool PTEBufferSizeNotExceededY[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX]; + bool PTEBufferSizeNotExceededC[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX]; + bool PrefetchSupported[DC__VOLTAGE_STATES + 1]; + bool VRatioInPrefetchSupported[DC__VOLTAGE_STATES + 1]; + bool DISPCLK_DPPCLK_Support[DC__VOLTAGE_STATES + 1]; + bool TotalAvailablePipesSupport[DC__VOLTAGE_STATES + 1]; + bool UrgentLatencySupport[DC__VOLTAGE_STATES + 1]; + bool ModeSupport[DC__VOLTAGE_STATES + 1]; + bool DIOSupport[DC__VOLTAGE_STATES + 1]; + bool NotEnoughDSCUnits[DC__VOLTAGE_STATES + 1]; + bool DSCCLKRequiredMoreThanSupported[DC__VOLTAGE_STATES + 1]; + bool ROBSupport[DC__VOLTAGE_STATES + 1]; + bool PTEBufferSizeNotExceeded[DC__VOLTAGE_STATES + 1]; + bool RequiresDSC[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX]; + bool IsErrorResult[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX]; + bool ViewportSizeSupport[DC__VOLTAGE_STATES + 1]; + bool prefetch_vm_bw_valid; + bool prefetch_row_bw_valid; + bool NumberOfOTGSupport; + bool NonsupportedDSCInputBPC; + bool WritebackScaleRatioAndTapsSupport; + bool CursorSupport; + bool PitchSupport; + + double WritebackLineBufferLumaBufferSize; + double WritebackLineBufferChromaBufferSize; + double WritebackMinHSCLRatio; + double WritebackMinVSCLRatio; + double WritebackMaxHSCLRatio; + double WritebackMaxVSCLRatio; + double WritebackMaxHSCLTaps; + double WritebackMaxVSCLTaps; + unsigned int MaxNumDPP; + unsigned int MaxNumOTG; + double CursorBufferSize; + double CursorChunkSize; + unsigned int Mode; + double NoOfDPP[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX]; + double OutputLinkDPLanes[DC__NUM_DPP__MAX]; + double SwathWidthYPerState[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX]; + double SwathHeightYPerState[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX]; + double SwathHeightCPerState[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX]; + double UrgentLatencySupportUsPerState[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX]; + double VRatioPreY[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX]; + double VRatioPreC[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX]; + double RequiredPrefetchPixelDataBW[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX]; + double RequiredDPPCLK[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX]; + double RequiredDISPCLK[DC__VOLTAGE_STATES + 1]; + double TotalNumberOfActiveDPP[DC__VOLTAGE_STATES + 1]; + double TotalNumberOfDCCActiveDPP[DC__VOLTAGE_STATES + 1]; + double PrefetchBW[DC__NUM_DPP__MAX]; + double PDEAndMetaPTEBytesPerFrame[DC__NUM_DPP__MAX]; + double MetaRowBytes[DC__NUM_DPP__MAX]; + double DPTEBytesPerRow[DC__NUM_DPP__MAX]; + double PrefetchLinesY[DC__NUM_DPP__MAX]; + double PrefetchLinesC[DC__NUM_DPP__MAX]; + unsigned int MaxNumSwY[DC__NUM_DPP__MAX]; + unsigned int MaxNumSwC[DC__NUM_DPP__MAX]; + double PrefillY[DC__NUM_DPP__MAX]; + double PrefillC[DC__NUM_DPP__MAX]; + double LineTimesForPrefetch[DC__NUM_DPP__MAX]; + double LinesForMetaPTE[DC__NUM_DPP__MAX]; + double LinesForMetaAndDPTERow[DC__NUM_DPP__MAX]; + double MinDPPCLKUsingSingleDPP[DC__NUM_DPP__MAX]; + double RequiresFEC[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX]; + unsigned int OutputBppPerState[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX]; + double DSCDelayPerState[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX]; + unsigned int Read256BlockHeightY[DC__NUM_DPP__MAX]; + unsigned int Read256BlockWidthY[DC__NUM_DPP__MAX]; + unsigned int Read256BlockHeightC[DC__NUM_DPP__MAX]; + unsigned int Read256BlockWidthC[DC__NUM_DPP__MAX]; + unsigned int ImmediateFlipBytes[DC__NUM_DPP__MAX]; + double MaxSwathHeightY[DC__NUM_DPP__MAX]; + double MaxSwathHeightC[DC__NUM_DPP__MAX]; + double MinSwathHeightY[DC__NUM_DPP__MAX]; + double MinSwathHeightC[DC__NUM_DPP__MAX]; + double PSCL_FACTOR[DC__NUM_DPP__MAX]; + double PSCL_FACTOR_CHROMA[DC__NUM_DPP__MAX]; + double MaximumVStartup[DC__NUM_DPP__MAX]; + double AlignedDCCMetaPitch[DC__NUM_DPP__MAX]; + double AlignedYPitch[DC__NUM_DPP__MAX]; + double AlignedCPitch[DC__NUM_DPP__MAX]; + double MaximumSwathWidth[DC__NUM_DPP__MAX]; + double final_flip_bw[DC__NUM_DPP__MAX]; + double ImmediateFlipSupportedForState[DC__VOLTAGE_STATES + 1]; + + double WritebackLumaVExtra; + double WritebackChromaVExtra; + double WritebackRequiredDISPCLK; + double MaximumSwathWidthSupport; + double MaximumSwathWidthInDETBuffer; + double MaximumSwathWidthInLineBuffer; + double MaxDispclkRoundedDownToDFSGranularity; + double MaxDppclkRoundedDownToDFSGranularity; + double PlaneRequiredDISPCLKWithoutODMCombine; + double PlaneRequiredDISPCLK; + double TotalNumberOfActiveOTG; + double FECOverhead; + double EffectiveFECOverhead; + unsigned int Outbpp; + unsigned int OutbppDSC; + double TotalDSCUnitsRequired; + double bpp; + unsigned int slices; + double SwathWidthGranularityY; + double RoundedUpMaxSwathSizeBytesY; + double SwathWidthGranularityC; + double RoundedUpMaxSwathSizeBytesC; + double LinesInDETLuma; + double LinesInDETChroma; + double EffectiveDETLBLinesLuma; + double EffectiveDETLBLinesChroma; + double ProjectedDCFCLKDeepSleep; + double PDEAndMetaPTEBytesPerFrameY; + double PDEAndMetaPTEBytesPerFrameC; + unsigned int MetaRowBytesY; + unsigned int MetaRowBytesC; + unsigned int DPTEBytesPerRowC; + unsigned int DPTEBytesPerRowY; + double ExtraLatency; + double TimeCalc; + double TWait; + double MaximumReadBandwidthWithPrefetch; + double total_dcn_read_bw_with_flip; }; #endif /* _DML2_DISPLAY_MODE_VBA_H_ */ diff --git a/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.c b/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.c index 9cbd415e508d3..2af6d150cc463 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.c @@ -35,6 +35,18 @@ double dml_max(double a, double b) { return (double) dcn_bw_max2(a, b); } +double dml_max3(double a, double b, double c) +{ + return dml_max(dml_max(a, b), c); +} +double dml_max4(double a, double b, double c, double d) +{ + return dml_max(dml_max(a, b), dml_max(c, d)); +} +double dml_max5(double a, double b, double c, double d, double e) +{ + return dml_max(dml_max4(a, b, c, d), e); +} double dml_ceil(double a, double granularity) { diff --git a/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.h b/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.h index 19271e79abcc8..ba01bbb007fc0 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.h +++ b/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.h @@ -36,6 +36,9 @@ double dml_min(double a, double b); double dml_max(double a, double b); +double dml_max3(double a, double b, double c); +double dml_max4(double a, double b, double c, double d); +double dml_max5(double a, double b, double c, double d, double e); bool dml_util_is_420(enum source_format_class sorce_format); double dml_ceil_ex(double x, double granularity); double dml_floor_ex(double x, double granularity); From c81a351ab9c054e28544f31f715ad50cfe54089d Mon Sep 17 00:00:00 2001 From: Dmytro Laktyushkin Date: Wed, 20 Sep 2017 17:50:02 -0400 Subject: [PATCH 059/155] drm/amd/display: extract global sync params from vba Signed-off-by: Dmytro Laktyushkin Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../drm/amd/display/dc/dml/display_mode_vba.c | 32 +++++++++++++------ .../drm/amd/display/dc/dml/display_mode_vba.h | 3 ++ 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c index e1a3182d58b3a..054b5067fc17f 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c +++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c @@ -88,7 +88,10 @@ static bool CalculatePrefetchSchedule( double *VRatioPrefetchC, double *RequiredPrefetchPixDataBW, unsigned int *VStartupRequiredWhenNotEnoughTimeForDynamicMetadata, - double *Tno_bw); + double *Tno_bw, + unsigned int *VUpdateOffsetPix, + unsigned int *VUpdateWidthPix, + unsigned int *VReadyOffsetPix); static double RoundToDFSGranularityUp(double Clock, double VCOSpeed); static double RoundToDFSGranularityDown(double Clock, double VCOSpeed); static double CalculatePrefetchSourceLines( @@ -264,7 +267,7 @@ unsigned int dml_get_voltage_level( memcpy(mode_lib->vba.cache_pipes, pipes, sizeof(*pipes) * num_pipes); mode_lib->vba.cache_num_pipes = num_pipes; - if (need_recalculate) + if (need_recalculate && pipes[0].clks_cfg.dppclk_mhz != 0) recalculate(mode_lib); else { fetch_socbb_params(mode_lib); @@ -1066,10 +1069,13 @@ static bool CalculatePrefetchSchedule( double *VRatioPrefetchC, double *RequiredPrefetchPixDataBW, unsigned int *VStartupRequiredWhenNotEnoughTimeForDynamicMetadata, - double *Tno_bw) + double *Tno_bw, + unsigned int *VUpdateOffsetPix, + unsigned int *VUpdateWidthPix, + unsigned int *VReadyOffsetPix) { bool MyError = false; - unsigned int DPPCycles, DISPCLKCycles, VUpdateOffsetPix, VUpdateWidthPix, VReadyOffsetPix; + unsigned int DPPCycles, DISPCLKCycles; double DSTTotalPixelsAfterScaler, TotalRepeaterDelayTime; double Tdm, LineTime, Tsetup; double dst_y_prefetch_equ; @@ -1110,17 +1116,17 @@ static bool CalculatePrefetchSchedule( *DSTYAfterScaler = dml_floor(DSTTotalPixelsAfterScaler / HTotal, 1); *DSTXAfterScaler = DSTTotalPixelsAfterScaler - ((double) (*DSTYAfterScaler * HTotal)); - VUpdateOffsetPix = dml_ceil(HTotal / 4.0, 1); + *VUpdateOffsetPix = dml_ceil(HTotal / 4.0, 1); TotalRepeaterDelayTime = MaxInterDCNTileRepeaters * (2.0 / DPPCLK + 3.0 / DISPCLK); - VUpdateWidthPix = (14.0 / DCFClkDeepSleep + 12.0 / DPPCLK + TotalRepeaterDelayTime) + *VUpdateWidthPix = (14.0 / DCFClkDeepSleep + 12.0 / DPPCLK + TotalRepeaterDelayTime) * PixelClock; - VReadyOffsetPix = dml_max( + *VReadyOffsetPix = dml_max( 150.0 / DPPCLK, TotalRepeaterDelayTime + 20.0 / DCFClkDeepSleep + 10.0 / DPPCLK) * PixelClock; - Tsetup = (double) (VUpdateOffsetPix + VUpdateWidthPix + VReadyOffsetPix) / PixelClock; + Tsetup = (double) (*VUpdateOffsetPix + *VUpdateWidthPix + *VReadyOffsetPix) / PixelClock; LineTime = (double) HTotal / PixelClock; @@ -2710,7 +2716,10 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman &mode_lib->vba.VRatioPrefetchC[k], &mode_lib->vba.RequiredPrefetchPixDataBW[k], &mode_lib->vba.VStartupRequiredWhenNotEnoughTimeForDynamicMetadata, - &mode_lib->vba.Tno_bw[k]); + &mode_lib->vba.Tno_bw[k], + &mode_lib->vba.VUpdateOffsetPix[k], + &mode_lib->vba.VUpdateWidthPix[k], + &mode_lib->vba.VReadyOffsetPix[k]); if (mode_lib->vba.BlendingAndTiming[k] == k) { mode_lib->vba.VStartup[k] = dml_min( mode_lib->vba.VStartupLines, @@ -5805,7 +5814,10 @@ static void ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_ &mode_lib->vba.VRatioPreC[i][k], &mode_lib->vba.RequiredPrefetchPixelDataBW[i][k], &mode_lib->vba.VStartupRequiredWhenNotEnoughTimeForDynamicMetadata, - &mode_lib->vba.Tno_bw[k]); + &mode_lib->vba.Tno_bw[k], + &mode_lib->vba.VUpdateOffsetPix[k], + &mode_lib->vba.VUpdateWidthPix[k], + &mode_lib->vba.VReadyOffsetPix[k]); } for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { mode_lib->vba.cursor_bw[k] = mode_lib->vba.NumberOfCursors[k] diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h index 346ffea843c99..5758c3fd39bae 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h +++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h @@ -383,6 +383,9 @@ struct vba_vars_st { double DPPCLK_calculated[DC__NUM_DPP__MAX]; unsigned int VStartup[DC__NUM_DPP__MAX]; + unsigned int VUpdateOffsetPix[DC__NUM_DPP__MAX]; + unsigned int VUpdateWidthPix[DC__NUM_DPP__MAX]; + unsigned int VReadyOffsetPix[DC__NUM_DPP__MAX]; unsigned int VStartupRequiredWhenNotEnoughTimeForDynamicMetadata; double ImmediateFlipBW; From 09f2317be4e86a60b481ce14da84c0752f848235 Mon Sep 17 00:00:00 2001 From: Dmytro Laktyushkin Date: Wed, 20 Sep 2017 18:32:51 -0400 Subject: [PATCH 060/155] drm/amd/display: change dml vba cursor count define to correct one Signed-off-by: Dmytro Laktyushkin Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c | 2 +- drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c index 054b5067fc17f..a11b37c50d960 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c +++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c @@ -633,7 +633,7 @@ static void fetch_pipe_params(struct display_mode_lib *mode_lib) mode_lib->vba.NumberOfCursors[mode_lib->vba.NumberOfActivePlanes] = 0; // The DML spreadsheet assumes that the two cursors utilize the same amount of bandwidth. We'll // calculate things a little more accurately - for (k = 0; k < DC__NUM_CURSOR; ++k) { + for (k = 0; k < DC__NUM_CURSOR__MAX; ++k) { switch (k) { case 0: mode_lib->vba.CursorBPP[mode_lib->vba.NumberOfActivePlanes][0] = diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h index 5758c3fd39bae..63ad4a7bfeb51 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h +++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h @@ -332,8 +332,8 @@ struct vba_vars_st { unsigned int BlendingAndTiming[DC__NUM_DPP__MAX]; bool SynchronizedVBlank; unsigned int NumberOfCursors[DC__NUM_DPP__MAX]; - unsigned int CursorWidth[DC__NUM_DPP__MAX][DC__NUM_CURSOR]; - unsigned int CursorBPP[DC__NUM_DPP__MAX][DC__NUM_CURSOR]; + unsigned int CursorWidth[DC__NUM_DPP__MAX][DC__NUM_CURSOR__MAX]; + unsigned int CursorBPP[DC__NUM_DPP__MAX][DC__NUM_CURSOR__MAX]; bool XFCEnabled[DC__NUM_DPP__MAX]; bool ScalerEnabled[DC__NUM_DPP__MAX]; From 0fc899b0f1d522efc171c09cb36ce1d27cd75de2 Mon Sep 17 00:00:00 2001 From: Yongqiang Sun Date: Wed, 27 Sep 2017 17:28:11 -0400 Subject: [PATCH 061/155] drm/amd/display: Enable double buffer as per vertical interrupt enabled. Signed-off-by: Yongqiang Sun Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../drm/amd/display/dc/dcn10/dcn10_timing_generator.c | 11 +++++++++++ .../drm/amd/display/dc/dcn10/dcn10_timing_generator.h | 4 ++++ 2 files changed, 15 insertions(+) diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.c index 7cd10cbc5497f..8dbc82ff9b3a3 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.c @@ -299,6 +299,17 @@ static void tgn10_program_timing( static void tgn10_unblank_crtc(struct timing_generator *tg) { struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg); + uint32_t vertical_interrupt_enable = 0; + + REG_GET(OTG_VERTICAL_INTERRUPT2_CONTROL, + OTG_VERTICAL_INTERRUPT2_INT_ENABLE, &vertical_interrupt_enable); + + /* temporary work around for vertical interrupt, once vertical interrupt enabled, + * this check will be removed. + */ + if (vertical_interrupt_enable) + REG_UPDATE(OTG_DOUBLE_BUFFER_CONTROL, + OTG_BLANK_DATA_DOUBLE_BUFFER_EN, 1); REG_UPDATE_2(OTG_BLANK_CONTROL, OTG_BLANK_DATA_EN, 0, diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.h index 0826d73b98093..7d4818d7aa31b 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.h +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.h @@ -65,6 +65,7 @@ SRI(OTG_NOM_VERT_POSITION, OTG, inst),\ SRI(OTG_BLACK_COLOR, OTG, inst),\ SRI(OTG_CLOCK_CONTROL, OTG, inst),\ + SRI(OTG_VERTICAL_INTERRUPT2_CONTROL, OTG, inst),\ SRI(OTG_VERTICAL_INTERRUPT2_POSITION, OTG, inst),\ SRI(OPTC_INPUT_CLOCK_CONTROL, ODM, inst),\ SRI(OPTC_DATA_SOURCE_SELECT, ODM, inst),\ @@ -117,6 +118,7 @@ struct dcn_tg_registers { uint32_t OTG_TEST_PATTERN_CONTROL; uint32_t OTG_TEST_PATTERN_COLOR; uint32_t OTG_CLOCK_CONTROL; + uint32_t OTG_VERTICAL_INTERRUPT2_CONTROL; uint32_t OTG_VERTICAL_INTERRUPT2_POSITION; uint32_t OPTC_INPUT_CLOCK_CONTROL; uint32_t OPTC_DATA_SOURCE_SELECT; @@ -196,6 +198,7 @@ struct dcn_tg_registers { SF(OTG0_OTG_CLOCK_CONTROL, OTG_CLOCK_EN, mask_sh),\ SF(OTG0_OTG_CLOCK_CONTROL, OTG_CLOCK_ON, mask_sh),\ SF(OTG0_OTG_CLOCK_CONTROL, OTG_CLOCK_GATE_DIS, mask_sh),\ + SF(OTG0_OTG_VERTICAL_INTERRUPT2_CONTROL, OTG_VERTICAL_INTERRUPT2_INT_ENABLE, mask_sh),\ SF(OTG0_OTG_VERTICAL_INTERRUPT2_POSITION, OTG_VERTICAL_INTERRUPT2_LINE_START, mask_sh),\ SF(ODM0_OPTC_INPUT_CLOCK_CONTROL, OPTC_INPUT_CLK_EN, mask_sh),\ SF(ODM0_OPTC_INPUT_CLOCK_CONTROL, OPTC_INPUT_CLK_ON, mask_sh),\ @@ -302,6 +305,7 @@ struct dcn_tg_registers { type OTG_CLOCK_EN;\ type OTG_CLOCK_ON;\ type OTG_CLOCK_GATE_DIS;\ + type OTG_VERTICAL_INTERRUPT2_INT_ENABLE;\ type OTG_VERTICAL_INTERRUPT2_LINE_START;\ type OPTC_INPUT_CLK_EN;\ type OPTC_INPUT_CLK_ON;\ From 6a2b691f0985d16c16b70dbc4b5727afabde6ba9 Mon Sep 17 00:00:00 2001 From: Tony Cheng Date: Tue, 26 Sep 2017 22:16:11 -0400 Subject: [PATCH 062/155] drm/amd/display: wrong VM setting cause invalid DF request from DCN fix typo in register field. we are lucky the shift/mask is the same, no behavior change add globals to experiment with using different VM settings Signed-off-by: Tony Cheng Reviewed-by: Yongqiang Sun Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.c | 11 +++++++---- .../gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.h | 2 ++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.c index b61f41c613589..c09e65a0031a9 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.c @@ -632,6 +632,9 @@ bool min10_is_flip_pending(struct mem_input *mem_input) return false; } +uint32_t aperture_default_system = 1; +uint32_t context0_default_system; /* = 0;*/ + static void min10_set_vm_system_aperture_settings(struct mem_input *mem_input, struct vm_system_aperture_param *apt) { @@ -645,7 +648,7 @@ static void min10_set_vm_system_aperture_settings(struct mem_input *mem_input, mc_vm_apt_high.quad_part = apt->sys_high.quad_part >> 12; REG_SET_2(DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, 0, - MC_VM_SYSTEM_APERTURE_DEFAULT_SYSTEM, 1, /* 1 = system physical memory */ + MC_VM_SYSTEM_APERTURE_DEFAULT_SYSTEM, aperture_default_system, /* 1 = system physical memory */ MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, mc_vm_apt_default.high_part); REG_SET(DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, 0, MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, mc_vm_apt_default.low_part); @@ -684,9 +687,9 @@ static void min10_set_vm_context0_settings(struct mem_input *mem_input, VM_CONTEXT0_PAGE_TABLE_END_ADDR_LSB, vm0->pte_end.low_part); /* fault handling */ - REG_SET(DCN_VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_MSB, 0, - VM_CONTEXT0_PAGE_TABLE_END_ADDR_MSB, vm0->fault_default.high_part); - /* VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_SYSTEM, 0 */ + REG_SET_2(DCN_VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_MSB, 0, + VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_MSB, vm0->fault_default.high_part, + VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_SYSTEM, context0_default_system); REG_SET(DCN_VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_LSB, 0, VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_LSB, vm0->fault_default.low_part); diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.h index fdeb0e87463e5..15231e86e6c6a 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.h +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.h @@ -369,6 +369,7 @@ struct dcn_mi_registers { MI_SF(HUBPREQ0_DCN_VM_CONTEXT0_PAGE_TABLE_END_ADDR_MSB, VM_CONTEXT0_PAGE_TABLE_END_ADDR_MSB, mask_sh),\ MI_SF(HUBPREQ0_DCN_VM_CONTEXT0_PAGE_TABLE_END_ADDR_LSB, VM_CONTEXT0_PAGE_TABLE_END_ADDR_LSB, mask_sh),\ MI_SF(HUBPREQ0_DCN_VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_MSB, VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_MSB, mask_sh),\ + MI_SF(HUBPREQ0_DCN_VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_MSB, VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_SYSTEM, mask_sh),\ MI_SF(HUBPREQ0_DCN_VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_LSB, VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_LSB, mask_sh),\ MI_SF(HUBPREQ0_DCN_VM_SYSTEM_APERTURE_LOW_ADDR_MSB, MC_VM_SYSTEM_APERTURE_LOW_ADDR_MSB, mask_sh),\ MI_SF(HUBPREQ0_DCN_VM_SYSTEM_APERTURE_LOW_ADDR_LSB, MC_VM_SYSTEM_APERTURE_LOW_ADDR_LSB, mask_sh),\ @@ -522,6 +523,7 @@ struct dcn_mi_registers { type VM_CONTEXT0_PAGE_TABLE_END_ADDR_MSB;\ type VM_CONTEXT0_PAGE_TABLE_END_ADDR_LSB;\ type VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_MSB;\ + type VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_SYSTEM;\ type VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_LSB;\ type ENABLE_L1_TLB;\ type SYSTEM_ACCESS_MODE;\ From 96687275555a166951d77d845a924ee07b854822 Mon Sep 17 00:00:00 2001 From: Roman Li Date: Wed, 27 Sep 2017 17:57:37 -0400 Subject: [PATCH 063/155] drm/amd/display: Fix hotplug after s3 resume. On S3 resume the HPD6 irq source was not reenabled due to loop boundary bug. Signed-off-by: Roman Li Reviewed-by: Mikita Lipski Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c index 52b6e4a91d8b4..8de19ba5b2e39 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c @@ -462,7 +462,7 @@ int amdgpu_dm_irq_resume_early(struct amdgpu_device *adev) DRM_DEBUG_KMS("DM_IRQ: early resume\n"); /* re-enable short pulse interrupts HW interrupt */ - for (src = DC_IRQ_SOURCE_HPD1RX; src < DC_IRQ_SOURCE_HPD6RX + 1; src++) { + for (src = DC_IRQ_SOURCE_HPD1RX; src <= DC_IRQ_SOURCE_HPD6RX + 1; src++) { hnd_list_l = &adev->dm.irq_handler_list_low_tab[src].head; hnd_list_h = &adev->dm.irq_handler_list_high_tab[src]; if (!list_empty(hnd_list_l) || !list_empty(hnd_list_h)) @@ -488,7 +488,7 @@ int amdgpu_dm_irq_resume_late(struct amdgpu_device *adev) * Renable HW interrupt for HPD and only since FLIP and VBLANK * will be enabled from manage_dm_interrupts on enable CRTC. */ - for (src = DC_IRQ_SOURCE_HPD1; src < DC_IRQ_SOURCE_HPD6; src++) { + for (src = DC_IRQ_SOURCE_HPD1; src <= DC_IRQ_SOURCE_HPD6; src++) { hnd_list_l = &adev->dm.irq_handler_list_low_tab[src].head; hnd_list_h = &adev->dm.irq_handler_list_high_tab[src]; if (!list_empty(hnd_list_l) || !list_empty(hnd_list_h)) From 3eab79163fcb0f7777440dfe360d2eedbbcc47b9 Mon Sep 17 00:00:00 2001 From: Shirish S Date: Tue, 26 Sep 2017 15:35:42 +0530 Subject: [PATCH 064/155] drm/amd/display: make FBC configurable option Currently FBC is guarded with ENABLE_FBC macro, which needs to be manually enabled in Makefile. This patch moves it to Kconfig so that there wont be any need to additional patch to be carried for enabling or disabling on every SoC. Signed-off-by: Shirish S Reviewed-by: Roman Li Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/Kconfig | 10 ++++++++++ drivers/gpu/drm/amd/display/dc/core/dc.c | 2 +- drivers/gpu/drm/amd/display/dc/dc.h | 4 ++-- drivers/gpu/drm/amd/display/dc/dc_types.h | 2 +- .../amd/display/dc/dce110/dce110_compressor.c | 2 +- .../amd/display/dc/dce110/dce110_hw_sequencer.c | 16 ++++++++-------- .../drm/amd/display/dc/dce110/dce110_resource.c | 4 ++-- 7 files changed, 25 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/amd/display/Kconfig b/drivers/gpu/drm/amd/display/Kconfig index 6d1086d0a277f..ec3285f655177 100644 --- a/drivers/gpu/drm/amd/display/Kconfig +++ b/drivers/gpu/drm/amd/display/Kconfig @@ -17,6 +17,16 @@ config DRM_AMD_DC_PRE_VEGA by default. This includes Polaris, Carrizo, Tonga, Bonaire, and Hawaii. +config DRM_AMD_DC_FBC + bool "AMD FBC - Enable Frame Buffer Compression" + depends on DRM_AMD_DC + help + Choose this option if you want to use frame buffer compression + support. + This is a power optimisation feature, check its availability + on your hardware before enabling this option. + + config DRM_AMD_DC_DCN1_0 bool "DCN 1.0 Raven family" depends on DRM_AMD_DC && X86 diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 3439bc46a4a24..a5c72dbc2dccb 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -507,7 +507,7 @@ static bool construct(struct dc *dc, dc_version = resource_parse_asic_id(init_params->asic_id); dc->ctx->dce_version = dc_version; -#ifdef ENABLE_FBC +#if defined(CONFIG_DRM_AMD_DC_FBC) dc->ctx->fbc_gpu_addr = init_params->fbc_gpu_addr; #endif /* Resource should construct all asic specific resources. diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index bf83459456a80..adadfad2bd51d 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -258,7 +258,7 @@ struct dc { struct dm_pp_display_configuration prev_display_config; /* FBC compressor */ -#ifdef ENABLE_FBC +#if defined(CONFIG_DRM_AMD_DC_FBC) struct compressor *fbc_compressor; #endif }; @@ -293,7 +293,7 @@ struct dc_init_data { struct dc_config flags; uint32_t log_mask; -#ifdef ENABLE_FBC +#if defined(CONFIG_DRM_AMD_DC_FBC) uint64_t fbc_gpu_addr; #endif }; diff --git a/drivers/gpu/drm/amd/display/dc/dc_types.h b/drivers/gpu/drm/amd/display/dc/dc_types.h index 4bd74fc6c782d..a8698e399111a 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_types.h @@ -92,7 +92,7 @@ struct dc_context { bool created_bios; struct gpio_service *gpio_service; struct i2caux *i2caux; -#ifdef ENABLE_FBC +#if defined(CONFIG_DRM_AMD_DC_FBC) uint64_t fbc_gpu_addr; #endif }; diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_compressor.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_compressor.c index 3872febb4f6b4..6923662413cde 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_compressor.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_compressor.c @@ -514,7 +514,7 @@ void dce110_compressor_construct(struct dce110_compressor *compressor, compressor->base.lpt_channels_num = 0; compressor->base.attached_inst = 0; compressor->base.is_enabled = false; -#ifdef ENABLE_FBC +#if defined(CONFIG_DRM_AMD_DC_FBC) compressor->base.funcs = &dce110_compressor_funcs; #endif diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c index a891e387ed7b5..247e81806c4a4 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c @@ -34,7 +34,7 @@ #include "dce/dce_hwseq.h" #include "gpio_service_interface.h" -#ifdef ENABLE_FBC +#if defined(CONFIG_DRM_AMD_DC_FBC) #include "dce110_compressor.h" #endif @@ -1445,7 +1445,7 @@ static void power_down_all_hw_blocks(struct dc *dc) power_down_clock_sources(dc); -#ifdef ENABLE_FBC +#if defined(CONFIG_DRM_AMD_DC_FBC) if (dc->fbc_compressor) dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor); #endif @@ -1618,7 +1618,7 @@ static void set_static_screen_control(struct pipe_ctx **pipe_ctx, if (events->cursor_update) value |= 0x2; -#ifdef ENABLE_FBC +#if defined(CONFIG_DRM_AMD_DC_FBC) value |= 0x84; #endif @@ -1748,7 +1748,7 @@ static void apply_min_clocks( } } -#ifdef ENABLE_FBC +#if defined(CONFIG_DRM_AMD_DC_FBC) /* * Check if FBC can be enabled @@ -1940,7 +1940,7 @@ enum dc_status dce110_apply_ctx_to_hw( set_safe_displaymarks(&context->res_ctx, dc->res_pool); -#ifdef ENABLE_FBC +#if defined(CONFIG_DRM_AMD_DC_FBC) if (dc->fbc_compressor) dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor); #endif @@ -2124,7 +2124,7 @@ enum dc_status dce110_apply_ctx_to_hw( dcb->funcs->set_scratch_critical_state(dcb, false); -#ifdef ENABLE_FBC +#if defined(CONFIG_DRM_AMD_DC_FBC) if (dc->fbc_compressor) enable_fbc(dc, context); @@ -2533,7 +2533,7 @@ static void init_hw(struct dc *dc) abm->funcs->init_backlight(abm); abm->funcs->abm_init(abm); } -#ifdef ENABLE_FBC +#if defined(CONFIG_DRM_AMD_DC_FBC) if (dc->fbc_compressor) dc->fbc_compressor->funcs->power_up_fbc(dc->fbc_compressor); #endif @@ -2781,7 +2781,7 @@ static void dce110_program_front_end_for_pipe( program_scaler(dc, pipe_ctx); -#ifdef ENABLE_FBC +#if defined(CONFIG_DRM_AMD_DC_FBC) if (dc->fbc_compressor && old_pipe->stream) { if (plane_state->tiling_info.gfx8.array_mode == DC_ARRAY_LINEAR_GENERAL) dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor); diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c index 8e4ec61d59a4b..db96d2b47ff16 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c @@ -52,7 +52,7 @@ #include "dce/dce_abm.h" #include "dce/dce_dmcu.h" -#ifdef ENABLE_FBC +#if defined(CONFIG_DRM_AMD_DC_FBC) #include "dce110/dce110_compressor.h" #endif @@ -1279,7 +1279,7 @@ static bool construct( } } -#ifdef ENABLE_FBC +#if defined(CONFIG_DRM_AMD_DC_FBC) dc->fbc_compressor = dce110_compressor_create(ctx); From 50d4cfdc118122f58ffdb09607a57c621e24d777 Mon Sep 17 00:00:00 2001 From: Yongqiang Sun Date: Thu, 28 Sep 2017 10:40:10 -0400 Subject: [PATCH 065/155] drm/amd/display: Program front end first when set mode. Signed-off-by: Yongqiang Sun Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc.c | 27 ++++++++++++------- .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 5 ++-- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index a5c72dbc2dccb..f9bac11d39500 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -763,16 +763,6 @@ static bool dc_commit_state_no_check(struct dc *dc, struct dc_state *context) if (!dcb->funcs->is_accelerated_mode(dcb)) dc->hwss.enable_accelerated_mode(dc); - dc->hwss.ready_shared_resources(dc, context); - - for (i = 0; i < dc->res_pool->pipe_count; i++) { - pipe = &context->res_ctx.pipe_ctx[i]; - dc->hwss.wait_for_mpcc_disconnect(dc, dc->res_pool, pipe); - } - result = dc->hwss.apply_ctx_to_hw(dc, context); - - program_timing_sync(dc, context); - for (i = 0; i < context->stream_count; i++) { const struct dc_sink *sink = context->streams[i]->sink; @@ -798,6 +788,13 @@ static bool dc_commit_state_no_check(struct dc *dc, struct dc_state *context) } } + for (j = 0; j < MAX_PIPES; j++) { + pipe = &context->res_ctx.pipe_ctx[j]; + + if (!pipe->top_pipe && pipe->stream == context->streams[i]) + dc->hwss.pipe_control_lock(dc, pipe, false); + } + CONN_MSG_MODE(sink->link, "{%dx%d, %dx%d@%dKhz}", context->streams[i]->timing.h_addressable, context->streams[i]->timing.v_addressable, @@ -806,6 +803,16 @@ static bool dc_commit_state_no_check(struct dc *dc, struct dc_state *context) context->streams[i]->timing.pix_clk_khz); } + dc->hwss.ready_shared_resources(dc, context); + + for (i = 0; i < dc->res_pool->pipe_count; i++) { + pipe = &context->res_ctx.pipe_ctx[i]; + dc->hwss.wait_for_mpcc_disconnect(dc, dc->res_pool, pipe); + } + result = dc->hwss.apply_ctx_to_hw(dc, context); + + program_timing_sync(dc, context); + dc_enable_stereo(dc, context, dc_streams, context->stream_count); dc_release_state(dc->current_state); diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index 86cfab33feea8..84d9d202d3b5b 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -2283,8 +2283,6 @@ static void update_dchubp_dpp( */ REG_UPDATE(DCHUBP_CNTL[pipe_ctx->pipe_idx], HUBP_VTG_SEL, pipe_ctx->stream_res.tg->inst); - dc->hwss.update_plane_addr(dc, pipe_ctx); - mi->funcs->mem_input_setup( mi, &pipe_ctx->dlg_regs, @@ -2353,6 +2351,8 @@ static void update_dchubp_dpp( &plane_state->dcc, plane_state->horizontal_mirror); + dc->hwss.update_plane_addr(dc, pipe_ctx); + if (is_pipe_tree_visible(pipe_ctx)) mi->funcs->set_blank(mi, false); } @@ -2556,6 +2556,7 @@ static void dcn10_apply_ctx_for_surface( old_pipe_ctx->top_pipe = NULL; old_pipe_ctx->bottom_pipe = NULL; old_pipe_ctx->plane_state = NULL; + old_pipe_ctx->stream = NULL; dm_logger_write(dc->ctx->logger, LOG_DC, "Reset mpcc for pipe %d\n", From 4176664b1fc8aa052f886037590cac4fb0dd8afb Mon Sep 17 00:00:00 2001 From: Charlene Liu Date: Wed, 27 Sep 2017 23:23:16 -0400 Subject: [PATCH 066/155] drm/amd/display: audio dynamic resource acquired related Signed-off-by: Charlene Liu Reviewed-by: Anthony Koo Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_link.c | 4 ++-- .../drm/amd/display/dc/core/dc_link_hwss.c | 2 +- .../gpu/drm/amd/display/dc/core/dc_resource.c | 24 ++++++++++++++----- drivers/gpu/drm/amd/display/dc/dc.h | 1 + .../display/dc/dce110/dce110_hw_sequencer.c | 12 ++++++++-- .../display/dc/dce110/dce110_hw_sequencer.h | 2 +- .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 2 +- .../gpu/drm/amd/display/dc/inc/core_types.h | 7 +++++- .../gpu/drm/amd/display/dc/inc/hw_sequencer.h | 3 ++- drivers/gpu/drm/amd/display/dc/inc/resource.h | 5 ++++ 10 files changed, 47 insertions(+), 15 deletions(-) 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 e414e4770789f..2d59f77fa9a27 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c @@ -2323,14 +2323,14 @@ void core_link_enable_stream( allocate_mst_payload(pipe_ctx); } -void core_link_disable_stream(struct pipe_ctx *pipe_ctx) +void core_link_disable_stream(struct pipe_ctx *pipe_ctx, int option) { struct dc *core_dc = pipe_ctx->stream->ctx->dc; if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) deallocate_mst_payload(pipe_ctx); - core_dc->hwss.disable_stream(pipe_ctx); + core_dc->hwss.disable_stream(pipe_ctx, option); disable_link(pipe_ctx->stream->sink->link, pipe_ctx->stream->signal); } 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 34b6d1cb151ee..9a33b471270a1 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 @@ -282,7 +282,7 @@ void dp_retrain_link_dp_test(struct dc_link *link, dp_receiver_power_ctrl(link, false); - link->dc->hwss.disable_stream(&pipes[i]); + link->dc->hwss.disable_stream(&pipes[i], KEEP_ACQUIRED_RESOURCE); link->link_enc->funcs->disable_output( link->link_enc, 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 bbfec7cb2ad19..68c613229a109 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -242,7 +242,10 @@ bool resource_construct( pool->stream_enc_count++; } } - + dc->caps.dynamic_audio = false; + if (pool->audio_count < pool->stream_enc_count) { + dc->caps.dynamic_audio = true; + } for (i = 0; i < num_virtual_links; i++) { pool->stream_enc[pool->stream_enc_count] = virtual_stream_encoder_create( @@ -1330,7 +1333,7 @@ static void update_stream_engine_usage( } /* TODO: release audio object */ -static void update_audio_usage( +void update_audio_usage( struct resource_context *res_ctx, const struct resource_pool *pool, struct audio *audio, @@ -1414,12 +1417,21 @@ static struct audio *find_first_free_audio( const struct resource_pool *pool) { int i; - for (i = 0; i < pool->audio_count; i++) { - if (res_ctx->is_audio_acquired[i] == false) { - return pool->audios[i]; + if (pool->audio_count >= pool->stream_enc_count) { + for (i = 0; i < pool->audio_count; i++) { + if ((res_ctx->is_audio_acquired[i] == false) && (res_ctx->is_stream_enc_acquired[i] == true)) { + /*we have enough audio endpoint, no need to do dynamic distribution*/ + return pool->audios[i]; + } } - } + } else { /*first come first serve*/ + for (i = 0; i < pool->audio_count; i++) { + if (res_ctx->is_audio_acquired[i] == false) { + return pool->audios[i]; + } + } + } return 0; } diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index adadfad2bd51d..2517fb821fffe 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -58,6 +58,7 @@ struct dc_caps { uint32_t i2c_speed_in_khz; unsigned int max_cursor_size; bool dcc_const_color; + bool dynamic_audio; }; struct dc_dcc_surface_param { diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c index 247e81806c4a4..453d2ffd5c4a0 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c @@ -985,10 +985,11 @@ void hwss_edp_backlight_control( link_transmitter_control(link->dc->ctx->dc_bios, &cntl); } -void dce110_disable_stream(struct pipe_ctx *pipe_ctx) +void dce110_disable_stream(struct pipe_ctx *pipe_ctx, int option) { struct dc_stream_state *stream = pipe_ctx->stream; struct dc_link *link = stream->sink->link; + struct dc *dc = pipe_ctx->stream->ctx->dc; if (pipe_ctx->stream_res.audio) { pipe_ctx->stream_res.audio->funcs->az_disable(pipe_ctx->stream_res.audio); @@ -999,6 +1000,13 @@ void dce110_disable_stream(struct pipe_ctx *pipe_ctx) else pipe_ctx->stream_res.stream_enc->funcs->hdmi_audio_disable( pipe_ctx->stream_res.stream_enc); + /*don't free audio if it is from retrain or internal disable stream*/ + if (option == FREE_ACQUIRED_RESOURCE && dc->caps.dynamic_audio == true) { + /*we have to dynamic arbitrate the audio endpoints*/ + pipe_ctx->stream_res.audio = NULL; + /*we free the resource, need reset is_audio_acquired*/ + update_audio_usage(&dc->current_state->res_ctx, dc->res_pool, pipe_ctx->stream_res.audio, false); + } /* TODO: notify audio driver for if audio modes list changed * add audio mode list change flag */ @@ -1871,7 +1879,7 @@ static void dce110_reset_hw_ctx_wrap( pipe_need_reprogram(pipe_ctx_old, pipe_ctx)) { struct clock_source *old_clk = pipe_ctx_old->clock_source; - core_link_disable_stream(pipe_ctx_old); + core_link_disable_stream(pipe_ctx_old, FREE_ACQUIRED_RESOURCE); pipe_ctx_old->stream_res.tg->funcs->set_blank(pipe_ctx_old->stream_res.tg, true); if (!hwss_wait_for_blank_complete(pipe_ctx_old->stream_res.tg)) { dm_error("DC: failed to blank crtc!\n"); diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h index a1e964af60ac1..4d72bb99be934 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h @@ -47,7 +47,7 @@ void dce110_set_displaymarks( void dce110_enable_stream(struct pipe_ctx *pipe_ctx); -void dce110_disable_stream(struct pipe_ctx *pipe_ctx); +void dce110_disable_stream(struct pipe_ctx *pipe_ctx, int option); void dce110_unblank_stream(struct pipe_ctx *pipe_ctx, struct dc_link_settings *link_settings); diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index 84d9d202d3b5b..072c48188b793 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -1025,7 +1025,7 @@ static void reset_back_end_for_pipe( * which is used by otg. Move disable_link after disable_crtc */ if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) - core_link_disable_stream(pipe_ctx); + core_link_disable_stream(pipe_ctx, FREE_ACQUIRED_RESOURCE); /* by upper caller loop, parent pipe: pipe0, will be reset last. * back end share by all pipes and will be disable only when disable diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_types.h b/drivers/gpu/drm/amd/display/dc/inc/core_types.h index ff23f268fe02e..5230dddc86171 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h +++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h @@ -58,6 +58,11 @@ struct link_init_data { TODO: remove it when DC is complete. */ }; +enum { + FREE_ACQUIRED_RESOURCE = 0, + KEEP_ACQUIRED_RESOURCE = 1, +}; + struct dc_link *link_create(const struct link_init_data *init_params); void link_destroy(struct dc_link **link); @@ -72,7 +77,7 @@ void core_link_enable_stream( struct dc_state *state, struct pipe_ctx *pipe_ctx); -void core_link_disable_stream(struct pipe_ctx *pipe_ctx); +void core_link_disable_stream(struct pipe_ctx *pipe_ctx, int option); void core_link_set_avmute(struct pipe_ctx *pipe_ctx, bool enable); /********** DAL Core*********************/ diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h index bf3ab5d7398e3..8734689a9245b 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h @@ -134,7 +134,8 @@ struct hw_sequencer_funcs { void (*enable_stream)(struct pipe_ctx *pipe_ctx); - void (*disable_stream)(struct pipe_ctx *pipe_ctx); + void (*disable_stream)(struct pipe_ctx *pipe_ctx, + int option); void (*unblank_stream)(struct pipe_ctx *pipe_ctx, struct dc_link_settings *link_settings); diff --git a/drivers/gpu/drm/amd/display/dc/inc/resource.h b/drivers/gpu/drm/amd/display/dc/inc/resource.h index 614bb691ab59d..5467332faf7b0 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/resource.h +++ b/drivers/gpu/drm/amd/display/dc/inc/resource.h @@ -164,4 +164,9 @@ bool pipe_need_reprogram( void resource_build_bit_depth_reduction_params(struct dc_stream_state *stream, struct bit_depth_reduction_params *fmt_bit_depth); +void update_audio_usage( + struct resource_context *res_ctx, + const struct resource_pool *pool, + struct audio *audio, + bool acquired); #endif /* DRIVERS_GPU_DRM_AMD_DC_DEV_DC_INC_RESOURCE_H_ */ From b7901be0ed5d43525ac2c3fc2a3f9a0cdc5d069c Mon Sep 17 00:00:00 2001 From: Yue Hin Lau Date: Thu, 28 Sep 2017 14:54:58 -0400 Subject: [PATCH 067/155] drm/amd/display: renaming mem input to hubp Signed-off-by: Yue Hin Lau Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../amd/display/dc/dcn10/dcn10_mem_input.c | 76 +++++++++---------- .../amd/display/dc/dcn10/dcn10_mem_input.h | 24 +++--- 2 files changed, 50 insertions(+), 50 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.c index c09e65a0031a9..46086bec9982a 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.c @@ -38,7 +38,7 @@ #define FN(reg_name, field_name) \ mi->mi_shift->field_name, mi->mi_mask->field_name -void min10_set_blank(struct mem_input *mem_input, bool blank) +void hubp1_set_blank(struct mem_input *mem_input, bool blank) { struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input); uint32_t blank_en = blank ? 1 : 0; @@ -56,7 +56,7 @@ void min10_set_blank(struct mem_input *mem_input, bool blank) } } -static void min10_set_hubp_blank_en(struct mem_input *mem_input, bool blank) +static void hubp1_set_hubp_blank_en(struct mem_input *mem_input, bool blank) { struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input); uint32_t blank_en = blank ? 1 : 0; @@ -64,7 +64,7 @@ static void min10_set_hubp_blank_en(struct mem_input *mem_input, bool blank) REG_UPDATE(DCHUBP_CNTL, HUBP_BLANK_EN, blank_en); } -static void min10_vready_workaround(struct mem_input *mem_input, +static void hubp1_vready_workaround(struct mem_input *mem_input, struct _vcs_dpi_display_pipe_dest_params_st *pipe_dest) { uint32_t value = 0; @@ -87,7 +87,7 @@ static void min10_vready_workaround(struct mem_input *mem_input, REG_WRITE(HUBPREQ_DEBUG_DB, value); } -void min10_program_tiling( +void hubp1_program_tiling( struct dcn10_mem_input *mi, const union dc_tiling_info *info, const enum surface_pixel_format pixel_format) @@ -107,7 +107,7 @@ void min10_program_tiling( PIPE_ALIGNED, info->gfx9.pipe_aligned); } -void min10_program_size_and_rotation( +void hubp1_program_size_and_rotation( struct dcn10_mem_input *mi, enum dc_rotation_angle rotation, enum surface_pixel_format format, @@ -169,7 +169,7 @@ void min10_program_size_and_rotation( H_MIRROR_EN, mirror); } -void min10_program_pixel_format( +void hubp1_program_pixel_format( struct dcn10_mem_input *mi, enum surface_pixel_format format) { @@ -245,7 +245,7 @@ void min10_program_pixel_format( /* don't see the need of program the xbar in DCN 1.0 */ } -bool min10_program_surface_flip_and_addr( +bool hubp1_program_surface_flip_and_addr( struct mem_input *mem_input, const struct dc_plane_address *address, bool flip_immediate) @@ -395,7 +395,7 @@ bool min10_program_surface_flip_and_addr( return true; } -void min10_dcc_control(struct mem_input *mem_input, bool enable, +void hubp1_dcc_control(struct mem_input *mem_input, bool enable, bool independent_64b_blks) { uint32_t dcc_en = enable ? 1 : 0; @@ -407,7 +407,7 @@ void min10_dcc_control(struct mem_input *mem_input, bool enable, PRIMARY_SURFACE_DCC_IND_64B_BLK, dcc_ind_64b_blk); } -static void min10_program_surface_config( +static void hubp1_program_surface_config( struct mem_input *mem_input, enum surface_pixel_format format, union dc_tiling_info *tiling_info, @@ -418,14 +418,14 @@ static void min10_program_surface_config( { struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input); - min10_dcc_control(mem_input, dcc->enable, dcc->grph.independent_64b_blks); - min10_program_tiling(mi, tiling_info, format); - min10_program_size_and_rotation( + hubp1_dcc_control(mem_input, dcc->enable, dcc->grph.independent_64b_blks); + hubp1_program_tiling(mi, tiling_info, format); + hubp1_program_size_and_rotation( mi, rotation, format, plane_size, dcc, horizontal_mirror); - min10_program_pixel_format(mi, format); + hubp1_program_pixel_format(mi, format); } -void min10_program_requestor( +void hubp1_program_requestor( struct mem_input *mem_input, struct _vcs_dpi_display_rq_regs_st *rq_regs) { @@ -459,7 +459,7 @@ void min10_program_requestor( } -void min10_program_deadline( +void hubp1_program_deadline( struct mem_input *mem_input, struct _vcs_dpi_display_dlg_regs_st *dlg_attr, struct _vcs_dpi_display_ttu_regs_st *ttu_attr) @@ -580,7 +580,7 @@ void min10_program_deadline( ttu_attr->refcyc_per_req_delivery_pre_c); } -static void min10_setup( +static void hubp1_setup( struct mem_input *mem_input, struct _vcs_dpi_display_dlg_regs_st *dlg_attr, struct _vcs_dpi_display_ttu_regs_st *ttu_attr, @@ -590,12 +590,12 @@ static void min10_setup( /* otg is locked when this func is called. Register are double buffered. * disable the requestors is not needed */ - min10_program_requestor(mem_input, rq_regs); - min10_program_deadline(mem_input, dlg_attr, ttu_attr); - min10_vready_workaround(mem_input, pipe_dest); + hubp1_program_requestor(mem_input, rq_regs); + hubp1_program_deadline(mem_input, dlg_attr, ttu_attr); + hubp1_vready_workaround(mem_input, pipe_dest); } -void min10_program_display_marks( +void hubp1_program_display_marks( struct mem_input *mem_input, struct dce_watermarks nbp, struct dce_watermarks stutter, @@ -607,7 +607,7 @@ void min10_program_display_marks( */ } -bool min10_is_flip_pending(struct mem_input *mem_input) +bool hubp1_is_flip_pending(struct mem_input *mem_input) { uint32_t flip_pending = 0; struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input); @@ -635,7 +635,7 @@ bool min10_is_flip_pending(struct mem_input *mem_input) uint32_t aperture_default_system = 1; uint32_t context0_default_system; /* = 0;*/ -static void min10_set_vm_system_aperture_settings(struct mem_input *mem_input, +static void hubp1_set_vm_system_aperture_settings(struct mem_input *mem_input, struct vm_system_aperture_param *apt) { struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input); @@ -664,7 +664,7 @@ static void min10_set_vm_system_aperture_settings(struct mem_input *mem_input, MC_VM_SYSTEM_APERTURE_HIGH_ADDR_LSB, mc_vm_apt_high.low_part); } -static void min10_set_vm_context0_settings(struct mem_input *mem_input, +static void hubp1_set_vm_context0_settings(struct mem_input *mem_input, const struct vm_context0_param *vm0) { struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input); @@ -848,7 +848,7 @@ static enum cursor_lines_per_chunk ippn10_get_lines_per_chunk( return line_per_chunk; } -void ippn10_cursor_set_attributes( +void hubp1_cursor_set_attributes( struct mem_input *mem_input, const struct dc_cursor_attributes *attr) { @@ -876,7 +876,7 @@ void ippn10_cursor_set_attributes( attr->color_format); } -void ippn10_cursor_set_position( +void hubp1_cursor_set_position( struct mem_input *mem_input, const struct dc_cursor_position *pos, const struct dc_cursor_mi_param *param) @@ -913,7 +913,7 @@ void ippn10_cursor_set_position( cur_en = 0; /* not visible beyond left edge*/ if (cur_en && REG_READ(CURSOR_SURFACE_ADDRESS) == 0) - ippn10_cursor_set_attributes(mem_input, &mem_input->curs_attr); + hubp1_cursor_set_attributes(mem_input, &mem_input->curs_attr); REG_UPDATE(CURSOR_CONTROL, CURSOR_ENABLE, cur_en); @@ -931,21 +931,21 @@ void ippn10_cursor_set_position( } static struct mem_input_funcs dcn10_mem_input_funcs = { - .mem_input_program_display_marks = min10_program_display_marks, + .mem_input_program_display_marks = hubp1_program_display_marks, .mem_input_program_surface_flip_and_addr = - min10_program_surface_flip_and_addr, + hubp1_program_surface_flip_and_addr, .mem_input_program_surface_config = - min10_program_surface_config, - .mem_input_is_flip_pending = min10_is_flip_pending, - .mem_input_setup = min10_setup, - .mem_input_set_vm_system_aperture_settings = min10_set_vm_system_aperture_settings, - .mem_input_set_vm_context0_settings = min10_set_vm_context0_settings, - .set_blank = min10_set_blank, - .dcc_control = min10_dcc_control, + hubp1_program_surface_config, + .mem_input_is_flip_pending = hubp1_is_flip_pending, + .mem_input_setup = hubp1_setup, + .mem_input_set_vm_system_aperture_settings = hubp1_set_vm_system_aperture_settings, + .mem_input_set_vm_context0_settings = hubp1_set_vm_context0_settings, + .set_blank = hubp1_set_blank, + .dcc_control = hubp1_dcc_control, .mem_program_viewport = min_set_viewport, - .set_hubp_blank_en = min10_set_hubp_blank_en, - .set_cursor_attributes = ippn10_cursor_set_attributes, - .set_cursor_position = ippn10_cursor_set_position, + .set_hubp_blank_en = hubp1_set_hubp_blank_en, + .set_cursor_attributes = hubp1_cursor_set_attributes, + .set_cursor_position = hubp1_cursor_set_position, }; /*****************************************/ diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.h index 15231e86e6c6a..653875285b702 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.h +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.h @@ -591,20 +591,20 @@ struct dcn10_mem_input { const struct dcn_mi_mask *mi_mask; }; -void min10_program_deadline( +void hubp1_program_deadline( struct mem_input *mem_input, struct _vcs_dpi_display_dlg_regs_st *dlg_attr, struct _vcs_dpi_display_ttu_regs_st *ttu_attr); -void min10_program_requestor( +void hubp1_program_requestor( struct mem_input *mem_input, struct _vcs_dpi_display_rq_regs_st *rq_regs); -void min10_program_pixel_format( +void hubp1_program_pixel_format( struct dcn10_mem_input *mi, enum surface_pixel_format format); -void min10_program_size_and_rotation( +void hubp1_program_size_and_rotation( struct dcn10_mem_input *mi, enum dc_rotation_angle rotation, enum surface_pixel_format format, @@ -612,39 +612,39 @@ void min10_program_size_and_rotation( struct dc_plane_dcc_param *dcc, bool horizontal_mirror); -void min10_program_tiling( +void hubp1_program_tiling( struct dcn10_mem_input *mi, const union dc_tiling_info *info, const enum surface_pixel_format pixel_format); -void min10_dcc_control(struct mem_input *mem_input, +void hubp1_dcc_control(struct mem_input *mem_input, bool enable, bool independent_64b_blks); -void min10_program_display_marks( +void hubp1_program_display_marks( struct mem_input *mem_input, struct dce_watermarks nbp, struct dce_watermarks stutter, struct dce_watermarks urgent, uint32_t total_dest_line_time_ns); -bool min10_program_surface_flip_and_addr( +bool hubp1_program_surface_flip_and_addr( struct mem_input *mem_input, const struct dc_plane_address *address, bool flip_immediate); -bool min10_is_flip_pending(struct mem_input *mem_input); +bool hubp1_is_flip_pending(struct mem_input *mem_input); -void ippn10_cursor_set_attributes( +void hubp1_cursor_set_attributes( struct mem_input *mem_input, const struct dc_cursor_attributes *attr); -void ippn10_cursor_set_position( +void hubp1_cursor_set_position( struct mem_input *mem_input, const struct dc_cursor_position *pos, const struct dc_cursor_mi_param *param); -void min10_set_blank(struct mem_input *mem_input, bool blank); +void hubp1_set_blank(struct mem_input *mem_input, bool blank); void min_set_viewport(struct mem_input *mem_input, const struct rect *viewport, From 66bfd4fd17737d0a644fa74e0cb309c0daf8fb22 Mon Sep 17 00:00:00 2001 From: Charlene Liu Date: Thu, 28 Sep 2017 15:38:01 -0400 Subject: [PATCH 068/155] drm/amd/display: arbitration find the matching dig-az first. [Description] this change is in branch already. without this change, after resume, az_inst might swapped. Signed-off-by: Charlene Liu Reviewed-by: Anthony Koo Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/core/dc_resource.c | 20 ++++++++----------- 1 file changed, 8 insertions(+), 12 deletions(-) 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 68c613229a109..c31dccdc3d2e5 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -1417,19 +1417,15 @@ static struct audio *find_first_free_audio( const struct resource_pool *pool) { int i; - if (pool->audio_count >= pool->stream_enc_count) { - for (i = 0; i < pool->audio_count; i++) { - if ((res_ctx->is_audio_acquired[i] == false) && (res_ctx->is_stream_enc_acquired[i] == true)) { - /*we have enough audio endpoint, no need to do dynamic distribution*/ - return pool->audios[i]; - } + for (i = 0; i < pool->audio_count; i++) { + if ((res_ctx->is_audio_acquired[i] == false) && (res_ctx->is_stream_enc_acquired[i] == true)) { + return pool->audios[i]; } - } else { /*first come first serve*/ - for (i = 0; i < pool->audio_count; i++) { - if (res_ctx->is_audio_acquired[i] == false) { - - return pool->audios[i]; - } + } + /*not found the matching one, first come first serve*/ + for (i = 0; i < pool->audio_count; i++) { + if (res_ctx->is_audio_acquired[i] == false) { + return pool->audios[i]; } } return 0; From e4b3b5ccd9835bafab67851a7cc759c9250a8a9d Mon Sep 17 00:00:00 2001 From: Yue Hin Lau Date: Thu, 28 Sep 2017 16:09:56 -0400 Subject: [PATCH 069/155] drm/amd/display: Making hubp1_program_surface_config public Signed-off-by: Yue Hin Lau Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.c | 3 ++- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.h | 9 +++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.c index 46086bec9982a..2336da54000c5 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.c @@ -407,7 +407,7 @@ void hubp1_dcc_control(struct mem_input *mem_input, bool enable, PRIMARY_SURFACE_DCC_IND_64B_BLK, dcc_ind_64b_blk); } -static void hubp1_program_surface_config( +void hubp1_program_surface_config( struct mem_input *mem_input, enum surface_pixel_format format, union dc_tiling_info *tiling_info, @@ -970,3 +970,4 @@ void dcn10_mem_input_construct( mi->base.mpcc_id = 0xf; } + diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.h index 653875285b702..5c5eed5c95d57 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.h +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.h @@ -591,6 +591,15 @@ struct dcn10_mem_input { const struct dcn_mi_mask *mi_mask; }; +void hubp1_program_surface_config( + struct mem_input *mem_input, + enum surface_pixel_format format, + union dc_tiling_info *tiling_info, + union plane_size *plane_size, + enum dc_rotation_angle rotation, + struct dc_plane_dcc_param *dcc, + bool horizontal_mirror); + void hubp1_program_deadline( struct mem_input *mem_input, struct _vcs_dpi_display_dlg_regs_st *dlg_attr, From c018b04b7c17e0814bc75b09d782204d73c64b1b Mon Sep 17 00:00:00 2001 From: Roman Li Date: Thu, 28 Sep 2017 12:57:21 -0400 Subject: [PATCH 070/155] drm/amd/display: Fix irq enable/disable on resume. Fixing loop boundaries in irq enable/disable on resume. Signed-off-by: Roman Li Reviewed-by: Mikita Lipski Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c index 8de19ba5b2e39..b9e4d38310011 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c @@ -435,7 +435,7 @@ int amdgpu_dm_irq_suspend(struct amdgpu_device *adev) * Disable HW interrupt for HPD and HPDRX only since FLIP and VBLANK * will be disabled from manage_dm_interrupts on disable CRTC. */ - for (src = DC_IRQ_SOURCE_HPD1; src < DC_IRQ_SOURCE_HPD6RX; src++) { + for (src = DC_IRQ_SOURCE_HPD1; src <= DC_IRQ_SOURCE_HPD6RX; src++) { hnd_list_l = &adev->dm.irq_handler_list_low_tab[src].head; hnd_list_h = &adev->dm.irq_handler_list_high_tab[src]; if (!list_empty(hnd_list_l) || !list_empty(hnd_list_h)) @@ -462,7 +462,7 @@ int amdgpu_dm_irq_resume_early(struct amdgpu_device *adev) DRM_DEBUG_KMS("DM_IRQ: early resume\n"); /* re-enable short pulse interrupts HW interrupt */ - for (src = DC_IRQ_SOURCE_HPD1RX; src <= DC_IRQ_SOURCE_HPD6RX + 1; src++) { + for (src = DC_IRQ_SOURCE_HPD1RX; src <= DC_IRQ_SOURCE_HPD6RX; src++) { hnd_list_l = &adev->dm.irq_handler_list_low_tab[src].head; hnd_list_h = &adev->dm.irq_handler_list_high_tab[src]; if (!list_empty(hnd_list_l) || !list_empty(hnd_list_h)) From 4bd29c34988be0c24759d5d58df424f861a8bf24 Mon Sep 17 00:00:00 2001 From: Jerry Zuo Date: Thu, 28 Sep 2017 16:20:30 -0400 Subject: [PATCH 071/155] drm/amd/display: Do not access fbdev helper members Original code is no longer needed and tested without loop. Signed-off-by: Harry Wentland Signed-off-by: Jerry Zuo Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher --- .../drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c index 610375b2a04b9..382f499cb60dd 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c @@ -397,21 +397,10 @@ static void dm_dp_mst_register_connector(struct drm_connector *connector) { struct drm_device *dev = connector->dev; struct amdgpu_device *adev = dev->dev_private; - int i; drm_modeset_lock_all(dev); - if (adev->mode_info.rfbdev) { - /*Do not add if already registered in past*/ - for (i = 0; i < adev->mode_info.rfbdev->helper.connector_count; i++) { - if (adev->mode_info.rfbdev->helper.connector_info[i]->connector - == connector) { - drm_modeset_unlock_all(dev); - return; - } - } - + if (adev->mode_info.rfbdev) drm_fb_helper_add_one_connector(&adev->mode_info.rfbdev->helper, connector); - } else DRM_ERROR("adev->mode_info.rfbdev is NULL\n"); From 365c7c975dcd1a2158ed33dab76c1d308f9f9906 Mon Sep 17 00:00:00 2001 From: Jerry Zuo Date: Thu, 28 Sep 2017 16:58:32 -0400 Subject: [PATCH 072/155] drm/amd/display: Remove drm_modeset_lock in MST code Locks are no longer needed since the drm framework takes care of correct locking. Signed-off-by: Harry Wentland Signed-off-by: Jerry Zuo Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher --- .../drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c index 382f499cb60dd..3b05da7a90e86 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c @@ -287,9 +287,10 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr, struct amdgpu_device *adev = dev->dev_private; struct amdgpu_dm_connector *aconnector; struct drm_connector *connector; + struct drm_connector_list_iter conn_iter; - drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + drm_connector_list_iter_begin(dev, &conn_iter); + drm_for_each_connector_iter(connector, &conn_iter) { aconnector = to_amdgpu_dm_connector(connector); if (aconnector->mst_port == master && !aconnector->port) { @@ -299,11 +300,11 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr, aconnector->port = port; drm_mode_connector_set_path_property(connector, pathprop); - drm_modeset_unlock(&dev->mode_config.connection_mutex); + drm_connector_list_iter_end(&conn_iter); return &aconnector->base; } } - drm_modeset_unlock(&dev->mode_config.connection_mutex); + drm_connector_list_iter_end(&conn_iter); aconnector = kzalloc(sizeof(*aconnector), GFP_KERNEL); if (!aconnector) @@ -398,14 +399,11 @@ static void dm_dp_mst_register_connector(struct drm_connector *connector) struct drm_device *dev = connector->dev; struct amdgpu_device *adev = dev->dev_private; - drm_modeset_lock_all(dev); if (adev->mode_info.rfbdev) drm_fb_helper_add_one_connector(&adev->mode_info.rfbdev->helper, connector); else DRM_ERROR("adev->mode_info.rfbdev is NULL\n"); - drm_modeset_unlock_all(dev); - drm_connector_register(connector); } From 734a092b1fe407319c8a4f38f9b4a647ddb54c2c Mon Sep 17 00:00:00 2001 From: Eric Bernstein Date: Fri, 29 Sep 2017 15:30:17 -0400 Subject: [PATCH 073/155] drm/amd/display: clean up dcn10 dpp after HW review Signed-off-by: Eric Bernstein Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc_hw_types.h | 2 + .../gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h | 20 +++++ .../drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c | 85 ++++++++++--------- 3 files changed, 65 insertions(+), 42 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h index 4ab109314e4b7..1a9f57fb0838c 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h @@ -204,6 +204,8 @@ enum surface_pixel_format { /*grow 444 video here if necessary */ }; + + /* Pixel format */ enum pixel_format { /*graph*/ diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h index 889f91cf47cf7..153aa3c327629 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h @@ -1265,6 +1265,21 @@ struct dcn10_dpp { }; +enum lb_memory_config { + /* Enable all 3 pieces of memory */ + LB_MEMORY_CONFIG_0 = 0, + + /* Enable only the first piece of memory */ + LB_MEMORY_CONFIG_1 = 1, + + /* Enable only the second piece of memory */ + LB_MEMORY_CONFIG_2 = 2, + + /* Only applicable in 4:2:0 mode, enable all 3 pieces of memory and the + * last piece of chroma memory used for the luma storage + */ + LB_MEMORY_CONFIG_3 = 3 +}; enum dcn10_input_csc_select { INPUT_CSC_SELECT_BYPASS = 0, @@ -1272,6 +1287,11 @@ enum dcn10_input_csc_select { INPUT_CSC_SELECT_COMA }; +bool is_lb_conf_valid( + int ceil_vratio, + int num_partitions, + int vtaps); + void ippn10_degamma_ram_select( struct transform *xfm_base, bool use_ram_a); diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c index fa2ab9952388f..c5267e42a2f2b 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c @@ -57,22 +57,6 @@ enum dcn10_coef_filter_type_sel { SCL_COEF_ALPHA_HORZ_FILTER = 5 }; -enum lb_memory_config { - /* Enable all 3 pieces of memory */ - LB_MEMORY_CONFIG_0 = 0, - - /* Enable only the first piece of memory */ - LB_MEMORY_CONFIG_1 = 1, - - /* Enable only the second piece of memory */ - LB_MEMORY_CONFIG_2 = 2, - - /* Only applicable in 4:2:0 mode, enable all 3 pieces of memory and the - * last piece of chroma memory used for the luma storage - */ - LB_MEMORY_CONFIG_3 = 3 -}; - enum dscl_autocal_mode { AUTOCAL_MODE_OFF = 0, @@ -161,23 +145,37 @@ static int get_pixel_depth_val(enum lb_pixel_depth depth) } } -static enum dscl_mode_sel get_dscl_mode( - const struct scaler_data *data, bool dbg_always_scale) +static bool is_video_format(enum pixel_format format) { - const long long one = dal_fixed31_32_one.value; - bool ycbcr = false; - bool format420 = false; + if (format >= PIXEL_FORMAT_VIDEO_BEGIN + && format <= PIXEL_FORMAT_VIDEO_END) + return true; + else + return false; +} - if (data->format == PIXEL_FORMAT_FP16) - return DSCL_MODE_DSCL_BYPASS; +static bool is_420_format(enum pixel_format format) +{ + if (format == PIXEL_FORMAT_420BPP8 || + format == PIXEL_FORMAT_420BPP10) + return true; + else + return false; +} - if (data->format >= PIXEL_FORMAT_VIDEO_BEGIN - && data->format <= PIXEL_FORMAT_VIDEO_END) - ycbcr = true; +static enum dscl_mode_sel get_dscl_mode( + struct transform *xfm_base, + const struct scaler_data *data, + bool dbg_always_scale) +{ + struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); + const long long one = dal_fixed31_32_one.value; - if (data->format == PIXEL_FORMAT_420BPP8 || - data->format == PIXEL_FORMAT_420BPP10) - format420 = true; + if (xfm->tf_mask->PIXEL_DEPTH) { + /* DSCL caps: LB data is fixed format */ + if (data->format == PIXEL_FORMAT_FP16) + return DSCL_MODE_DSCL_BYPASS; + } if (data->ratios.horz.value == one && data->ratios.vert.value == one @@ -186,8 +184,8 @@ static enum dscl_mode_sel get_dscl_mode( && !dbg_always_scale) return DSCL_MODE_SCALING_444_BYPASS; - if (!format420) { - if (ycbcr) + if (!is_420_format(data->format)) { + if (is_video_format(data->format)) return DSCL_MODE_SCALING_444_YCBCR_ENABLE; else return DSCL_MODE_SCALING_444_RGB_ENABLE; @@ -205,11 +203,12 @@ static void dpp_set_lb( const struct line_buffer_params *lb_params, enum lb_memory_config mem_size_config) { - uint32_t pixel_depth = get_pixel_depth_val(lb_params->depth); - uint32_t dyn_pix_depth = lb_params->dynamic_pixel_depth; - /* LB */ if (xfm->tf_mask->PIXEL_DEPTH) { + /* DSCL caps: LB data is fixed format */ + uint32_t pixel_depth = get_pixel_depth_val(lb_params->depth); + uint32_t dyn_pix_depth = lb_params->dynamic_pixel_depth; + REG_SET_7(LB_DATA_FORMAT, 0, PIXEL_DEPTH, pixel_depth, /* Pixel depth stored in LB */ PIXEL_EXPAN_MODE, lb_params->pixel_expan_mode, /* Pixel expansion mode */ @@ -401,7 +400,7 @@ static int get_lb_depth_bpc(enum lb_pixel_depth depth) } } -static void calc_lb_num_partitions( +static void dscl1_calc_lb_num_partitions( const struct scaler_data *scl_data, enum lb_memory_config lb_config, int *num_part_y, @@ -426,6 +425,7 @@ static void calc_lb_num_partitions( lb_memory_size_c = 1088; lb_memory_size_a = 1312; } else if (lb_config == LB_MEMORY_CONFIG_3) { + /* 420 mode: using 3rd mem from Y, Cr and Cb */ lb_memory_size = 816 + 1088 + 848 + 848 + 848; lb_memory_size_c = 816 + 1088; lb_memory_size_a = 984 + 1312 + 456; @@ -449,7 +449,7 @@ static void calc_lb_num_partitions( } -static bool is_lb_conf_valid(int ceil_vratio, int num_partitions, int vtaps) +bool is_lb_conf_valid(int ceil_vratio, int num_partitions, int vtaps) { if (ceil_vratio > 2) return vtaps <= (num_partitions - ceil_vratio + 2); @@ -467,14 +467,14 @@ static enum lb_memory_config dpp10_find_lb_memory_config( int ceil_vratio = dal_fixed31_32_ceil(scl_data->ratios.vert); int ceil_vratio_c = dal_fixed31_32_ceil(scl_data->ratios.vert_c); - calc_lb_num_partitions( + dscl1_calc_lb_num_partitions( scl_data, LB_MEMORY_CONFIG_1, &num_part_y, &num_part_c); if (is_lb_conf_valid(ceil_vratio, num_part_y, vtaps) && is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c)) return LB_MEMORY_CONFIG_1; - calc_lb_num_partitions( + dscl1_calc_lb_num_partitions( scl_data, LB_MEMORY_CONFIG_2, &num_part_y, &num_part_c); if (is_lb_conf_valid(ceil_vratio, num_part_y, vtaps) @@ -483,7 +483,7 @@ static enum lb_memory_config dpp10_find_lb_memory_config( if (scl_data->format == PIXEL_FORMAT_420BPP8 || scl_data->format == PIXEL_FORMAT_420BPP10) { - calc_lb_num_partitions( + dscl1_calc_lb_num_partitions( scl_data, LB_MEMORY_CONFIG_3, &num_part_y, &num_part_c); if (is_lb_conf_valid(ceil_vratio, num_part_y, vtaps) @@ -491,7 +491,7 @@ static enum lb_memory_config dpp10_find_lb_memory_config( return LB_MEMORY_CONFIG_3; } - calc_lb_num_partitions( + dscl1_calc_lb_num_partitions( scl_data, LB_MEMORY_CONFIG_0, &num_part_y, &num_part_c); /*Ensure we can support the requested number of vtaps*/ @@ -511,6 +511,7 @@ static enum lb_memory_config find_lb_memory_config(struct dcn10_dpp *xfm, return mem_cfg; if (xfm->tf_mask->PIXEL_DEPTH) { + /* DSCL caps: LB data is fixed format */ mem_cfg = dpp10_find_lb_memory_config(scl_data); } return mem_cfg; @@ -523,7 +524,7 @@ void dpp_set_scaler_auto_scale( enum lb_memory_config lb_config; struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); enum dscl_mode_sel dscl_mode = get_dscl_mode( - scl_data, xfm_base->ctx->dc->debug.always_scale); + xfm_base, scl_data, xfm_base->ctx->dc->debug.always_scale); bool ycbcr = scl_data->format >= PIXEL_FORMAT_VIDEO_BEGIN && scl_data->format <= PIXEL_FORMAT_VIDEO_END; @@ -655,7 +656,7 @@ void dcn10_dpp_dscl_set_scaler_manual_scale( enum lb_memory_config lb_config; struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); enum dscl_mode_sel dscl_mode = get_dscl_mode( - scl_data, xfm_base->ctx->dc->debug.always_scale); + xfm_base, scl_data, xfm_base->ctx->dc->debug.always_scale); bool ycbcr = scl_data->format >= PIXEL_FORMAT_VIDEO_BEGIN && scl_data->format <= PIXEL_FORMAT_VIDEO_END; From 3af89b96b2f22119556b8e89edde72951f6bd410 Mon Sep 17 00:00:00 2001 From: Charlene Liu Date: Sat, 30 Sep 2017 21:03:40 -0400 Subject: [PATCH 074/155] drm/amd/display: Add stereo_support debug flag Signed-off-by: Charlene Liu Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc.h | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 2517fb821fffe..172050ad845d9 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -217,6 +217,7 @@ struct dc_debug { bool force_abm_enable; bool disable_hbup_pg; bool disable_dpp_pg; + bool stereo_support; }; struct dc_state; struct resource_pool; From 13ab1b44151195823fa0e2ceace1cf4687266dba Mon Sep 17 00:00:00 2001 From: Yongqiang Sun Date: Thu, 28 Sep 2017 17:18:27 -0400 Subject: [PATCH 075/155] drm/amd/display: Fixed extend to second screen mode hang 1. Fixed acquire free split pipe bug. 2. Change return value for dc_add_stream_to_ctx from bool to enum. 4. Remove redundant apply_ctx_for_surface calling 5. Unlock pipe after back end programming. Signed-off-by: Yongqiang Sun Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 4 +- drivers/gpu/drm/amd/display/dc/core/dc.c | 48 ++++++++++--------- .../gpu/drm/amd/display/dc/core/dc_resource.c | 9 ++-- drivers/gpu/drm/amd/display/dc/dc.h | 2 +- 4 files changed, 32 insertions(+), 31 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 0707bec111a53..8653453566b8e 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -4495,10 +4495,10 @@ static int dm_update_crtcs_state(struct dc *dc, DRM_DEBUG_DRIVER("Enabling DRM crtc: %d\n", crtc->base.id); - if (!dc_add_stream_to_ctx( + if (dc_add_stream_to_ctx( dc, dm_state->context, - dm_new_crtc_state->stream)) { + dm_new_crtc_state->stream) != DC_OK) { ret = -EINVAL; goto fail; } diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index f9bac11d39500..33a63c7d7a8e2 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -766,34 +766,27 @@ static bool dc_commit_state_no_check(struct dc *dc, struct dc_state *context) for (i = 0; i < context->stream_count; i++) { const struct dc_sink *sink = context->streams[i]->sink; - for (j = 0; j < context->stream_status[i].plane_count; j++) { - dc->hwss.apply_ctx_for_surface( - dc, context->streams[i], - context->stream_status[i].plane_count, - context); + dc->hwss.apply_ctx_for_surface( + dc, context->streams[i], + context->stream_status[i].plane_count, + context); - /* - * enable stereo - * TODO rework dc_enable_stereo call to work with validation sets? - */ - for (k = 0; k < MAX_PIPES; k++) { - pipe = &context->res_ctx.pipe_ctx[k]; - - for (l = 0 ; pipe && l < context->stream_count; l++) { - if (context->streams[l] && - context->streams[l] == pipe->stream && - dc->hwss.setup_stereo) - dc->hwss.setup_stereo(pipe, dc); - } + /* + * enable stereo + * TODO rework dc_enable_stereo call to work with validation sets? + */ + for (k = 0; k < MAX_PIPES; k++) { + pipe = &context->res_ctx.pipe_ctx[k]; + + for (l = 0 ; pipe && l < context->stream_count; l++) { + if (context->streams[l] && + context->streams[l] == pipe->stream && + dc->hwss.setup_stereo) + dc->hwss.setup_stereo(pipe, dc); } } - for (j = 0; j < MAX_PIPES; j++) { - pipe = &context->res_ctx.pipe_ctx[j]; - if (!pipe->top_pipe && pipe->stream == context->streams[i]) - dc->hwss.pipe_control_lock(dc, pipe, false); - } CONN_MSG_MODE(sink->link, "{%dx%d, %dx%d@%dKhz}", context->streams[i]->timing.h_addressable, @@ -815,6 +808,15 @@ static bool dc_commit_state_no_check(struct dc *dc, struct dc_state *context) dc_enable_stereo(dc, context, dc_streams, context->stream_count); + for (i = 0; i < context->stream_count; i++) { + for (j = 0; j < MAX_PIPES; j++) { + pipe = &context->res_ctx.pipe_ctx[j]; + + if (!pipe->top_pipe && pipe->stream == context->streams[i]) + dc->hwss.pipe_control_lock(dc, pipe, false); + } + } + dc_release_state(dc->current_state); dc->current_state = context; 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 c31dccdc3d2e5..c60f530697084 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -1446,7 +1446,7 @@ bool resource_is_stream_unchanged( return false; } -bool dc_add_stream_to_ctx( +enum dc_status dc_add_stream_to_ctx( struct dc *dc, struct dc_state *new_ctx, struct dc_stream_state *stream) @@ -1467,7 +1467,7 @@ bool dc_add_stream_to_ctx( if (res != DC_OK) DC_ERROR("Adding stream %p to context failed with err %d!\n", stream, res); - return res == DC_OK; + return res; } bool dc_remove_stream_from_ctx( @@ -1640,10 +1640,9 @@ enum dc_status resource_map_pool_resources( /* acquire new resources */ pipe_idx = acquire_first_free_pipe(&context->res_ctx, pool, stream); -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) if (pipe_idx < 0) - acquire_first_split_pipe(&context->res_ctx, pool, stream); -#endif + pipe_idx = acquire_first_split_pipe(&context->res_ctx, pool, stream); + if (pipe_idx < 0) return DC_NO_CONTROLLER_RESOURCE; diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 172050ad845d9..eeb8ee5acdc1e 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -631,7 +631,7 @@ bool dc_stream_get_scanoutpos(const struct dc_stream_state *stream, uint32_t *h_position, uint32_t *v_position); -bool dc_add_stream_to_ctx( +enum dc_status dc_add_stream_to_ctx( struct dc *dc, struct dc_state *new_ctx, struct dc_stream_state *stream); From 309c42efdab945071c693a51334fbaeb0a700b0d Mon Sep 17 00:00:00 2001 From: Yongqiang Sun Date: Mon, 2 Oct 2017 17:08:24 -0400 Subject: [PATCH 076/155] drm/amd/display: wa to program split pipedegamma regs after mode set. Signed-off-by: Yongqiang Sun Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 33a63c7d7a8e2..09bab93815a3c 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -1282,7 +1282,9 @@ static void commit_planes_for_stream(struct dc *dc, if (update_type == UPDATE_TYPE_FAST) continue; - if (srf_updates[i].in_transfer_func) + /* work around to program degamma regs for split pipe after set mode. */ + if (srf_updates[i].in_transfer_func || (pipe_ctx->top_pipe && + pipe_ctx->top_pipe->plane_state == pipe_ctx->plane_state)) dc->hwss.set_input_transfer_func( pipe_ctx, pipe_ctx->plane_state); From f6cb588a42a7812e65eff368d3d1134ee1a88489 Mon Sep 17 00:00:00 2001 From: Charlene Liu Date: Mon, 2 Oct 2017 16:25:58 -0400 Subject: [PATCH 077/155] drm/amd/display: Add debug flag for VSR support Signed-off-by: Charlene Liu Reviewed-by: Krunoslav Kovac Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc.h | 1 + drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c | 1 + drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.c | 1 + 3 files changed, 3 insertions(+) diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index eeb8ee5acdc1e..defc44393b381 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -218,6 +218,7 @@ struct dc_debug { bool disable_hbup_pg; bool disable_dpp_pg; bool stereo_support; + bool vsr_support; }; struct dc_state; struct resource_pool; diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c index 3000ddab23578..1b108ae2e6560 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c @@ -428,6 +428,7 @@ static const struct dc_debug debug_defaults_drv = { .pipe_split_policy = MPC_SPLIT_AVOID_MULT_DISP, .disable_dcc = DCC_ENABLE, .voltage_align_fclk = true, + .vsr_support = true, }; static const struct dc_debug debug_defaults_diags = { diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.c index 8dbc82ff9b3a3..178dadda74f97 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.c @@ -25,6 +25,7 @@ #include "reg_helper.h" #include "dcn10_timing_generator.h" +#include "dc.h" #define REG(reg)\ tgn10->tg_regs->reg From 458e9d03875ec6cb2ee37b64cf201bc80401bf92 Mon Sep 17 00:00:00 2001 From: Bhawanpreet Lakha Date: Mon, 2 Oct 2017 12:00:24 -0400 Subject: [PATCH 078/155] drm/amd/display: fix re-enabling stutter for raven We were overwriting the whole register which was re-enabling stutter for raven. Now we are reading the register then setting the values only for pstate. Signed-off-by: Bhawanpreet Lakha Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h | 4 ++++ .../gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 9 ++++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h index 0a058e0c3fec8..9a04b8758888d 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h @@ -446,6 +446,8 @@ struct dce_hwseq_registers { HWS_SF(, DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL, DCHUBBUB_ARB_WATERMARK_CHANGE_DONE_INTERRUPT_DISABLE, mask_sh), \ HWS_SF(, DCHUBBUB_ARB_DRAM_STATE_CNTL, DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_VALUE, mask_sh), \ HWS_SF(, DCHUBBUB_ARB_DRAM_STATE_CNTL, DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE, mask_sh), \ + HWS_SF(, DCHUBBUB_ARB_DRAM_STATE_CNTL, DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_VALUE, mask_sh), \ + HWS_SF(, DCHUBBUB_ARB_DRAM_STATE_CNTL, DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_ENABLE, mask_sh), \ HWS_SF(, DCHUBBUB_ARB_SAT_LEVEL, DCHUBBUB_ARB_SAT_LEVEL, mask_sh), \ HWS_SF(, DCHUBBUB_ARB_DF_REQ_OUTSTAND, DCHUBBUB_ARB_MIN_REQ_OUTSTAND, mask_sh), \ HWS_SF(, DCFCLK_CNTL, DCFCLK_GATE_DIS, mask_sh) @@ -554,6 +556,8 @@ struct dce_hwseq_registers { type DCHUBBUB_ARB_WATERMARK_CHANGE_DONE_INTERRUPT_DISABLE;\ type DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_VALUE;\ type DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE;\ + type DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_VALUE;\ + type DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_ENABLE;\ type DCHUBBUB_ARB_SAT_LEVEL;\ type DCHUBBUB_ARB_MIN_REQ_OUTSTAND;\ type OPP_PIPE_CLOCK_EN;\ diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index 072c48188b793..db774b3c3721b 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -253,7 +253,6 @@ static void verify_allow_pstate_change_high( unsigned int debug_index = 0x7; unsigned int debug_data; - unsigned int force_allow_pstate = 0x30; unsigned int i; if (forced_pstate_allow) { @@ -261,7 +260,9 @@ static void verify_allow_pstate_change_high( * we verify_allow_pstate_change_high. so disable force * here so we can check status */ - REG_WRITE(DCHUBBUB_ARB_DRAM_STATE_CNTL, 0); + REG_UPDATE_2(DCHUBBUB_ARB_DRAM_STATE_CNTL, + DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_VALUE, 0, + DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_ENABLE, 0); forced_pstate_allow = false; } @@ -304,7 +305,9 @@ static void verify_allow_pstate_change_high( /* force pstate allow to prevent system hang * and break to debugger to investigate */ - REG_WRITE(DCHUBBUB_ARB_DRAM_STATE_CNTL, force_allow_pstate); + REG_UPDATE_2(DCHUBBUB_ARB_DRAM_STATE_CNTL, + DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_VALUE, 1, + DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_ENABLE, 1); forced_pstate_allow = true; if (should_log_hw_state) { From 73fb63e74fb26c12bc847fd28596cc4e088e870b Mon Sep 17 00:00:00 2001 From: Charlene Liu Date: Mon, 2 Oct 2017 18:01:36 -0400 Subject: [PATCH 079/155] drm/amd/display: reject 3D mode based on static debug flag. Signed-off-by: Charlene Liu Reviewed-by: Krunoslav Kovac Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc.h | 2 +- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c | 1 + drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.c | 3 +++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index defc44393b381..4c47a489c87a0 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -217,7 +217,7 @@ struct dc_debug { bool force_abm_enable; bool disable_hbup_pg; bool disable_dpp_pg; - bool stereo_support; + bool disable_stereo_support; bool vsr_support; }; struct dc_state; diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c index 1b108ae2e6560..f168335e95bf2 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c @@ -428,6 +428,7 @@ static const struct dc_debug debug_defaults_drv = { .pipe_split_policy = MPC_SPLIT_AVOID_MULT_DISP, .disable_dcc = DCC_ENABLE, .voltage_align_fclk = true, + .disable_stereo_support = true, .vsr_support = true, }; diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.c index 178dadda74f97..1994865d43517 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.c @@ -499,6 +499,9 @@ static bool tgn10_validate_timing( timing->timing_3d_format != TIMING_3D_FORMAT_INBAND_FA) return false; + if (timing->timing_3d_format != TIMING_3D_FORMAT_NONE && + tg->ctx->dc->debug.disable_stereo_support) + return false; /* Temporarily blocking interlacing mode until it's supported */ if (timing->flags.INTERLACE == 1) return false; From ff79cbdccea94935ff9d2111458e439e28c86e74 Mon Sep 17 00:00:00 2001 From: Bhawanpreet Lakha Date: Mon, 2 Oct 2017 13:40:02 -0400 Subject: [PATCH 080/155] drm/amd/display: increase pstate wait timeout For linux it takes longer than 40us so increasing it to 200us. Also added debug prints regarding the change Signed-off-by: Bhawanpreet Lakha Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index db774b3c3721b..012ba7c9ca8de 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -245,8 +245,13 @@ static void verify_allow_pstate_change_high( { /* pstate latency is ~20us so if we wait over 40us and pstate allow * still not asserted, we are probably stuck and going to hang + * + * TODO: Figure out why it takes ~100us on linux + * pstate takes around ~100us on linux. Unknown currently as to + * why it takes that long on linux */ - static unsigned int pstate_wait_timeout_us = 40; + static unsigned int pstate_wait_timeout_us = 200; + static unsigned int pstate_wait_expected_timeout_us = 40; static unsigned int max_sampled_pstate_wait_us; /* data collection */ static bool forced_pstate_allow; /* help with revert wa */ static bool should_log_hw_state; /* prevent hw state log by default */ @@ -293,9 +298,15 @@ static void verify_allow_pstate_change_high( for (i = 0; i < pstate_wait_timeout_us; i++) { debug_data = REG_READ(DCHUBBUB_TEST_DEBUG_DATA); - if (debug_data & (1 << 30)) - return; + if (debug_data & (1 << 30)) { + + if (i > pstate_wait_expected_timeout_us) + dm_logger_write(hws->ctx->logger, LOG_WARNING, + "pstate took longer than expected ~%dus", + i); + return; + } if (max_sampled_pstate_wait_us < i) max_sampled_pstate_wait_us = i; @@ -314,6 +325,9 @@ static void verify_allow_pstate_change_high( dcn10_log_hw_state(hws->ctx->dc); } + dm_logger_write(hws->ctx->logger, LOG_WARNING, + "pstate TEST_DEBUG_DATA: 0x%X", + debug_data); BREAK_TO_DEBUGGER(); } From bac4c5592774fef2503c3204e8f947ce595bfcdf Mon Sep 17 00:00:00 2001 From: Dmytro Laktyushkin Date: Tue, 3 Oct 2017 11:11:28 -0400 Subject: [PATCH 081/155] drm/amd/display: block video planes >4k on dcn10 Signed-off-by: Dmytro Laktyushkin Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c index f168335e95bf2..4dd7c3af51e6c 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c @@ -1163,6 +1163,14 @@ static void dcn10_destroy_resource_pool(struct resource_pool **pool) *pool = NULL; } +enum dc_status dcn10_validate_plane(const struct dc_plane_state *plane_state) +{ + if (plane_state->format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN + && plane_state->src_rect.width > 3840) + return DC_FAIL_SURFACE_VALIDATE; + + return DC_OK; +} static struct dc_cap_funcs cap_funcs = { .get_dcc_compression_cap = get_dcc_compression_cap @@ -1174,6 +1182,7 @@ static struct resource_funcs dcn10_res_pool_funcs = { .validate_guaranteed = dcn10_validate_guaranteed, .validate_bandwidth = dcn_validate_bandwidth, .acquire_idle_pipe_for_layer = dcn10_acquire_idle_pipe_for_layer, + .validate_plane = dcn10_validate_plane, .add_stream_to_ctx = dcn10_add_stream_to_ctx }; From 8e7095b909dd5451c92dc04420891a578e2f3152 Mon Sep 17 00:00:00 2001 From: Dmytro Laktyushkin Date: Tue, 3 Oct 2017 12:54:18 -0400 Subject: [PATCH 082/155] drm/amd/display: add max_video_width cap to dc Signed-off-by: Dmytro Laktyushkin Reviewed-by: Dmytro Laktyushkin Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 6 ++---- drivers/gpu/drm/amd/display/dc/dc.h | 1 + drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c | 2 +- drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.h | 2 +- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c | 6 ++++-- drivers/gpu/drm/amd/display/dc/inc/core_types.h | 2 +- 6 files changed, 10 insertions(+), 9 deletions(-) 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 c60f530697084..7d750369b78b5 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -2750,11 +2750,9 @@ bool dc_validate_stream(struct dc *dc, struct dc_stream_state *stream) bool dc_validate_plane(struct dc *dc, const struct dc_plane_state *plane_state) { - struct dc *core_dc = dc; - /* TODO For now validates pixel format only */ - if (core_dc->res_pool->funcs->validate_plane) - return core_dc->res_pool->funcs->validate_plane(plane_state) == DC_OK; + if (dc->res_pool->funcs->validate_plane) + return dc->res_pool->funcs->validate_plane(plane_state, &dc->caps) == DC_OK; return true; } diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 4c47a489c87a0..5a378cc5daafc 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -57,6 +57,7 @@ struct dc_caps { uint32_t max_downscale_ratio; uint32_t i2c_speed_in_khz; unsigned int max_cursor_size; + unsigned int max_video_width; bool dcc_const_color; bool dynamic_audio; }; diff --git a/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c b/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c index b1cf591b34083..90911258bdb3a 100644 --- a/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c @@ -743,7 +743,7 @@ static void dce100_destroy_resource_pool(struct resource_pool **pool) *pool = NULL; } -enum dc_status dce100_validate_plane(const struct dc_plane_state *plane_state) +enum dc_status dce100_validate_plane(const struct dc_plane_state *plane_state, struct dc_caps *caps) { if (plane_state->format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) diff --git a/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.h b/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.h index f52cae24ee233..de8fdf438f9b3 100644 --- a/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.h +++ b/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.h @@ -16,7 +16,7 @@ struct resource_pool *dce100_create_resource_pool( uint8_t num_virtual_links, struct dc *dc); -enum dc_status dce100_validate_plane(const struct dc_plane_state *plane_state); +enum dc_status dce100_validate_plane(const struct dc_plane_state *plane_state, struct dc_caps *caps); enum dc_status dce100_add_stream_to_ctx( struct dc *dc, diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c index 4dd7c3af51e6c..2caad73257e0b 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c @@ -1163,10 +1163,11 @@ static void dcn10_destroy_resource_pool(struct resource_pool **pool) *pool = NULL; } -enum dc_status dcn10_validate_plane(const struct dc_plane_state *plane_state) +static enum dc_status dcn10_validate_plane(const struct dc_plane_state *plane_state, struct dc_caps *caps) { if (plane_state->format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN - && plane_state->src_rect.width > 3840) + && caps->max_video_width != 0 + && plane_state->src_rect.width > caps->max_video_width) return DC_FAIL_SURFACE_VALIDATE; return DC_OK; @@ -1222,6 +1223,7 @@ static bool construct( /* max pipe num for ASIC before check pipe fuses */ pool->base.pipe_count = pool->base.res_cap->num_timing_generator; + dc->caps.max_video_width = 3840; dc->caps.max_downscale_ratio = 200; dc->caps.i2c_speed_in_khz = 100; dc->caps.max_cursor_size = 256; diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_types.h b/drivers/gpu/drm/amd/display/dc/inc/core_types.h index 5230dddc86171..118122d12e2b2 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h +++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h @@ -111,7 +111,7 @@ struct resource_funcs { const struct resource_pool *pool, struct dc_stream_state *stream); - enum dc_status (*validate_plane)(const struct dc_plane_state *plane_state); + enum dc_status (*validate_plane)(const struct dc_plane_state *plane_state, struct dc_caps *caps); enum dc_status (*add_stream_to_ctx)( struct dc *dc, From d050f8ed14494ea23c6e10b5893010946ef0f78b Mon Sep 17 00:00:00 2001 From: Hersen Wu Date: Fri, 29 Sep 2017 16:36:34 -0400 Subject: [PATCH 083/155] drm/amd/display: add dpms state to DC - avoid eDP screen flash 4 times when resume from s3 - improve s3 and boot time Signed-off-by: Hersen Wu Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc.c | 39 ++++++++++++++++++- drivers/gpu/drm/amd/display/dc/core/dc_link.c | 4 ++ drivers/gpu/drm/amd/display/dc/dc.h | 5 +++ .../display/dc/dce110/dce110_hw_sequencer.c | 13 +++---- .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 11 +++--- 5 files changed, 58 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 09bab93815a3c..d963de753e631 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -332,7 +332,16 @@ static void set_dither_option(struct dc_stream_state *stream, { struct bit_depth_reduction_params params; struct dc_link *link = stream->status.link; - struct pipe_ctx *pipes = link->dc->current_state->res_ctx.pipe_ctx; + struct pipe_ctx *pipes; + int i; + + for (i = 0; i < MAX_PIPES; i++) { + if (link->dc->current_state->res_ctx.pipe_ctx[i].stream == + stream) { + pipes = &link->dc->current_state->res_ctx.pipe_ctx[i]; + break; + } + } memset(¶ms, 0, sizeof(params)); if (!stream) @@ -349,6 +358,31 @@ static void set_dither_option(struct dc_stream_state *stream, opp_program_bit_depth_reduction(pipes->stream_res.opp, ¶ms); } +void set_dpms( + struct dc *dc, + struct dc_stream_state *stream, + bool dpms_off) +{ + struct pipe_ctx *pipe_ctx; + int i; + + for (i = 0; i < MAX_PIPES; i++) { + if (dc->current_state->res_ctx.pipe_ctx[i].stream == stream) { + pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i]; + break; + } + } + + if (stream->dpms_off != dpms_off) { + stream->dpms_off = dpms_off; + if (dpms_off) + core_link_disable_stream(pipe_ctx, + KEEP_ACQUIRED_RESOURCE); + else + core_link_enable_stream(dc->current_state, pipe_ctx); + } +} + static void allocate_dc_stream_funcs(struct dc *dc) { if (dc->hwss.set_drr != NULL) { @@ -371,6 +405,9 @@ static void allocate_dc_stream_funcs(struct dc *dc) dc->stream_funcs.set_dither_option = set_dither_option; + dc->stream_funcs.set_dpms = + set_dpms; + dc->link_funcs.set_drive_settings = set_drive_settings; 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 2d59f77fa9a27..72e56fbe4a427 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c @@ -2321,6 +2321,10 @@ void core_link_enable_stream( if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) allocate_mst_payload(pipe_ctx); + + if (dc_is_dp_signal(pipe_ctx->stream->signal)) + core_dc->hwss.unblank_stream(pipe_ctx, + &pipe_ctx->stream->sink->link->cur_link_settings); } void core_link_disable_stream(struct pipe_ctx *pipe_ctx, int option) diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 5a378cc5daafc..7a5e53ffac2e8 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -133,6 +133,10 @@ struct dc_stream_state_funcs { void (*set_dither_option)(struct dc_stream_state *stream, enum dc_dither_option option); + + void (*set_dpms)(struct dc *dc, + struct dc_stream_state *stream, + bool dpms_off); }; struct link_training_settings; @@ -566,6 +570,7 @@ struct dc_stream_state { int phy_pix_clk; enum signal_type signal; + bool dpms_off; struct dc_stream_status status; diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c index 453d2ffd5c4a0..81ebf2b9c71dc 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c @@ -1364,12 +1364,8 @@ static enum dc_status apply_single_controller_ctx_to_hw( resource_build_info_frame(pipe_ctx); dce110_update_info_frame(pipe_ctx); if (!pipe_ctx_old->stream) { - core_link_enable_stream(context, pipe_ctx); - - - if (dc_is_dp_signal(pipe_ctx->stream->signal)) - dce110_unblank_stream(pipe_ctx, - &stream->sink->link->cur_link_settings); + if (!pipe_ctx->stream->dpms_off) + core_link_enable_stream(context, pipe_ctx); } pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != 0; @@ -1879,7 +1875,10 @@ static void dce110_reset_hw_ctx_wrap( pipe_need_reprogram(pipe_ctx_old, pipe_ctx)) { struct clock_source *old_clk = pipe_ctx_old->clock_source; - core_link_disable_stream(pipe_ctx_old, FREE_ACQUIRED_RESOURCE); + /* disable already, no need to disable again */ + if (!pipe_ctx->stream->dpms_off) + core_link_disable_stream(pipe_ctx_old, FREE_ACQUIRED_RESOURCE); + pipe_ctx_old->stream_res.tg->funcs->set_blank(pipe_ctx_old->stream_res.tg, true); if (!hwss_wait_for_blank_complete(pipe_ctx_old->stream_res.tg)) { dm_error("DC: failed to blank crtc!\n"); diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index 012ba7c9ca8de..494f833208f92 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -1037,12 +1037,11 @@ static void reset_back_end_for_pipe( return; } - /* TODOFPGA break core_link_disable_stream into 2 functions: - * disable_stream and disable_link. disable_link will disable PHYPLL - * which is used by otg. Move disable_link after disable_crtc - */ - if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) - core_link_disable_stream(pipe_ctx, FREE_ACQUIRED_RESOURCE); + if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) { + /* DPMS may already disable */ + if (!pipe_ctx->stream->dpms_off) + core_link_disable_stream(pipe_ctx, FREE_ACQUIRED_RESOURCE); + } /* by upper caller loop, parent pipe: pipe0, will be reset last. * back end share by all pipes and will be disable only when disable From 067c878a220cbe6198b3cfdc7f372adab4762ad8 Mon Sep 17 00:00:00 2001 From: Yongqiang Sun Date: Tue, 3 Oct 2017 15:03:49 -0400 Subject: [PATCH 084/155] drm/amd/display: Fixed switching mode half screen gamma incorrect. Half screen gamma setting and cursor are incorrect when switching mode through win+p due to wrong programming gamma sequence (In case of bottom pipe, gamma and cursor are programmed before front end programmed, pipe is power gated). change: 1. Cache curor attributes to stream 2. Move set gamma and cursor inside front end programming. Signed-off-by: Yongqiang Sun Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc.c | 15 --------------- drivers/gpu/drm/amd/display/dc/core/dc_stream.c | 9 ++++++++- drivers/gpu/drm/amd/display/dc/dc.h | 4 +++- .../amd/display/dc/dce110/dce110_hw_sequencer.c | 10 ++++++++++ .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 17 +++++++++++++++++ 5 files changed, 38 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index d963de753e631..92fab09843e49 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -1269,10 +1269,6 @@ static void commit_planes_for_stream(struct dc *dc, /* Full fe update*/ for (j = 0; j < dc->res_pool->pipe_count; j++) { struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j]; - struct pipe_ctx *cur_pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[j]; - bool is_new_pipe_surface = cur_pipe_ctx->plane_state != pipe_ctx->plane_state; - struct dc_cursor_position position = { 0 }; - if (update_type != UPDATE_TYPE_FULL || !pipe_ctx->plane_state) continue; @@ -1283,17 +1279,6 @@ static void commit_planes_for_stream(struct dc *dc, dc->hwss.apply_ctx_for_surface( dc, pipe_ctx->stream, stream_status->plane_count, context); } - - /* TODO: this is a hack w/a for switching from mpo to pipe split */ - dc_stream_set_cursor_position(pipe_ctx->stream, &position); - - if (is_new_pipe_surface) { - dc->hwss.update_plane_addr(dc, pipe_ctx); - dc->hwss.set_input_transfer_func( - pipe_ctx, pipe_ctx->plane_state); - dc->hwss.set_output_transfer_func( - pipe_ctx, pipe_ctx->stream); - } } if (update_type > UPDATE_TYPE_FAST) 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 c19b478bcdc77..3dd44bef56eba 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c @@ -173,7 +173,7 @@ struct dc_stream_status *dc_stream_get_status( * Update the cursor attributes and set cursor surface address */ bool dc_stream_set_cursor_attributes( - const struct dc_stream_state *stream, + struct dc_stream_state *stream, const struct dc_cursor_attributes *attributes) { int i; @@ -189,6 +189,11 @@ bool dc_stream_set_cursor_attributes( return false; } + if (attributes->address.quad_part == 0) { + dm_error("DC: Cursor address is 0!\n"); + return false; + } + core_dc = stream->ctx->dc; res_ctx = &core_dc->current_state->res_ctx; @@ -214,6 +219,8 @@ bool dc_stream_set_cursor_attributes( pipe_ctx->plane_res.xfm, attributes); } + stream->cursor_attributes = *attributes; + return true; } diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 7a5e53ffac2e8..c832d5abbbdf1 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -574,6 +574,8 @@ struct dc_stream_state { struct dc_stream_status status; + struct dc_cursor_attributes cursor_attributes; + /* from stream struct */ struct kref refcount; }; @@ -1013,7 +1015,7 @@ struct dc_sink *dc_sink_create(const struct dc_sink_init_data *init_params); ******************************************************************************/ /* TODO: Deprecated once we switch to dc_set_cursor_position */ bool dc_stream_set_cursor_attributes( - const struct dc_stream_state *stream, + struct dc_stream_state *stream, const struct dc_cursor_attributes *attributes); bool dc_stream_set_cursor_position( diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c index 81ebf2b9c71dc..bf73182464018 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c @@ -2725,6 +2725,8 @@ static void dce110_program_front_end_for_pipe( struct dc_plane_state *plane_state = pipe_ctx->plane_state; struct xfm_grph_csc_adjustment adjust; struct out_csc_color_matrix tbl_entry; + struct pipe_ctx *cur_pipe_ctx = + &dc->current_state->res_ctx.pipe_ctx[pipe_ctx->pipe_idx]; unsigned int i; memset(&tbl_entry, 0, sizeof(tbl_entry)); @@ -2815,6 +2817,14 @@ static void dce110_program_front_end_for_pipe( &plane_state->tiling_info, plane_state->rotation); + /* Moved programming gamma from dc to hwss */ + if (cur_pipe_ctx->plane_state != pipe_ctx->plane_state) { + dc->hwss.set_input_transfer_func( + pipe_ctx, pipe_ctx->plane_state); + dc->hwss.set_output_transfer_func( + pipe_ctx, pipe_ctx->stream); + } + dm_logger_write(dc->ctx->logger, LOG_SURFACE, "Pipe:%d 0x%x: addr hi:0x%x, " "addr low:0x%x, " diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index 494f833208f92..ee63155c18958 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -2408,6 +2408,10 @@ static void program_all_pipe_in_tree( } if (pipe_ctx->plane_state != NULL) { + struct dc_cursor_position position = { 0 }; + struct pipe_ctx *cur_pipe_ctx = + &dc->current_state->res_ctx.pipe_ctx[pipe_ctx->pipe_idx]; + dcn10_power_on_fe(dc, pipe_ctx, context); /* temporary dcn1 wa: @@ -2422,6 +2426,19 @@ static void program_all_pipe_in_tree( toggle_watermark_change_req(dc->hwseq); update_dchubp_dpp(dc, pipe_ctx, context); + + /* TODO: this is a hack w/a for switching from mpo to pipe split */ + dc_stream_set_cursor_position(pipe_ctx->stream, &position); + + dc_stream_set_cursor_attributes(pipe_ctx->stream, + &pipe_ctx->stream->cursor_attributes); + + if (cur_pipe_ctx->plane_state != pipe_ctx->plane_state) { + dc->hwss.set_input_transfer_func( + pipe_ctx, pipe_ctx->plane_state); + dc->hwss.set_output_transfer_func( + pipe_ctx, pipe_ctx->stream); + } } if (dc->debug.sanity_checks) { From c196cbe065da1c9b5f7683af9cdd0889760151c1 Mon Sep 17 00:00:00 2001 From: Hersen Wu Date: Tue, 3 Oct 2017 16:47:02 -0400 Subject: [PATCH 085/155] drm/amd/display: add dpms state to DC follow up Signed-off-by: Hersen Wu Reviewed-by: Tony Cheng Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 92fab09843e49..4cdb855ef8558 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -332,7 +332,7 @@ static void set_dither_option(struct dc_stream_state *stream, { struct bit_depth_reduction_params params; struct dc_link *link = stream->status.link; - struct pipe_ctx *pipes; + struct pipe_ctx *pipes = NULL; int i; for (i = 0; i < MAX_PIPES; i++) { @@ -344,7 +344,7 @@ static void set_dither_option(struct dc_stream_state *stream, } memset(¶ms, 0, sizeof(params)); - if (!stream) + if (!pipes) return; if (option > DITHER_OPTION_MAX) return; From 8459f633b65a81979b9b233ed0a91a9fdc98b7bd Mon Sep 17 00:00:00 2001 From: Eric Yang Date: Tue, 3 Oct 2017 18:15:51 -0400 Subject: [PATCH 086/155] drm/amd/display: Handle case when stream not found in set_dpms When validate with context fail to add stream to the context, we have a case where set_dpms won't be able to find the stream that need to be disabled. Signed-off-by: Eric Yang Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 4cdb855ef8558..fe66c6a21bc3f 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -363,7 +363,7 @@ void set_dpms( struct dc_stream_state *stream, bool dpms_off) { - struct pipe_ctx *pipe_ctx; + struct pipe_ctx *pipe_ctx = NULL; int i; for (i = 0; i < MAX_PIPES; i++) { @@ -373,6 +373,11 @@ void set_dpms( } } + if (!pipe_ctx) { + ASSERT(0); + return; + } + if (stream->dpms_off != dpms_off) { stream->dpms_off = dpms_off; if (dpms_off) From 410d0b39e2247778db5ead9d40330837fecb7a43 Mon Sep 17 00:00:00 2001 From: Harry Wentland Date: Mon, 2 Oct 2017 15:27:26 -0400 Subject: [PATCH 087/155] drm/amd/display: Ignore wrong tautological warning Some of our HW calcs functions compares a var against itself to check for NaN. Gcc isn't fond of it and wrongfully warns about a tautological comparison. Disable this check for dcn_calcs_math.c. Signed-off-by: Harry Wentland Reviewed-by: Dmytro Laktyushkin Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/calcs/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/calcs/Makefile b/drivers/gpu/drm/amd/display/dc/calcs/Makefile index a095472bf4b53..41ef35995b029 100644 --- a/drivers/gpu/drm/amd/display/dc/calcs/Makefile +++ b/drivers/gpu/drm/amd/display/dc/calcs/Makefile @@ -5,7 +5,7 @@ CFLAGS_dcn_calcs.o := -mhard-float -msse -mpreferred-stack-boundary=4 CFLAGS_dcn_calc_auto.o := -mhard-float -msse -mpreferred-stack-boundary=4 -CFLAGS_dcn_calc_math.o := -mhard-float -msse -mpreferred-stack-boundary=4 +CFLAGS_dcn_calc_math.o := -mhard-float -msse -mpreferred-stack-boundary=4 -Wno-tautological-compare BW_CALCS = dce_calcs.o bw_fixed.o custom_float.o From 4e9ba34f7bd54bcf4bf97ecfdd18fa60c152978c Mon Sep 17 00:00:00 2001 From: Tony Cheng Date: Tue, 3 Oct 2017 18:19:01 -0400 Subject: [PATCH 088/155] drm/amd/display: dal 3.1.04 Signed-off-by: Tony Cheng Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index c832d5abbbdf1..8fa9ef1167fad 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -38,7 +38,7 @@ #include "inc/compressor.h" #include "dml/display_mode_lib.h" -#define DC_VER "3.1.03" +#define DC_VER "3.1.04" #define MAX_SURFACES 3 #define MAX_STREAMS 6 From 0c63c115f254c1024d0679de859283ae48d2cf1b Mon Sep 17 00:00:00 2001 From: Eric Bernstein Date: Wed, 4 Oct 2017 16:56:27 -0400 Subject: [PATCH 089/155] drm/amd/display: group DCN watermark registers Signed-off-by: Eric Bernstein Reviewed-by: Charlene Liu Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/dce/dce_hwseq.h | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h index 9a04b8758888d..52506155e3612 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h @@ -163,23 +163,15 @@ SR(REFCLK_CNTL), \ SR(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A),\ SR(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_A),\ - SR(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A),\ - SR(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A),\ SR(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A),\ SR(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B),\ SR(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_B),\ - SR(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B),\ - SR(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B),\ SR(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B),\ SR(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C),\ SR(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_C),\ - SR(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C),\ - SR(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C),\ SR(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C),\ SR(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D),\ SR(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_D),\ - SR(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D),\ - SR(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D),\ SR(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D),\ SR(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL),\ SR(DCHUBBUB_ARB_DRAM_STATE_CNTL),\ @@ -207,8 +199,19 @@ MMHUB_SR(MC_VM_SYSTEM_APERTURE_LOW_ADDR),\ MMHUB_SR(MC_VM_SYSTEM_APERTURE_HIGH_ADDR) +#define HWSEQ_SR_WATERMARK_REG_LIST()\ + SR(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A),\ + SR(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A),\ + SR(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B),\ + SR(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B),\ + SR(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C),\ + SR(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C),\ + SR(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D),\ + SR(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D) + #define HWSEQ_DCN1_REG_LIST()\ HWSEQ_DCN_REG_LIST(), \ + HWSEQ_SR_WATERMARK_REG_LIST(), \ HWSEQ_PIXEL_RATE_REG_LIST(OTG), \ HWSEQ_PHYPLL_REG_LIST(OTG), \ SR(DCHUBBUB_SDPIF_FB_TOP),\ From 8feabd03d34e4555c119e69269dae28f52e0d86c Mon Sep 17 00:00:00 2001 From: Yue Hin Lau Date: Mon, 2 Oct 2017 14:39:42 -0400 Subject: [PATCH 090/155] drm/amd/display: rename struct mem_input to hubp for dcn Signed-off-by: Yue Hin Lau Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/calcs/dcn_calcs.c | 1 + drivers/gpu/drm/amd/display/dc/core/dc.c | 1 + .../gpu/drm/amd/display/dc/core/dc_resource.c | 3 +- .../gpu/drm/amd/display/dc/core/dc_stream.c | 22 ++- .../drm/amd/display/dc/dce/dce_mem_input.c | 3 - .../display/dc/dce110/dce110_hw_sequencer.c | 19 ++- .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 88 +++++----- .../amd/display/dc/dcn10/dcn10_mem_input.c | 157 ++++++++---------- .../amd/display/dc/dcn10/dcn10_mem_input.h | 49 +++--- .../drm/amd/display/dc/dcn10/dcn10_resource.c | 26 +-- .../gpu/drm/amd/display/dc/inc/core_types.h | 4 +- drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h | 105 ++++++++++++ .../gpu/drm/amd/display/dc/inc/hw/mem_input.h | 3 - 13 files changed, 286 insertions(+), 195 deletions(-) create mode 100644 drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c index fd1db8dc2f352..c37f130b0170a 100644 --- a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c +++ b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c @@ -485,6 +485,7 @@ static void split_stream_across_pipes( secondary_pipe->pipe_idx = pipe_idx; secondary_pipe->plane_res.mi = pool->mis[secondary_pipe->pipe_idx]; + secondary_pipe->plane_res.hubp = pool->hubps[secondary_pipe->pipe_idx]; secondary_pipe->plane_res.ipp = pool->ipps[secondary_pipe->pipe_idx]; secondary_pipe->plane_res.xfm = pool->transforms[secondary_pipe->pipe_idx]; if (primary_pipe->bottom_pipe) { diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index fe66c6a21bc3f..4df5bf750257a 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -47,6 +47,7 @@ #include "dc_link_ddc.h" #include "dm_helpers.h" #include "mem_input.h" +#include "hubp.h" /******************************************************************************* 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 7d750369b78b5..4fb4f0068f1b4 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -1024,7 +1024,7 @@ static int acquire_first_split_pipe( memset(pipe_ctx, 0, sizeof(*pipe_ctx)); pipe_ctx->stream_res.tg = pool->timing_generators[i]; - pipe_ctx->plane_res.mi = pool->mis[i]; + pipe_ctx->plane_res.hubp = pool->hubps[i]; pipe_ctx->plane_res.ipp = pool->ipps[i]; pipe_ctx->plane_res.xfm = pool->transforms[i]; pipe_ctx->stream_res.opp = pool->opps[i]; @@ -1359,6 +1359,7 @@ static int acquire_first_free_pipe( pipe_ctx->stream_res.tg = pool->timing_generators[i]; pipe_ctx->plane_res.mi = pool->mis[i]; + pipe_ctx->plane_res.hubp = pool->hubps[i]; pipe_ctx->plane_res.ipp = pool->ipps[i]; pipe_ctx->plane_res.xfm = pool->transforms[i]; pipe_ctx->stream_res.opp = pool->opps[i]; 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 3dd44bef56eba..411678736ed4b 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c @@ -200,7 +200,7 @@ bool dc_stream_set_cursor_attributes( for (i = 0; i < MAX_PIPES; i++) { struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i]; - if (pipe_ctx->stream != stream || !pipe_ctx->plane_res.mi || !pipe_ctx->plane_res.xfm) + if (pipe_ctx->stream != stream || !pipe_ctx->plane_res.xfm) continue; if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state) continue; @@ -210,10 +210,15 @@ bool dc_stream_set_cursor_attributes( pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes( pipe_ctx->plane_res.ipp, attributes); - if (pipe_ctx->plane_res.mi->funcs->set_cursor_attributes != NULL) + if (pipe_ctx->plane_res.hubp != NULL) + pipe_ctx->plane_res.hubp->funcs->set_cursor_attributes( + pipe_ctx->plane_res.hubp, attributes); + + if (pipe_ctx->plane_res.mi != NULL) pipe_ctx->plane_res.mi->funcs->set_cursor_attributes( pipe_ctx->plane_res.mi, attributes); + if (pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes != NULL) pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes( pipe_ctx->plane_res.xfm, attributes); @@ -248,7 +253,7 @@ bool dc_stream_set_cursor_position( for (i = 0; i < MAX_PIPES; i++) { struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i]; struct input_pixel_processor *ipp = pipe_ctx->plane_res.ipp; - struct mem_input *mi = pipe_ctx->plane_res.mi; + struct hubp *hubp = pipe_ctx->plane_res.hubp; struct transform *xfm = pipe_ctx->plane_res.xfm; struct dc_cursor_position pos_cpy = *position; struct dc_cursor_mi_param param = { @@ -260,7 +265,7 @@ bool dc_stream_set_cursor_position( }; if (pipe_ctx->stream != stream || - !pipe_ctx->plane_res.mi || + (!pipe_ctx->plane_res.mi && !pipe_ctx->plane_res.hubp) || !pipe_ctx->plane_state || !pipe_ctx->plane_res.xfm) continue; @@ -276,11 +281,12 @@ bool dc_stream_set_cursor_position( if (ipp->funcs->ipp_cursor_set_position != NULL) ipp->funcs->ipp_cursor_set_position(ipp, &pos_cpy, ¶m); - if (mi->funcs->set_cursor_attributes != NULL) - mi->funcs->set_cursor_position(mi, &pos_cpy, ¶m); + if (hubp != NULL) + hubp->funcs->set_cursor_position(hubp, &pos_cpy, ¶m); + + if (xfm != NULL) + xfm->funcs->set_cursor_position(xfm, &pos_cpy, ¶m, hubp->curs_attr.width); - if (xfm->funcs->set_cursor_attributes != NULL) - xfm->funcs->set_cursor_position(xfm, &pos_cpy, ¶m, mi->curs_attr.width); } return true; diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c b/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c index 83d9caa4f4388..ed301c3b27367 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c @@ -685,9 +685,6 @@ void dce_mem_input_construct( dce_mi->regs = regs; dce_mi->shifts = mi_shift; dce_mi->masks = mi_mask; - - dce_mi->base.mpcc_id = 0xf; - dce_mi->base.opp_id = 0xf; } void dce112_mem_input_construct( diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c index bf73182464018..867a0eb9f2e06 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c @@ -1378,15 +1378,14 @@ static enum dc_status apply_single_controller_ctx_to_hw( } /* mst support - use total stream count */ -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) - if (pipe_ctx->plane_res.mi->funcs->allocate_mem_input != NULL) -#endif + if (pipe_ctx->plane_res.mi != NULL) { pipe_ctx->plane_res.mi->funcs->allocate_mem_input( - pipe_ctx->plane_res.mi, - stream->timing.h_total, - stream->timing.v_total, - stream->timing.pix_clk_khz, - context->stream_count); + pipe_ctx->plane_res.mi, + stream->timing.h_total, + stream->timing.v_total, + stream->timing.pix_clk_khz, + context->stream_count); + } pipe_ctx->stream->sink->link->psr_enabled = false; @@ -1556,7 +1555,7 @@ static void set_safe_displaymarks( SAFE_NBP_MARK, SAFE_NBP_MARK, SAFE_NBP_MARK, SAFE_NBP_MARK }; for (i = 0; i < MAX_PIPES; i++) { - if (res_ctx->pipe_ctx[i].stream == NULL) + if (res_ctx->pipe_ctx[i].stream == NULL || res_ctx->pipe_ctx[i].plane_res.mi == NULL) continue; res_ctx->pipe_ctx[i].plane_res.mi->funcs->mem_input_program_display_marks( @@ -1565,6 +1564,7 @@ static void set_safe_displaymarks( max_marks, max_marks, MAX_WATERMARK); + if (i == underlay_idx) res_ctx->pipe_ctx[i].plane_res.mi->funcs->mem_input_program_chroma_display_marks( res_ctx->pipe_ctx[i].plane_res.mi, @@ -1572,6 +1572,7 @@ static void set_safe_displaymarks( max_marks, max_marks, MAX_WATERMARK); + } } diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index ee63155c18958..c34dbcd1fba41 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -172,10 +172,10 @@ static void dcn10_log_hw_state(struct dc *dc) "min_ttu_vblank \t qos_low_wm \t qos_high_wm \n"); for (i = 0; i < pool->pipe_count; i++) { - struct mem_input *mi = pool->mis[i]; + struct hubp *hubp = pool->hubps[i]; struct dcn_hubp_state s; - dcn10_mem_input_read_state(TO_DCN10_MEM_INPUT(mi), &s); + hubp1_read_state(TO_DCN10_HUBP(hubp), &s); DTN_INFO("[%d]:\t %xh \t %xh \t %d \t %d \t " "%xh \t %xh \t %xh \t " @@ -803,7 +803,7 @@ static void power_on_plane( static void undo_DEGVIDCN10_253_wa(struct dc *dc) { struct dce_hwseq *hws = dc->hwseq; - struct mem_input *mi = dc->res_pool->mis[0]; + struct hubp *hubp = dc->res_pool->hubps[0]; int pwr_status = 0; REG_GET(DOMAIN0_PG_STATUS, DOMAIN0_PGFSM_PWR_STATUS, &pwr_status); @@ -811,7 +811,7 @@ static void undo_DEGVIDCN10_253_wa(struct dc *dc) if (pwr_status == 2) return; - mi->funcs->set_blank(mi, true); + hubp->funcs->set_blank(hubp, true); REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1); @@ -824,7 +824,7 @@ static void undo_DEGVIDCN10_253_wa(struct dc *dc) static void apply_DEGVIDCN10_253_wa(struct dc *dc) { struct dce_hwseq *hws = dc->hwseq; - struct mem_input *mi = dc->res_pool->mis[0]; + struct hubp *hubp = dc->res_pool->hubps[0]; if (dc->debug.disable_stutter) return; @@ -836,7 +836,7 @@ static void apply_DEGVIDCN10_253_wa(struct dc *dc) REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 0); - mi->funcs->set_hubp_blank_en(mi, false); + hubp->funcs->set_hubp_blank_en(hubp, false); } static void bios_golden_init(struct dc *dc) @@ -1070,7 +1070,7 @@ static void reset_back_end_for_pipe( static void plane_atomic_disconnect(struct dc *dc, int fe_idx) { - struct mem_input *mi = dc->res_pool->mis[fe_idx]; + struct hubp *hubp = dc->res_pool->hubps[fe_idx]; struct mpc *mpc = dc->res_pool->mpc; int opp_id, z_idx; int mpcc_id = -1; @@ -1094,7 +1094,7 @@ static void plane_atomic_disconnect(struct dc *dc, if (dc->debug.sanity_checks) verify_allow_pstate_change_high(dc->hwseq); - mi->funcs->dcc_control(mi, false, false); + hubp->funcs->dcc_control(hubp, false, false); if (dc->debug.sanity_checks) verify_allow_pstate_change_high(dc->hwseq); @@ -1108,20 +1108,20 @@ static void plane_atomic_disable(struct dc *dc, int fe_idx) { struct dce_hwseq *hws = dc->hwseq; - struct mem_input *mi = dc->res_pool->mis[fe_idx]; + struct hubp *hubp = dc->res_pool->hubps[fe_idx]; struct mpc *mpc = dc->res_pool->mpc; - int opp_id = mi->opp_id; + int opp_id = hubp->opp_id; if (opp_id == 0xf) return; - mpc->funcs->wait_for_idle(mpc, mi->mpcc_id); - dc->res_pool->opps[mi->opp_id]->mpcc_disconnect_pending[mi->mpcc_id] = false; + mpc->funcs->wait_for_idle(mpc, hubp->mpcc_id); + dc->res_pool->opps[hubp->opp_id]->mpcc_disconnect_pending[hubp->mpcc_id] = false; /*dm_logger_write(dc->ctx->logger, LOG_ERROR, "[debug_mpo: atomic disable finished on mpcc %d]\n", fe_idx);*/ - mi->funcs->set_blank(mi, true); + hubp->funcs->set_blank(hubp, true); if (dc->debug.sanity_checks) verify_allow_pstate_change_high(dc->hwseq); @@ -1171,7 +1171,7 @@ static void reset_front_end( { struct dce_hwseq *hws = dc->hwseq; struct timing_generator *tg; - int opp_id = dc->res_pool->mis[fe_idx]->opp_id; + int opp_id = dc->res_pool->hubps[fe_idx]->opp_id; /*Already reset*/ if (opp_id == 0xf) @@ -1353,8 +1353,8 @@ static void dcn10_update_plane_addr(const struct dc *dc, struct pipe_ctx *pipe_c if (plane_state == NULL) return; addr_patched = patch_address_for_sbs_tb_stereo(pipe_ctx, &addr); - pipe_ctx->plane_res.mi->funcs->mem_input_program_surface_flip_and_addr( - pipe_ctx->plane_res.mi, + pipe_ctx->plane_res.hubp->funcs->hubp_program_surface_flip_and_addr( + pipe_ctx->plane_res.hubp, &plane_state->address, plane_state->flip_immediate); plane_state->status.requested_address = plane_state->address; @@ -1759,8 +1759,8 @@ static void dcn10_pipe_control_lock( struct pipe_ctx *pipe, bool lock) { - struct mem_input *mi = NULL; - mi = dc->res_pool->mis[pipe->pipe_idx]; + struct hubp *hubp = NULL; + hubp = dc->res_pool->hubps[pipe->pipe_idx]; /* use TG master update lock to lock everything on the TG * therefore only top pipe need to lock */ @@ -2181,7 +2181,7 @@ static void dcn10_get_surface_visual_confirm_color( } } -static void mmhub_read_vm_system_aperture_settings(struct dcn10_mem_input *mi, +static void mmhub_read_vm_system_aperture_settings(struct dcn10_hubp *hubp1, struct vm_system_aperture_param *apt, struct dce_hwseq *hws) { @@ -2206,7 +2206,7 @@ static void mmhub_read_vm_system_aperture_settings(struct dcn10_mem_input *mi, } /* Temporary read settings, future will get values from kmd directly */ -static void mmhub_read_vm_context0_settings(struct dcn10_mem_input *mi, +static void mmhub_read_vm_context0_settings(struct dcn10_hubp *hubp1, struct vm_context0_param *vm0, struct dce_hwseq *hws) { @@ -2250,22 +2250,22 @@ static void mmhub_read_vm_context0_settings(struct dcn10_mem_input *mi, vm0->pte_base.quad_part -= fb_offset.quad_part; } -static void dcn10_program_pte_vm(struct mem_input *mem_input, +static void dcn10_program_pte_vm(struct hubp *hubp, enum surface_pixel_format format, union dc_tiling_info *tiling_info, enum dc_rotation_angle rotation, struct dce_hwseq *hws) { - struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input); + struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); struct vm_system_aperture_param apt = { {{ 0 } } }; struct vm_context0_param vm0 = { { { 0 } } }; - mmhub_read_vm_system_aperture_settings(mi, &apt, hws); - mmhub_read_vm_context0_settings(mi, &vm0, hws); + mmhub_read_vm_system_aperture_settings(hubp1, &apt, hws); + mmhub_read_vm_context0_settings(hubp1, &vm0, hws); - mem_input->funcs->mem_input_set_vm_system_aperture_settings(mem_input, &apt); - mem_input->funcs->mem_input_set_vm_context0_settings(mem_input, &vm0); + hubp->funcs->hubp_set_vm_system_aperture_settings(hubp, &apt); + hubp->funcs->hubp_set_vm_context0_settings(hubp, &vm0); } static void update_dchubp_dpp( @@ -2274,7 +2274,7 @@ static void update_dchubp_dpp( struct dc_state *context) { struct dce_hwseq *hws = dc->hwseq; - struct mem_input *mi = pipe_ctx->plane_res.mi; + struct hubp *hubp = pipe_ctx->plane_res.hubp; struct transform *xfm = pipe_ctx->plane_res.xfm; struct dc_plane_state *plane_state = pipe_ctx->plane_state; union plane_size size = plane_state->plane_size; @@ -2299,8 +2299,8 @@ static void update_dchubp_dpp( */ REG_UPDATE(DCHUBP_CNTL[pipe_ctx->pipe_idx], HUBP_VTG_SEL, pipe_ctx->stream_res.tg->inst); - mi->funcs->mem_input_setup( - mi, + hubp->funcs->hubp_setup( + hubp, &pipe_ctx->dlg_regs, &pipe_ctx->ttu_regs, &pipe_ctx->rq_regs, @@ -2310,7 +2310,7 @@ static void update_dchubp_dpp( if (dc->config.gpu_vm_support) dcn10_program_pte_vm( - pipe_ctx->plane_res.mi, + pipe_ctx->plane_res.hubp, plane_state->format, &plane_state->tiling_info, plane_state->rotation, @@ -2321,7 +2321,7 @@ static void update_dchubp_dpp( plane_state->format, EXPANSION_MODE_ZERO); - mpcc_cfg.dpp_id = mi->inst; + mpcc_cfg.dpp_id = hubp->inst; mpcc_cfg.opp_id = pipe_ctx->stream_res.opp->inst; mpcc_cfg.tree_cfg = &(pipe_ctx->stream_res.opp->mpc_tree); for (top_pipe = pipe_ctx->top_pipe; top_pipe; top_pipe = top_pipe->top_pipe) @@ -2340,15 +2340,15 @@ static void update_dchubp_dpp( mpcc_cfg.pre_multiplied_alpha = is_rgb_cspace( pipe_ctx->stream->output_color_space) && per_pixel_alpha; - mi->mpcc_id = dc->res_pool->mpc->funcs->add(dc->res_pool->mpc, &mpcc_cfg); - mi->opp_id = mpcc_cfg.opp_id; + hubp->mpcc_id = dc->res_pool->mpc->funcs->add(dc->res_pool->mpc, &mpcc_cfg); + hubp->opp_id = mpcc_cfg.opp_id; pipe_ctx->plane_res.scl_data.lb_params.alpha_en = per_pixel_alpha; pipe_ctx->plane_res.scl_data.lb_params.depth = LB_PIXEL_DEPTH_30BPP; /* scaler configuration */ pipe_ctx->plane_res.xfm->funcs->transform_set_scaler( pipe_ctx->plane_res.xfm, &pipe_ctx->plane_res.scl_data); - mi->funcs->mem_program_viewport(mi, + hubp->funcs->mem_program_viewport(hubp, &pipe_ctx->plane_res.scl_data.viewport, &pipe_ctx->plane_res.scl_data.viewport_c); /*gamut remap*/ @@ -2358,8 +2358,8 @@ static void update_dchubp_dpp( pipe_ctx->stream->output_color_space, pipe_ctx->stream->csc_color_matrix.matrix); - mi->funcs->mem_input_program_surface_config( - mi, + hubp->funcs->hubp_program_surface_config( + hubp, plane_state->format, &plane_state->tiling_info, &size, @@ -2370,7 +2370,7 @@ static void update_dchubp_dpp( dc->hwss.update_plane_addr(dc, pipe_ctx); if (is_pipe_tree_visible(pipe_ctx)) - mi->funcs->set_blank(mi, false); + hubp->funcs->set_blank(hubp, false); } @@ -2550,7 +2550,7 @@ static void dcn10_apply_ctx_for_surface( */ if (pipe_ctx->plane_state && !old_pipe_ctx->plane_state) { - if (pipe_ctx->plane_res.mi->opp_id != 0xf && pipe_ctx->stream_res.tg->inst == be_idx) { + if (pipe_ctx->plane_res.hubp->opp_id != 0xf && pipe_ctx->stream_res.tg->inst == be_idx) { dcn10_power_down_fe(dc, pipe_ctx->pipe_idx); /* * power down fe will unlock when calling reset, need @@ -2577,7 +2577,7 @@ static void dcn10_apply_ctx_for_surface( &(old_pipe_ctx->stream_res.opp->mpc_tree), old_pipe_ctx->stream_res.opp->inst, old_pipe_ctx->pipe_idx); - old_pipe_ctx->stream_res.opp->mpcc_disconnect_pending[old_pipe_ctx->plane_res.mi->mpcc_id] = true; + old_pipe_ctx->stream_res.opp->mpcc_disconnect_pending[old_pipe_ctx->plane_res.hubp->mpcc_id] = true; /*dm_logger_write(dc->ctx->logger, LOG_ERROR, "[debug_mpo: apply_ctx disconnect pending on mpcc %d]\n", @@ -2861,7 +2861,7 @@ static void dcn10_wait_for_mpcc_disconnect( if (pipe_ctx->stream_res.opp->mpcc_disconnect_pending[i]) { res_pool->mpc->funcs->wait_for_idle(res_pool->mpc, i); pipe_ctx->stream_res.opp->mpcc_disconnect_pending[i] = false; - res_pool->mis[i]->funcs->set_blank(res_pool->mis[i], true); + res_pool->hubps[i]->funcs->set_blank(res_pool->hubps[i], true); /*dm_logger_write(dc->ctx->logger, LOG_ERROR, "[debug_mpo: wait_for_mpcc finished waiting on mpcc %d]\n", i);*/ @@ -2892,11 +2892,11 @@ void dcn10_update_pending_status(struct pipe_ctx *pipe_ctx) return; plane_state->status.is_flip_pending = - pipe_ctx->plane_res.mi->funcs->mem_input_is_flip_pending( - pipe_ctx->plane_res.mi); + pipe_ctx->plane_res.hubp->funcs->hubp_is_flip_pending( + pipe_ctx->plane_res.hubp); - plane_state->status.current_address = pipe_ctx->plane_res.mi->current_address; - if (pipe_ctx->plane_res.mi->current_address.type == PLN_ADDR_TYPE_GRPH_STEREO && + plane_state->status.current_address = pipe_ctx->plane_res.hubp->current_address; + if (pipe_ctx->plane_res.hubp->current_address.type == PLN_ADDR_TYPE_GRPH_STEREO && tg->funcs->is_stereo_left_eye) { plane_state->status.is_right_eye = !tg->funcs->is_stereo_left_eye(pipe_ctx->stream_res.tg); diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.c index 2336da54000c5..9ee42d9840fb2 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.c @@ -29,18 +29,18 @@ #include "basics/conversion.h" #define REG(reg)\ - mi->mi_regs->reg + hubp1->mi_regs->reg #define CTX \ - mi->base.ctx + hubp1->base.ctx #undef FN #define FN(reg_name, field_name) \ - mi->mi_shift->field_name, mi->mi_mask->field_name + hubp1->mi_shift->field_name, hubp1->mi_mask->field_name -void hubp1_set_blank(struct mem_input *mem_input, bool blank) +void hubp1_set_blank(struct hubp *hubp, bool blank) { - struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input); + struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); uint32_t blank_en = blank ? 1 : 0; REG_UPDATE_2(DCHUBP_CNTL, @@ -51,24 +51,24 @@ void hubp1_set_blank(struct mem_input *mem_input, bool blank) REG_WAIT(DCHUBP_CNTL, HUBP_NO_OUTSTANDING_REQ, 1, 1, 200); - mem_input->mpcc_id = 0xf; - mem_input->opp_id = 0xf; + hubp->mpcc_id = 0xf; + hubp->opp_id = 0xf; } } -static void hubp1_set_hubp_blank_en(struct mem_input *mem_input, bool blank) +static void hubp1_set_hubp_blank_en(struct hubp *hubp, bool blank) { - struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input); + struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); uint32_t blank_en = blank ? 1 : 0; REG_UPDATE(DCHUBP_CNTL, HUBP_BLANK_EN, blank_en); } -static void hubp1_vready_workaround(struct mem_input *mem_input, +static void hubp1_vready_workaround(struct hubp *hubp, struct _vcs_dpi_display_pipe_dest_params_st *pipe_dest) { uint32_t value = 0; - struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input); + struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); /* set HBUBREQ_DEBUG_DB[12] = 1 */ value = REG_READ(HUBPREQ_DEBUG_DB); @@ -88,7 +88,7 @@ static void hubp1_vready_workaround(struct mem_input *mem_input, } void hubp1_program_tiling( - struct dcn10_mem_input *mi, + struct dcn10_hubp *hubp1, const union dc_tiling_info *info, const enum surface_pixel_format pixel_format) { @@ -108,7 +108,7 @@ void hubp1_program_tiling( } void hubp1_program_size_and_rotation( - struct dcn10_mem_input *mi, + struct dcn10_hubp *hubp1, enum dc_rotation_angle rotation, enum surface_pixel_format format, const union plane_size *plane_size, @@ -170,7 +170,7 @@ void hubp1_program_size_and_rotation( } void hubp1_program_pixel_format( - struct dcn10_mem_input *mi, + struct dcn10_hubp *hubp1, enum surface_pixel_format format) { uint32_t red_bar = 3; @@ -246,11 +246,11 @@ void hubp1_program_pixel_format( } bool hubp1_program_surface_flip_and_addr( - struct mem_input *mem_input, + struct hubp *hubp, const struct dc_plane_address *address, bool flip_immediate) { - struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input); + struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); /* program flip type */ REG_SET(DCSURF_FLIP_CONTROL, 0, @@ -387,20 +387,20 @@ bool hubp1_program_surface_flip_and_addr( break; } - mem_input->request_address = *address; + hubp->request_address = *address; if (flip_immediate) - mem_input->current_address = *address; + hubp->current_address = *address; return true; } -void hubp1_dcc_control(struct mem_input *mem_input, bool enable, +void hubp1_dcc_control(struct hubp *hubp, bool enable, bool independent_64b_blks) { uint32_t dcc_en = enable ? 1 : 0; uint32_t dcc_ind_64b_blk = independent_64b_blks ? 1 : 0; - struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input); + struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); REG_UPDATE_2(DCSURF_SURFACE_CONTROL, PRIMARY_SURFACE_DCC_EN, dcc_en, @@ -408,7 +408,7 @@ void hubp1_dcc_control(struct mem_input *mem_input, bool enable, } void hubp1_program_surface_config( - struct mem_input *mem_input, + struct hubp *hubp, enum surface_pixel_format format, union dc_tiling_info *tiling_info, union plane_size *plane_size, @@ -416,20 +416,20 @@ void hubp1_program_surface_config( struct dc_plane_dcc_param *dcc, bool horizontal_mirror) { - struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input); + struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); - hubp1_dcc_control(mem_input, dcc->enable, dcc->grph.independent_64b_blks); - hubp1_program_tiling(mi, tiling_info, format); + hubp1_dcc_control(hubp, dcc->enable, dcc->grph.independent_64b_blks); + hubp1_program_tiling(hubp1, tiling_info, format); hubp1_program_size_and_rotation( - mi, rotation, format, plane_size, dcc, horizontal_mirror); - hubp1_program_pixel_format(mi, format); + hubp1, rotation, format, plane_size, dcc, horizontal_mirror); + hubp1_program_pixel_format(hubp1, format); } void hubp1_program_requestor( - struct mem_input *mem_input, + struct hubp *hubp, struct _vcs_dpi_display_rq_regs_st *rq_regs) { - struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input); + struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); REG_UPDATE(HUBPRET_CONTROL, DET_BUF_PLANE1_BASE_ADDRESS, rq_regs->plane1_base_address); @@ -460,11 +460,11 @@ void hubp1_program_requestor( void hubp1_program_deadline( - struct mem_input *mem_input, + struct hubp *hubp, struct _vcs_dpi_display_dlg_regs_st *dlg_attr, struct _vcs_dpi_display_ttu_regs_st *ttu_attr) { - struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input); + struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); /* DLG - Per hubp */ REG_SET_2(BLANK_OFFSET_0, 0, @@ -581,7 +581,7 @@ void hubp1_program_deadline( } static void hubp1_setup( - struct mem_input *mem_input, + struct hubp *hubp, struct _vcs_dpi_display_dlg_regs_st *dlg_attr, struct _vcs_dpi_display_ttu_regs_st *ttu_attr, struct _vcs_dpi_display_rq_regs_st *rq_regs, @@ -590,27 +590,15 @@ static void hubp1_setup( /* otg is locked when this func is called. Register are double buffered. * disable the requestors is not needed */ - hubp1_program_requestor(mem_input, rq_regs); - hubp1_program_deadline(mem_input, dlg_attr, ttu_attr); - hubp1_vready_workaround(mem_input, pipe_dest); + hubp1_program_requestor(hubp, rq_regs); + hubp1_program_deadline(hubp, dlg_attr, ttu_attr); + hubp1_vready_workaround(hubp, pipe_dest); } -void hubp1_program_display_marks( - struct mem_input *mem_input, - struct dce_watermarks nbp, - struct dce_watermarks stutter, - struct dce_watermarks urgent, - uint32_t total_dest_line_time_ns) -{ - /* only for dce - * dcn use only program_watermarks - */ -} - -bool hubp1_is_flip_pending(struct mem_input *mem_input) +bool hubp1_is_flip_pending(struct hubp *hubp) { uint32_t flip_pending = 0; - struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input); + struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); struct dc_plane_address earliest_inuse_address; REG_GET(DCSURF_FLIP_CONTROL, @@ -625,20 +613,20 @@ bool hubp1_is_flip_pending(struct mem_input *mem_input) if (flip_pending) return true; - if (earliest_inuse_address.grph.addr.quad_part != mem_input->request_address.grph.addr.quad_part) + if (earliest_inuse_address.grph.addr.quad_part != hubp->request_address.grph.addr.quad_part) return true; - mem_input->current_address = mem_input->request_address; + hubp->current_address = hubp->request_address; return false; } uint32_t aperture_default_system = 1; uint32_t context0_default_system; /* = 0;*/ -static void hubp1_set_vm_system_aperture_settings(struct mem_input *mem_input, +static void hubp1_set_vm_system_aperture_settings(struct hubp *hubp, struct vm_system_aperture_param *apt) { - struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input); + struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); PHYSICAL_ADDRESS_LOC mc_vm_apt_default; PHYSICAL_ADDRESS_LOC mc_vm_apt_low; PHYSICAL_ADDRESS_LOC mc_vm_apt_high; @@ -664,10 +652,10 @@ static void hubp1_set_vm_system_aperture_settings(struct mem_input *mem_input, MC_VM_SYSTEM_APERTURE_HIGH_ADDR_LSB, mc_vm_apt_high.low_part); } -static void hubp1_set_vm_context0_settings(struct mem_input *mem_input, +static void hubp1_set_vm_context0_settings(struct hubp *hubp, const struct vm_context0_param *vm0) { - struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input); + struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); /* pte base */ REG_SET(DCN_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_MSB, 0, VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_MSB, vm0->pte_base.high_part); @@ -700,11 +688,11 @@ static void hubp1_set_vm_context0_settings(struct mem_input *mem_input, } void min_set_viewport( - struct mem_input *mem_input, + struct hubp *hubp, const struct rect *viewport, const struct rect *viewport_c) { - struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input); + struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); REG_SET_2(DCSURF_PRI_VIEWPORT_DIMENSION, 0, PRI_VIEWPORT_WIDTH, viewport->width, @@ -733,7 +721,7 @@ void min_set_viewport( PRI_VIEWPORT_Y_START_C, viewport_c->y); } -void dcn10_mem_input_read_state(struct dcn10_mem_input *mi, +void hubp1_read_state(struct dcn10_hubp *hubp1, struct dcn_hubp_state *s) { REG_GET(DCSURF_SURFACE_CONFIG, @@ -783,7 +771,7 @@ enum cursor_lines_per_chunk { }; static bool ippn10_cursor_program_control( - struct dcn10_mem_input *mi, + struct dcn10_hubp *hubp1, bool pixel_data_invert, enum dc_cursor_color_format color_format) { @@ -849,15 +837,15 @@ static enum cursor_lines_per_chunk ippn10_get_lines_per_chunk( } void hubp1_cursor_set_attributes( - struct mem_input *mem_input, + struct hubp *hubp, const struct dc_cursor_attributes *attr) { - struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input); + struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); enum cursor_pitch hw_pitch = ippn10_get_cursor_pitch(attr->pitch); enum cursor_lines_per_chunk lpc = ippn10_get_lines_per_chunk( attr->width, attr->color_format); - mem_input->curs_attr = *attr; + hubp->curs_attr = *attr; REG_UPDATE(CURSOR_SURFACE_ADDRESS_HIGH, CURSOR_SURFACE_ADDRESS_HIGH, attr->address.high_part); @@ -871,17 +859,17 @@ void hubp1_cursor_set_attributes( CURSOR_MODE, attr->color_format, CURSOR_PITCH, hw_pitch, CURSOR_LINES_PER_CHUNK, lpc); - ippn10_cursor_program_control(mi, + ippn10_cursor_program_control(hubp1, attr->attribute_flags.bits.INVERT_PIXEL_DATA, attr->color_format); } void hubp1_cursor_set_position( - struct mem_input *mem_input, + struct hubp *hubp, const struct dc_cursor_position *pos, const struct dc_cursor_mi_param *param) { - struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input); + struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); int src_x_offset = pos->x - pos->x_hotspot - param->viewport_x_start; uint32_t cur_en = pos->enable ? 1 : 0; uint32_t dst_x_offset = (src_x_offset >= 0) ? src_x_offset : 0; @@ -893,7 +881,7 @@ void hubp1_cursor_set_position( * TODO: Look at combining cursor_set_position() and * cursor_set_attributes() into cursor_update() */ - if (mem_input->curs_attr.address.quad_part == 0) + if (hubp->curs_attr.address.quad_part == 0) return; dst_x_offset *= param->ref_clk_khz; @@ -909,11 +897,11 @@ void hubp1_cursor_set_position( if (src_x_offset >= (int)param->viewport_width) cur_en = 0; /* not visible beyond right edge*/ - if (src_x_offset + (int)mem_input->curs_attr.width < 0) + if (src_x_offset + (int)hubp->curs_attr.width < 0) cur_en = 0; /* not visible beyond left edge*/ if (cur_en && REG_READ(CURSOR_SURFACE_ADDRESS) == 0) - hubp1_cursor_set_attributes(mem_input, &mem_input->curs_attr); + hubp1_cursor_set_attributes(hubp, &hubp->curs_attr); REG_UPDATE(CURSOR_CONTROL, CURSOR_ENABLE, cur_en); @@ -930,16 +918,15 @@ void hubp1_cursor_set_position( /* TODO Handle surface pixel formats other than 4:4:4 */ } -static struct mem_input_funcs dcn10_mem_input_funcs = { - .mem_input_program_display_marks = hubp1_program_display_marks, - .mem_input_program_surface_flip_and_addr = +static struct hubp_funcs dcn10_hubp_funcs = { + .hubp_program_surface_flip_and_addr = hubp1_program_surface_flip_and_addr, - .mem_input_program_surface_config = + .hubp_program_surface_config = hubp1_program_surface_config, - .mem_input_is_flip_pending = hubp1_is_flip_pending, - .mem_input_setup = hubp1_setup, - .mem_input_set_vm_system_aperture_settings = hubp1_set_vm_system_aperture_settings, - .mem_input_set_vm_context0_settings = hubp1_set_vm_context0_settings, + .hubp_is_flip_pending = hubp1_is_flip_pending, + .hubp_setup = hubp1_setup, + .hubp_set_vm_system_aperture_settings = hubp1_set_vm_system_aperture_settings, + .hubp_set_vm_context0_settings = hubp1_set_vm_context0_settings, .set_blank = hubp1_set_blank, .dcc_control = hubp1_dcc_control, .mem_program_viewport = min_set_viewport, @@ -952,22 +939,22 @@ static struct mem_input_funcs dcn10_mem_input_funcs = { /* Constructor, Destructor */ /*****************************************/ -void dcn10_mem_input_construct( - struct dcn10_mem_input *mi, +void dcn10_hubp_construct( + struct dcn10_hubp *hubp1, struct dc_context *ctx, uint32_t inst, const struct dcn_mi_registers *mi_regs, const struct dcn_mi_shift *mi_shift, const struct dcn_mi_mask *mi_mask) { - mi->base.funcs = &dcn10_mem_input_funcs; - mi->base.ctx = ctx; - mi->mi_regs = mi_regs; - mi->mi_shift = mi_shift; - mi->mi_mask = mi_mask; - mi->base.inst = inst; - mi->base.opp_id = 0xf; - mi->base.mpcc_id = 0xf; + hubp1->base.funcs = &dcn10_hubp_funcs; + hubp1->base.ctx = ctx; + hubp1->mi_regs = mi_regs; + hubp1->mi_shift = mi_shift; + hubp1->mi_mask = mi_mask; + hubp1->base.inst = inst; + hubp1->base.opp_id = 0xf; + hubp1->base.mpcc_id = 0xf; } diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.h index 5c5eed5c95d57..66db453c801b9 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.h +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.h @@ -25,10 +25,10 @@ #ifndef __DC_MEM_INPUT_DCN10_H__ #define __DC_MEM_INPUT_DCN10_H__ -#include "mem_input.h" +#include "hubp.h" -#define TO_DCN10_MEM_INPUT(mi)\ - container_of(mi, struct dcn10_mem_input, base) +#define TO_DCN10_HUBP(hubp)\ + container_of(hubp, struct dcn10_hubp, base) #define MI_REG_LIST_DCN(id)\ SRI(DCHUBP_CNTL, HUBP, id),\ @@ -584,15 +584,15 @@ struct dcn_mi_mask { DCN_MI_REG_FIELD_LIST(uint32_t); }; -struct dcn10_mem_input { - struct mem_input base; +struct dcn10_hubp { + struct hubp base; const struct dcn_mi_registers *mi_regs; const struct dcn_mi_shift *mi_shift; const struct dcn_mi_mask *mi_mask; }; void hubp1_program_surface_config( - struct mem_input *mem_input, + struct hubp *hubp, enum surface_pixel_format format, union dc_tiling_info *tiling_info, union plane_size *plane_size, @@ -601,20 +601,20 @@ void hubp1_program_surface_config( bool horizontal_mirror); void hubp1_program_deadline( - struct mem_input *mem_input, + struct hubp *hubp, struct _vcs_dpi_display_dlg_regs_st *dlg_attr, struct _vcs_dpi_display_ttu_regs_st *ttu_attr); void hubp1_program_requestor( - struct mem_input *mem_input, + struct hubp *hubp, struct _vcs_dpi_display_rq_regs_st *rq_regs); void hubp1_program_pixel_format( - struct dcn10_mem_input *mi, + struct dcn10_hubp *hubp, enum surface_pixel_format format); void hubp1_program_size_and_rotation( - struct dcn10_mem_input *mi, + struct dcn10_hubp *hubp, enum dc_rotation_angle rotation, enum surface_pixel_format format, const union plane_size *plane_size, @@ -622,45 +622,38 @@ void hubp1_program_size_and_rotation( bool horizontal_mirror); void hubp1_program_tiling( - struct dcn10_mem_input *mi, + struct dcn10_hubp *hubp, const union dc_tiling_info *info, const enum surface_pixel_format pixel_format); -void hubp1_dcc_control(struct mem_input *mem_input, +void hubp1_dcc_control(struct hubp *hubp, bool enable, bool independent_64b_blks); -void hubp1_program_display_marks( - struct mem_input *mem_input, - struct dce_watermarks nbp, - struct dce_watermarks stutter, - struct dce_watermarks urgent, - uint32_t total_dest_line_time_ns); - bool hubp1_program_surface_flip_and_addr( - struct mem_input *mem_input, + struct hubp *hubp, const struct dc_plane_address *address, bool flip_immediate); -bool hubp1_is_flip_pending(struct mem_input *mem_input); +bool hubp1_is_flip_pending(struct hubp *hubp); void hubp1_cursor_set_attributes( - struct mem_input *mem_input, + struct hubp *hubp, const struct dc_cursor_attributes *attr); void hubp1_cursor_set_position( - struct mem_input *mem_input, + struct hubp *hubp, const struct dc_cursor_position *pos, const struct dc_cursor_mi_param *param); -void hubp1_set_blank(struct mem_input *mem_input, bool blank); +void hubp1_set_blank(struct hubp *hubp, bool blank); -void min_set_viewport(struct mem_input *mem_input, +void min_set_viewport(struct hubp *hubp, const struct rect *viewport, const struct rect *viewport_c); -void dcn10_mem_input_construct( - struct dcn10_mem_input *mi, +void dcn10_hubp_construct( + struct dcn10_hubp *hubp1, struct dc_context *ctx, uint32_t inst, const struct dcn_mi_registers *mi_regs, @@ -684,7 +677,7 @@ struct dcn_hubp_state { uint32_t qos_level_low_wm; uint32_t qos_level_high_wm; }; -void dcn10_mem_input_read_state(struct dcn10_mem_input *mi, +void hubp1_read_state(struct dcn10_hubp *hubp1, struct dcn_hubp_state *s); #endif diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c index 2caad73257e0b..93edbba762e88 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c @@ -704,9 +704,9 @@ static void destruct(struct dcn10_resource_pool *pool) if (pool->base.ipps[i] != NULL) pool->base.ipps[i]->funcs->ipp_destroy(&pool->base.ipps[i]); - if (pool->base.mis[i] != NULL) { - kfree(TO_DCN10_MEM_INPUT(pool->base.mis[i])); - pool->base.mis[i] = NULL; + if (pool->base.hubps[i] != NULL) { + kfree(TO_DCN10_HUBP(pool->base.hubps[i])); + pool->base.hubps[i] = NULL; } if (pool->base.irqs != NULL) { @@ -753,19 +753,19 @@ static void destruct(struct dcn10_resource_pool *pool) kfree(pool->base.pp_smu); } -static struct mem_input *dcn10_mem_input_create( +static struct hubp *dcn10_hubp_create( struct dc_context *ctx, uint32_t inst) { - struct dcn10_mem_input *mem_inputn10 = - kzalloc(sizeof(struct dcn10_mem_input), GFP_KERNEL); + struct dcn10_hubp *hubp1 = + kzalloc(sizeof(struct dcn10_hubp), GFP_KERNEL); - if (!mem_inputn10) + if (!hubp1) return NULL; - dcn10_mem_input_construct(mem_inputn10, ctx, inst, - &mi_regs[inst], &mi_shift, &mi_mask); - return &mem_inputn10->base; + dcn10_hubp_construct(hubp1, ctx, inst, + &mi_regs[inst], &mi_shift, &mi_mask); + return &hubp1->base; } static void get_pixel_clock_parameters( @@ -918,7 +918,7 @@ static struct pipe_ctx *dcn10_acquire_idle_pipe_for_layer( idle_pipe->stream_res.tg = head_pipe->stream_res.tg; idle_pipe->stream_res.opp = head_pipe->stream_res.opp; - idle_pipe->plane_res.mi = pool->mis[idle_pipe->pipe_idx]; + idle_pipe->plane_res.hubp = pool->hubps[idle_pipe->pipe_idx]; idle_pipe->plane_res.ipp = pool->ipps[idle_pipe->pipe_idx]; idle_pipe->plane_res.xfm = pool->transforms[idle_pipe->pipe_idx]; @@ -1357,8 +1357,8 @@ static bool construct( if ((pipe_fuses & (1 << i)) != 0) continue; - pool->base.mis[j] = dcn10_mem_input_create(ctx, i); - if (pool->base.mis[j] == NULL) { + pool->base.hubps[j] = dcn10_hubp_create(ctx, i); + if (pool->base.hubps[j] == NULL) { BREAK_TO_DEBUGGER(); dm_error( "DC: failed to create memory input!\n"); diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_types.h b/drivers/gpu/drm/amd/display/dc/inc/core_types.h index 118122d12e2b2..45518c05e8464 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h +++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h @@ -32,6 +32,7 @@ #include "ddc_service_types.h" #include "dc_bios_types.h" #include "mem_input.h" +#include "hubp.h" #if defined(CONFIG_DRM_AMD_DC_DCN1_0) #include "mpc.h" #endif @@ -129,6 +130,7 @@ struct audio_support{ struct resource_pool { struct mem_input *mis[MAX_PIPES]; + struct hubp *hubps[MAX_PIPES]; struct input_pixel_processor *ipps[MAX_PIPES]; struct transform *transforms[MAX_PIPES]; struct output_pixel_processor *opps[MAX_PIPES]; @@ -178,7 +180,7 @@ struct stream_resource { struct plane_resource { struct scaler_data scl_data; - + struct hubp *hubp; struct mem_input *mi; struct input_pixel_processor *ipp; struct transform *xfm; diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h b/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h new file mode 100644 index 0000000000000..0d186be24cf4f --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h @@ -0,0 +1,105 @@ +/* + * Copyright 2012-15 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: AMD + * + */ + +#ifndef __DAL_HUBP_H__ +#define __DAL_HUBP_H__ + +#include "mem_input.h" + +struct hubp { + struct hubp_funcs *funcs; + struct dc_context *ctx; + struct dc_plane_address request_address; + struct dc_plane_address current_address; + int inst; + int opp_id; + int mpcc_id; + struct dc_cursor_attributes curs_attr; +}; + + +struct hubp_funcs { + void (*hubp_setup)( + struct hubp *hubp, + struct _vcs_dpi_display_dlg_regs_st *dlg_regs, + struct _vcs_dpi_display_ttu_regs_st *ttu_regs, + struct _vcs_dpi_display_rq_regs_st *rq_regs, + struct _vcs_dpi_display_pipe_dest_params_st *pipe_dest); + + void (*dcc_control)(struct hubp *hubp, bool enable, + bool independent_64b_blks); + void (*mem_program_viewport)( + struct hubp *hubp, + const struct rect *viewport, + const struct rect *viewport_c); + + bool (*hubp_program_surface_flip_and_addr)( + struct hubp *hubp, + const struct dc_plane_address *address, + bool flip_immediate); + + void (*hubp_program_pte_vm)( + struct hubp *hubp, + enum surface_pixel_format format, + union dc_tiling_info *tiling_info, + enum dc_rotation_angle rotation); + + void (*hubp_set_vm_system_aperture_settings)( + struct hubp *hubp, + struct vm_system_aperture_param *apt); + + void (*hubp_set_vm_context0_settings)( + struct hubp *hubp, + const struct vm_context0_param *vm0); + + void (*hubp_program_surface_config)( + struct hubp *hubp, + enum surface_pixel_format format, + union dc_tiling_info *tiling_info, + union plane_size *plane_size, + enum dc_rotation_angle rotation, + struct dc_plane_dcc_param *dcc, + bool horizontal_mirror); + + bool (*hubp_is_flip_pending)(struct hubp *hubp); + + void (*hubp_update_dchub)(struct hubp *hubp, + struct dchub_init_data *dh_data); + + void (*set_blank)(struct hubp *hubp, bool blank); + void (*set_hubp_blank_en)(struct hubp *hubp, bool blank); + + void (*set_cursor_attributes)( + struct hubp *hubp, + const struct dc_cursor_attributes *attr); + + void (*set_cursor_position)( + struct hubp *hubp, + const struct dc_cursor_position *pos, + const struct dc_cursor_mi_param *param); + +}; + +#endif diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/mem_input.h b/drivers/gpu/drm/amd/display/dc/inc/hw/mem_input.h index 5c8e45ba8f45c..3e1e7e6a8792d 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/mem_input.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/mem_input.h @@ -69,10 +69,7 @@ struct mem_input { struct dc_plane_address request_address; struct dc_plane_address current_address; int inst; - int opp_id; - int mpcc_id; struct stutter_modes stutter_mode; - struct dc_cursor_attributes curs_attr; }; struct vm_system_aperture_param { From 81739b7f49bfded3bbd0b29c5213e9bcbea3c58d Mon Sep 17 00:00:00 2001 From: Eric Bernstein Date: Mon, 2 Oct 2017 15:03:50 -0400 Subject: [PATCH 091/155] drm/amd/display: Add DPP capabilities Signed-off-by: Eric Bernstein Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c | 5 ++ .../gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h | 23 +++------- .../drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c | 42 ++++++----------- .../gpu/drm/amd/display/dc/inc/hw/transform.h | 46 +++++++++++++++++++ 4 files changed, 72 insertions(+), 44 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c index 05df3b2229459..fb3c78858ebeb 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c @@ -444,6 +444,10 @@ static const struct transform_funcs dcn10_dpp_funcs = { .set_cursor_position = dcn10_set_cursor_position, }; +static struct dpp_caps dcn10_dpp_cap = { + .dscl_data_proc_format = DSCL_DATA_PRCESSING_FIXED_FORMAT, + .dscl_calc_lb_num_partitions = dscl1_calc_lb_num_partitions, +}; /*****************************************/ /* Constructor, Destructor */ @@ -461,6 +465,7 @@ void dcn10_dpp_construct( xfm->base.inst = inst; xfm->base.funcs = &dcn10_dpp_funcs; + xfm->base.caps = &dcn10_dpp_cap; xfm->tf_regs = tf_regs; xfm->tf_shift = tf_shift; diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h index 153aa3c327629..4cf18a500dcde 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h @@ -1264,23 +1264,6 @@ struct dcn10_dpp { bool is_write_to_ram_a_safe; }; - -enum lb_memory_config { - /* Enable all 3 pieces of memory */ - LB_MEMORY_CONFIG_0 = 0, - - /* Enable only the first piece of memory */ - LB_MEMORY_CONFIG_1 = 1, - - /* Enable only the second piece of memory */ - LB_MEMORY_CONFIG_2 = 2, - - /* Only applicable in 4:2:0 mode, enable all 3 pieces of memory and the - * last piece of chroma memory used for the luma storage - */ - LB_MEMORY_CONFIG_3 = 3 -}; - enum dcn10_input_csc_select { INPUT_CSC_SELECT_BYPASS = 0, INPUT_CSC_SELECT_ICSC, @@ -1292,6 +1275,12 @@ bool is_lb_conf_valid( int num_partitions, int vtaps); +void dscl1_calc_lb_num_partitions( + const struct scaler_data *scl_data, + enum lb_memory_config lb_config, + int *num_part_y, + int *num_part_c); + void ippn10_degamma_ram_select( struct transform *xfm_base, bool use_ram_a); diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c index c5267e42a2f2b..830dbd5d41444 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c @@ -31,6 +31,7 @@ #include "dcn10_dpp.h" #include "basics/conversion.h" + #define NUM_PHASES 64 #define HORZ_MAX_TAPS 8 #define VERT_MAX_TAPS 8 @@ -168,11 +169,10 @@ static enum dscl_mode_sel get_dscl_mode( const struct scaler_data *data, bool dbg_always_scale) { - struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); const long long one = dal_fixed31_32_one.value; - if (xfm->tf_mask->PIXEL_DEPTH) { - /* DSCL caps: LB data is fixed format */ + if (xfm_base->caps->dscl_data_proc_format == DSCL_DATA_PRCESSING_FIXED_FORMAT) { + /* DSCL is processing data in fixed format */ if (data->format == PIXEL_FORMAT_FP16) return DSCL_MODE_DSCL_BYPASS; } @@ -204,8 +204,8 @@ static void dpp_set_lb( enum lb_memory_config mem_size_config) { /* LB */ - if (xfm->tf_mask->PIXEL_DEPTH) { - /* DSCL caps: LB data is fixed format */ + if (xfm->base.caps->dscl_data_proc_format == DSCL_DATA_PRCESSING_FIXED_FORMAT) { + /* DSCL caps: pixel data processed in fixed format */ uint32_t pixel_depth = get_pixel_depth_val(lb_params->depth); uint32_t dyn_pix_depth = lb_params->dynamic_pixel_depth; @@ -400,7 +400,7 @@ static int get_lb_depth_bpc(enum lb_pixel_depth depth) } } -static void dscl1_calc_lb_num_partitions( +void dscl1_calc_lb_num_partitions( const struct scaler_data *scl_data, enum lb_memory_config lb_config, int *num_part_y, @@ -458,7 +458,7 @@ bool is_lb_conf_valid(int ceil_vratio, int num_partitions, int vtaps) } /*find first match configuration which meets the min required lb size*/ -static enum lb_memory_config dpp10_find_lb_memory_config( +static enum lb_memory_config find_lb_memory_config(struct dcn10_dpp *xfm, const struct scaler_data *scl_data) { int num_part_y, num_part_c; @@ -466,15 +466,19 @@ static enum lb_memory_config dpp10_find_lb_memory_config( int vtaps_c = scl_data->taps.v_taps_c; int ceil_vratio = dal_fixed31_32_ceil(scl_data->ratios.vert); int ceil_vratio_c = dal_fixed31_32_ceil(scl_data->ratios.vert_c); + enum lb_memory_config mem_cfg = LB_MEMORY_CONFIG_0; + + if (xfm->base.ctx->dc->debug.use_max_lb) + return mem_cfg; - dscl1_calc_lb_num_partitions( + xfm->base.caps->dscl_calc_lb_num_partitions( scl_data, LB_MEMORY_CONFIG_1, &num_part_y, &num_part_c); if (is_lb_conf_valid(ceil_vratio, num_part_y, vtaps) && is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c)) return LB_MEMORY_CONFIG_1; - dscl1_calc_lb_num_partitions( + xfm->base.caps->dscl_calc_lb_num_partitions( scl_data, LB_MEMORY_CONFIG_2, &num_part_y, &num_part_c); if (is_lb_conf_valid(ceil_vratio, num_part_y, vtaps) @@ -483,7 +487,7 @@ static enum lb_memory_config dpp10_find_lb_memory_config( if (scl_data->format == PIXEL_FORMAT_420BPP8 || scl_data->format == PIXEL_FORMAT_420BPP10) { - dscl1_calc_lb_num_partitions( + xfm->base.caps->dscl_calc_lb_num_partitions( scl_data, LB_MEMORY_CONFIG_3, &num_part_y, &num_part_c); if (is_lb_conf_valid(ceil_vratio, num_part_y, vtaps) @@ -491,7 +495,7 @@ static enum lb_memory_config dpp10_find_lb_memory_config( return LB_MEMORY_CONFIG_3; } - dscl1_calc_lb_num_partitions( + xfm->base.caps->dscl_calc_lb_num_partitions( scl_data, LB_MEMORY_CONFIG_0, &num_part_y, &num_part_c); /*Ensure we can support the requested number of vtaps*/ @@ -501,22 +505,6 @@ static enum lb_memory_config dpp10_find_lb_memory_config( return LB_MEMORY_CONFIG_0; } -/*find first match configuration which meets the min required lb size*/ -static enum lb_memory_config find_lb_memory_config(struct dcn10_dpp *xfm, - const struct scaler_data *scl_data) -{ - enum lb_memory_config mem_cfg = LB_MEMORY_CONFIG_0; - - if (xfm->base.ctx->dc->debug.use_max_lb) - return mem_cfg; - - if (xfm->tf_mask->PIXEL_DEPTH) { - /* DSCL caps: LB data is fixed format */ - mem_cfg = dpp10_find_lb_memory_config(scl_data); - } - return mem_cfg; -} - void dpp_set_scaler_auto_scale( struct transform *xfm_base, const struct scaler_data *scl_data) diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/transform.h b/drivers/gpu/drm/amd/display/dc/inc/hw/transform.h index f95621dfd4d48..7c08bc62c1f53 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/transform.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/transform.h @@ -38,6 +38,7 @@ struct transform { const struct transform_funcs *funcs; struct dc_context *ctx; int inst; + struct dpp_caps *caps; struct pwl_params regamma_params; }; @@ -109,6 +110,22 @@ enum graphics_gamut_adjust_type { GRAPHICS_GAMUT_ADJUST_TYPE_SW /* use adjustments */ }; +enum lb_memory_config { + /* Enable all 3 pieces of memory */ + LB_MEMORY_CONFIG_0 = 0, + + /* Enable only the first piece of memory */ + LB_MEMORY_CONFIG_1 = 1, + + /* Enable only the second piece of memory */ + LB_MEMORY_CONFIG_2 = 2, + + /* Only applicable in 4:2:0 mode, enable all 3 pieces of memory and the + * last piece of chroma memory used for the luma storage + */ + LB_MEMORY_CONFIG_3 = 3 +}; + struct xfm_grph_csc_adjustment { struct fixed31_32 temperature_matrix[CSC_TEMPERATURE_MATRIX_SIZE]; enum graphics_gamut_adjust_type gamut_adjust_type; @@ -262,4 +279,33 @@ const uint16_t *get_filter_6tap_64p(struct fixed31_32 ratio); const uint16_t *get_filter_7tap_64p(struct fixed31_32 ratio); const uint16_t *get_filter_8tap_64p(struct fixed31_32 ratio); + +/* Defines the pixel processing capability of the DSCL */ +enum dscl_data_processing_format { + DSCL_DATA_PRCESSING_FIXED_FORMAT, /* The DSCL processes pixel data in fixed format */ + DSCL_DATA_PRCESSING_FLOAT_FORMAT, /* The DSCL processes pixel data in float format */ +}; + +/* + * The DPP capabilities structure contains enumerations to specify the + * HW processing features and an associated function pointers to + * provide the function interface that can be overloaded for implementations + * based on different capabilities + */ +struct dpp_caps { + /* DSCL processing pixel data in fixed or float format */ + enum dscl_data_processing_format dscl_data_proc_format; + + /* Calculates the number of partitions in the line buffer. + * The implementation of this function is overloaded for + * different versions of DSCL LB. + */ + void (*dscl_calc_lb_num_partitions)( + const struct scaler_data *scl_data, + enum lb_memory_config lb_config, + int *num_part_y, + int *num_part_c); +}; + + #endif From e66a575508b5a11df7a670265c91981e4d735749 Mon Sep 17 00:00:00 2001 From: Andrew Jiang Date: Wed, 4 Oct 2017 14:10:16 -0400 Subject: [PATCH 092/155] drm/amd/display: Add missing newlines in pstate wait debug messages These were spamming the debugger logs. Signed-off-by: Andrew Jiang Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index c34dbcd1fba41..059da7882a68a 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -302,7 +302,7 @@ static void verify_allow_pstate_change_high( if (i > pstate_wait_expected_timeout_us) dm_logger_write(hws->ctx->logger, LOG_WARNING, - "pstate took longer than expected ~%dus", + "pstate took longer than expected ~%dus\n", i); return; @@ -326,7 +326,7 @@ static void verify_allow_pstate_change_high( } dm_logger_write(hws->ctx->logger, LOG_WARNING, - "pstate TEST_DEBUG_DATA: 0x%X", + "pstate TEST_DEBUG_DATA: 0x%X\n", debug_data); BREAK_TO_DEBUGGER(); } From abb4986eea1670922a0b89ef62688b4b649bd3c6 Mon Sep 17 00:00:00 2001 From: Andrew Jiang Date: Wed, 4 Oct 2017 15:55:45 -0400 Subject: [PATCH 093/155] drm/amd/display: Fix up plane_states add/remove logic Our plane_states array trimming logic was faulty, we should be starting to shuffle from the plane that was just released, not from the very beginning of the array. Also get rid of a leftover line that was setting the plane state at the stream index to null, leading to issues. Also move the dc_plane_state_retain call to where we reference plane_state, in case we do hit the error case where we can't get a free pipe. Signed-off-by: Andrew Jiang Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) 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 4fb4f0068f1b4..c80bde94472f3 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -1073,9 +1073,6 @@ bool dc_add_plane_to_context( return false; } - /* retain new surfaces */ - dc_plane_state_retain(plane_state); - free_pipe = acquire_free_pipe_for_stream(context, pool, stream); #if defined(CONFIG_DRM_AMD_DC_DCN1_0) @@ -1085,11 +1082,11 @@ bool dc_add_plane_to_context( free_pipe = &context->res_ctx.pipe_ctx[pipe_idx]; } #endif - if (!free_pipe) { - stream_status->plane_states[i] = NULL; + if (!free_pipe) return false; - } + /* retain new surfaces */ + dc_plane_state_retain(plane_state); free_pipe->plane_state = plane_state; if (head_pipe != free_pipe) { @@ -1181,8 +1178,8 @@ bool dc_remove_plane_from_context( stream_status->plane_count--; - /* Trim back arrays */ - for (i = 0; i < stream_status->plane_count; i++) + /* Start at the plane we've just released, and move all the planes one index forward to "trim" the array */ + for (; i < stream_status->plane_count; i++) stream_status->plane_states[i] = stream_status->plane_states[i + 1]; stream_status->plane_states[stream_status->plane_count] = NULL; From 179584ef6d9d763f9f17d2fe627c2d801e9a0973 Mon Sep 17 00:00:00 2001 From: Tony Cheng Date: Thu, 5 Oct 2017 14:15:44 -0400 Subject: [PATCH 094/155] drm/amd/display: dal 3.1.05 Signed-off-by: Tony Cheng Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 8fa9ef1167fad..6e9b21928d4f3 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -38,7 +38,7 @@ #include "inc/compressor.h" #include "dml/display_mode_lib.h" -#define DC_VER "3.1.04" +#define DC_VER "3.1.05" #define MAX_SURFACES 3 #define MAX_STREAMS 6 From 86be9a0495c6b4ca8ec37b652152df947c155848 Mon Sep 17 00:00:00 2001 From: Yue Hin Lau Date: Thu, 5 Oct 2017 12:30:14 -0400 Subject: [PATCH 095/155] drm/amd/display: renaming filename for hubp Signed-off-by: Yue Hin Lau Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn10/Makefile | 2 +- .../amd/display/dc/dcn10/{dcn10_mem_input.c => dcn10_hubp.c} | 2 +- .../amd/display/dc/dcn10/{dcn10_mem_input.h => dcn10_hubp.h} | 0 drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 2 +- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c | 2 +- 5 files changed, 4 insertions(+), 4 deletions(-) rename drivers/gpu/drm/amd/display/dc/dcn10/{dcn10_mem_input.c => dcn10_hubp.c} (99%) rename drivers/gpu/drm/amd/display/dc/dcn10/{dcn10_mem_input.h => dcn10_hubp.h} (100%) diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/Makefile b/drivers/gpu/drm/amd/display/dc/dcn10/Makefile index 6b19106f46795..ebeb88283a143 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/Makefile +++ b/drivers/gpu/drm/amd/display/dc/dcn10/Makefile @@ -3,7 +3,7 @@ DCN10 = dcn10_resource.o dcn10_ipp.o dcn10_hw_sequencer.o \ dcn10_dpp.o dcn10_opp.o dcn10_timing_generator.o \ - dcn10_mem_input.o dcn10_mpc.o \ + dcn10_hubp.o dcn10_mpc.o \ dcn10_dpp_dscl.o dcn10_dpp_cm.o dcn10_cm_common.o AMD_DAL_DCN10 = $(addprefix $(AMDDALPATH)/dc/dcn10/,$(DCN10)) diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c similarity index 99% rename from drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.c rename to drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c index 9ee42d9840fb2..b13dee64e0ce6 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c @@ -24,9 +24,9 @@ */ #include "dm_services.h" #include "dce_calcs.h" -#include "dcn10_mem_input.h" #include "reg_helper.h" #include "basics/conversion.h" +#include "dcn10_hubp.h" #define REG(reg)\ hubp1->mi_regs->reg diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h similarity index 100% rename from drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.h rename to drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index 059da7882a68a..6b866b1699859 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -31,7 +31,6 @@ #include "dce110/dce110_hw_sequencer.h" #include "dce/dce_hwseq.h" #include "abm.h" -#include "dcn10/dcn10_mem_input.h" #include "dcn10/dcn10_timing_generator.h" #include "dcn10/dcn10_dpp.h" #include "dcn10/dcn10_mpc.h" @@ -41,6 +40,7 @@ #include "mpc.h" #include "reg_helper.h" #include "custom_float.h" +#include "dcn10_hubp.h" #define CTX \ hws->ctx diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c index 93edbba762e88..1da5105ed30a9 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c @@ -42,12 +42,12 @@ #include "dce/dce_stream_encoder.h" #include "dce/dce_clocks.h" #include "dce/dce_clock_source.h" -#include "dcn10/dcn10_mem_input.h" #include "dce/dce_audio.h" #include "dce/dce_hwseq.h" #include "../virtual/virtual_stream_encoder.h" #include "dce110/dce110_resource.h" #include "dce112/dce112_resource.h" +#include "dcn10_hubp.h" #include "vega10/soc15ip.h" From 2938bbb646107d4e39bf850a5bc09385abd012e8 Mon Sep 17 00:00:00 2001 From: SivapiriyanKumarasamy Date: Wed, 4 Oct 2017 14:24:53 -0400 Subject: [PATCH 096/155] drm/amd/display: Pull transfer func defines into DC Signed-off-by: SivapiriyanKumarasamy Reviewed-by: Anthony Koo Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc.h | 38 +++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 6e9b21928d4f3..c7b31adc736e2 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -318,6 +318,38 @@ enum { TRANSFER_FUNC_POINTS = 1025 }; +// Moved here from color module for linux +enum color_transfer_func { + transfer_func_unknown, + transfer_func_srgb, + transfer_func_bt709, + transfer_func_pq2084, + transfer_func_pq2084_interim, + transfer_func_linear_0_1, + transfer_func_linear_0_125, + transfer_func_dolbyvision, + transfer_func_gamma_22, + transfer_func_gamma_26 +}; + +enum color_color_space { + color_space_unsupported, + color_space_srgb, + color_space_bt601, + color_space_bt709, + color_space_xv_ycc_bt601, + color_space_xv_ycc_bt709, + color_space_xr_rgb, + color_space_bt2020, + color_space_adobe, + color_space_dci_p3, + color_space_sc_rgb_ms_ref, + color_space_display_native, + color_space_app_ctrl, + color_space_dolby_vision, + color_space_custom_coordinates +}; + struct dc_hdr_static_metadata { /* display chromaticities and white point in units of 0.00001 */ unsigned int chromaticity_green_x; @@ -398,6 +430,12 @@ struct dc_plane_state { struct dc_gamma *gamma_correction; struct dc_transfer_func *in_transfer_func; + // sourceContentAttribute cache + bool is_source_input_valid; + struct dc_hdr_static_metadata source_input_mastering_info; + enum color_color_space source_input_color_space; + enum color_transfer_func source_input_tf; + enum dc_color_space color_space; enum surface_pixel_format format; enum dc_rotation_angle rotation; From 80e80ec817f161560b4159608fb41bd289abede3 Mon Sep 17 00:00:00 2001 From: Bhawanpreet Lakha Date: Tue, 3 Oct 2017 13:53:51 -0400 Subject: [PATCH 097/155] drm/amd/display: Fix underscan not using proper scaling fix underscan not being set correctly Signed-off-by: Bhawanpreet Lakha Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 4df5bf750257a..12aeb6d83f42a 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -1362,7 +1362,7 @@ void dc_commit_updates_for_stream(struct dc *dc, enum surface_update_type update_type; struct dc_state *context; struct dc_context *dc_ctx = dc->ctx; - int i; + int i, j; stream_status = dc_stream_get_status(stream); context = dc->current_state; @@ -1396,8 +1396,17 @@ void dc_commit_updates_for_stream(struct dc *dc, if (srf_updates[i].flip_addr) surface->address = srf_updates[i].flip_addr->address; - } + if (update_type >= UPDATE_TYPE_MED) { + for (j = 0; j < dc->res_pool->pipe_count; j++) { + struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j]; + + if (pipe_ctx->plane_state != surface) + continue; + resource_build_scaling_params(pipe_ctx); + } + } + } commit_planes_for_stream( dc, From 8534575fed085a78a847f88fbc929d9c4a8c3255 Mon Sep 17 00:00:00 2001 From: Eric Bernstein Date: Thu, 5 Oct 2017 14:27:27 -0400 Subject: [PATCH 098/155] drm/amd/display: Expose some MPC functions for reuse Signed-off-by: Eric Bernstein Reviewed-by: Eric Bernstein Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c | 11 +++-- .../gpu/drm/amd/display/dc/dcn10/dcn10_mpc.h | 45 ++++++++++++++----- .../drm/amd/display/dc/dcn10/dcn10_resource.c | 6 ++- drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h | 7 +-- 4 files changed, 48 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c index 334f072cea1df..76573e1f5b015 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c @@ -65,7 +65,7 @@ static void mpc10_set_bg_color( MPCC_BG_B_CB, bg_b_cb); } -static void mpc10_assert_idle_mpcc(struct mpc *mpc, int id) +void mpc10_assert_idle_mpcc(struct mpc *mpc, int id) { struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc); @@ -116,7 +116,7 @@ static void mpc10_assert_mpcc_idle_before_connect(struct dcn10_mpc *mpc10, int i } } -static void mpc10_mpcc_remove( +void mpc10_mpcc_remove( struct mpc *mpc, struct mpc_tree_cfg *tree_cfg, int opp_id, @@ -265,7 +265,7 @@ static void mpc10_add_to_tree_cfg( tree_cfg->num_pipes++; } -static int mpc10_mpcc_add(struct mpc *mpc, struct mpcc_cfg *cfg) +int mpc10_mpcc_add(struct mpc *mpc, struct mpcc_cfg *cfg) { struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc); int mpcc_id, z_idx; @@ -313,7 +313,7 @@ static int mpc10_mpcc_add(struct mpc *mpc, struct mpcc_cfg *cfg) return mpcc_id; } -static void mpc10_update_blend_mode( +void mpc10_update_blend_mode( struct mpc *mpc, struct mpcc_cfg *cfg) { @@ -339,8 +339,7 @@ const struct mpc_funcs dcn10_mpc_funcs = { .add = mpc10_mpcc_add, .remove = mpc10_mpcc_remove, .wait_for_idle = mpc10_assert_idle_mpcc, - .set_denorm = NULL, - .update_blend_mode = mpc10_update_blend_mode + .update_blend_mode = mpc10_update_blend_mode, }; void dcn10_mpc_construct(struct dcn10_mpc *mpc10, diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.h index 94f890a0ad408..683ce4aaa76ef 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.h +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.h @@ -34,7 +34,6 @@ #define MAX_OPP 6 #define MPC_COMMON_REG_LIST_DCN1_0(inst) \ - SRII(MUX, MPC_OUT, inst),\ SRII(MPCC_TOP_SEL, MPCC, inst),\ SRII(MPCC_BOT_SEL, MPCC, inst),\ SRII(MPCC_CONTROL, MPCC, inst),\ @@ -45,17 +44,19 @@ SRII(MPCC_BG_B_CB, MPCC, inst),\ SRII(MPCC_BG_B_CB, MPCC, inst) -struct dcn_mpc_registers { - uint32_t MPCC_TOP_SEL[MAX_MPCC]; - uint32_t MPCC_BOT_SEL[MAX_MPCC]; - uint32_t MPCC_CONTROL[MAX_MPCC]; - uint32_t MPCC_STATUS[MAX_MPCC]; - uint32_t MPCC_OPP_ID[MAX_MPCC]; - uint32_t MPCC_BG_G_Y[MAX_MPCC]; - uint32_t MPCC_BG_R_CR[MAX_MPCC]; - uint32_t MPCC_BG_B_CB[MAX_MPCC]; +#define MPC_OUT_MUX_COMMON_REG_LIST_DCN1_0(inst) \ + SRII(MUX, MPC_OUT, inst) + +#define MPC_COMMON_REG_VARIABLE_LIST \ + uint32_t MPCC_TOP_SEL[MAX_MPCC]; \ + uint32_t MPCC_BOT_SEL[MAX_MPCC]; \ + uint32_t MPCC_CONTROL[MAX_MPCC]; \ + uint32_t MPCC_STATUS[MAX_MPCC]; \ + uint32_t MPCC_OPP_ID[MAX_MPCC]; \ + uint32_t MPCC_BG_G_Y[MAX_MPCC]; \ + uint32_t MPCC_BG_R_CR[MAX_MPCC]; \ + uint32_t MPCC_BG_B_CB[MAX_MPCC]; \ uint32_t MUX[MAX_OPP]; -}; #define MPC_COMMON_MASK_SH_LIST_DCN1_0(mask_sh)\ SF(MPCC0_MPCC_TOP_SEL, MPCC_TOP_SEL, mask_sh),\ @@ -87,6 +88,10 @@ struct dcn_mpc_registers { type MPCC_BG_B_CB;\ type MPC_OUT_MUX; +struct dcn_mpc_registers { + MPC_COMMON_REG_VARIABLE_LIST +}; + struct dcn_mpc_shift { MPC_REG_FIELD_LIST(uint8_t) }; @@ -112,4 +117,22 @@ void dcn10_mpc_construct(struct dcn10_mpc *mpcc10, const struct dcn_mpc_mask *mpc_mask, int num_mpcc); +int mpc10_mpcc_add( + struct mpc *mpc, + struct mpcc_cfg *cfg); + +void mpc10_mpcc_remove( + struct mpc *mpc, + struct mpc_tree_cfg *tree_cfg, + int opp_id, + int dpp_id); + +void mpc10_assert_idle_mpcc( + struct mpc *mpc, + int id); + +void mpc10_update_blend_mode( + struct mpc *mpc, + struct mpcc_cfg *cfg); + #endif diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c index 1da5105ed30a9..4764590f90973 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c @@ -329,7 +329,11 @@ static const struct dcn_mpc_registers mpc_regs = { MPC_COMMON_REG_LIST_DCN1_0(0), MPC_COMMON_REG_LIST_DCN1_0(1), MPC_COMMON_REG_LIST_DCN1_0(2), - MPC_COMMON_REG_LIST_DCN1_0(3) + MPC_COMMON_REG_LIST_DCN1_0(3), + MPC_OUT_MUX_COMMON_REG_LIST_DCN1_0(0), + MPC_OUT_MUX_COMMON_REG_LIST_DCN1_0(1), + MPC_OUT_MUX_COMMON_REG_LIST_DCN1_0(2), + MPC_OUT_MUX_COMMON_REG_LIST_DCN1_0(3) }; static const struct dcn_mpc_shift mpc_shift = { diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h b/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h index fb590f5353a04..d4188b2c0626d 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h @@ -46,15 +46,16 @@ struct mpc { struct mpc_funcs { int (*add)(struct mpc *mpc, struct mpcc_cfg *cfg); + void (*remove)(struct mpc *mpc, struct mpc_tree_cfg *tree_cfg, int opp_id, int mpcc_inst); + void (*wait_for_idle)(struct mpc *mpc, int id); - void (*set_denorm)(struct mpc *mpc, - int opp_id, - enum dc_color_depth output_depth); + void (*update_blend_mode)(struct mpc *mpc, struct mpcc_cfg *cfg); + }; #endif From be5a55dc3de9bc5764b3eb4ba6f743783584aa58 Mon Sep 17 00:00:00 2001 From: Bhawanpreet Lakha Date: Thu, 5 Oct 2017 13:32:29 -0400 Subject: [PATCH 099/155] drm/amd/display: change when to set tap_hardcode_coeff Set hardcode_coeff only when BOTH chroma and luma taps are more than 1 without this underscan with h or v set to 0 darkens the screen (either h or v set to 0, not both) Signed-off-by: Bhawanpreet Lakha Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c index 830dbd5d41444..eda6c8010fb8a 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c @@ -306,10 +306,10 @@ static void dpp_set_scl_filter( h_2tap_hardcode_coef_en = scl_data->taps.h_taps < 3 && scl_data->taps.h_taps_c < 3 - && (scl_data->taps.h_taps > 1 || scl_data->taps.h_taps_c > 1); + && (scl_data->taps.h_taps > 1 && scl_data->taps.h_taps_c > 1); v_2tap_hardcode_coef_en = scl_data->taps.v_taps < 3 && scl_data->taps.v_taps_c < 3 - && (scl_data->taps.v_taps > 1 || scl_data->taps.v_taps_c > 1); + && (scl_data->taps.v_taps > 1 && scl_data->taps.v_taps_c > 1); h_2tap_sharp_en = h_2tap_hardcode_coef_en && h_2tap_sharp_factor != 0; v_2tap_sharp_en = v_2tap_hardcode_coef_en && v_2tap_sharp_factor != 0; From 3411eac1a144ac5ad5a7ab994645724130bb2996 Mon Sep 17 00:00:00 2001 From: Vitaly Prosyak Date: Thu, 5 Oct 2017 10:45:50 -0500 Subject: [PATCH 100/155] drm/amd/display: [RV] bug in cm programming When surface bigger then 10 bpc the output pixel does not match to the required value.Update CRC's. Signed-off-by: Vitaly Prosyak Reviewed-by: Jordan Lazare Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h | 6 +++++- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm.c | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h index 4cf18a500dcde..c2e3ff883537c 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h @@ -164,7 +164,8 @@ SRI(CM_IGAM_LUT_RW_CONTROL, CM, id), \ SRI(CM_IGAM_LUT_RW_INDEX, CM, id), \ SRI(CM_IGAM_LUT_SEQ_COLOR, CM, id), \ - SRI(CURSOR_CONTROL, CURSOR, id) + SRI(CURSOR_CONTROL, CURSOR, id), \ + SRI(CM_CMOUT_CONTROL, CM, id) #define TF_REG_LIST_SH_MASK_DCN(mask_sh)\ @@ -401,6 +402,7 @@ TF_SF(CM0_CM_CONTROL, CM_BYPASS_EN, mask_sh), \ TF_SF(CM0_CM_IGAM_LUT_SEQ_COLOR, CM_IGAM_LUT_SEQ_COLOR, mask_sh), \ TF_SF(CNVC_CFG0_FORMAT_CONTROL, OUTPUT_FP, mask_sh), \ + TF_SF(CM0_CM_CMOUT_CONTROL, CM_CMOUT_ROUND_TRUNC_MODE, mask_sh), \ TF_SF(CURSOR0_CURSOR_CONTROL, CURSOR_MODE, mask_sh), \ TF_SF(CURSOR0_CURSOR_CONTROL, CURSOR_PITCH, mask_sh), \ TF_SF(CURSOR0_CURSOR_CONTROL, CURSOR_LINES_PER_CHUNK, mask_sh), \ @@ -549,6 +551,7 @@ type CM_RGAM_RAMA_EXP_REGION33_LUT_OFFSET; \ type CM_RGAM_RAMA_EXP_REGION33_NUM_SEGMENTS; \ type CM_RGAM_LUT_MODE; \ + type CM_CMOUT_ROUND_TRUNC_MODE; \ type OBUF_BYPASS; \ type OBUF_H_2X_UPSCALE_EN; \ type CM_BLNDGAM_LUT_MODE; \ @@ -1081,6 +1084,7 @@ struct dcn_dpp_registers { uint32_t CM_RGAM_RAMA_REGION_0_1; uint32_t CM_RGAM_RAMA_REGION_32_33; uint32_t CM_RGAM_CONTROL; + uint32_t CM_CMOUT_CONTROL; uint32_t OBUF_CONTROL; uint32_t CM_BLNDGAM_LUT_WRITE_EN_MASK; uint32_t CM_BLNDGAM_CONTROL; diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm.c index 61e2a8919e9ce..f88fd2e2e0aaf 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm.c @@ -602,7 +602,7 @@ static void ippn10_enable_cm_block( struct transform *xfm_base) { struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); - + REG_UPDATE(CM_CMOUT_CONTROL, CM_CMOUT_ROUND_TRUNC_MODE, 8); REG_UPDATE(CM_CONTROL, CM_BYPASS_EN, 0); } From 886daac91d4c794fa76a0e5cf1101bdb329f3fe3 Mon Sep 17 00:00:00 2001 From: Jerry Zuo Date: Thu, 5 Oct 2017 15:37:46 -0400 Subject: [PATCH 101/155] drm/amd/display: Fix a logic defect in cursor move Regression caused by: Ib98354194d7 Need to check crtc->stream before updating cursor attributes and position. Signed-off-by: Jerry Zuo Reviewed-by: Roman Li Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 8653453566b8e..17fb636648f4a 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -3736,14 +3736,15 @@ static void handle_cursor_update(struct drm_plane *plane, attributes.pitch = attributes.width; - if (!dc_stream_set_cursor_attributes(crtc_state->stream, - &attributes)) - DRM_ERROR("DC failed to set cursor attributes\n"); + if (crtc_state->stream) { + if (!dc_stream_set_cursor_attributes(crtc_state->stream, + &attributes)) + DRM_ERROR("DC failed to set cursor attributes\n"); - if (crtc_state->stream) if (!dc_stream_set_cursor_position(crtc_state->stream, &position)) DRM_ERROR("DC failed to set cursor position\n"); + } } static void prepare_flip_isr(struct amdgpu_crtc *acrtc) From e6f4f9cfde0f586c276190f541ecfc80d9b688bc Mon Sep 17 00:00:00 2001 From: Eric Yang Date: Thu, 5 Oct 2017 16:00:29 -0400 Subject: [PATCH 102/155] drm/amd/display: fix null dereference in reset hw ctx Signed-off-by: Eric Yang Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c index 867a0eb9f2e06..5e5763c0ee94b 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c @@ -1877,7 +1877,7 @@ static void dce110_reset_hw_ctx_wrap( struct clock_source *old_clk = pipe_ctx_old->clock_source; /* disable already, no need to disable again */ - if (!pipe_ctx->stream->dpms_off) + if (pipe_ctx->stream && !pipe_ctx->stream->dpms_off) core_link_disable_stream(pipe_ctx_old, FREE_ACQUIRED_RESOURCE); pipe_ctx_old->stream_res.tg->funcs->set_blank(pipe_ctx_old->stream_res.tg, true); From 39a4e6608f28586dee77daf8dc3af53e7829d2a8 Mon Sep 17 00:00:00 2001 From: Yue Hin Lau Date: Thu, 5 Oct 2017 17:57:35 -0400 Subject: [PATCH 103/155] drm/amd/display: add null check for cursor functions Signed-off-by: Yue Hin Lau Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_stream.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) 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 411678736ed4b..10421ea31373f 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c @@ -210,11 +210,13 @@ bool dc_stream_set_cursor_attributes( pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes( pipe_ctx->plane_res.ipp, attributes); - if (pipe_ctx->plane_res.hubp != NULL) + if (pipe_ctx->plane_res.hubp != NULL && + pipe_ctx->plane_res.hubp->funcs->set_cursor_attributes != NULL) pipe_ctx->plane_res.hubp->funcs->set_cursor_attributes( pipe_ctx->plane_res.hubp, attributes); - if (pipe_ctx->plane_res.mi != NULL) + if (pipe_ctx->plane_res.mi != NULL && + pipe_ctx->plane_res.mi->funcs->set_cursor_attributes != NULL) pipe_ctx->plane_res.mi->funcs->set_cursor_attributes( pipe_ctx->plane_res.mi, attributes); @@ -253,6 +255,7 @@ bool dc_stream_set_cursor_position( for (i = 0; i < MAX_PIPES; i++) { struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i]; struct input_pixel_processor *ipp = pipe_ctx->plane_res.ipp; + struct mem_input *mi = pipe_ctx->plane_res.mi; struct hubp *hubp = pipe_ctx->plane_res.hubp; struct transform *xfm = pipe_ctx->plane_res.xfm; struct dc_cursor_position pos_cpy = *position; @@ -281,10 +284,13 @@ bool dc_stream_set_cursor_position( if (ipp->funcs->ipp_cursor_set_position != NULL) ipp->funcs->ipp_cursor_set_position(ipp, &pos_cpy, ¶m); - if (hubp != NULL) + if (mi != NULL && mi->funcs->set_cursor_position != NULL) + mi->funcs->set_cursor_position(mi, &pos_cpy, ¶m); + + if (hubp != NULL && hubp->funcs->set_cursor_position != NULL) hubp->funcs->set_cursor_position(hubp, &pos_cpy, ¶m); - if (xfm != NULL) + if (xfm != NULL && xfm->funcs->set_cursor_position != NULL) xfm->funcs->set_cursor_position(xfm, &pos_cpy, ¶m, hubp->curs_attr.width); } From d94585a06b8197a723787c6c5502872abcff0e8e Mon Sep 17 00:00:00 2001 From: Yue Hin Lau Date: Thu, 5 Oct 2017 16:47:49 -0400 Subject: [PATCH 104/155] drm/amd/display: rename transform to dpp for dcn Signed-off-by: Yue Hin Lau Reviewed-by: Eric Bernstein Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/calcs/dcn_calcs.c | 1 + drivers/gpu/drm/amd/display/dc/core/dc.c | 1 + .../gpu/drm/amd/display/dc/core/dc_resource.c | 16 +- .../gpu/drm/amd/display/dc/core/dc_stream.c | 16 +- .../gpu/drm/amd/display/dc/core/dc_surface.c | 1 + .../gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c | 144 +++++----- .../gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h | 94 +++---- .../drm/amd/display/dc/dcn10/dcn10_dpp_cm.c | 261 +++++++++--------- .../drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c | 104 +++---- .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 59 ++-- .../drm/amd/display/dc/dcn10/dcn10_resource.c | 22 +- .../gpu/drm/amd/display/dc/inc/core_types.h | 3 + drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h | 134 +++++++++ 13 files changed, 509 insertions(+), 347 deletions(-) create mode 100644 drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c index c37f130b0170a..cf0c1459f546f 100644 --- a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c +++ b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c @@ -488,6 +488,7 @@ static void split_stream_across_pipes( secondary_pipe->plane_res.hubp = pool->hubps[secondary_pipe->pipe_idx]; secondary_pipe->plane_res.ipp = pool->ipps[secondary_pipe->pipe_idx]; secondary_pipe->plane_res.xfm = pool->transforms[secondary_pipe->pipe_idx]; + secondary_pipe->plane_res.dpp = pool->dpps[secondary_pipe->pipe_idx]; if (primary_pipe->bottom_pipe) { ASSERT(primary_pipe->bottom_pipe != secondary_pipe); secondary_pipe->bottom_pipe = primary_pipe->bottom_pipe; diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 12aeb6d83f42a..80ddccc2570a0 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -38,6 +38,7 @@ #include "bios_parser_interface.h" #include "include/irq_service_interface.h" #include "transform.h" +#include "dpp.h" #include "timing_generator.h" #include "virtual/virtual_link_encoder.h" 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 c80bde94472f3..303d7ec684d91 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -31,6 +31,7 @@ #include "opp.h" #include "timing_generator.h" #include "transform.h" +#include "dpp.h" #include "core_types.h" #include "set_mode_types.h" #include "virtual/virtual_stream_encoder.h" @@ -853,8 +854,13 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx) pipe_ctx->plane_res.scl_data.v_active = timing->v_addressable; /* Taps calculations */ - res = pipe_ctx->plane_res.xfm->funcs->transform_get_optimal_number_of_taps( - pipe_ctx->plane_res.xfm, &pipe_ctx->plane_res.scl_data, &plane_state->scaling_quality); + if (pipe_ctx->plane_res.xfm != NULL) + res = pipe_ctx->plane_res.xfm->funcs->transform_get_optimal_number_of_taps( + pipe_ctx->plane_res.xfm, &pipe_ctx->plane_res.scl_data, &plane_state->scaling_quality); + + if (pipe_ctx->plane_res.dpp != NULL) + res = pipe_ctx->plane_res.dpp->funcs->dpp_get_optimal_number_of_taps( + pipe_ctx->plane_res.dpp, &pipe_ctx->plane_res.scl_data, &plane_state->scaling_quality); if (!res) { /* Try 24 bpp linebuffer */ @@ -862,6 +868,9 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx) res = pipe_ctx->plane_res.xfm->funcs->transform_get_optimal_number_of_taps( pipe_ctx->plane_res.xfm, &pipe_ctx->plane_res.scl_data, &plane_state->scaling_quality); + + res = pipe_ctx->plane_res.dpp->funcs->dpp_get_optimal_number_of_taps( + pipe_ctx->plane_res.dpp, &pipe_ctx->plane_res.scl_data, &plane_state->scaling_quality); } if (res) @@ -1026,7 +1035,7 @@ static int acquire_first_split_pipe( pipe_ctx->stream_res.tg = pool->timing_generators[i]; pipe_ctx->plane_res.hubp = pool->hubps[i]; pipe_ctx->plane_res.ipp = pool->ipps[i]; - pipe_ctx->plane_res.xfm = pool->transforms[i]; + pipe_ctx->plane_res.dpp = pool->dpps[i]; pipe_ctx->stream_res.opp = pool->opps[i]; pipe_ctx->pipe_idx = i; @@ -1359,6 +1368,7 @@ static int acquire_first_free_pipe( pipe_ctx->plane_res.hubp = pool->hubps[i]; pipe_ctx->plane_res.ipp = pool->ipps[i]; pipe_ctx->plane_res.xfm = pool->transforms[i]; + pipe_ctx->plane_res.dpp = pool->dpps[i]; pipe_ctx->stream_res.opp = pool->opps[i]; pipe_ctx->pipe_idx = i; 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 10421ea31373f..97f040a258206 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c @@ -200,7 +200,7 @@ bool dc_stream_set_cursor_attributes( for (i = 0; i < MAX_PIPES; i++) { struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i]; - if (pipe_ctx->stream != stream || !pipe_ctx->plane_res.xfm) + if (pipe_ctx->stream != stream || (!pipe_ctx->plane_res.xfm && !pipe_ctx->plane_res.dpp)) continue; if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state) continue; @@ -221,9 +221,15 @@ bool dc_stream_set_cursor_attributes( pipe_ctx->plane_res.mi, attributes); - if (pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes != NULL) + if (pipe_ctx->plane_res.xfm != NULL && + pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes != NULL) pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes( pipe_ctx->plane_res.xfm, attributes); + + if (pipe_ctx->plane_res.dpp != NULL && + pipe_ctx->plane_res.dpp->funcs->set_cursor_attributes != NULL) + pipe_ctx->plane_res.dpp->funcs->set_cursor_attributes( + pipe_ctx->plane_res.dpp, attributes); } stream->cursor_attributes = *attributes; @@ -258,6 +264,7 @@ bool dc_stream_set_cursor_position( struct mem_input *mi = pipe_ctx->plane_res.mi; struct hubp *hubp = pipe_ctx->plane_res.hubp; struct transform *xfm = pipe_ctx->plane_res.xfm; + struct dpp *dpp = pipe_ctx->plane_res.dpp; struct dc_cursor_position pos_cpy = *position; struct dc_cursor_mi_param param = { .pixel_clk_khz = stream->timing.pix_clk_khz, @@ -270,7 +277,7 @@ bool dc_stream_set_cursor_position( if (pipe_ctx->stream != stream || (!pipe_ctx->plane_res.mi && !pipe_ctx->plane_res.hubp) || !pipe_ctx->plane_state || - !pipe_ctx->plane_res.xfm) + (!pipe_ctx->plane_res.xfm && !pipe_ctx->plane_res.dpp)) continue; if (pipe_ctx->plane_state->address.type @@ -293,6 +300,9 @@ bool dc_stream_set_cursor_position( if (xfm != NULL && xfm->funcs->set_cursor_position != NULL) xfm->funcs->set_cursor_position(xfm, &pos_cpy, ¶m, hubp->curs_attr.width); + if (dpp != NULL && dpp->funcs->set_cursor_position != NULL) + dpp->funcs->set_cursor_position(dpp, &pos_cpy, ¶m, hubp->curs_attr.width); + } return true; 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 d43783a45ab61..5aa2270f36fd5 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_surface.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_surface.c @@ -30,6 +30,7 @@ /* DC core (private) */ #include "core_types.h" #include "transform.h" +#include "dpp.h" /******************************************************************************* * Private functions diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c index fb3c78858ebeb..5960e491159d9 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c @@ -39,14 +39,14 @@ #define BLACK_OFFSET_CBCR 0x8000 #define REG(reg)\ - xfm->tf_regs->reg + dpp->tf_regs->reg #define CTX \ - xfm->base.ctx + dpp->base.ctx #undef FN #define FN(reg_name, field_name) \ - xfm->tf_shift->field_name, xfm->tf_mask->field_name + dpp->tf_shift->field_name, dpp->tf_mask->field_name enum pixel_format_description { PIXEL_FORMAT_FIXED = 0, @@ -99,7 +99,7 @@ enum gamut_remap_select { }; /* Program gamut remap in bypass mode */ -void dpp_set_gamut_remap_bypass(struct dcn10_dpp *xfm) +void dpp_set_gamut_remap_bypass(struct dcn10_dpp *dpp) { REG_SET(CM_GAMUT_REMAP_CONTROL, 0, CM_GAMUT_REMAP_MODE, 0); @@ -110,7 +110,7 @@ void dpp_set_gamut_remap_bypass(struct dcn10_dpp *xfm) bool dpp_get_optimal_number_of_taps( - struct transform *xfm, + struct dpp *dpp, struct scaler_data *scl_data, const struct scaling_taps *in_taps) { @@ -154,7 +154,7 @@ bool dpp_get_optimal_number_of_taps( else scl_data->taps.h_taps_c = in_taps->h_taps_c; - if (!xfm->ctx->dc->debug.always_scale) { + if (!dpp->ctx->dc->debug.always_scale) { if (IDENTITY_RATIO(scl_data->ratios.horz)) scl_data->taps.h_taps = 1; if (IDENTITY_RATIO(scl_data->ratios.vert)) @@ -169,14 +169,14 @@ bool dpp_get_optimal_number_of_taps( return true; } -void dpp_reset(struct transform *xfm_base) +void dpp_reset(struct dpp *dpp_base) { - struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); + struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base); - xfm->filter_h_c = NULL; - xfm->filter_v_c = NULL; - xfm->filter_h = NULL; - xfm->filter_v = NULL; + dpp->filter_h_c = NULL; + dpp->filter_v_c = NULL; + dpp->filter_h = NULL; + dpp->filter_v = NULL; /* set boundary mode to 0 */ REG_SET(DSCL_CONTROL, 0, SCL_BOUNDARY_MODE, 0); @@ -184,28 +184,28 @@ void dpp_reset(struct transform *xfm_base) -static void dcn10_dpp_cm_set_regamma_pwl( - struct transform *xfm_base, const struct pwl_params *params) +static void dpp1_cm_set_regamma_pwl( + struct dpp *dpp_base, const struct pwl_params *params) { - struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); + struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base); - dcn10_dpp_cm_power_on_regamma_lut(xfm_base, true); - dcn10_dpp_cm_configure_regamma_lut(xfm_base, xfm->is_write_to_ram_a_safe); + dpp1_cm_power_on_regamma_lut(dpp_base, true); + dpp1_cm_configure_regamma_lut(dpp_base, dpp->is_write_to_ram_a_safe); - if (xfm->is_write_to_ram_a_safe) - dcn10_dpp_cm_program_regamma_luta_settings(xfm_base, params); + if (dpp->is_write_to_ram_a_safe) + dpp1_cm_program_regamma_luta_settings(dpp_base, params); else - dcn10_dpp_cm_program_regamma_lutb_settings(xfm_base, params); + dpp1_cm_program_regamma_lutb_settings(dpp_base, params); - dcn10_dpp_cm_program_regamma_lut( - xfm_base, params->rgb_resulted, params->hw_points_num); + dpp1_cm_program_regamma_lut( + dpp_base, params->rgb_resulted, params->hw_points_num); } -static void dcn10_dpp_cm_set_regamma_mode( - struct transform *xfm_base, +static void dpp1_cm_set_regamma_mode( + struct dpp *dpp_base, enum opp_regamma mode) { - struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); + struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base); uint32_t re_mode = 0; uint32_t obuf_bypass = 0; /* need for pipe split */ uint32_t obuf_hupscale = 0; @@ -221,8 +221,8 @@ static void dcn10_dpp_cm_set_regamma_mode( re_mode = 2; break; case OPP_REGAMMA_USER: - re_mode = xfm->is_write_to_ram_a_safe ? 3 : 4; - xfm->is_write_to_ram_a_safe = !xfm->is_write_to_ram_a_safe; + re_mode = dpp->is_write_to_ram_a_safe ? 3 : 4; + dpp->is_write_to_ram_a_safe = !dpp->is_write_to_ram_a_safe; break; default: break; @@ -234,7 +234,7 @@ static void dcn10_dpp_cm_set_regamma_mode( OBUF_H_2X_UPSCALE_EN, obuf_hupscale); } -static void ippn10_setup_format_flags(enum surface_pixel_format input_format,\ +static void dpp1_setup_format_flags(enum surface_pixel_format input_format,\ enum pixel_format_description *fmt) { @@ -247,11 +247,11 @@ static void ippn10_setup_format_flags(enum surface_pixel_format input_format,\ *fmt = PIXEL_FORMAT_FIXED; } -static void ippn10_set_degamma_format_float( - struct transform *xfm_base, +static void dpp1_set_degamma_format_float( + struct dpp *dpp_base, bool is_float) { - struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); + struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base); if (is_float) { REG_UPDATE(CM_IGAM_CONTROL, CM_IGAM_INPUT_FORMAT, 3); @@ -262,8 +262,8 @@ static void ippn10_set_degamma_format_float( } } -void ippn10_cnv_setup ( - struct transform *xfm_base, +void dpp1_cnv_setup ( + struct dpp *dpp_base, enum surface_pixel_format input_format, enum expansion_mode mode) { @@ -273,10 +273,10 @@ void ippn10_cnv_setup ( enum dc_color_space color_space; enum dcn10_input_csc_select select; bool is_float; - struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); + struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base); bool force_disable_cursor = false; - ippn10_setup_format_flags(input_format, &fmt); + dpp1_setup_format_flags(input_format, &fmt); alpha_en = 1; pixel_format = 0; color_space = COLOR_SPACE_SRGB; @@ -304,7 +304,7 @@ void ippn10_cnv_setup ( break; } - ippn10_set_degamma_format_float(xfm_base, is_float); + dpp1_set_degamma_format_float(dpp_base, is_float); switch (input_format) { case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555: @@ -362,7 +362,7 @@ void ippn10_cnv_setup ( CNVC_SURFACE_PIXEL_FORMAT, pixel_format); REG_UPDATE(FORMAT_CONTROL, FORMAT_CONTROL__ALPHA_EN, alpha_en); - ippn10_program_input_csc(xfm_base, color_space, select); + dpp1_program_input_csc(dpp_base, color_space, select); if (force_disable_cursor) { REG_UPDATE(CURSOR_CONTROL, @@ -373,10 +373,10 @@ void ippn10_cnv_setup ( } void dcn10_set_cursor_attributes( - struct transform *xfm_base, + struct dpp *dpp_base, const struct dc_cursor_attributes *attr) { - struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); + struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base); enum dc_cursor_color_format color_format = attr->color_format; REG_UPDATE_2(CURSOR0_CONTROL, @@ -401,12 +401,12 @@ void dcn10_set_cursor_attributes( void dcn10_set_cursor_position( - struct transform *xfm_base, + struct dpp *dpp_base, const struct dc_cursor_position *pos, const struct dc_cursor_mi_param *param, uint32_t width) { - struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); + struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base); int src_x_offset = pos->x - pos->x_hotspot - param->viewport_x_start; uint32_t cur_en = pos->enable ? 1 : 0; @@ -421,25 +421,25 @@ void dcn10_set_cursor_position( } -static const struct transform_funcs dcn10_dpp_funcs = { - .transform_reset = dpp_reset, - .transform_set_scaler = dcn10_dpp_dscl_set_scaler_manual_scale, - .transform_get_optimal_number_of_taps = dpp_get_optimal_number_of_taps, - .transform_set_gamut_remap = dcn10_dpp_cm_set_gamut_remap, - .opp_set_csc_adjustment = dcn10_dpp_cm_set_output_csc_adjustment, - .opp_set_csc_default = dcn10_dpp_cm_set_output_csc_default, - .opp_power_on_regamma_lut = dcn10_dpp_cm_power_on_regamma_lut, - .opp_program_regamma_lut = dcn10_dpp_cm_program_regamma_lut, - .opp_configure_regamma_lut = dcn10_dpp_cm_configure_regamma_lut, - .opp_program_regamma_lutb_settings = dcn10_dpp_cm_program_regamma_lutb_settings, - .opp_program_regamma_luta_settings = dcn10_dpp_cm_program_regamma_luta_settings, - .opp_program_regamma_pwl = dcn10_dpp_cm_set_regamma_pwl, - .opp_set_regamma_mode = dcn10_dpp_cm_set_regamma_mode, - .ipp_set_degamma = ippn10_set_degamma, - .ipp_program_input_lut = ippn10_program_input_lut, - .ipp_program_degamma_pwl = ippn10_set_degamma_pwl, - .ipp_setup = ippn10_cnv_setup, - .ipp_full_bypass = ippn10_full_bypass, +static const struct dpp_funcs dcn10_dpp_funcs = { + .dpp_reset = dpp_reset, + .dpp_set_scaler = dpp1_dscl_set_scaler_manual_scale, + .dpp_get_optimal_number_of_taps = dpp_get_optimal_number_of_taps, + .dpp_set_gamut_remap = dpp1_cm_set_gamut_remap, + .opp_set_csc_adjustment = dpp1_cm_set_output_csc_adjustment, + .opp_set_csc_default = dpp1_cm_set_output_csc_default, + .opp_power_on_regamma_lut = dpp1_cm_power_on_regamma_lut, + .opp_program_regamma_lut = dpp1_cm_program_regamma_lut, + .opp_configure_regamma_lut = dpp1_cm_configure_regamma_lut, + .opp_program_regamma_lutb_settings = dpp1_cm_program_regamma_lutb_settings, + .opp_program_regamma_luta_settings = dpp1_cm_program_regamma_luta_settings, + .opp_program_regamma_pwl = dpp1_cm_set_regamma_pwl, + .opp_set_regamma_mode = dpp1_cm_set_regamma_mode, + .ipp_set_degamma = dpp1_set_degamma, + .ipp_program_input_lut = dpp1_program_input_lut, + .ipp_program_degamma_pwl = dpp1_set_degamma_pwl, + .ipp_setup = dpp1_cnv_setup, + .ipp_full_bypass = dpp1_full_bypass, .set_cursor_attributes = dcn10_set_cursor_attributes, .set_cursor_position = dcn10_set_cursor_position, }; @@ -453,29 +453,29 @@ static struct dpp_caps dcn10_dpp_cap = { /* Constructor, Destructor */ /*****************************************/ -void dcn10_dpp_construct( - struct dcn10_dpp *xfm, +void dpp1_construct( + struct dcn10_dpp *dpp, struct dc_context *ctx, uint32_t inst, const struct dcn_dpp_registers *tf_regs, const struct dcn_dpp_shift *tf_shift, const struct dcn_dpp_mask *tf_mask) { - xfm->base.ctx = ctx; + dpp->base.ctx = ctx; - xfm->base.inst = inst; - xfm->base.funcs = &dcn10_dpp_funcs; - xfm->base.caps = &dcn10_dpp_cap; + dpp->base.inst = inst; + dpp->base.funcs = &dcn10_dpp_funcs; + dpp->base.caps = &dcn10_dpp_cap; - xfm->tf_regs = tf_regs; - xfm->tf_shift = tf_shift; - xfm->tf_mask = tf_mask; + dpp->tf_regs = tf_regs; + dpp->tf_shift = tf_shift; + dpp->tf_mask = tf_mask; - xfm->lb_pixel_depth_supported = + dpp->lb_pixel_depth_supported = LB_PIXEL_DEPTH_18BPP | LB_PIXEL_DEPTH_24BPP | LB_PIXEL_DEPTH_30BPP; - xfm->lb_bits_per_entry = LB_BITS_PER_ENTRY; - xfm->lb_memory_size = LB_TOTAL_NUMBER_OF_ENTRIES; /*0x1404*/ + dpp->lb_bits_per_entry = LB_BITS_PER_ENTRY; + dpp->lb_memory_size = LB_TOTAL_NUMBER_OF_ENTRIES; /*0x1404*/ } diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h index c2e3ff883537c..fe6c0aa13da4a 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h @@ -25,10 +25,10 @@ #ifndef __DAL_DPP_DCN10_H__ #define __DAL_DPP_DCN10_H__ -#include "transform.h" +#include "dpp.h" -#define TO_DCN10_DPP(transform)\ - container_of(transform, struct dcn10_dpp, base) +#define TO_DCN10_DPP(dpp)\ + container_of(dpp, struct dcn10_dpp, base) /* TODO: Use correct number of taps. Using polaris values for now */ #define LB_TOTAL_NUMBER_OF_ENTRIES 5124 @@ -1252,7 +1252,7 @@ struct dcn_dpp_registers { }; struct dcn10_dpp { - struct transform base; + struct dpp base; const struct dcn_dpp_registers *tf_regs; const struct dcn_dpp_shift *tf_shift; @@ -1285,99 +1285,99 @@ void dscl1_calc_lb_num_partitions( int *num_part_y, int *num_part_c); -void ippn10_degamma_ram_select( - struct transform *xfm_base, +void dpp1_degamma_ram_select( + struct dpp *dpp_base, bool use_ram_a); -void ippn10_program_degamma_luta_settings( - struct transform *xfm_base, +void dpp1_program_degamma_luta_settings( + struct dpp *dpp_base, const struct pwl_params *params); -void ippn10_program_degamma_lutb_settings( - struct transform *xfm_base, +void dpp1_program_degamma_lutb_settings( + struct dpp *dpp_base, const struct pwl_params *params); -void ippn10_program_degamma_lut( - struct transform *xfm_base, +void dpp1_program_degamma_lut( + struct dpp *dpp_base, const struct pwl_result_data *rgb, uint32_t num, bool is_ram_a); -void ippn10_power_on_degamma_lut( - struct transform *xfm_base, +void dpp1_power_on_degamma_lut( + struct dpp *dpp_base, bool power_on); -void ippn10_program_input_csc( - struct transform *xfm_base, +void dpp1_program_input_csc( + struct dpp *dpp_base, enum dc_color_space color_space, enum dcn10_input_csc_select select); -void ippn10_program_input_lut( - struct transform *xfm_base, +void dpp1_program_input_lut( + struct dpp *dpp_base, const struct dc_gamma *gamma); -void ippn10_full_bypass(struct transform *xfm_base); +void dpp1_full_bypass(struct dpp *dpp_base); -void ippn10_set_degamma( - struct transform *xfm_base, +void dpp1_set_degamma( + struct dpp *dpp_base, enum ipp_degamma_mode mode); -void ippn10_set_degamma_pwl(struct transform *xfm_base, +void dpp1_set_degamma_pwl(struct dpp *dpp_base, const struct pwl_params *params); bool dpp_get_optimal_number_of_taps( - struct transform *xfm, + struct dpp *dpp, struct scaler_data *scl_data, const struct scaling_taps *in_taps); -void dpp_reset(struct transform *xfm_base); +void dpp_reset(struct dpp *dpp_base); -void dcn10_dpp_cm_program_regamma_lut( - struct transform *xfm_base, +void dpp1_cm_program_regamma_lut( + struct dpp *dpp_base, const struct pwl_result_data *rgb, uint32_t num); -void dcn10_dpp_cm_power_on_regamma_lut( - struct transform *xfm_base, +void dpp1_cm_power_on_regamma_lut( + struct dpp *dpp_base, bool power_on); -void dcn10_dpp_cm_configure_regamma_lut( - struct transform *xfm_base, +void dpp1_cm_configure_regamma_lut( + struct dpp *dpp_base, bool is_ram_a); /*program re gamma RAM A*/ -void dcn10_dpp_cm_program_regamma_luta_settings( - struct transform *xfm_base, +void dpp1_cm_program_regamma_luta_settings( + struct dpp *dpp_base, const struct pwl_params *params); /*program re gamma RAM B*/ -void dcn10_dpp_cm_program_regamma_lutb_settings( - struct transform *xfm_base, +void dpp1_cm_program_regamma_lutb_settings( + struct dpp *dpp_base, const struct pwl_params *params); -void dcn10_dpp_cm_set_output_csc_adjustment( - struct transform *xfm_base, +void dpp1_cm_set_output_csc_adjustment( + struct dpp *dpp_base, const struct out_csc_color_matrix *tbl_entry); -void dcn10_dpp_cm_set_output_csc_default( - struct transform *xfm_base, +void dpp1_cm_set_output_csc_default( + struct dpp *dpp_base, const struct default_adjustment *default_adjust); -void dcn10_dpp_cm_set_gamut_remap( - struct transform *xfm, - const struct xfm_grph_csc_adjustment *adjust); +void dpp1_cm_set_gamut_remap( + struct dpp *dpp, + const struct dpp_grph_csc_adjustment *adjust); -void dcn10_dpp_dscl_set_scaler_manual_scale( - struct transform *xfm_base, +void dpp1_dscl_set_scaler_manual_scale( + struct dpp *dpp_base, const struct scaler_data *scl_data); -void ippn10_cnv_setup ( - struct transform *xfm_base, +void dpp1_cnv_setup ( + struct dpp *dpp_base, enum surface_pixel_format input_format, enum expansion_mode mode); -void ippn10_full_bypass(struct transform *xfm_base); +void dpp1_full_bypass(struct dpp *dpp_base); -void dcn10_dpp_construct(struct dcn10_dpp *xfm110, +void dpp1_construct(struct dcn10_dpp *dpp1, struct dc_context *ctx, uint32_t inst, const struct dcn_dpp_registers *tf_regs, diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm.c index f88fd2e2e0aaf..7784001c3a17a 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm.c @@ -40,14 +40,14 @@ #define BLACK_OFFSET_CBCR 0x8000 #define REG(reg)\ - xfm->tf_regs->reg + dpp->tf_regs->reg #define CTX \ - xfm->base.ctx + dpp->base.ctx #undef FN #define FN(reg_name, field_name) \ - xfm->tf_shift->field_name, xfm->tf_mask->field_name + dpp->tf_shift->field_name, dpp->tf_mask->field_name struct dcn10_input_csc_matrix { enum dc_color_space color_space; @@ -120,7 +120,7 @@ static const struct dcn10_input_csc_matrix dcn10_input_csc_matrix[] = { static void program_gamut_remap( - struct dcn10_dpp *xfm, + struct dcn10_dpp *dpp, const uint16_t *regval, enum gamut_remap_select select) { @@ -146,10 +146,10 @@ static void program_gamut_remap( break; } - gam_regs.shifts.csc_c11 = xfm->tf_shift->CM_GAMUT_REMAP_C11; - gam_regs.masks.csc_c11 = xfm->tf_mask->CM_GAMUT_REMAP_C11; - gam_regs.shifts.csc_c12 = xfm->tf_shift->CM_GAMUT_REMAP_C12; - gam_regs.masks.csc_c12 = xfm->tf_mask->CM_GAMUT_REMAP_C12; + gam_regs.shifts.csc_c11 = dpp->tf_shift->CM_GAMUT_REMAP_C11; + gam_regs.masks.csc_c11 = dpp->tf_mask->CM_GAMUT_REMAP_C11; + gam_regs.shifts.csc_c12 = dpp->tf_shift->CM_GAMUT_REMAP_C12; + gam_regs.masks.csc_c12 = dpp->tf_mask->CM_GAMUT_REMAP_C12; if (select == GAMUT_REMAP_COEFF) { @@ -157,7 +157,7 @@ static void program_gamut_remap( gam_regs.csc_c33_c34 = REG(CM_GAMUT_REMAP_C33_C34); cm_helper_program_color_matrices( - xfm->base.ctx, + dpp->base.ctx, regval, &gam_regs); @@ -167,7 +167,7 @@ static void program_gamut_remap( gam_regs.csc_c33_c34 = REG(CM_COMA_C33_C34); cm_helper_program_color_matrices( - xfm->base.ctx, + dpp->base.ctx, regval, &gam_regs); @@ -177,7 +177,7 @@ static void program_gamut_remap( gam_regs.csc_c33_c34 = REG(CM_COMB_C33_C34); cm_helper_program_color_matrices( - xfm->base.ctx, + dpp->base.ctx, regval, &gam_regs); } @@ -188,15 +188,15 @@ static void program_gamut_remap( } -void dcn10_dpp_cm_set_gamut_remap( - struct transform *xfm, - const struct xfm_grph_csc_adjustment *adjust) +void dpp1_cm_set_gamut_remap( + struct dpp *dpp_base, + const struct dpp_grph_csc_adjustment *adjust) { - struct dcn10_dpp *dcn_xfm = TO_DCN10_DPP(xfm); + struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base); if (adjust->gamut_adjust_type != GRAPHICS_GAMUT_ADJUST_TYPE_SW) /* Bypass if type is bypass or hw */ - program_gamut_remap(dcn_xfm, NULL, GAMUT_REMAP_BYPASS); + program_gamut_remap(dpp, NULL, GAMUT_REMAP_BYPASS); else { struct fixed31_32 arr_matrix[12]; uint16_t arr_reg_val[12]; @@ -219,16 +219,16 @@ void dcn10_dpp_cm_set_gamut_remap( convert_float_matrix( arr_reg_val, arr_matrix, 12); - program_gamut_remap(dcn_xfm, arr_reg_val, GAMUT_REMAP_COEFF); + program_gamut_remap(dpp, arr_reg_val, GAMUT_REMAP_COEFF); } } -void dcn10_dpp_cm_set_output_csc_default( - struct transform *xfm_base, +void dpp1_cm_set_output_csc_default( + struct dpp *dpp_base, const struct default_adjustment *default_adjust) { - struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); + struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base); uint32_t ocsc_mode = 0; if (default_adjust != NULL) { @@ -260,35 +260,35 @@ void dcn10_dpp_cm_set_output_csc_default( } -static void dcn10_dpp_cm_get_reg_field( - struct dcn10_dpp *xfm, +static void dpp1_cm_get_reg_field( + struct dcn10_dpp *dpp, struct xfer_func_reg *reg) { - reg->shifts.exp_region0_lut_offset = xfm->tf_shift->CM_RGAM_RAMA_EXP_REGION0_LUT_OFFSET; - reg->masks.exp_region0_lut_offset = xfm->tf_mask->CM_RGAM_RAMA_EXP_REGION0_LUT_OFFSET; - reg->shifts.exp_region0_num_segments = xfm->tf_shift->CM_RGAM_RAMA_EXP_REGION0_NUM_SEGMENTS; - reg->masks.exp_region0_num_segments = xfm->tf_mask->CM_RGAM_RAMA_EXP_REGION0_NUM_SEGMENTS; - reg->shifts.exp_region1_lut_offset = xfm->tf_shift->CM_RGAM_RAMA_EXP_REGION1_LUT_OFFSET; - reg->masks.exp_region1_lut_offset = xfm->tf_mask->CM_RGAM_RAMA_EXP_REGION1_LUT_OFFSET; - reg->shifts.exp_region1_num_segments = xfm->tf_shift->CM_RGAM_RAMA_EXP_REGION1_NUM_SEGMENTS; - reg->masks.exp_region1_num_segments = xfm->tf_mask->CM_RGAM_RAMA_EXP_REGION1_NUM_SEGMENTS; - - reg->shifts.field_region_end = xfm->tf_shift->CM_RGAM_RAMB_EXP_REGION_END_B; - reg->masks.field_region_end = xfm->tf_mask->CM_RGAM_RAMB_EXP_REGION_END_B; - reg->shifts.field_region_end_slope = xfm->tf_shift->CM_RGAM_RAMB_EXP_REGION_END_SLOPE_B; - reg->masks.field_region_end_slope = xfm->tf_mask->CM_RGAM_RAMB_EXP_REGION_END_SLOPE_B; - reg->shifts.field_region_end_base = xfm->tf_shift->CM_RGAM_RAMB_EXP_REGION_END_BASE_B; - reg->masks.field_region_end_base = xfm->tf_mask->CM_RGAM_RAMB_EXP_REGION_END_BASE_B; - reg->shifts.field_region_linear_slope = xfm->tf_shift->CM_RGAM_RAMB_EXP_REGION_LINEAR_SLOPE_B; - reg->masks.field_region_linear_slope = xfm->tf_mask->CM_RGAM_RAMB_EXP_REGION_LINEAR_SLOPE_B; - reg->shifts.exp_region_start = xfm->tf_shift->CM_RGAM_RAMB_EXP_REGION_START_B; - reg->masks.exp_region_start = xfm->tf_mask->CM_RGAM_RAMB_EXP_REGION_START_B; - reg->shifts.exp_resion_start_segment = xfm->tf_shift->CM_RGAM_RAMB_EXP_REGION_START_SEGMENT_B; - reg->masks.exp_resion_start_segment = xfm->tf_mask->CM_RGAM_RAMB_EXP_REGION_START_SEGMENT_B; + reg->shifts.exp_region0_lut_offset = dpp->tf_shift->CM_RGAM_RAMA_EXP_REGION0_LUT_OFFSET; + reg->masks.exp_region0_lut_offset = dpp->tf_mask->CM_RGAM_RAMA_EXP_REGION0_LUT_OFFSET; + reg->shifts.exp_region0_num_segments = dpp->tf_shift->CM_RGAM_RAMA_EXP_REGION0_NUM_SEGMENTS; + reg->masks.exp_region0_num_segments = dpp->tf_mask->CM_RGAM_RAMA_EXP_REGION0_NUM_SEGMENTS; + reg->shifts.exp_region1_lut_offset = dpp->tf_shift->CM_RGAM_RAMA_EXP_REGION1_LUT_OFFSET; + reg->masks.exp_region1_lut_offset = dpp->tf_mask->CM_RGAM_RAMA_EXP_REGION1_LUT_OFFSET; + reg->shifts.exp_region1_num_segments = dpp->tf_shift->CM_RGAM_RAMA_EXP_REGION1_NUM_SEGMENTS; + reg->masks.exp_region1_num_segments = dpp->tf_mask->CM_RGAM_RAMA_EXP_REGION1_NUM_SEGMENTS; + + reg->shifts.field_region_end = dpp->tf_shift->CM_RGAM_RAMB_EXP_REGION_END_B; + reg->masks.field_region_end = dpp->tf_mask->CM_RGAM_RAMB_EXP_REGION_END_B; + reg->shifts.field_region_end_slope = dpp->tf_shift->CM_RGAM_RAMB_EXP_REGION_END_SLOPE_B; + reg->masks.field_region_end_slope = dpp->tf_mask->CM_RGAM_RAMB_EXP_REGION_END_SLOPE_B; + reg->shifts.field_region_end_base = dpp->tf_shift->CM_RGAM_RAMB_EXP_REGION_END_BASE_B; + reg->masks.field_region_end_base = dpp->tf_mask->CM_RGAM_RAMB_EXP_REGION_END_BASE_B; + reg->shifts.field_region_linear_slope = dpp->tf_shift->CM_RGAM_RAMB_EXP_REGION_LINEAR_SLOPE_B; + reg->masks.field_region_linear_slope = dpp->tf_mask->CM_RGAM_RAMB_EXP_REGION_LINEAR_SLOPE_B; + reg->shifts.exp_region_start = dpp->tf_shift->CM_RGAM_RAMB_EXP_REGION_START_B; + reg->masks.exp_region_start = dpp->tf_mask->CM_RGAM_RAMB_EXP_REGION_START_B; + reg->shifts.exp_resion_start_segment = dpp->tf_shift->CM_RGAM_RAMB_EXP_REGION_START_SEGMENT_B; + reg->masks.exp_resion_start_segment = dpp->tf_mask->CM_RGAM_RAMB_EXP_REGION_START_SEGMENT_B; } -static void dcn10_dpp_cm_program_color_matrix( - struct dcn10_dpp *xfm, +static void dpp1_cm_program_color_matrix( + struct dcn10_dpp *dpp, const struct out_csc_color_matrix *tbl_entry) { uint32_t mode; @@ -301,10 +301,10 @@ static void dcn10_dpp_cm_program_color_matrix( return; } - gam_regs.shifts.csc_c11 = xfm->tf_shift->CM_OCSC_C11; - gam_regs.masks.csc_c11 = xfm->tf_mask->CM_OCSC_C11; - gam_regs.shifts.csc_c12 = xfm->tf_shift->CM_OCSC_C12; - gam_regs.masks.csc_c12 = xfm->tf_mask->CM_OCSC_C12; + gam_regs.shifts.csc_c11 = dpp->tf_shift->CM_OCSC_C11; + gam_regs.masks.csc_c11 = dpp->tf_mask->CM_OCSC_C11; + gam_regs.shifts.csc_c12 = dpp->tf_shift->CM_OCSC_C12; + gam_regs.masks.csc_c12 = dpp->tf_mask->CM_OCSC_C12; if (mode == 4) { @@ -312,7 +312,7 @@ static void dcn10_dpp_cm_program_color_matrix( gam_regs.csc_c33_c34 = REG(CM_OCSC_C33_C34); cm_helper_program_color_matrices( - xfm->base.ctx, + dpp->base.ctx, tbl_entry->regval, &gam_regs); @@ -322,17 +322,17 @@ static void dcn10_dpp_cm_program_color_matrix( gam_regs.csc_c33_c34 = REG(CM_COMB_C33_C34); cm_helper_program_color_matrices( - xfm->base.ctx, + dpp->base.ctx, tbl_entry->regval, &gam_regs); } } -void dcn10_dpp_cm_set_output_csc_adjustment( - struct transform *xfm_base, +void dpp1_cm_set_output_csc_adjustment( + struct dpp *dpp_base, const struct out_csc_color_matrix *tbl_entry) { - struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); + struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base); //enum csc_color_mode config = CSC_COLOR_MODE_GRAPHICS_OUTPUT_CSC; uint32_t ocsc_mode = 4; @@ -364,26 +364,26 @@ void dcn10_dpp_cm_set_output_csc_adjustment( */ REG_SET(CM_OCSC_CONTROL, 0, CM_OCSC_MODE, ocsc_mode); - dcn10_dpp_cm_program_color_matrix(xfm, tbl_entry); + dpp1_cm_program_color_matrix(dpp, tbl_entry); } -void dcn10_dpp_cm_power_on_regamma_lut( - struct transform *xfm_base, +void dpp1_cm_power_on_regamma_lut( + struct dpp *dpp_base, bool power_on) { - struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); + struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base); REG_SET(CM_MEM_PWR_CTRL, 0, RGAM_MEM_PWR_FORCE, power_on == true ? 0:1); } -void dcn10_dpp_cm_program_regamma_lut( - struct transform *xfm_base, +void dpp1_cm_program_regamma_lut( + struct dpp *dpp_base, const struct pwl_result_data *rgb, uint32_t num) { uint32_t i; - struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); + struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base); for (i = 0 ; i < num; i++) { REG_SET(CM_RGAM_LUT_DATA, 0, CM_RGAM_LUT_DATA, rgb[i].red_reg); REG_SET(CM_RGAM_LUT_DATA, 0, CM_RGAM_LUT_DATA, rgb[i].green_reg); @@ -400,11 +400,11 @@ void dcn10_dpp_cm_program_regamma_lut( } -void dcn10_dpp_cm_configure_regamma_lut( - struct transform *xfm_base, +void dpp1_cm_configure_regamma_lut( + struct dpp *dpp_base, bool is_ram_a) { - struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); + struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base); REG_UPDATE(CM_RGAM_LUT_WRITE_EN_MASK, CM_RGAM_LUT_WRITE_EN_MASK, 7); @@ -414,14 +414,14 @@ void dcn10_dpp_cm_configure_regamma_lut( } /*program re gamma RAM A*/ -void dcn10_dpp_cm_program_regamma_luta_settings( - struct transform *xfm_base, +void dpp1_cm_program_regamma_luta_settings( + struct dpp *dpp_base, const struct pwl_params *params) { - struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); + struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base); struct xfer_func_reg gam_regs; - dcn10_dpp_cm_get_reg_field(xfm, &gam_regs); + dpp1_cm_get_reg_field(dpp, &gam_regs); gam_regs.start_cntl_b = REG(CM_RGAM_RAMA_START_CNTL_B); gam_regs.start_cntl_g = REG(CM_RGAM_RAMA_START_CNTL_G); @@ -438,19 +438,19 @@ void dcn10_dpp_cm_program_regamma_luta_settings( gam_regs.region_start = REG(CM_RGAM_RAMA_REGION_0_1); gam_regs.region_end = REG(CM_RGAM_RAMA_REGION_32_33); - cm_helper_program_xfer_func(xfm->base.ctx, params, &gam_regs); + cm_helper_program_xfer_func(dpp->base.ctx, params, &gam_regs); } /*program re gamma RAM B*/ -void dcn10_dpp_cm_program_regamma_lutb_settings( - struct transform *xfm_base, +void dpp1_cm_program_regamma_lutb_settings( + struct dpp *dpp_base, const struct pwl_params *params) { - struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); + struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base); struct xfer_func_reg gam_regs; - dcn10_dpp_cm_get_reg_field(xfm, &gam_regs); + dpp1_cm_get_reg_field(dpp, &gam_regs); gam_regs.start_cntl_b = REG(CM_RGAM_RAMB_START_CNTL_B); gam_regs.start_cntl_g = REG(CM_RGAM_RAMB_START_CNTL_G); @@ -467,15 +467,15 @@ void dcn10_dpp_cm_program_regamma_lutb_settings( gam_regs.region_start = REG(CM_RGAM_RAMB_REGION_0_1); gam_regs.region_end = REG(CM_RGAM_RAMB_REGION_32_33); - cm_helper_program_xfer_func(xfm->base.ctx, params, &gam_regs); + cm_helper_program_xfer_func(dpp->base.ctx, params, &gam_regs); } -void ippn10_program_input_csc( - struct transform *xfm_base, +void dpp1_program_input_csc( + struct dpp *dpp_base, enum dc_color_space color_space, enum dcn10_input_csc_select select) { - struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); + struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base); int i; int arr_size = sizeof(dcn10_input_csc_matrix)/sizeof(struct dcn10_input_csc_matrix); const uint16_t *regval = NULL; @@ -503,10 +503,10 @@ void ippn10_program_input_csc( REG_SET(CM_ICSC_CONTROL, 0, CM_ICSC_MODE, selection); - gam_regs.shifts.csc_c11 = xfm->tf_shift->CM_ICSC_C11; - gam_regs.masks.csc_c11 = xfm->tf_mask->CM_ICSC_C11; - gam_regs.shifts.csc_c12 = xfm->tf_shift->CM_ICSC_C12; - gam_regs.masks.csc_c12 = xfm->tf_mask->CM_ICSC_C12; + gam_regs.shifts.csc_c11 = dpp->tf_shift->CM_ICSC_C11; + gam_regs.masks.csc_c11 = dpp->tf_mask->CM_ICSC_C11; + gam_regs.shifts.csc_c12 = dpp->tf_shift->CM_ICSC_C12; + gam_regs.masks.csc_c12 = dpp->tf_mask->CM_ICSC_C12; if (select == INPUT_CSC_SELECT_ICSC) { @@ -515,7 +515,7 @@ void ippn10_program_input_csc( gam_regs.csc_c33_c34 = REG(CM_ICSC_C33_C34); cm_helper_program_color_matrices( - xfm->base.ctx, + dpp->base.ctx, regval, &gam_regs); } else { @@ -524,21 +524,21 @@ void ippn10_program_input_csc( gam_regs.csc_c33_c34 = REG(CM_COMA_C33_C34); cm_helper_program_color_matrices( - xfm->base.ctx, + dpp->base.ctx, regval, &gam_regs); } } /*program de gamma RAM B*/ -void ippn10_program_degamma_lutb_settings( - struct transform *xfm_base, +void dpp1_program_degamma_lutb_settings( + struct dpp *dpp_base, const struct pwl_params *params) { - struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); + struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base); struct xfer_func_reg gam_regs; - dcn10_dpp_cm_get_reg_field(xfm, &gam_regs); + dpp1_cm_get_reg_field(dpp, &gam_regs); gam_regs.start_cntl_b = REG(CM_DGAM_RAMB_START_CNTL_B); gam_regs.start_cntl_g = REG(CM_DGAM_RAMB_START_CNTL_G); @@ -556,18 +556,18 @@ void ippn10_program_degamma_lutb_settings( gam_regs.region_end = REG(CM_DGAM_RAMB_REGION_14_15); - cm_helper_program_xfer_func(xfm->base.ctx, params, &gam_regs); + cm_helper_program_xfer_func(dpp->base.ctx, params, &gam_regs); } /*program de gamma RAM A*/ -void ippn10_program_degamma_luta_settings( - struct transform *xfm_base, +void dpp1_program_degamma_luta_settings( + struct dpp *dpp_base, const struct pwl_params *params) { - struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); + struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base); struct xfer_func_reg gam_regs; - dcn10_dpp_cm_get_reg_field(xfm, &gam_regs); + dpp1_cm_get_reg_field(dpp, &gam_regs); gam_regs.start_cntl_b = REG(CM_DGAM_RAMA_START_CNTL_B); gam_regs.start_cntl_g = REG(CM_DGAM_RAMA_START_CNTL_G); @@ -584,34 +584,35 @@ void ippn10_program_degamma_luta_settings( gam_regs.region_start = REG(CM_DGAM_RAMA_REGION_0_1); gam_regs.region_end = REG(CM_DGAM_RAMA_REGION_14_15); - cm_helper_program_xfer_func(xfm->base.ctx, params, &gam_regs); + cm_helper_program_xfer_func(dpp->base.ctx, params, &gam_regs); } -void ippn10_power_on_degamma_lut( - struct transform *xfm_base, +void dpp1_power_on_degamma_lut( + struct dpp *dpp_base, bool power_on) { - struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); + struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base); REG_SET(CM_MEM_PWR_CTRL, 0, SHARED_MEM_PWR_DIS, power_on == true ? 0:1); } -static void ippn10_enable_cm_block( - struct transform *xfm_base) +static void dpp1_enable_cm_block( + struct dpp *dpp_base) { - struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); + struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base); + REG_UPDATE(CM_CMOUT_CONTROL, CM_CMOUT_ROUND_TRUNC_MODE, 8); REG_UPDATE(CM_CONTROL, CM_BYPASS_EN, 0); } -void ippn10_set_degamma( - struct transform *xfm_base, +void dpp1_set_degamma( + struct dpp *dpp_base, enum ipp_degamma_mode mode) { - struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); - ippn10_enable_cm_block(xfm_base); + struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base); + dpp1_enable_cm_block(dpp_base); switch (mode) { case IPP_DEGAMMA_MODE_BYPASS: @@ -630,11 +631,11 @@ void ippn10_set_degamma( } } -void ippn10_degamma_ram_select( - struct transform *xfm_base, +void dpp1_degamma_ram_select( + struct dpp *dpp_base, bool use_ram_a) { - struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); + struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base); if (use_ram_a) REG_UPDATE(CM_DGAM_CONTROL, CM_DGAM_LUT_MODE, 3); @@ -643,13 +644,13 @@ void ippn10_degamma_ram_select( } -static bool ippn10_degamma_ram_inuse( - struct transform *xfm_base, +static bool dpp1_degamma_ram_inuse( + struct dpp *dpp_base, bool *ram_a_inuse) { bool ret = false; uint32_t status_reg = 0; - struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); + struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base); REG_GET(CM_IGAM_LUT_RW_CONTROL, CM_IGAM_DGAM_CONFIG_STATUS, &status_reg); @@ -664,15 +665,15 @@ static bool ippn10_degamma_ram_inuse( return ret; } -void ippn10_program_degamma_lut( - struct transform *xfm_base, +void dpp1_program_degamma_lut( + struct dpp *dpp_base, const struct pwl_result_data *rgb, uint32_t num, bool is_ram_a) { uint32_t i; - struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); + struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base); REG_UPDATE(CM_IGAM_LUT_RW_CONTROL, CM_IGAM_LUT_HOST_EN, 0); REG_UPDATE(CM_DGAM_LUT_WRITE_EN_MASK, CM_DGAM_LUT_WRITE_EN_MASK, 7); @@ -694,27 +695,27 @@ void ippn10_program_degamma_lut( } } -void ippn10_set_degamma_pwl(struct transform *xfm_base, +void dpp1_set_degamma_pwl(struct dpp *dpp_base, const struct pwl_params *params) { bool is_ram_a = true; - ippn10_power_on_degamma_lut(xfm_base, true); - ippn10_enable_cm_block(xfm_base); - ippn10_degamma_ram_inuse(xfm_base, &is_ram_a); + dpp1_power_on_degamma_lut(dpp_base, true); + dpp1_enable_cm_block(dpp_base); + dpp1_degamma_ram_inuse(dpp_base, &is_ram_a); if (is_ram_a == true) - ippn10_program_degamma_lutb_settings(xfm_base, params); + dpp1_program_degamma_lutb_settings(dpp_base, params); else - ippn10_program_degamma_luta_settings(xfm_base, params); + dpp1_program_degamma_luta_settings(dpp_base, params); - ippn10_program_degamma_lut(xfm_base, params->rgb_resulted, + dpp1_program_degamma_lut(dpp_base, params->rgb_resulted, params->hw_points_num, !is_ram_a); - ippn10_degamma_ram_select(xfm_base, !is_ram_a); + dpp1_degamma_ram_select(dpp_base, !is_ram_a); } -void ippn10_full_bypass(struct transform *xfm_base) +void dpp1_full_bypass(struct dpp *dpp_base) { - struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); + struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base); /* Input pixel format: ARGB8888 */ REG_SET(CNVC_SURFACE_PIXEL_FORMAT, 0, @@ -727,19 +728,19 @@ void ippn10_full_bypass(struct transform *xfm_base) FORMAT_EXPANSION_MODE, 0); /* COLOR_KEYER_CONTROL.COLOR_KEYER_EN = 0 this should be default */ - if (xfm->tf_mask->CM_BYPASS_EN) + if (dpp->tf_mask->CM_BYPASS_EN) REG_SET(CM_CONTROL, 0, CM_BYPASS_EN, 1); /* Setting degamma bypass for now */ REG_SET(CM_DGAM_CONTROL, 0, CM_DGAM_LUT_MODE, 0); } -static bool ippn10_ingamma_ram_inuse(struct transform *xfm_base, +static bool dpp1_ingamma_ram_inuse(struct dpp *dpp_base, bool *ram_a_inuse) { bool in_use = false; uint32_t status_reg = 0; - struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); + struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base); REG_GET(CM_IGAM_LUT_RW_CONTROL, CM_IGAM_DGAM_CONFIG_STATUS, &status_reg); @@ -765,19 +766,19 @@ static bool ippn10_ingamma_ram_inuse(struct transform *xfm_base, * In the future, this function should support additional input gamma methods, * such as piecewise linear mapping, and input gamma bypass. */ -void ippn10_program_input_lut( - struct transform *xfm_base, +void dpp1_program_input_lut( + struct dpp *dpp_base, const struct dc_gamma *gamma) { int i; - struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); + struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base); bool rama_occupied = false; uint32_t ram_num; // Power on LUT memory. REG_SET(CM_MEM_PWR_CTRL, 0, SHARED_MEM_PWR_DIS, 1); - ippn10_enable_cm_block(xfm_base); + dpp1_enable_cm_block(dpp_base); // Determine whether to use RAM A or RAM B - ippn10_ingamma_ram_inuse(xfm_base, &rama_occupied); + dpp1_ingamma_ram_inuse(dpp_base, &rama_occupied); if (!rama_occupied) REG_UPDATE(CM_IGAM_LUT_RW_CONTROL, CM_IGAM_LUT_SEL, 0); else diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c index eda6c8010fb8a..b443a90974b93 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c @@ -40,14 +40,14 @@ #define BLACK_OFFSET_CBCR 0x8000 #define REG(reg)\ - xfm->tf_regs->reg + dpp->tf_regs->reg #define CTX \ - xfm->base.ctx + dpp->base.ctx #undef FN #define FN(reg_name, field_name) \ - xfm->tf_shift->field_name, xfm->tf_mask->field_name + dpp->tf_shift->field_name, dpp->tf_mask->field_name enum dcn10_coef_filter_type_sel { SCL_COEF_LUMA_VERT_FILTER = 0, @@ -86,7 +86,7 @@ enum dscl_mode_sel { }; static void dpp_set_overscan( - struct dcn10_dpp *xfm, + struct dcn10_dpp *dpp, const struct scaler_data *data) { uint32_t left = data->recout.x; @@ -114,7 +114,7 @@ static void dpp_set_overscan( } static void dpp_set_otg_blank( - struct dcn10_dpp *xfm, const struct scaler_data *data) + struct dcn10_dpp *dpp, const struct scaler_data *data) { uint32_t h_blank_start = data->h_active; uint32_t h_blank_end = 0; @@ -165,13 +165,13 @@ static bool is_420_format(enum pixel_format format) } static enum dscl_mode_sel get_dscl_mode( - struct transform *xfm_base, + struct dpp *dpp_base, const struct scaler_data *data, bool dbg_always_scale) { const long long one = dal_fixed31_32_one.value; - if (xfm_base->caps->dscl_data_proc_format == DSCL_DATA_PRCESSING_FIXED_FORMAT) { + if (dpp_base->caps->dscl_data_proc_format == DSCL_DATA_PRCESSING_FIXED_FORMAT) { /* DSCL is processing data in fixed format */ if (data->format == PIXEL_FORMAT_FP16) return DSCL_MODE_DSCL_BYPASS; @@ -199,12 +199,12 @@ static enum dscl_mode_sel get_dscl_mode( } static void dpp_set_lb( - struct dcn10_dpp *xfm, + struct dcn10_dpp *dpp, const struct line_buffer_params *lb_params, enum lb_memory_config mem_size_config) { /* LB */ - if (xfm->base.caps->dscl_data_proc_format == DSCL_DATA_PRCESSING_FIXED_FORMAT) { + if (dpp->base.caps->dscl_data_proc_format == DSCL_DATA_PRCESSING_FIXED_FORMAT) { /* DSCL caps: pixel data processed in fixed format */ uint32_t pixel_depth = get_pixel_depth_val(lb_params->depth); uint32_t dyn_pix_depth = lb_params->dynamic_pixel_depth; @@ -250,7 +250,7 @@ static const uint16_t *get_filter_coeffs_64p(int taps, struct fixed31_32 ratio) } static void dpp_set_scaler_filter( - struct dcn10_dpp *xfm, + struct dcn10_dpp *dpp, uint32_t taps, enum dcn10_coef_filter_type_sel filter_type, const uint16_t *filter) @@ -288,7 +288,7 @@ static void dpp_set_scaler_filter( } static void dpp_set_scl_filter( - struct dcn10_dpp *xfm, + struct dcn10_dpp *dpp, const struct scaler_data *scl_data, bool chroma_coef_mode) { @@ -330,16 +330,16 @@ static void dpp_set_scl_filter( filter_v = get_filter_coeffs_64p( scl_data->taps.v_taps, scl_data->ratios.vert); - filter_updated = (filter_h && (filter_h != xfm->filter_h)) - || (filter_v && (filter_v != xfm->filter_v)); + filter_updated = (filter_h && (filter_h != dpp->filter_h)) + || (filter_v && (filter_v != dpp->filter_v)); if (chroma_coef_mode) { filter_h_c = get_filter_coeffs_64p( scl_data->taps.h_taps_c, scl_data->ratios.horz_c); filter_v_c = get_filter_coeffs_64p( scl_data->taps.v_taps_c, scl_data->ratios.vert_c); - filter_updated = filter_updated || (filter_h_c && (filter_h_c != xfm->filter_h_c)) - || (filter_v_c && (filter_v_c != xfm->filter_v_c)); + filter_updated = filter_updated || (filter_h_c && (filter_h_c != dpp->filter_h_c)) + || (filter_v_c && (filter_v_c != dpp->filter_v_c)); } if (filter_updated) { @@ -347,34 +347,34 @@ static void dpp_set_scl_filter( if (!h_2tap_hardcode_coef_en && filter_h) { dpp_set_scaler_filter( - xfm, scl_data->taps.h_taps, + dpp, scl_data->taps.h_taps, SCL_COEF_LUMA_HORZ_FILTER, filter_h); } - xfm->filter_h = filter_h; + dpp->filter_h = filter_h; if (!v_2tap_hardcode_coef_en && filter_v) { dpp_set_scaler_filter( - xfm, scl_data->taps.v_taps, + dpp, scl_data->taps.v_taps, SCL_COEF_LUMA_VERT_FILTER, filter_v); } - xfm->filter_v = filter_v; + dpp->filter_v = filter_v; if (chroma_coef_mode) { if (!h_2tap_hardcode_coef_en && filter_h_c) { dpp_set_scaler_filter( - xfm, scl_data->taps.h_taps_c, + dpp, scl_data->taps.h_taps_c, SCL_COEF_CHROMA_HORZ_FILTER, filter_h_c); } if (!v_2tap_hardcode_coef_en && filter_v_c) { dpp_set_scaler_filter( - xfm, scl_data->taps.v_taps_c, + dpp, scl_data->taps.v_taps_c, SCL_COEF_CHROMA_VERT_FILTER, filter_v_c); } } - xfm->filter_h_c = filter_h_c; - xfm->filter_v_c = filter_v_c; + dpp->filter_h_c = filter_h_c; + dpp->filter_v_c = filter_v_c; coef_ram_current = get_reg_field_value_ex( - scl_mode, xfm->tf_mask->SCL_COEF_RAM_SELECT_CURRENT, - xfm->tf_shift->SCL_COEF_RAM_SELECT_CURRENT); + scl_mode, dpp->tf_mask->SCL_COEF_RAM_SELECT_CURRENT, + dpp->tf_shift->SCL_COEF_RAM_SELECT_CURRENT); /* Swap coefficient RAM and set chroma coefficient mode */ REG_SET_2(SCL_MODE, scl_mode, @@ -458,7 +458,7 @@ bool is_lb_conf_valid(int ceil_vratio, int num_partitions, int vtaps) } /*find first match configuration which meets the min required lb size*/ -static enum lb_memory_config find_lb_memory_config(struct dcn10_dpp *xfm, +static enum lb_memory_config find_lb_memory_config(struct dcn10_dpp *dpp, const struct scaler_data *scl_data) { int num_part_y, num_part_c; @@ -468,17 +468,17 @@ static enum lb_memory_config find_lb_memory_config(struct dcn10_dpp *xfm, int ceil_vratio_c = dal_fixed31_32_ceil(scl_data->ratios.vert_c); enum lb_memory_config mem_cfg = LB_MEMORY_CONFIG_0; - if (xfm->base.ctx->dc->debug.use_max_lb) + if (dpp->base.ctx->dc->debug.use_max_lb) return mem_cfg; - xfm->base.caps->dscl_calc_lb_num_partitions( + dpp->base.caps->dscl_calc_lb_num_partitions( scl_data, LB_MEMORY_CONFIG_1, &num_part_y, &num_part_c); if (is_lb_conf_valid(ceil_vratio, num_part_y, vtaps) && is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c)) return LB_MEMORY_CONFIG_1; - xfm->base.caps->dscl_calc_lb_num_partitions( + dpp->base.caps->dscl_calc_lb_num_partitions( scl_data, LB_MEMORY_CONFIG_2, &num_part_y, &num_part_c); if (is_lb_conf_valid(ceil_vratio, num_part_y, vtaps) @@ -487,7 +487,7 @@ static enum lb_memory_config find_lb_memory_config(struct dcn10_dpp *xfm, if (scl_data->format == PIXEL_FORMAT_420BPP8 || scl_data->format == PIXEL_FORMAT_420BPP10) { - xfm->base.caps->dscl_calc_lb_num_partitions( + dpp->base.caps->dscl_calc_lb_num_partitions( scl_data, LB_MEMORY_CONFIG_3, &num_part_y, &num_part_c); if (is_lb_conf_valid(ceil_vratio, num_part_y, vtaps) @@ -495,7 +495,7 @@ static enum lb_memory_config find_lb_memory_config(struct dcn10_dpp *xfm, return LB_MEMORY_CONFIG_3; } - xfm->base.caps->dscl_calc_lb_num_partitions( + dpp->base.caps->dscl_calc_lb_num_partitions( scl_data, LB_MEMORY_CONFIG_0, &num_part_y, &num_part_c); /*Ensure we can support the requested number of vtaps*/ @@ -506,27 +506,27 @@ static enum lb_memory_config find_lb_memory_config(struct dcn10_dpp *xfm, } void dpp_set_scaler_auto_scale( - struct transform *xfm_base, + struct dpp *dpp_base, const struct scaler_data *scl_data) { enum lb_memory_config lb_config; - struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); + struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base); enum dscl_mode_sel dscl_mode = get_dscl_mode( - xfm_base, scl_data, xfm_base->ctx->dc->debug.always_scale); + dpp_base, scl_data, dpp_base->ctx->dc->debug.always_scale); bool ycbcr = scl_data->format >= PIXEL_FORMAT_VIDEO_BEGIN && scl_data->format <= PIXEL_FORMAT_VIDEO_END; - dpp_set_overscan(xfm, scl_data); + dpp_set_overscan(dpp, scl_data); - dpp_set_otg_blank(xfm, scl_data); + dpp_set_otg_blank(dpp, scl_data); REG_UPDATE(SCL_MODE, DSCL_MODE, dscl_mode); if (dscl_mode == DSCL_MODE_DSCL_BYPASS) return; - lb_config = find_lb_memory_config(xfm, scl_data); - dpp_set_lb(xfm, &scl_data->lb_params, lb_config); + lb_config = find_lb_memory_config(dpp, scl_data); + dpp_set_lb(dpp, &scl_data->lb_params, lb_config); if (dscl_mode == DSCL_MODE_SCALING_444_BYPASS) return; @@ -554,12 +554,12 @@ void dpp_set_scaler_auto_scale( SCL_V_NUM_TAPS_C, scl_data->taps.v_taps_c - 1, SCL_H_NUM_TAPS_C, scl_data->taps.h_taps_c - 1); - dpp_set_scl_filter(xfm, scl_data, ycbcr); + dpp_set_scl_filter(dpp, scl_data, ycbcr); } static void dpp_set_manual_ratio_init( - struct dcn10_dpp *xfm, const struct scaler_data *data) + struct dcn10_dpp *dpp, const struct scaler_data *data) { uint32_t init_frac = 0; uint32_t init_int = 0; @@ -619,7 +619,7 @@ static void dpp_set_manual_ratio_init( static void dpp_set_recout( - struct dcn10_dpp *xfm, const struct rect *recout) + struct dcn10_dpp *dpp, const struct rect *recout) { REG_SET_2(RECOUT_START, 0, /* First pixel of RECOUT */ @@ -632,24 +632,24 @@ static void dpp_set_recout( RECOUT_WIDTH, recout->width, /* Number of RECOUT vertical lines */ RECOUT_HEIGHT, recout->height - - xfm->base.ctx->dc->debug.surface_visual_confirm * 4 * - (xfm->base.inst + 1)); + - dpp->base.ctx->dc->debug.surface_visual_confirm * 4 * + (dpp->base.inst + 1)); } /* Main function to program scaler and line buffer in manual scaling mode */ -void dcn10_dpp_dscl_set_scaler_manual_scale( - struct transform *xfm_base, +void dpp1_dscl_set_scaler_manual_scale( + struct dpp *dpp_base, const struct scaler_data *scl_data) { enum lb_memory_config lb_config; - struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); + struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base); enum dscl_mode_sel dscl_mode = get_dscl_mode( - xfm_base, scl_data, xfm_base->ctx->dc->debug.always_scale); + dpp_base, scl_data, dpp_base->ctx->dc->debug.always_scale); bool ycbcr = scl_data->format >= PIXEL_FORMAT_VIDEO_BEGIN && scl_data->format <= PIXEL_FORMAT_VIDEO_END; /* Recout */ - dpp_set_recout(xfm, &scl_data->recout); + dpp_set_recout(dpp, &scl_data->recout); /* MPC Size */ REG_SET_2(MPC_SIZE, 0, @@ -665,8 +665,8 @@ void dcn10_dpp_dscl_set_scaler_manual_scale( return; /* LB */ - lb_config = find_lb_memory_config(xfm, scl_data); - dpp_set_lb(xfm, &scl_data->lb_params, lb_config); + lb_config = find_lb_memory_config(dpp, scl_data); + dpp_set_lb(dpp, &scl_data->lb_params, lb_config); if (dscl_mode == DSCL_MODE_SCALING_444_BYPASS) return; @@ -689,7 +689,7 @@ void dcn10_dpp_dscl_set_scaler_manual_scale( SCL_BLACK_OFFSET_CBCR, BLACK_OFFSET_RGB_Y); /* Manually calculate scale ratio and init values */ - dpp_set_manual_ratio_init(xfm, scl_data); + dpp_set_manual_ratio_init(dpp, scl_data); /* HTaps/VTaps */ REG_SET_4(SCL_TAP_CONTROL, 0, @@ -698,5 +698,5 @@ void dcn10_dpp_dscl_set_scaler_manual_scale( SCL_V_NUM_TAPS_C, scl_data->taps.v_taps_c - 1, SCL_H_NUM_TAPS_C, scl_data->taps.h_taps_c - 1); - dpp_set_scl_filter(xfm, scl_data, ycbcr); + dpp_set_scl_filter(dpp, scl_data, ycbcr); } diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index 6b866b1699859..b69884549fc51 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -895,10 +895,10 @@ static void dcn10_init_hw(struct dc *dc) } for (i = 0; i < dc->res_pool->pipe_count; i++) { - struct transform *xfm = dc->res_pool->transforms[i]; + struct dpp *dpp = dc->res_pool->dpps[i]; struct timing_generator *tg = dc->res_pool->timing_generators[i]; - xfm->funcs->transform_reset(xfm); + dpp->funcs->dpp_reset(dpp); dc->res_pool->mpc->funcs->remove( dc->res_pool->mpc, &(dc->res_pool->opps[i]->mpc_tree), dc->res_pool->opps[i]->inst, i); @@ -1146,14 +1146,14 @@ static void plane_atomic_disable(struct dc *dc, static void plane_atomic_power_down(struct dc *dc, int fe_idx) { struct dce_hwseq *hws = dc->hwseq; - struct transform *xfm = dc->res_pool->transforms[fe_idx]; + struct dpp *dpp = dc->res_pool->dpps[fe_idx]; if (REG(DC_IP_REQUEST_CNTL)) { REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1); dpp_pg_control(hws, fe_idx, false); hubp_pg_control(hws, fe_idx, false); - xfm->funcs->transform_reset(xfm); + dpp->funcs->dpp_reset(dpp); REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 0); dm_logger_write(dc->ctx->logger, LOG_DEBUG, @@ -1203,7 +1203,7 @@ static void reset_front_end( static void dcn10_power_down_fe(struct dc *dc, int fe_idx) { struct dce_hwseq *hws = dc->hwseq; - struct transform *xfm = dc->res_pool->transforms[fe_idx]; + struct dpp *dpp = dc->res_pool->dpps[fe_idx]; reset_front_end(dc, fe_idx); @@ -1211,7 +1211,7 @@ static void dcn10_power_down_fe(struct dc *dc, int fe_idx) IP_REQUEST_EN, 1); dpp_pg_control(hws, fe_idx, false); hubp_pg_control(hws, fe_idx, false); - xfm->funcs->transform_reset(xfm); + dpp->funcs->dpp_reset(dpp); REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 0); dm_logger_write(dc->ctx->logger, LOG_DEBUG, @@ -1365,34 +1365,34 @@ static void dcn10_update_plane_addr(const struct dc *dc, struct pipe_ctx *pipe_c static bool dcn10_set_input_transfer_func( struct pipe_ctx *pipe_ctx, const struct dc_plane_state *plane_state) { - struct transform *xfm_base = pipe_ctx->plane_res.xfm; + struct dpp *dpp_base = pipe_ctx->plane_res.dpp; const struct dc_transfer_func *tf = NULL; bool result = true; - if (xfm_base == NULL) + if (dpp_base == NULL) return false; if (plane_state->in_transfer_func) tf = plane_state->in_transfer_func; if (plane_state->gamma_correction && dce_use_lut(plane_state)) - xfm_base->funcs->ipp_program_input_lut(xfm_base, + dpp_base->funcs->ipp_program_input_lut(dpp_base, plane_state->gamma_correction); if (tf == NULL) - xfm_base->funcs->ipp_set_degamma(xfm_base, IPP_DEGAMMA_MODE_BYPASS); + dpp_base->funcs->ipp_set_degamma(dpp_base, IPP_DEGAMMA_MODE_BYPASS); else if (tf->type == TF_TYPE_PREDEFINED) { switch (tf->tf) { case TRANSFER_FUNCTION_SRGB: - xfm_base->funcs->ipp_set_degamma(xfm_base, + dpp_base->funcs->ipp_set_degamma(dpp_base, IPP_DEGAMMA_MODE_HW_sRGB); break; case TRANSFER_FUNCTION_BT709: - xfm_base->funcs->ipp_set_degamma(xfm_base, + dpp_base->funcs->ipp_set_degamma(dpp_base, IPP_DEGAMMA_MODE_HW_xvYCC); break; case TRANSFER_FUNCTION_LINEAR: - xfm_base->funcs->ipp_set_degamma(xfm_base, + dpp_base->funcs->ipp_set_degamma(dpp_base, IPP_DEGAMMA_MODE_BYPASS); break; case TRANSFER_FUNCTION_PQ: @@ -1403,7 +1403,7 @@ static bool dcn10_set_input_transfer_func( break; } } else if (tf->type == TF_TYPE_BYPASS) { - xfm_base->funcs->ipp_set_degamma(xfm_base, IPP_DEGAMMA_MODE_BYPASS); + dpp_base->funcs->ipp_set_degamma(dpp_base, IPP_DEGAMMA_MODE_BYPASS); } else { /*TF_TYPE_DISTRIBUTED_POINTS*/ result = false; @@ -1730,25 +1730,25 @@ static bool dcn10_set_output_transfer_func( struct pipe_ctx *pipe_ctx, const struct dc_stream_state *stream) { - struct transform *xfm = pipe_ctx->plane_res.xfm; + struct dpp *dpp = pipe_ctx->plane_res.dpp; - if (xfm == NULL) + if (dpp == NULL) return false; - xfm->regamma_params.hw_points_num = GAMMA_HW_POINTS_NUM; + dpp->regamma_params.hw_points_num = GAMMA_HW_POINTS_NUM; if (stream->out_transfer_func && stream->out_transfer_func->type == TF_TYPE_PREDEFINED && stream->out_transfer_func->tf == TRANSFER_FUNCTION_SRGB) { - xfm->funcs->opp_set_regamma_mode(xfm, OPP_REGAMMA_SRGB); + dpp->funcs->opp_set_regamma_mode(dpp, OPP_REGAMMA_SRGB); } else if (dcn10_translate_regamma_to_hw_format( - stream->out_transfer_func, &xfm->regamma_params)) { - xfm->funcs->opp_program_regamma_pwl(xfm, &xfm->regamma_params); - xfm->funcs->opp_set_regamma_mode(xfm, OPP_REGAMMA_USER); + stream->out_transfer_func, &dpp->regamma_params)) { + dpp->funcs->opp_program_regamma_pwl(dpp, &dpp->regamma_params); + dpp->funcs->opp_set_regamma_mode(dpp, OPP_REGAMMA_USER); } else { - xfm->funcs->opp_set_regamma_mode(xfm, OPP_REGAMMA_BYPASS); + dpp->funcs->opp_set_regamma_mode(dpp, OPP_REGAMMA_BYPASS); } return true; @@ -2033,7 +2033,7 @@ static void dcn10_power_on_fe( static void program_gamut_remap(struct pipe_ctx *pipe_ctx) { - struct xfm_grph_csc_adjustment adjust; + struct dpp_grph_csc_adjustment adjust; memset(&adjust, 0, sizeof(adjust)); adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS; @@ -2069,7 +2069,7 @@ static void program_gamut_remap(struct pipe_ctx *pipe_ctx) gamut_remap_matrix.matrix[10]; } - pipe_ctx->plane_res.xfm->funcs->transform_set_gamut_remap(pipe_ctx->plane_res.xfm, &adjust); + pipe_ctx->plane_res.dpp->funcs->dpp_set_gamut_remap(pipe_ctx->plane_res.dpp, &adjust); } @@ -2091,7 +2091,7 @@ static void program_csc_matrix(struct pipe_ctx *pipe_ctx, tbl_entry.color_space = color_space; //tbl_entry.regval = matrix; - pipe_ctx->plane_res.xfm->funcs->opp_set_csc_adjustment(pipe_ctx->plane_res.xfm, &tbl_entry); + pipe_ctx->plane_res.dpp->funcs->opp_set_csc_adjustment(pipe_ctx->plane_res.dpp, &tbl_entry); } } static bool is_lower_pipe_tree_visible(struct pipe_ctx *pipe_ctx) @@ -2275,7 +2275,7 @@ static void update_dchubp_dpp( { struct dce_hwseq *hws = dc->hwseq; struct hubp *hubp = pipe_ctx->plane_res.hubp; - struct transform *xfm = pipe_ctx->plane_res.xfm; + struct dpp *dpp = pipe_ctx->plane_res.dpp; struct dc_plane_state *plane_state = pipe_ctx->plane_state; union plane_size size = plane_state->plane_size; struct mpcc_cfg mpcc_cfg = {0}; @@ -2317,7 +2317,7 @@ static void update_dchubp_dpp( hws ); - xfm->funcs->ipp_setup(xfm, + dpp->funcs->ipp_setup(dpp, plane_state->format, EXPANSION_MODE_ZERO); @@ -2346,8 +2346,9 @@ static void update_dchubp_dpp( pipe_ctx->plane_res.scl_data.lb_params.alpha_en = per_pixel_alpha; pipe_ctx->plane_res.scl_data.lb_params.depth = LB_PIXEL_DEPTH_30BPP; /* scaler configuration */ - pipe_ctx->plane_res.xfm->funcs->transform_set_scaler( - pipe_ctx->plane_res.xfm, &pipe_ctx->plane_res.scl_data); + pipe_ctx->plane_res.dpp->funcs->dpp_set_scaler( + pipe_ctx->plane_res.dpp, &pipe_ctx->plane_res.scl_data); + hubp->funcs->mem_program_viewport(hubp, &pipe_ctx->plane_res.scl_data.viewport, &pipe_ctx->plane_res.scl_data.viewport_c); diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c index 4764590f90973..4dbaf9a2f2752 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c @@ -446,13 +446,13 @@ static const struct dc_debug debug_defaults_diags = { .disable_pplib_wm_range = true }; -static void dcn10_dpp_destroy(struct transform **xfm) +static void dcn10_dpp_destroy(struct dpp **dpp) { - kfree(TO_DCN10_DPP(*xfm)); - *xfm = NULL; + kfree(TO_DCN10_DPP(*dpp)); + *dpp = NULL; } -static struct transform *dcn10_dpp_create( +static struct dpp *dcn10_dpp_create( struct dc_context *ctx, uint32_t inst) { @@ -462,8 +462,8 @@ static struct transform *dcn10_dpp_create( if (!dpp) return NULL; - dcn10_dpp_construct(dpp, ctx, inst, - &tf_regs[inst], &tf_shift, &tf_mask); + dpp1_construct(dpp, ctx, inst, + &tf_regs[inst], &tf_shift, &tf_mask); return &dpp->base; } @@ -702,8 +702,8 @@ static void destruct(struct dcn10_resource_pool *pool) if (pool->base.opps[i] != NULL) pool->base.opps[i]->funcs->opp_destroy(&pool->base.opps[i]); - if (pool->base.transforms[i] != NULL) - dcn10_dpp_destroy(&pool->base.transforms[i]); + if (pool->base.dpps[i] != NULL) + dcn10_dpp_destroy(&pool->base.dpps[i]); if (pool->base.ipps[i] != NULL) pool->base.ipps[i]->funcs->ipp_destroy(&pool->base.ipps[i]); @@ -924,7 +924,7 @@ static struct pipe_ctx *dcn10_acquire_idle_pipe_for_layer( idle_pipe->plane_res.hubp = pool->hubps[idle_pipe->pipe_idx]; idle_pipe->plane_res.ipp = pool->ipps[idle_pipe->pipe_idx]; - idle_pipe->plane_res.xfm = pool->transforms[idle_pipe->pipe_idx]; + idle_pipe->plane_res.dpp = pool->dpps[idle_pipe->pipe_idx]; return idle_pipe; } @@ -1377,8 +1377,8 @@ static bool construct( goto ipp_create_fail; } - pool->base.transforms[j] = dcn10_dpp_create(ctx, i); - if (pool->base.transforms[j] == NULL) { + pool->base.dpps[j] = dcn10_dpp_create(ctx, i); + if (pool->base.dpps[j] == NULL) { BREAK_TO_DEBUGGER(); dm_error( "DC: failed to create dpp!\n"); diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_types.h b/drivers/gpu/drm/amd/display/dc/inc/core_types.h index 45518c05e8464..b69f321e2ab6d 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h +++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h @@ -84,6 +84,7 @@ void core_link_set_avmute(struct pipe_ctx *pipe_ctx, bool enable); /********** DAL Core*********************/ #include "display_clock.h" #include "transform.h" +#include "dpp.h" struct resource_pool; struct dc_state; @@ -133,6 +134,7 @@ struct resource_pool { struct hubp *hubps[MAX_PIPES]; struct input_pixel_processor *ipps[MAX_PIPES]; struct transform *transforms[MAX_PIPES]; + struct dpp *dpps[MAX_PIPES]; struct output_pixel_processor *opps[MAX_PIPES]; struct timing_generator *timing_generators[MAX_PIPES]; struct stream_encoder *stream_enc[MAX_PIPES * 2]; @@ -184,6 +186,7 @@ struct plane_resource { struct mem_input *mi; struct input_pixel_processor *ipp; struct transform *xfm; + struct dpp *dpp; }; struct pipe_ctx { diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h new file mode 100644 index 0000000000000..83a68460edcda --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h @@ -0,0 +1,134 @@ +/* + * Copyright 2012-15 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: AMD + * + */ + + +#ifndef __DAL_DPP_H__ +#define __DAL_DPP_H__ + +#include "transform.h" + +struct dpp { + const struct dpp_funcs *funcs; + struct dc_context *ctx; + int inst; + struct dpp_caps *caps; + struct pwl_params regamma_params; +}; + +struct dpp_grph_csc_adjustment { + struct fixed31_32 temperature_matrix[CSC_TEMPERATURE_MATRIX_SIZE]; + enum graphics_gamut_adjust_type gamut_adjust_type; +}; + +struct dpp_funcs { + void (*dpp_reset)(struct dpp *dpp); + + void (*dpp_set_scaler)(struct dpp *dpp, + const struct scaler_data *scl_data); + + void (*dpp_set_pixel_storage_depth)( + struct dpp *dpp, + enum lb_pixel_depth depth, + const struct bit_depth_reduction_params *bit_depth_params); + + bool (*dpp_get_optimal_number_of_taps)( + struct dpp *dpp, + struct scaler_data *scl_data, + const struct scaling_taps *in_taps); + + void (*dpp_set_gamut_remap)( + struct dpp *dpp, + const struct dpp_grph_csc_adjustment *adjust); + + void (*opp_set_csc_default)( + struct dpp *dpp, + const struct default_adjustment *default_adjust); + + void (*opp_set_csc_adjustment)( + struct dpp *dpp, + const struct out_csc_color_matrix *tbl_entry); + + void (*opp_power_on_regamma_lut)( + struct dpp *dpp, + bool power_on); + + void (*opp_program_regamma_lut)( + struct dpp *dpp, + const struct pwl_result_data *rgb, + uint32_t num); + + void (*opp_configure_regamma_lut)( + struct dpp *dpp, + bool is_ram_a); + + void (*opp_program_regamma_lutb_settings)( + struct dpp *dpp, + const struct pwl_params *params); + + void (*opp_program_regamma_luta_settings)( + struct dpp *dpp, + const struct pwl_params *params); + + void (*opp_program_regamma_pwl)( + struct dpp *dpp, const struct pwl_params *params); + + void (*opp_set_regamma_mode)( + struct dpp *dpp_base, + enum opp_regamma mode); + + void (*ipp_set_degamma)( + struct dpp *dpp_base, + enum ipp_degamma_mode mode); + + void (*ipp_program_input_lut)( + struct dpp *dpp_base, + const struct dc_gamma *gamma); + + void (*ipp_program_degamma_pwl)(struct dpp *dpp_base, + const struct pwl_params *params); + + void (*ipp_setup)( + struct dpp *dpp_base, + enum surface_pixel_format input_format, + enum expansion_mode mode); + + void (*ipp_full_bypass)(struct dpp *dpp_base); + + void (*set_cursor_attributes)( + struct dpp *dpp_base, + const struct dc_cursor_attributes *attr); + + void (*set_cursor_position)( + struct dpp *dpp_base, + const struct dc_cursor_position *pos, + const struct dc_cursor_mi_param *param, + uint32_t width + ); + +}; + + + +#endif From 3df8fcafb7edab79d76c4c76c93446b91eb4916f Mon Sep 17 00:00:00 2001 From: "Leo (Sunpeng) Li" Date: Wed, 4 Oct 2017 12:47:13 -0400 Subject: [PATCH 105/155] drm/amd/display: Do not set bandwidth on page flips. Which removes a lockdep warning for a possible deadlock situation: While holding the drm event mutex (hard irq safe), dc_post_update_surfaces_to_stream eventually acquires the atom context lock, which is hard irq unsafe. We should only be calling it on full updates anyways. Also remove a redundant call to dc_post_update_surfaces_to_stream, dc_commit_updates_for_stream already calls it. Signed-off-by: Leo (Sunpeng) Li Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 80ddccc2570a0..9d750fa29a876 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -980,8 +980,6 @@ bool dc_commit_planes_to_stream( new_plane_count, dc_stream, stream_update, plane_states, state); - dc_post_update_surfaces_to_stream(dc); - kfree(stream_update); return true; } @@ -1418,7 +1416,8 @@ void dc_commit_updates_for_stream(struct dc *dc, update_type, context); - dc_post_update_surfaces_to_stream(dc); + if (update_type >= UPDATE_TYPE_FULL) + dc_post_update_surfaces_to_stream(dc); if (dc->current_state != context) { From 9bbc30310f240c9400e31c7ab7b7edd2b76b3589 Mon Sep 17 00:00:00 2001 From: Jerry Zuo Date: Fri, 6 Oct 2017 15:08:07 -0400 Subject: [PATCH 106/155] drm/amd/display: Remove a false-positive error message To avoid confusion, need to suppress the error message when get -ERESTARTSYS error code. It is normal when getting interrupted by signals in the process of a wait for the buffer to become unreserved. Only propagate to user-mode for further action, no need to pop up error message. Signed-off-by: Jerry Zuo Reviewed-by: Sun peng Li Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 17fb636648f4a..09163d8d9332b 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -1790,7 +1790,9 @@ static int get_fb_info(const struct amdgpu_framebuffer *amdgpu_fb, int r = amdgpu_bo_reserve(rbo, false); if (unlikely(r)) { - DRM_ERROR("Unable to reserve buffer\n"); + // Don't show error msg. when return -ERESTARTSYS + if (r != -ERESTARTSYS) + DRM_ERROR("Unable to reserve buffer: %d\n", r); return r; } From 215a6f05bcc18ffcd953a8527639ea1f571f4d81 Mon Sep 17 00:00:00 2001 From: Dmytro Laktyushkin Date: Fri, 6 Oct 2017 15:40:07 -0400 Subject: [PATCH 107/155] drm/amd/display: add performance trace macro to dc Signed-off-by: Dmytro Laktyushkin Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../display/amdgpu_dm/amdgpu_dm_services.c | 6 ++ .../gpu/drm/amd/display/dc/basics/logger.c | 78 ++++++------------- .../gpu/drm/amd/display/dc/basics/logger.h | 37 --------- .../gpu/drm/amd/display/dc/calcs/dcn_calcs.c | 5 +- drivers/gpu/drm/amd/display/dc/dc.h | 1 + .../drm/amd/display/dc/dce/dce_link_encoder.c | 5 -- .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 40 +++++----- .../drm/amd/display/dc/dcn10/dcn10_resource.c | 1 + drivers/gpu/drm/amd/display/dc/dm_services.h | 2 + .../amd/display/include/logger_interface.h | 28 +++++++ .../drm/amd/display/include/logger_types.h | 36 ++++++++- 11 files changed, 118 insertions(+), 121 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c index 26bf9918fcb79..5df8fd5b537ce 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c @@ -35,6 +35,12 @@ #include "amdgpu_dm_irq.h" #include "amdgpu_pm.h" +unsigned long long dm_get_timestamp(struct dc_context *ctx) +{ + /* TODO: return actual timestamp */ + return 0; +} + bool dm_write_persistent_data(struct dc_context *ctx, const struct dc_sink *sink, const char *module_name, diff --git a/drivers/gpu/drm/amd/display/dc/basics/logger.c b/drivers/gpu/drm/amd/display/dc/basics/logger.c index afb6d2d80e0c7..e04e8ecd48748 100644 --- a/drivers/gpu/drm/amd/display/dc/basics/logger.c +++ b/drivers/gpu/drm/amd/display/dc/basics/logger.c @@ -80,8 +80,6 @@ static bool construct(struct dc_context *ctx, struct dal_logger *logger, logger->buffer_read_offset = 0; logger->buffer_write_offset = 0; - logger->write_wrap_count = 0; - logger->read_wrap_count = 0; logger->open_count = 0; logger->flags.bits.ENABLE_CONSOLE = 1; @@ -162,23 +160,24 @@ static void log_to_debug_console(struct log_entry *entry) } /* Print everything unread existing in log_buffer to debug console*/ -static void flush_to_debug_console(struct dal_logger *logger) +void dm_logger_flush_buffer(struct dal_logger *logger, bool should_warn) { - int i = logger->buffer_read_offset; - char *string_start = &logger->log_buffer[i]; + char *string_start = &logger->log_buffer[logger->buffer_read_offset]; - dm_output_to_console( - "---------------- FLUSHING LOG BUFFER ----------------\n"); - while (i < logger->buffer_write_offset) { + if (should_warn) + dm_output_to_console( + "---------------- FLUSHING LOG BUFFER ----------------\n"); + while (logger->buffer_read_offset < logger->buffer_write_offset) { - if (logger->log_buffer[i] == '\0') { + if (logger->log_buffer[logger->buffer_read_offset] == '\0') { dm_output_to_console("%s", string_start); - string_start = (char *)logger->log_buffer + i + 1; + string_start = logger->log_buffer + logger->buffer_read_offset + 1; } - i++; + logger->buffer_read_offset++; } - dm_output_to_console( - "-------------- END FLUSHING LOG BUFFER --------------\n\n"); + if (should_warn) + dm_output_to_console( + "-------------- END FLUSHING LOG BUFFER --------------\n\n"); } static void log_to_internal_buffer(struct log_entry *entry) @@ -195,35 +194,17 @@ static void log_to_internal_buffer(struct log_entry *entry) if (size > 0 && size < logger->log_buffer_size) { - int total_free_space = 0; - int space_before_wrap = 0; - - if (logger->buffer_write_offset > logger->buffer_read_offset) { - total_free_space = logger->log_buffer_size - - logger->buffer_write_offset + - logger->buffer_read_offset; - space_before_wrap = logger->log_buffer_size - - logger->buffer_write_offset; - } else if (logger->buffer_write_offset < - logger->buffer_read_offset) { - total_free_space = logger->log_buffer_size - - logger->buffer_read_offset + - logger->buffer_write_offset; - space_before_wrap = total_free_space; - } else if (logger->write_wrap_count != - logger->read_wrap_count) { - /* Buffer is completely full already */ - total_free_space = 0; - space_before_wrap = 0; - } else { + int buffer_space = logger->log_buffer_size - + logger->buffer_write_offset; + + if (logger->buffer_write_offset == logger->buffer_read_offset) { /* Buffer is empty, start writing at beginning */ - total_free_space = logger->log_buffer_size; - space_before_wrap = logger->log_buffer_size; + buffer_space = logger->log_buffer_size; logger->buffer_write_offset = 0; logger->buffer_read_offset = 0; } - if (space_before_wrap > size) { + if (buffer_space > size) { /* No wrap around, copy 'size' bytes * from 'entry->buf' to 'log_buffer' */ @@ -232,28 +213,12 @@ static void log_to_internal_buffer(struct log_entry *entry) entry->buf, size); logger->buffer_write_offset += size; - } else if (total_free_space > size) { - /* We have enough room without flushing, - * but need to wrap around */ - - int space_after_wrap = total_free_space - - space_before_wrap; - - memmove(logger->log_buffer + - logger->buffer_write_offset, - entry->buf, space_before_wrap); - memmove(logger->log_buffer, entry->buf + - space_before_wrap, space_after_wrap); - - logger->buffer_write_offset = space_after_wrap; - logger->write_wrap_count++; - } else { /* Not enough room remaining, we should flush * existing logs */ /* Flush existing unread logs to console */ - flush_to_debug_console(logger); + dm_logger_flush_buffer(logger, true); /* Start writing to beginning of buffer */ memmove(logger->log_buffer, entry->buf, size); @@ -325,9 +290,10 @@ void dm_logger_write( log_heading(&entry); size = dm_log_to_buffer( - buffer, LOG_MAX_LINE_SIZE, msg, args); + buffer, LOG_MAX_LINE_SIZE - 1, msg, args); - entry.buf_offset += size; + buffer[entry.buf_offset + size] = '\0'; + entry.buf_offset += size + 1; /* --Flush log_entry buffer-- */ /* print to kernel console */ diff --git a/drivers/gpu/drm/amd/display/dc/basics/logger.h b/drivers/gpu/drm/amd/display/dc/basics/logger.h index 2f7a5df4c8114..09722f0f8aa33 100644 --- a/drivers/gpu/drm/amd/display/dc/basics/logger.h +++ b/drivers/gpu/drm/amd/display/dc/basics/logger.h @@ -26,42 +26,5 @@ #ifndef __DAL_LOGGER_H__ #define __DAL_LOGGER_H__ -/* Structure for keeping track of offsets, buffer, etc */ - -#define DAL_LOGGER_BUFFER_MAX_SIZE 2048 - -/*Connectivity log needs to output EDID, which needs at lease 256x3 bytes, - * change log line size to 896 to meet the request. - */ -#define LOG_MAX_LINE_SIZE 896 - -#include "include/logger_types.h" - -struct dal_logger { - - /* How far into the circular buffer has been read by dsat - * Read offset should never cross write offset. Write \0's to - * read data just to be sure? - */ - uint32_t buffer_read_offset; - - /* How far into the circular buffer we have written - * Write offset should never cross read offset - */ - uint32_t buffer_write_offset; - - uint32_t write_wrap_count; - uint32_t read_wrap_count; - - uint32_t open_count; - - char *log_buffer; /* Pointer to malloc'ed buffer */ - uint32_t log_buffer_size; /* Size of circular buffer */ - - uint32_t mask; /*array of masks for major elements*/ - - union logger_flags flags; - struct dc_context *ctx; -}; #endif /* __DAL_LOGGER_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c index cf0c1459f546f..e1515230c6618 100644 --- a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c +++ b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c @@ -682,6 +682,7 @@ bool dcn_validate_bandwidth( bool bw_limit_pass; float bw_limit; + PERFORMANCE_TRACE_START(); if (dcn_bw_apply_registry_override(dc)) dcn_bw_sync_calcs_and_dml(dc); @@ -1089,6 +1090,8 @@ bool dcn_validate_bandwidth( kernel_fpu_end(); + PERFORMANCE_TRACE_END(); + if (bw_limit_pass && v->voltage_level != 5) return true; else @@ -1223,7 +1226,7 @@ unsigned int dcn_find_dcfclk_suits_all( else dcf_clk = dc->dcn_soc->dcfclkv_min0p65*1000; - dm_logger_write(dc->ctx->logger, LOG_HW_MARKS, + dm_logger_write(dc->ctx->logger, LOG_BANDWIDTH_CALCS, "\tdcf_clk for voltage = %d\n", dcf_clk); return dcf_clk; } diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index c7b31adc736e2..ace17d13683a0 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -224,6 +224,7 @@ struct dc_debug { bool disable_dpp_pg; bool disable_stereo_support; bool vsr_support; + bool performance_trace; }; struct dc_state; struct resource_pool; diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c index 0cf0fff74d44f..fe88852b47743 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c @@ -757,11 +757,6 @@ void dce110_link_encoder_construct( enc110->base.preferred_engine = ENGINE_ID_UNKNOWN; } - dm_logger_write(init_data->ctx->logger, LOG_I2C_AUX, - "Using channel: %s [%d]\n", - DECODE_CHANNEL_ID(init_data->channel), - init_data->channel); - /* Override features with DCE-specific values */ if (BP_RESULT_OK == bp_funcs->get_encoder_cap_info( enc110->base.ctx->dc_bios, enc110->base.id, diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index b69884549fc51..6e2cec643f312 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -468,7 +468,7 @@ static void program_watermarks( refclk_mhz, 0x1fffff); REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, prog_wm_value); - dm_logger_write(hws->ctx->logger, LOG_HW_MARKS, + dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS, "URGENCY_WATERMARK_A calculated =%d\n" "HW register value = 0x%x\n", watermarks->a.urgent_ns, prog_wm_value); @@ -476,7 +476,7 @@ static void program_watermarks( prog_wm_value = convert_and_clamp(watermarks->a.pte_meta_urgent_ns, refclk_mhz, 0x1fffff); REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_A, prog_wm_value); - dm_logger_write(hws->ctx->logger, LOG_HW_MARKS, + dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS, "PTE_META_URGENCY_WATERMARK_A calculated =%d\n" "HW register value = 0x%x\n", watermarks->a.pte_meta_urgent_ns, prog_wm_value); @@ -487,7 +487,7 @@ static void program_watermarks( refclk_mhz, 0x1fffff); REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, prog_wm_value); - dm_logger_write(hws->ctx->logger, LOG_HW_MARKS, + dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS, "SR_ENTER_EXIT_WATERMARK_A calculated =%d\n" "HW register value = 0x%x\n", watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); @@ -497,7 +497,7 @@ static void program_watermarks( watermarks->a.cstate_pstate.cstate_exit_ns, refclk_mhz, 0x1fffff); REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, prog_wm_value); - dm_logger_write(hws->ctx->logger, LOG_HW_MARKS, + dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS, "SR_EXIT_WATERMARK_A calculated =%d\n" "HW register value = 0x%x\n", watermarks->a.cstate_pstate.cstate_exit_ns, prog_wm_value); @@ -507,7 +507,7 @@ static void program_watermarks( watermarks->a.cstate_pstate.pstate_change_ns, refclk_mhz, 0x1fffff); REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, prog_wm_value); - dm_logger_write(hws->ctx->logger, LOG_HW_MARKS, + dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS, "DRAM_CLK_CHANGE_WATERMARK_A calculated =%d\n" "HW register value = 0x%x\n\n", watermarks->a.cstate_pstate.pstate_change_ns, prog_wm_value); @@ -517,7 +517,7 @@ static void program_watermarks( prog_wm_value = convert_and_clamp( watermarks->b.urgent_ns, refclk_mhz, 0x1fffff); REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, prog_wm_value); - dm_logger_write(hws->ctx->logger, LOG_HW_MARKS, + dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS, "URGENCY_WATERMARK_B calculated =%d\n" "HW register value = 0x%x\n", watermarks->b.urgent_ns, prog_wm_value); @@ -527,7 +527,7 @@ static void program_watermarks( watermarks->b.pte_meta_urgent_ns, refclk_mhz, 0x1fffff); REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_B, prog_wm_value); - dm_logger_write(hws->ctx->logger, LOG_HW_MARKS, + dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS, "PTE_META_URGENCY_WATERMARK_B calculated =%d\n" "HW register value = 0x%x\n", watermarks->b.pte_meta_urgent_ns, prog_wm_value); @@ -537,7 +537,7 @@ static void program_watermarks( watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns, refclk_mhz, 0x1fffff); REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, prog_wm_value); - dm_logger_write(hws->ctx->logger, LOG_HW_MARKS, + dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS, "SR_ENTER_WATERMARK_B calculated =%d\n" "HW register value = 0x%x\n", watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); @@ -547,7 +547,7 @@ static void program_watermarks( watermarks->b.cstate_pstate.cstate_exit_ns, refclk_mhz, 0x1fffff); REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, prog_wm_value); - dm_logger_write(hws->ctx->logger, LOG_HW_MARKS, + dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS, "SR_EXIT_WATERMARK_B calculated =%d\n" "HW register value = 0x%x\n", watermarks->b.cstate_pstate.cstate_exit_ns, prog_wm_value); @@ -556,7 +556,7 @@ static void program_watermarks( watermarks->b.cstate_pstate.pstate_change_ns, refclk_mhz, 0x1fffff); REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, prog_wm_value); - dm_logger_write(hws->ctx->logger, LOG_HW_MARKS, + dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS, "DRAM_CLK_CHANGE_WATERMARK_B calculated =%d\n\n" "HW register value = 0x%x\n", watermarks->b.cstate_pstate.pstate_change_ns, prog_wm_value); @@ -565,7 +565,7 @@ static void program_watermarks( prog_wm_value = convert_and_clamp( watermarks->c.urgent_ns, refclk_mhz, 0x1fffff); REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, prog_wm_value); - dm_logger_write(hws->ctx->logger, LOG_HW_MARKS, + dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS, "URGENCY_WATERMARK_C calculated =%d\n" "HW register value = 0x%x\n", watermarks->c.urgent_ns, prog_wm_value); @@ -575,7 +575,7 @@ static void program_watermarks( watermarks->c.pte_meta_urgent_ns, refclk_mhz, 0x1fffff); REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_C, prog_wm_value); - dm_logger_write(hws->ctx->logger, LOG_HW_MARKS, + dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS, "PTE_META_URGENCY_WATERMARK_C calculated =%d\n" "HW register value = 0x%x\n", watermarks->c.pte_meta_urgent_ns, prog_wm_value); @@ -585,7 +585,7 @@ static void program_watermarks( watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns, refclk_mhz, 0x1fffff); REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, prog_wm_value); - dm_logger_write(hws->ctx->logger, LOG_HW_MARKS, + dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS, "SR_ENTER_WATERMARK_C calculated =%d\n" "HW register value = 0x%x\n", watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); @@ -595,7 +595,7 @@ static void program_watermarks( watermarks->c.cstate_pstate.cstate_exit_ns, refclk_mhz, 0x1fffff); REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, prog_wm_value); - dm_logger_write(hws->ctx->logger, LOG_HW_MARKS, + dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS, "SR_EXIT_WATERMARK_C calculated =%d\n" "HW register value = 0x%x\n", watermarks->c.cstate_pstate.cstate_exit_ns, prog_wm_value); @@ -605,7 +605,7 @@ static void program_watermarks( watermarks->c.cstate_pstate.pstate_change_ns, refclk_mhz, 0x1fffff); REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, prog_wm_value); - dm_logger_write(hws->ctx->logger, LOG_HW_MARKS, + dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS, "DRAM_CLK_CHANGE_WATERMARK_C calculated =%d\n\n" "HW register value = 0x%x\n", watermarks->c.cstate_pstate.pstate_change_ns, prog_wm_value); @@ -614,7 +614,7 @@ static void program_watermarks( prog_wm_value = convert_and_clamp( watermarks->d.urgent_ns, refclk_mhz, 0x1fffff); REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, prog_wm_value); - dm_logger_write(hws->ctx->logger, LOG_HW_MARKS, + dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS, "URGENCY_WATERMARK_D calculated =%d\n" "HW register value = 0x%x\n", watermarks->d.urgent_ns, prog_wm_value); @@ -623,7 +623,7 @@ static void program_watermarks( watermarks->d.pte_meta_urgent_ns, refclk_mhz, 0x1fffff); REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_D, prog_wm_value); - dm_logger_write(hws->ctx->logger, LOG_HW_MARKS, + dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS, "PTE_META_URGENCY_WATERMARK_D calculated =%d\n" "HW register value = 0x%x\n", watermarks->d.pte_meta_urgent_ns, prog_wm_value); @@ -633,7 +633,7 @@ static void program_watermarks( watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns, refclk_mhz, 0x1fffff); REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, prog_wm_value); - dm_logger_write(hws->ctx->logger, LOG_HW_MARKS, + dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS, "SR_ENTER_WATERMARK_D calculated =%d\n" "HW register value = 0x%x\n", watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); @@ -643,7 +643,7 @@ static void program_watermarks( watermarks->d.cstate_pstate.cstate_exit_ns, refclk_mhz, 0x1fffff); REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, prog_wm_value); - dm_logger_write(hws->ctx->logger, LOG_HW_MARKS, + dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS, "SR_EXIT_WATERMARK_D calculated =%d\n" "HW register value = 0x%x\n", watermarks->d.cstate_pstate.cstate_exit_ns, prog_wm_value); @@ -653,7 +653,7 @@ static void program_watermarks( watermarks->d.cstate_pstate.pstate_change_ns, refclk_mhz, 0x1fffff); REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, prog_wm_value); - dm_logger_write(hws->ctx->logger, LOG_HW_MARKS, + dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS, "DRAM_CLK_CHANGE_WATERMARK_D calculated =%d\n" "HW register value = 0x%x\n\n", watermarks->d.cstate_pstate.pstate_change_ns, prog_wm_value); diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c index 4dbaf9a2f2752..d47ff7e6a5257 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c @@ -434,6 +434,7 @@ static const struct dc_debug debug_defaults_drv = { .voltage_align_fclk = true, .disable_stereo_support = true, .vsr_support = true, + .performance_trace = false, }; static const struct dc_debug debug_defaults_diags = { diff --git a/drivers/gpu/drm/amd/display/dc/dm_services.h b/drivers/gpu/drm/amd/display/dc/dm_services.h index a11991c382dec..d6b3b832986b5 100644 --- a/drivers/gpu/drm/amd/display/dc/dm_services.h +++ b/drivers/gpu/drm/amd/display/dc/dm_services.h @@ -418,6 +418,8 @@ bool dm_dmcu_set_pipe(struct dc_context *ctx, unsigned int controller_id); #define dm_log_to_buffer(buffer, size, fmt, args)\ vsnprintf(buffer, size, fmt, args) +unsigned long long dm_get_timestamp(struct dc_context *ctx); + /* * Debug and verification hooks */ diff --git a/drivers/gpu/drm/amd/display/include/logger_interface.h b/drivers/gpu/drm/amd/display/include/logger_interface.h index 5aaf2dacfe389..8e1fe70097be5 100644 --- a/drivers/gpu/drm/amd/display/include/logger_interface.h +++ b/drivers/gpu/drm/amd/display/include/logger_interface.h @@ -44,6 +44,8 @@ struct dal_logger *dal_logger_create(struct dc_context *ctx, uint32_t log_mask); uint32_t dal_logger_destroy(struct dal_logger **logger); +void dm_logger_flush_buffer(struct dal_logger *logger, bool should_warn); + void dm_logger_write( struct dal_logger *logger, enum dc_log_type log_type, @@ -157,4 +159,30 @@ void context_clock_trace( #define DTN_INFO_END() \ dm_dtn_log_end(dc_ctx) +#define PERFORMANCE_TRACE_START() \ + unsigned long long perf_trc_start_stmp = dm_get_timestamp(dc->ctx); \ + unsigned long long perf_trc_start_log_msk = dc->ctx->logger->mask; \ + unsigned int perf_trc_start_log_flags = dc->ctx->logger->flags.value; \ + if (dc->debug.performance_trace) {\ + dm_logger_flush_buffer(dc->ctx->logger, false);\ + dc->ctx->logger->mask = 1<ctx->logger->flags.bits.ENABLE_CONSOLE = 0;\ + dc->ctx->logger->flags.bits.ENABLE_BUFFER = 1;\ + } + +#define PERFORMANCE_TRACE_END() do {\ + unsigned long long perf_trc_end_stmp = dm_get_timestamp(dc->ctx);\ + if (dc->debug.performance_trace) {\ + dm_logger_write(dc->ctx->logger, \ + LOG_PERF_TRACE, \ + "%s duration: %d ticks\n", __func__,\ + perf_trc_end_stmp - perf_trc_start_stmp); \ + if (perf_trc_start_log_msk != 1<ctx->logger->mask = perf_trc_start_log_msk;\ + dc->ctx->logger->flags.value = perf_trc_start_log_flags;\ + dm_logger_flush_buffer(dc->ctx->logger, false);\ + } \ + } \ +} while (0) + #endif /* __DAL_LOGGER_INTERFACE_H__ */ diff --git a/drivers/gpu/drm/amd/display/include/logger_types.h b/drivers/gpu/drm/amd/display/include/logger_types.h index 1f22e84cedb90..e2ff8cd423d64 100644 --- a/drivers/gpu/drm/amd/display/include/logger_types.h +++ b/drivers/gpu/drm/amd/display/include/logger_types.h @@ -64,8 +64,7 @@ enum dc_log_type { LOG_EVENT_LINK_LOSS, LOG_EVENT_UNDERFLOW, LOG_IF_TRACE, - LOG_HW_MARKS, - LOG_PPLIB, + LOG_PERF_TRACE, LOG_SECTION_TOTAL_COUNT }; @@ -131,4 +130,37 @@ struct dc_log_type_info { char name[MAX_NAME_LEN]; }; +/* Structure for keeping track of offsets, buffer, etc */ + +#define DAL_LOGGER_BUFFER_MAX_SIZE 2048 + +/*Connectivity log needs to output EDID, which needs at lease 256x3 bytes, + * change log line size to 896 to meet the request. + */ +#define LOG_MAX_LINE_SIZE 896 + +struct dal_logger { + + /* How far into the circular buffer has been read by dsat + * Read offset should never cross write offset. Write \0's to + * read data just to be sure? + */ + uint32_t buffer_read_offset; + + /* How far into the circular buffer we have written + * Write offset should never cross read offset + */ + uint32_t buffer_write_offset; + + uint32_t open_count; + + char *log_buffer; /* Pointer to malloc'ed buffer */ + uint32_t log_buffer_size; /* Size of circular buffer */ + + uint32_t mask; /*array of masks for major elements*/ + + union logger_flags flags; + struct dc_context *ctx; +}; + #endif /* __DAL_LOGGER_TYPES_H__ */ From 199e458aafc241a2792b3f8a99d5a11aa7726a7d Mon Sep 17 00:00:00 2001 From: Dmytro Laktyushkin Date: Thu, 5 Oct 2017 19:15:25 -0400 Subject: [PATCH 108/155] drm/amd/display: Set addressable region as active + border This ensures that we do not draw the blank region onscreen, and that we do underscan instead. Signed-off-by: Andrew Jiang Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) 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 303d7ec684d91..454a521a268d2 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -850,6 +850,20 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx) */ pipe_ctx->plane_res.scl_data.lb_params.depth = LB_PIXEL_DEPTH_30BPP; + /** + * KMD sends us h and v_addressable without the borders, which causes us sometimes to draw + * the blank region on-screen. Correct for this by adding the borders back to their + * respective addressable values, and by shifting recout. + */ + timing->h_addressable += timing->h_border_left + timing->h_border_right; + timing->v_addressable += timing->v_border_top + timing->v_border_bottom; + pipe_ctx->plane_res.scl_data.recout.y += timing->v_border_top; + pipe_ctx->plane_res.scl_data.recout.x += timing->h_border_left; + timing->v_border_top = 0; + timing->v_border_bottom = 0; + timing->h_border_left = 0; + timing->h_border_right = 0; + pipe_ctx->plane_res.scl_data.h_active = timing->h_addressable; pipe_ctx->plane_res.scl_data.v_active = timing->v_addressable; From 9a5d9c48d883db4f7f3e5409062bef7d25165a95 Mon Sep 17 00:00:00 2001 From: "Leo (Sunpeng) Li" Date: Fri, 6 Oct 2017 11:57:40 -0400 Subject: [PATCH 109/155] drm/amd/display: Report stream as different on scaling change When scaling is enabled, our preference is to scale up to the prefered (native) mode. This means that hardware timings will be the same across a modeset. Therefore, also report mode as changed if source or destination rectangle is different. Signed-off-by: Leo (Sunpeng) Li Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 5 +++-- .../gpu/drm/amd/display/dc/core/dc_resource.c | 22 +++++++++++++++++++ drivers/gpu/drm/amd/display/dc/dc.h | 2 ++ 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 09163d8d9332b..fad40da8422ec 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -4428,12 +4428,13 @@ static int dm_update_crtcs_state(struct dc *dc, } } - if (dc_is_stream_unchanged(new_stream, dm_old_crtc_state->stream)) { + if (dc_is_stream_unchanged(new_stream, dm_old_crtc_state->stream) && + dc_is_stream_scaling_unchanged(new_stream, dm_old_crtc_state->stream)) { new_crtc_state->mode_changed = false; DRM_DEBUG_DRIVER("Mode change not required, setting mode_changed to %d", - new_crtc_state->mode_changed); + new_crtc_state->mode_changed); } 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 454a521a268d2..2a5c917724730 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -1335,6 +1335,28 @@ bool dc_is_stream_unchanged( return true; } +bool dc_is_stream_scaling_unchanged( + struct dc_stream_state *old_stream, struct dc_stream_state *stream) +{ + if (old_stream == stream) + return true; + + if (old_stream == NULL || stream == NULL) + return false; + + if (memcmp(&old_stream->src, + &stream->src, + sizeof(struct rect)) != 0) + return false; + + if (memcmp(&old_stream->dst, + &stream->dst, + sizeof(struct rect)) != 0) + return false; + + return true; +} + /* Maximum TMDS single link pixel clock 165MHz */ #define TMDS_MAX_PIXEL_CLOCK_IN_KHZ 165000 diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index ace17d13683a0..f60191d9c7e55 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -627,6 +627,8 @@ struct dc_stream_update { bool dc_is_stream_unchanged( struct dc_stream_state *old_stream, struct dc_stream_state *stream); +bool dc_is_stream_scaling_unchanged( + struct dc_stream_state *old_stream, struct dc_stream_state *stream); /* * Set up surface attributes and associate to a stream From 5771ec8fe8cb99c0db3115e81b4f69b1543c6982 Mon Sep 17 00:00:00 2001 From: "Leo (Sunpeng) Li" Date: Fri, 6 Oct 2017 15:11:41 -0400 Subject: [PATCH 110/155] drm/amd/display: ASSERT on dc_create_state failing. dc_create_state() returns NULL on allocation failure. Raise warning when that happens. Signed-off-by: Leo (Sunpeng) Li Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index fad40da8422ec..e439363ed54b4 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -702,6 +702,7 @@ int amdgpu_dm_display_resume(struct amdgpu_device *adev) dc_release_state(cached_state->context); cached_state->context = dc_create_state(); + ASSERT(cached_state->context); dc_resource_state_copy_construct_current(adev->dm.dc, cached_state->context); for_each_new_crtc_in_state(adev->dm.cached_state, crtc, new_crtc_state, i) { From 94c6d735e9ca13018da40f633fd602af6e272cc6 Mon Sep 17 00:00:00 2001 From: Harry Wentland Date: Fri, 13 Oct 2017 12:42:01 -0400 Subject: [PATCH 111/155] drm/amd/display: Fix non-DCN build Acquire_first_split_pipe only makes sense for DCN. Signed-off-by: Harry Wentland Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 2 ++ 1 file changed, 2 insertions(+) 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 2a5c917724730..55feb16b1fd73 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -1684,8 +1684,10 @@ enum dc_status resource_map_pool_resources( /* acquire new resources */ pipe_idx = acquire_first_free_pipe(&context->res_ctx, pool, stream); +#ifdef CONFIG_DRM_AMD_DC_DCN1_0 if (pipe_idx < 0) pipe_idx = acquire_first_split_pipe(&context->res_ctx, pool, stream); +#endif if (pipe_idx < 0) return DC_NO_CONTROLLER_RESOURCE; From 085b017bf81ad5c76118b3e1a9165c743927556b Mon Sep 17 00:00:00 2001 From: Harry Wentland Date: Tue, 10 Oct 2017 11:23:50 -0400 Subject: [PATCH 112/155] drm/amd/display: Fix warning about overflow v2: convert value to bool using !! Signed-off-by: Harry Wentland Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c index cb94e18cc4550..43e9a99592886 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c +++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c @@ -1042,13 +1042,13 @@ static enum bp_result get_embedded_panel_info_v2_1( info->lcd_timing.misc_info.VERTICAL_CUT_OFF = 0; info->lcd_timing.misc_info.H_REPLICATION_BY2 = - lvds->lcd_timing.miscinfo & ATOM_H_REPLICATIONBY2; + !!(lvds->lcd_timing.miscinfo & ATOM_H_REPLICATIONBY2); info->lcd_timing.misc_info.V_REPLICATION_BY2 = - lvds->lcd_timing.miscinfo & ATOM_V_REPLICATIONBY2; + !!(lvds->lcd_timing.miscinfo & ATOM_V_REPLICATIONBY2); info->lcd_timing.misc_info.COMPOSITE_SYNC = - lvds->lcd_timing.miscinfo & ATOM_COMPOSITESYNC; + !!(lvds->lcd_timing.miscinfo & ATOM_COMPOSITESYNC); info->lcd_timing.misc_info.INTERLACE = - lvds->lcd_timing.miscinfo & ATOM_INTERLACE; + !!(lvds->lcd_timing.miscinfo & ATOM_INTERLACE); /* not provided by VBIOS*/ info->lcd_timing.misc_info.DOUBLE_CLOCK = 0; @@ -1056,7 +1056,7 @@ static enum bp_result get_embedded_panel_info_v2_1( info->ss_id = 0; info->realtek_eDPToLVDS = - (lvds->dplvdsrxid == eDP_TO_LVDS_REALTEK_ID ? 1:0); + !!(lvds->dplvdsrxid == eDP_TO_LVDS_REALTEK_ID); return BP_RESULT_OK; } From 1a7e4f7407e8869759be7e715bce18698aadbe98 Mon Sep 17 00:00:00 2001 From: kbuild test robot Date: Fri, 13 Oct 2017 07:35:54 +0800 Subject: [PATCH 113/155] drm/amd/dc: fix semicolon.cocci warnings drivers/gpu/drm/amd/amdgpu/../display/dc/gpio/gpio_service.c:134:2-3: Unneeded semicolon Remove unneeded semicolon. Generated by: scripts/coccinelle/misc/semicolon.cocci Fixes: 80be23c57868 ("drm/amd/dc: Add dc display driver (v2)") CC: Harry Wentland Signed-off-by: Fengguang Wu Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c b/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c index d4e5ef64e4898..ff9d36b5866e0 100644 --- a/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c +++ b/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c @@ -132,7 +132,7 @@ struct gpio_service *dal_gpio_service_create( if (slot) kfree(slot); - }; + } failure_1: kfree(service); From 2979d7e973464c00154fa4fe029de128de3e51db Mon Sep 17 00:00:00 2001 From: kbuild test robot Date: Fri, 13 Oct 2017 07:17:48 +0800 Subject: [PATCH 114/155] drm/amd/display: fix ifnullfree.cocci warnings drivers/gpu/drm/amd/amdgpu/../display/dc/gpio/gpio_service.c:134:3-8: WARNING: NULL check before freeing functions like kfree, debugfs_remove, debugfs_remove_recursive or usb_free_urb is not needed. Maybe consider reorganizing relevant code to avoid passing NULL values. drivers/gpu/drm/amd/amdgpu/../display/dc/gpio/gpio_service.c:175:4-9: WARNING: NULL check before freeing functions like kfree, debugfs_remove, debugfs_remove_recursive or usb_free_urb is not needed. Maybe consider reorganizing relevant code to avoid passing NULL values. NULL check before some freeing functions is not needed. Based on checkpatch warning "kfree(NULL) is safe this check is probably not required" and kfreeaddr.cocci by Julia Lawall. Generated by: scripts/coccinelle/free/ifnullfree.cocci Fixes: f09cd1f46388 ("drm/amd/display: Use kernel alloc/free") Signed-off-by: Fengguang Wu Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c b/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c index ff9d36b5866e0..80038e0e610f4 100644 --- a/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c +++ b/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c @@ -130,8 +130,7 @@ struct gpio_service *dal_gpio_service_create( slot = service->busyness[index_of_id]; - if (slot) - kfree(slot); + kfree(slot); } failure_1: @@ -171,8 +170,7 @@ void dal_gpio_service_destroy( do { uint32_t *slot = (*ptr)->busyness[index_of_id]; - if (slot) - kfree(slot); + kfree(slot); ++index_of_id; } while (index_of_id < GPIO_ID_COUNT); From b0f8d4e963de8cd77c237a8ea37799f6f5ce995a Mon Sep 17 00:00:00 2001 From: Andrew Jiang Date: Fri, 6 Oct 2017 18:02:23 -0400 Subject: [PATCH 115/155] drm/amd/display: Don't set cursor address is 0 logging as errors This actually happens quite a bit, and having it as an error causes false positive messages when running tests. Signed-off-by: Andrew Jiang Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_stream.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 97f040a258206..5cf69af9693d2 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c @@ -190,7 +190,7 @@ bool dc_stream_set_cursor_attributes( } if (attributes->address.quad_part == 0) { - dm_error("DC: Cursor address is 0!\n"); + dm_output_to_console("DC: Cursor address is 0!\n"); return false; } From 4beb50ff5e96014787d8588a78d07e49df0d114a Mon Sep 17 00:00:00 2001 From: Harry Wentland Date: Wed, 4 Oct 2017 13:54:35 -0400 Subject: [PATCH 116/155] drm/amd/display: Fix warning about uninitialized variable Signed-off-by: Harry Wentland Reviewed-by: Bhawanpreet Lakha Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c b/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c index ed301c3b27367..0790f25c7b3b0 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c @@ -361,7 +361,7 @@ static void program_grph_pixel_format( enum surface_pixel_format format) { uint32_t red_xbar = 0, blue_xbar = 0; /* no swap */ - uint32_t grph_depth, grph_format; + uint32_t grph_depth = 0, grph_format = 0; uint32_t sign = 0, floating = 0; if (format == SURFACE_PIXEL_FORMAT_GRPH_ABGR8888 || From c12a7ba543d16c1770fb44670e5eb42ae524c502 Mon Sep 17 00:00:00 2001 From: Harry Wentland Date: Tue, 12 Sep 2017 20:04:48 -0400 Subject: [PATCH 117/155] drm/amd/display: Fix up some whitespace in handle_cursor_update Use combo of tabs and spaces Signed-off-by: Harry Wentland Acked-by: Alex Deucher Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index e439363ed54b4..60587d6f81d7b 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -3709,10 +3709,10 @@ static void handle_cursor_update(struct drm_plane *plane, return; DRM_DEBUG_DRIVER("%s: crtc_id=%d with size %d to %d\n", - __func__, - amdgpu_crtc->crtc_id, - plane->state->crtc_w, - plane->state->crtc_h); + __func__, + amdgpu_crtc->crtc_id, + plane->state->crtc_w, + plane->state->crtc_h); ret = get_cursor_position(plane, crtc, &position); if (ret) From 2126732fdaaa4101b186a76b4df52f575b5df4e5 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 28 Sep 2017 10:10:22 +1000 Subject: [PATCH 118/155] drm/amd/display: drop display_pipe_clocks.c. This code isn't used at all in the kernel tree, perhaps it can wait to be imported when it is. It also does a lot of floating point calcs, so probably good to drop it until it's needed and we can ensure proper fpu accessors. Signed-off-by: Dave Airlie Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dml/Makefile | 2 +- .../drm/amd/display/dc/dml/display_mode_lib.h | 1 - .../amd/display/dc/dml/display_pipe_clocks.c | 106 ------------------ .../amd/display/dc/dml/display_pipe_clocks.h | 37 ------ 4 files changed, 1 insertion(+), 145 deletions(-) delete mode 100644 drivers/gpu/drm/amd/display/dc/dml/display_pipe_clocks.c delete mode 100644 drivers/gpu/drm/amd/display/dc/dml/display_pipe_clocks.h diff --git a/drivers/gpu/drm/amd/display/dc/dml/Makefile b/drivers/gpu/drm/amd/display/dc/dml/Makefile index c6d9d9530d755..87bab8e8139fb 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/Makefile +++ b/drivers/gpu/drm/amd/display/dc/dml/Makefile @@ -13,7 +13,7 @@ CFLAGS_soc_bounding_box.o := -mhard-float -msse -mpreferred-stack-boundary=4 CFLAGS_dml_common_defs.o := -mhard-float -msse -mpreferred-stack-boundary=4 -DML = display_mode_lib.o display_pipe_clocks.o display_rq_dlg_calc.o \ +DML = display_mode_lib.o display_rq_dlg_calc.o \ display_rq_dlg_helpers.o dml1_display_rq_dlg_calc.o \ soc_bounding_box.o dml_common_defs.o display_mode_vba.o diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.h index 57f49d29c6b9d..ed77f96016ddd 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.h +++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.h @@ -29,7 +29,6 @@ #include "dml_common_defs.h" #include "soc_bounding_box.h" #include "display_mode_vba.h" -#include "display_pipe_clocks.h" #include "display_rq_dlg_calc.h" #include "dml1_display_rq_dlg_calc.h" diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_pipe_clocks.c b/drivers/gpu/drm/amd/display/dc/dml/display_pipe_clocks.c deleted file mode 100644 index 30c379d951569..0000000000000 --- a/drivers/gpu/drm/amd/display/dc/dml/display_pipe_clocks.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright 2017 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: AMD - * - */ - -#include "display_pipe_clocks.h" -#include "display_mode_lib.h" -#include "soc_bounding_box.h" - -display_pipe_clock_st dml_clks_get_pipe_clocks( - struct display_mode_lib *mode_lib, - display_e2e_pipe_params_st *e2e, - unsigned int num_pipes) -{ - display_pipe_clock_st clocks; - bool visited[DC__NUM_PIPES__MAX]; - double max_dispclk = 25.0; //the min dispclk is 25MHz, so keep the min dispclk caculated larger thant 25MHz - double dcfclk, socclk; - unsigned int i, j, k; - unsigned int dsc_inst = 0; - - DTRACE("Calculating pipe clocks..."); - - dcfclk = dml_socbb_voltage_scaling( - &mode_lib->soc, - (enum voltage_state) e2e[0].clks_cfg.voltage).dcfclk_mhz; - socclk = dml_socbb_voltage_scaling( - &mode_lib->soc, - (enum voltage_state) e2e[0].clks_cfg.voltage).socclk_mhz; - clocks.dcfclk_mhz = dcfclk; - clocks.socclk_mhz = socclk; - - max_dispclk = dml_max(max_dispclk, get_dispclk_calculated(mode_lib, e2e, num_pipes)); - clocks.dispclk_mhz = max_dispclk; - DTRACE(" dispclk: %f Mhz", clocks.dispclk_mhz); - DTRACE(" dcfclk: %f Mhz", clocks.dcfclk_mhz); - DTRACE(" socclk: %f Mhz", clocks.socclk_mhz); - - for (k = 0; k < num_pipes; ++k) - visited[k] = false; - - for (i = 0; i < num_pipes; i++) { - clocks.dppclk_mhz[i] = get_dppclk_calculated(mode_lib, e2e, num_pipes, i); - DTRACE(" dppclk%d: %f Mhz", i, clocks.dppclk_mhz[i]); - - if (e2e[i].pipe.src.is_hsplit && !visited[i]) { - unsigned int grp = e2e[i].pipe.src.hsplit_grp; - - for (j = i; j < num_pipes; j++) { - if (e2e[j].pipe.src.hsplit_grp == grp && e2e[j].pipe.src.is_hsplit - && !visited[j]) { - clocks.dscclk_mhz[j] = get_dscclk_calculated( - mode_lib, - e2e, - num_pipes, - dsc_inst); - DTRACE(" dscclk%d: %f Mhz", j, clocks.dscclk_mhz[j]); - visited[j] = true; - } - } - dsc_inst++; - } - - if (!visited[i]) { - unsigned int otg_inst = e2e[i].pipe.dest.otg_inst; - - for (j = i; j < num_pipes; j++) { - // assign dscclk to all planes with this otg, except if they're doing odm combine, or mpc combine - // which is handled by the conditions above, the odm_combine is not required, but it helps make sense of this code - if (e2e[j].pipe.dest.otg_inst == otg_inst - && !e2e[j].pipe.dest.odm_combine && !visited[j]) { - clocks.dscclk_mhz[j] = get_dscclk_calculated( - mode_lib, - e2e, - num_pipes, - dsc_inst); - DTRACE(" dscclk%d: %f Mhz", j, clocks.dscclk_mhz[j]); - visited[j] = true; - } - } - dsc_inst++; - } - } - - return clocks; -} diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_pipe_clocks.h b/drivers/gpu/drm/amd/display/dc/dml/display_pipe_clocks.h deleted file mode 100644 index a712dc3ecf4bc..0000000000000 --- a/drivers/gpu/drm/amd/display/dc/dml/display_pipe_clocks.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2017 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: AMD - * - */ -#ifndef __DISPLAY_PIPE_CLOCKS_H__ -#define __DISPLAY_PIPE_CLOCKS_H__ - -#include "dml_common_defs.h" - -struct display_mode_lib; - -display_pipe_clock_st dml_clks_get_pipe_clocks( - struct display_mode_lib *mode_lib, - display_e2e_pipe_params_st *e2e, - unsigned int num_pipes); - -#endif From 9a5bcd47ea0eb40c8a9e00f6797453c90fbd74d1 Mon Sep 17 00:00:00 2001 From: Eric Bernstein Date: Wed, 11 Oct 2017 15:14:46 -0400 Subject: [PATCH 119/155] drm/amd/display: check SR_WATERMARK regs prior to write Signed-off-by: Eric Bernstein Reviewed-by: Charlene Liu Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 144 +++++++++--------- 1 file changed, 74 insertions(+), 70 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index 6e2cec643f312..741b5e06d3149 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -481,27 +481,26 @@ static void program_watermarks( "HW register value = 0x%x\n", watermarks->a.pte_meta_urgent_ns, prog_wm_value); - - prog_wm_value = convert_and_clamp( - watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns, - refclk_mhz, 0x1fffff); - - REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, prog_wm_value); - dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS, - "SR_ENTER_EXIT_WATERMARK_A calculated =%d\n" - "HW register value = 0x%x\n", - watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); - - - prog_wm_value = convert_and_clamp( - watermarks->a.cstate_pstate.cstate_exit_ns, - refclk_mhz, 0x1fffff); - REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, prog_wm_value); - dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS, - "SR_EXIT_WATERMARK_A calculated =%d\n" - "HW register value = 0x%x\n", - watermarks->a.cstate_pstate.cstate_exit_ns, prog_wm_value); - + if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A)) { + prog_wm_value = convert_and_clamp( + watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns, + refclk_mhz, 0x1fffff); + REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, prog_wm_value); + dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS, + "SR_ENTER_EXIT_WATERMARK_A calculated =%d\n" + "HW register value = 0x%x\n", + watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); + + + prog_wm_value = convert_and_clamp( + watermarks->a.cstate_pstate.cstate_exit_ns, + refclk_mhz, 0x1fffff); + REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, prog_wm_value); + dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS, + "SR_EXIT_WATERMARK_A calculated =%d\n" + "HW register value = 0x%x\n", + watermarks->a.cstate_pstate.cstate_exit_ns, prog_wm_value); + } prog_wm_value = convert_and_clamp( watermarks->a.cstate_pstate.pstate_change_ns, @@ -533,24 +532,26 @@ static void program_watermarks( watermarks->b.pte_meta_urgent_ns, prog_wm_value); - prog_wm_value = convert_and_clamp( - watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns, - refclk_mhz, 0x1fffff); - REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, prog_wm_value); - dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS, - "SR_ENTER_WATERMARK_B calculated =%d\n" - "HW register value = 0x%x\n", - watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); + if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B)) { + prog_wm_value = convert_and_clamp( + watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns, + refclk_mhz, 0x1fffff); + REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, prog_wm_value); + dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS, + "SR_ENTER_WATERMARK_B calculated =%d\n" + "HW register value = 0x%x\n", + watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); - prog_wm_value = convert_and_clamp( - watermarks->b.cstate_pstate.cstate_exit_ns, - refclk_mhz, 0x1fffff); - REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, prog_wm_value); - dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS, - "SR_EXIT_WATERMARK_B calculated =%d\n" - "HW register value = 0x%x\n", - watermarks->b.cstate_pstate.cstate_exit_ns, prog_wm_value); + prog_wm_value = convert_and_clamp( + watermarks->b.cstate_pstate.cstate_exit_ns, + refclk_mhz, 0x1fffff); + REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, prog_wm_value); + dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS, + "SR_EXIT_WATERMARK_B calculated =%d\n" + "HW register value = 0x%x\n", + watermarks->b.cstate_pstate.cstate_exit_ns, prog_wm_value); + } prog_wm_value = convert_and_clamp( watermarks->b.cstate_pstate.pstate_change_ns, @@ -581,25 +582,26 @@ static void program_watermarks( watermarks->c.pte_meta_urgent_ns, prog_wm_value); - prog_wm_value = convert_and_clamp( - watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns, - refclk_mhz, 0x1fffff); - REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, prog_wm_value); - dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS, - "SR_ENTER_WATERMARK_C calculated =%d\n" - "HW register value = 0x%x\n", - watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); + if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C)) { + prog_wm_value = convert_and_clamp( + watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns, + refclk_mhz, 0x1fffff); + REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, prog_wm_value); + dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS, + "SR_ENTER_WATERMARK_C calculated =%d\n" + "HW register value = 0x%x\n", + watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); - prog_wm_value = convert_and_clamp( - watermarks->c.cstate_pstate.cstate_exit_ns, - refclk_mhz, 0x1fffff); - REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, prog_wm_value); - dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS, - "SR_EXIT_WATERMARK_C calculated =%d\n" - "HW register value = 0x%x\n", - watermarks->c.cstate_pstate.cstate_exit_ns, prog_wm_value); - + prog_wm_value = convert_and_clamp( + watermarks->c.cstate_pstate.cstate_exit_ns, + refclk_mhz, 0x1fffff); + REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, prog_wm_value); + dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS, + "SR_EXIT_WATERMARK_C calculated =%d\n" + "HW register value = 0x%x\n", + watermarks->c.cstate_pstate.cstate_exit_ns, prog_wm_value); + } prog_wm_value = convert_and_clamp( watermarks->c.cstate_pstate.pstate_change_ns, @@ -629,24 +631,26 @@ static void program_watermarks( watermarks->d.pte_meta_urgent_ns, prog_wm_value); - prog_wm_value = convert_and_clamp( - watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns, - refclk_mhz, 0x1fffff); - REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, prog_wm_value); - dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS, - "SR_ENTER_WATERMARK_D calculated =%d\n" - "HW register value = 0x%x\n", - watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); + if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D)) { + prog_wm_value = convert_and_clamp( + watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns, + refclk_mhz, 0x1fffff); + REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, prog_wm_value); + dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS, + "SR_ENTER_WATERMARK_D calculated =%d\n" + "HW register value = 0x%x\n", + watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); - prog_wm_value = convert_and_clamp( - watermarks->d.cstate_pstate.cstate_exit_ns, - refclk_mhz, 0x1fffff); - REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, prog_wm_value); - dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS, - "SR_EXIT_WATERMARK_D calculated =%d\n" - "HW register value = 0x%x\n", - watermarks->d.cstate_pstate.cstate_exit_ns, prog_wm_value); + prog_wm_value = convert_and_clamp( + watermarks->d.cstate_pstate.cstate_exit_ns, + refclk_mhz, 0x1fffff); + REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, prog_wm_value); + dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS, + "SR_EXIT_WATERMARK_D calculated =%d\n" + "HW register value = 0x%x\n", + watermarks->d.cstate_pstate.cstate_exit_ns, prog_wm_value); + } prog_wm_value = convert_and_clamp( From 58bb0e63dd99c4bdb84e79a95311bb6899789681 Mon Sep 17 00:00:00 2001 From: Andrew Jiang Date: Tue, 10 Oct 2017 14:36:39 -0400 Subject: [PATCH 120/155] drm/amd/display: Correct timings in build scaling params A previous patch set the addressable timing as active + border, when in fact, the VESA standard specifies active as equal to addressable + border. This patch makes the fix more correct and in line with the standard. Signed-off-by: Andrew Jiang Reviewed-by: Andrew Jiang Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/core/dc_resource.c | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) 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 55feb16b1fd73..0aca7a3d3dd6b 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -850,22 +850,11 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx) */ pipe_ctx->plane_res.scl_data.lb_params.depth = LB_PIXEL_DEPTH_30BPP; - /** - * KMD sends us h and v_addressable without the borders, which causes us sometimes to draw - * the blank region on-screen. Correct for this by adding the borders back to their - * respective addressable values, and by shifting recout. - */ - timing->h_addressable += timing->h_border_left + timing->h_border_right; - timing->v_addressable += timing->v_border_top + timing->v_border_bottom; - pipe_ctx->plane_res.scl_data.recout.y += timing->v_border_top; pipe_ctx->plane_res.scl_data.recout.x += timing->h_border_left; - timing->v_border_top = 0; - timing->v_border_bottom = 0; - timing->h_border_left = 0; - timing->h_border_right = 0; + pipe_ctx->plane_res.scl_data.recout.y += timing->v_border_top; - pipe_ctx->plane_res.scl_data.h_active = timing->h_addressable; - pipe_ctx->plane_res.scl_data.v_active = timing->v_addressable; + pipe_ctx->plane_res.scl_data.h_active = timing->h_addressable + timing->h_border_left + timing->h_border_right; + pipe_ctx->plane_res.scl_data.v_active = timing->v_addressable + timing->v_border_top + timing->v_border_bottom; /* Taps calculations */ if (pipe_ctx->plane_res.xfm != NULL) From 3e5e22154acfd89810d37aa4b3fac14014eb7ca8 Mon Sep 17 00:00:00 2001 From: Andrew Jiang Date: Wed, 11 Oct 2017 14:59:51 -0400 Subject: [PATCH 121/155] drm/amd/display: Add chip mask to HDMI retimer/redriver check There were cases where the chip caps held additional bits that led to the retimer/redriver check failing; use the proper mask to ensure that we have only the bits that we care about for the check in question. Signed-off-by: Andrew Jiang Reviewed-by: Charlene Liu Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_link.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) 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 72e56fbe4a427..004e0b0aad8a9 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c @@ -45,6 +45,7 @@ #include "dce/dce_11_0_enum.h" #include "dce/dce_11_0_sh_mask.h" +#define EXT_DISPLAY_PATH_CAPS__EXT_CHIP_MASK 0x007C /* Copied from atombios.h */ #define LINK_INFO(...) \ dm_logger_write(dc_ctx->logger, LOG_HW_HOTPLUG, \ __VA_ARGS__) @@ -1345,7 +1346,6 @@ static bool get_ext_hdmi_settings(struct pipe_ctx *pipe_ctx, sizeof(integrated_info->dp2_ext_hdmi_6g_reg_settings)); result = true; break; - default: break; } @@ -1682,7 +1682,9 @@ static void enable_link_hdmi(struct pipe_ctx *pipe_ctx) is_over_340mhz = true; if (dc_is_hdmi_signal(pipe_ctx->stream->signal)) { - if ((pipe_ctx->stream->sink->link->chip_caps >> 2) == 0x2) { + unsigned short masked_chip_caps = pipe_ctx->stream->sink->link->chip_caps & + EXT_DISPLAY_PATH_CAPS__EXT_CHIP_MASK; + if (masked_chip_caps == (0x2 << 2)) { /* DP159, Retimer settings */ eng_id = pipe_ctx->stream_res.stream_enc->id; @@ -1693,7 +1695,7 @@ static void enable_link_hdmi(struct pipe_ctx *pipe_ctx) write_i2c_default_retimer_setting(pipe_ctx, is_vga_mode, is_over_340mhz); } - } else if ((pipe_ctx->stream->sink->link->chip_caps >> 2) == 0x1) { + } else if (masked_chip_caps == (0x1 << 2)) { /* PI3EQX1204, Redriver settings */ write_i2c_redriver_setting(pipe_ctx, is_over_340mhz); } From 4e527c01aa7a31b7aad98fa5493944891b69238d Mon Sep 17 00:00:00 2001 From: Andrew Jiang Date: Wed, 11 Oct 2017 15:12:58 -0400 Subject: [PATCH 122/155] drm/amd/display: Add DIGD case when getting retimer settings One of the HDMI ports map to DIGD, which we did not map to DP3 ext HDMI settings. Add the DIGD case so that we can get proper retimer settings from SBIOS for that port. Signed-off-by: Andrew Jiang Reviewed-by: Charlene Liu Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_link.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) 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 004e0b0aad8a9..c47da645d3b8d 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c @@ -1346,6 +1346,18 @@ static bool get_ext_hdmi_settings(struct pipe_ctx *pipe_ctx, sizeof(integrated_info->dp2_ext_hdmi_6g_reg_settings)); result = true; break; + case ENGINE_ID_DIGD: + settings->slv_addr = integrated_info->dp3_ext_hdmi_slv_addr; + settings->reg_num = integrated_info->dp3_ext_hdmi_6g_reg_num; + settings->reg_num_6g = integrated_info->dp3_ext_hdmi_6g_reg_num; + memmove(settings->reg_settings, + integrated_info->dp3_ext_hdmi_reg_settings, + sizeof(integrated_info->dp3_ext_hdmi_reg_settings)); + memmove(settings->reg_settings_6g, + integrated_info->dp3_ext_hdmi_6g_reg_settings, + sizeof(integrated_info->dp3_ext_hdmi_6g_reg_settings)); + result = true; + break; default: break; } From 62c933f9c6bf287b5b911a1eb838bc942eaa7202 Mon Sep 17 00:00:00 2001 From: Yongqiang Sun Date: Tue, 10 Oct 2017 14:01:33 -0400 Subject: [PATCH 123/155] drm/amd/display: WA for 3 display play video hot plug. Three monitor connected and playing a video will occupy all 4 pipes, if hot plug forth display, commit streams will be failed due to no free pipe can be found. Work around: When forth monitor connected, mark video plane as a fake plane, remove it in dc, keep it in dm and report address to OS, until OS turn off MPO. Signed-off-by: Yongqiang Sun Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 10 +++++----- drivers/gpu/drm/amd/display/dc/core/dc.c | 4 ++-- drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 14 ++++++++------ drivers/gpu/drm/amd/display/dc/dc.h | 6 +++--- drivers/gpu/drm/amd/display/dc/inc/core_status.h | 15 ++++++++------- 5 files changed, 26 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 60587d6f81d7b..0d1b41298990d 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -2794,7 +2794,7 @@ int amdgpu_dm_connector_mode_valid(struct drm_connector *connector, stream->src.height = mode->vdisplay; stream->dst = stream->src; - if (dc_validate_stream(adev->dm.dc, stream)) + if (dc_validate_stream(adev->dm.dc, stream) == DC_OK) result = MODE_OK; dc_stream_release(stream); @@ -2839,7 +2839,7 @@ static int dm_crtc_helper_atomic_check(struct drm_crtc *crtc, if (!dm_crtc_state->stream) return 0; - if (dc_validate_stream(dc, dm_crtc_state->stream)) + if (dc_validate_stream(dc, dm_crtc_state->stream) == DC_OK) return 0; return ret; @@ -3034,7 +3034,7 @@ static int dm_plane_atomic_check(struct drm_plane *plane, if (!dm_plane_state->dc_state) return 0; - if (dc_validate_plane(dc, dm_plane_state->dc_state)) + if (dc_validate_plane(dc, dm_plane_state->dc_state) == DC_OK) return 0; return -EINVAL; @@ -4464,10 +4464,10 @@ static int dm_update_crtcs_state(struct dc *dc, crtc->base.id); /* i.e. reset mode */ - if (!dc_remove_stream_from_ctx( + if (dc_remove_stream_from_ctx( dc, dm_state->context, - dm_old_crtc_state->stream)) { + dm_old_crtc_state->stream) != DC_OK) { ret = -EINVAL; goto fail; } diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 9d750fa29a876..ff6bd384aece1 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -793,7 +793,7 @@ bool dc_enable_stereo( * Applies given context to HW and copy it into current context. * It's up to the user to release the src context afterwards. */ -static bool dc_commit_state_no_check(struct dc *dc, struct dc_state *context) +static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *context) { struct dc_bios *dcb = dc->ctx->dc_bios; enum dc_status result = DC_ERROR_UNEXPECTED; @@ -869,7 +869,7 @@ static bool dc_commit_state_no_check(struct dc *dc, struct dc_state *context) dc->hwss.optimize_shared_resources(dc); - return (result == DC_OK); + return result; } bool dc_commit_state(struct dc *dc, struct dc_state *context) 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 0aca7a3d3dd6b..d1cdf9f8853d7 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -1503,7 +1503,7 @@ enum dc_status dc_add_stream_to_ctx( return res; } -bool dc_remove_stream_from_ctx( +enum dc_status dc_remove_stream_from_ctx( struct dc *dc, struct dc_state *new_ctx, struct dc_stream_state *stream) @@ -2756,7 +2756,7 @@ void resource_build_bit_depth_reduction_params(struct dc_stream_state *stream, fmt_bit_depth->pixel_encoding = pixel_encoding; } -bool dc_validate_stream(struct dc *dc, struct dc_stream_state *stream) +enum dc_status dc_validate_stream(struct dc *dc, struct dc_stream_state *stream) { struct dc *core_dc = dc; struct dc_link *link = stream->sink->link; @@ -2780,14 +2780,16 @@ bool dc_validate_stream(struct dc *dc, struct dc_stream_state *stream) link, &stream->timing); - return res == DC_OK; + return res; } -bool dc_validate_plane(struct dc *dc, const struct dc_plane_state *plane_state) +enum dc_status dc_validate_plane(struct dc *dc, const struct dc_plane_state *plane_state) { + enum dc_status res = DC_OK; + /* TODO For now validates pixel format only */ if (dc->res_pool->funcs->validate_plane) - return dc->res_pool->funcs->validate_plane(plane_state, &dc->caps) == DC_OK; + return dc->res_pool->funcs->validate_plane(plane_state, &dc->caps); - return true; + return res; } diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index f60191d9c7e55..6c0de093a59e4 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -686,7 +686,7 @@ enum dc_status dc_add_stream_to_ctx( struct dc_state *new_ctx, struct dc_stream_state *stream); -bool dc_remove_stream_from_ctx( +enum dc_status dc_remove_stream_from_ctx( struct dc *dc, struct dc_state *new_ctx, struct dc_stream_state *stream); @@ -725,9 +725,9 @@ struct dc_validation_set { uint8_t plane_count; }; -bool dc_validate_stream(struct dc *dc, struct dc_stream_state *stream); +enum dc_status dc_validate_stream(struct dc *dc, struct dc_stream_state *stream); -bool dc_validate_plane(struct dc *dc, const struct dc_plane_state *plane_state); +enum dc_status dc_validate_plane(struct dc *dc, const struct dc_plane_state *plane_state); enum dc_status dc_validate_global_state( struct dc *dc, diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_status.h b/drivers/gpu/drm/amd/display/dc/inc/core_status.h index b5759c0e5a2ff..01df85641684f 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/core_status.h +++ b/drivers/gpu/drm/amd/display/dc/inc/core_status.h @@ -35,13 +35,14 @@ enum dc_status { DC_FAIL_CONTROLLER_VALIDATE = 5, DC_FAIL_ENC_VALIDATE = 6, DC_FAIL_ATTACH_SURFACES = 7, - DC_FAIL_SURFACE_VALIDATE = 8, - DC_NO_DP_LINK_BANDWIDTH = 9, - DC_EXCEED_DONGLE_MAX_CLK = 10, - DC_SURFACE_PIXEL_FORMAT_UNSUPPORTED = 11, - DC_FAIL_BANDWIDTH_VALIDATE = 12, /* BW and Watermark validation */ - DC_FAIL_SCALING = 13, - DC_FAIL_DP_LINK_TRAINING = 14, + DC_FAIL_DETACH_SURFACES = 8, + DC_FAIL_SURFACE_VALIDATE = 9, + DC_NO_DP_LINK_BANDWIDTH = 10, + DC_EXCEED_DONGLE_MAX_CLK = 11, + DC_SURFACE_PIXEL_FORMAT_UNSUPPORTED = 12, + DC_FAIL_BANDWIDTH_VALIDATE = 13, /* BW and Watermark validation */ + DC_FAIL_SCALING = 14, + DC_FAIL_DP_LINK_TRAINING = 15, DC_ERROR_UNEXPECTED = -1 }; From dd93752b6483094ec879efbbdb854967355b91ac Mon Sep 17 00:00:00 2001 From: Yue Hin Lau Date: Tue, 10 Oct 2017 17:58:41 -0400 Subject: [PATCH 124/155] drm/amd/display: rename dscl functions Signed-off-by: Yue Hin Lau Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c | 10 +- .../gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h | 4 +- .../drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c | 98 +++++++++---------- 3 files changed, 56 insertions(+), 56 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c index 5960e491159d9..74e7c82bdc76a 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c @@ -372,7 +372,7 @@ void dpp1_cnv_setup ( } } -void dcn10_set_cursor_attributes( +void dpp1_set_cursor_attributes( struct dpp *dpp_base, const struct dc_cursor_attributes *attr) { @@ -400,7 +400,7 @@ void dcn10_set_cursor_attributes( } -void dcn10_set_cursor_position( +void dpp1_set_cursor_position( struct dpp *dpp_base, const struct dc_cursor_position *pos, const struct dc_cursor_mi_param *param, @@ -440,13 +440,13 @@ static const struct dpp_funcs dcn10_dpp_funcs = { .ipp_program_degamma_pwl = dpp1_set_degamma_pwl, .ipp_setup = dpp1_cnv_setup, .ipp_full_bypass = dpp1_full_bypass, - .set_cursor_attributes = dcn10_set_cursor_attributes, - .set_cursor_position = dcn10_set_cursor_position, + .set_cursor_attributes = dpp1_set_cursor_attributes, + .set_cursor_position = dpp1_set_cursor_position, }; static struct dpp_caps dcn10_dpp_cap = { .dscl_data_proc_format = DSCL_DATA_PRCESSING_FIXED_FORMAT, - .dscl_calc_lb_num_partitions = dscl1_calc_lb_num_partitions, + .dscl_calc_lb_num_partitions = dpp1_dscl_calc_lb_num_partitions, }; /*****************************************/ diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h index fe6c0aa13da4a..a9782b1aba478 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h @@ -1274,12 +1274,12 @@ enum dcn10_input_csc_select { INPUT_CSC_SELECT_COMA }; -bool is_lb_conf_valid( +bool dpp1_dscl_is_lb_conf_valid( int ceil_vratio, int num_partitions, int vtaps); -void dscl1_calc_lb_num_partitions( +void dpp1_dscl_calc_lb_num_partitions( const struct scaler_data *scl_data, enum lb_memory_config lb_config, int *num_part_y, diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c index b443a90974b93..cbad36410b32c 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c @@ -85,7 +85,7 @@ enum dscl_mode_sel { DSCL_MODE_DSCL_BYPASS = 6 }; -static void dpp_set_overscan( +static void dpp1_dscl_set_overscan( struct dcn10_dpp *dpp, const struct scaler_data *data) { @@ -113,7 +113,7 @@ static void dpp_set_overscan( EXT_OVERSCAN_TOP, top); } -static void dpp_set_otg_blank( +static void dpp1_dscl_set_otg_blank( struct dcn10_dpp *dpp, const struct scaler_data *data) { uint32_t h_blank_start = data->h_active; @@ -130,7 +130,7 @@ static void dpp_set_otg_blank( OTG_V_BLANK_END, v_blank_end); } -static int get_pixel_depth_val(enum lb_pixel_depth depth) +static int dpp1_dscl_get_pixel_depth_val(enum lb_pixel_depth depth) { if (depth == LB_PIXEL_DEPTH_30BPP) return 0; /* 10 bpc */ @@ -146,7 +146,7 @@ static int get_pixel_depth_val(enum lb_pixel_depth depth) } } -static bool is_video_format(enum pixel_format format) +static bool dpp1_dscl_is_video_format(enum pixel_format format) { if (format >= PIXEL_FORMAT_VIDEO_BEGIN && format <= PIXEL_FORMAT_VIDEO_END) @@ -155,7 +155,7 @@ static bool is_video_format(enum pixel_format format) return false; } -static bool is_420_format(enum pixel_format format) +static bool dpp1_dscl_is_420_format(enum pixel_format format) { if (format == PIXEL_FORMAT_420BPP8 || format == PIXEL_FORMAT_420BPP10) @@ -164,7 +164,7 @@ static bool is_420_format(enum pixel_format format) return false; } -static enum dscl_mode_sel get_dscl_mode( +static enum dscl_mode_sel dpp1_dscl_get_dscl_mode( struct dpp *dpp_base, const struct scaler_data *data, bool dbg_always_scale) @@ -184,8 +184,8 @@ static enum dscl_mode_sel get_dscl_mode( && !dbg_always_scale) return DSCL_MODE_SCALING_444_BYPASS; - if (!is_420_format(data->format)) { - if (is_video_format(data->format)) + if (!dpp1_dscl_is_420_format(data->format)) { + if (dpp1_dscl_is_video_format(data->format)) return DSCL_MODE_SCALING_444_YCBCR_ENABLE; else return DSCL_MODE_SCALING_444_RGB_ENABLE; @@ -198,7 +198,7 @@ static enum dscl_mode_sel get_dscl_mode( return DSCL_MODE_SCALING_420_YCBCR_ENABLE; } -static void dpp_set_lb( +static void dpp1_dscl_set_lb( struct dcn10_dpp *dpp, const struct line_buffer_params *lb_params, enum lb_memory_config mem_size_config) @@ -206,7 +206,7 @@ static void dpp_set_lb( /* LB */ if (dpp->base.caps->dscl_data_proc_format == DSCL_DATA_PRCESSING_FIXED_FORMAT) { /* DSCL caps: pixel data processed in fixed format */ - uint32_t pixel_depth = get_pixel_depth_val(lb_params->depth); + uint32_t pixel_depth = dpp1_dscl_get_pixel_depth_val(lb_params->depth); uint32_t dyn_pix_depth = lb_params->dynamic_pixel_depth; REG_SET_7(LB_DATA_FORMAT, 0, @@ -224,7 +224,7 @@ static void dpp_set_lb( LB_MAX_PARTITIONS, 63); } -static const uint16_t *get_filter_coeffs_64p(int taps, struct fixed31_32 ratio) +static const uint16_t *dpp1_dscl_get_filter_coeffs_64p(int taps, struct fixed31_32 ratio) { if (taps == 8) return get_filter_8tap_64p(ratio); @@ -249,7 +249,7 @@ static const uint16_t *get_filter_coeffs_64p(int taps, struct fixed31_32 ratio) } } -static void dpp_set_scaler_filter( +static void dpp1_dscl_set_scaler_filter( struct dcn10_dpp *dpp, uint32_t taps, enum dcn10_coef_filter_type_sel filter_type, @@ -287,7 +287,7 @@ static void dpp_set_scaler_filter( } -static void dpp_set_scl_filter( +static void dpp1_dscl_set_scl_filter( struct dcn10_dpp *dpp, const struct scaler_data *scl_data, bool chroma_coef_mode) @@ -325,18 +325,18 @@ static void dpp_set_scl_filter( if (!v_2tap_hardcode_coef_en || !h_2tap_hardcode_coef_en) { bool filter_updated = false; - filter_h = get_filter_coeffs_64p( + filter_h = dpp1_dscl_get_filter_coeffs_64p( scl_data->taps.h_taps, scl_data->ratios.horz); - filter_v = get_filter_coeffs_64p( + filter_v = dpp1_dscl_get_filter_coeffs_64p( scl_data->taps.v_taps, scl_data->ratios.vert); filter_updated = (filter_h && (filter_h != dpp->filter_h)) || (filter_v && (filter_v != dpp->filter_v)); if (chroma_coef_mode) { - filter_h_c = get_filter_coeffs_64p( + filter_h_c = dpp1_dscl_get_filter_coeffs_64p( scl_data->taps.h_taps_c, scl_data->ratios.horz_c); - filter_v_c = get_filter_coeffs_64p( + filter_v_c = dpp1_dscl_get_filter_coeffs_64p( scl_data->taps.v_taps_c, scl_data->ratios.vert_c); filter_updated = filter_updated || (filter_h_c && (filter_h_c != dpp->filter_h_c)) || (filter_v_c && (filter_v_c != dpp->filter_v_c)); @@ -346,25 +346,25 @@ static void dpp_set_scl_filter( uint32_t scl_mode = REG_READ(SCL_MODE); if (!h_2tap_hardcode_coef_en && filter_h) { - dpp_set_scaler_filter( + dpp1_dscl_set_scaler_filter( dpp, scl_data->taps.h_taps, SCL_COEF_LUMA_HORZ_FILTER, filter_h); } dpp->filter_h = filter_h; if (!v_2tap_hardcode_coef_en && filter_v) { - dpp_set_scaler_filter( + dpp1_dscl_set_scaler_filter( dpp, scl_data->taps.v_taps, SCL_COEF_LUMA_VERT_FILTER, filter_v); } dpp->filter_v = filter_v; if (chroma_coef_mode) { if (!h_2tap_hardcode_coef_en && filter_h_c) { - dpp_set_scaler_filter( + dpp1_dscl_set_scaler_filter( dpp, scl_data->taps.h_taps_c, SCL_COEF_CHROMA_HORZ_FILTER, filter_h_c); } if (!v_2tap_hardcode_coef_en && filter_v_c) { - dpp_set_scaler_filter( + dpp1_dscl_set_scaler_filter( dpp, scl_data->taps.v_taps_c, SCL_COEF_CHROMA_VERT_FILTER, filter_v_c); } @@ -384,7 +384,7 @@ static void dpp_set_scl_filter( } } -static int get_lb_depth_bpc(enum lb_pixel_depth depth) +static int dpp1_dscl_get_lb_depth_bpc(enum lb_pixel_depth depth) { if (depth == LB_PIXEL_DEPTH_30BPP) return 10; @@ -400,7 +400,7 @@ static int get_lb_depth_bpc(enum lb_pixel_depth depth) } } -void dscl1_calc_lb_num_partitions( +void dpp1_dscl_calc_lb_num_partitions( const struct scaler_data *scl_data, enum lb_memory_config lb_config, int *num_part_y, @@ -410,7 +410,7 @@ void dscl1_calc_lb_num_partitions( scl_data->viewport.width : scl_data->recout.width; int line_size_c = scl_data->viewport_c.width < scl_data->recout.width ? scl_data->viewport_c.width : scl_data->recout.width; - int lb_bpc = get_lb_depth_bpc(scl_data->lb_params.depth); + int lb_bpc = dpp1_dscl_get_lb_depth_bpc(scl_data->lb_params.depth); int memory_line_size_y = (line_size * lb_bpc + 71) / 72; /* +71 to ceil */ int memory_line_size_c = (line_size_c * lb_bpc + 71) / 72; /* +71 to ceil */ int memory_line_size_a = (line_size + 5) / 6; /* +5 to ceil */ @@ -449,7 +449,7 @@ void dscl1_calc_lb_num_partitions( } -bool is_lb_conf_valid(int ceil_vratio, int num_partitions, int vtaps) +bool dpp1_dscl_is_lb_conf_valid(int ceil_vratio, int num_partitions, int vtaps) { if (ceil_vratio > 2) return vtaps <= (num_partitions - ceil_vratio + 2); @@ -458,7 +458,7 @@ bool is_lb_conf_valid(int ceil_vratio, int num_partitions, int vtaps) } /*find first match configuration which meets the min required lb size*/ -static enum lb_memory_config find_lb_memory_config(struct dcn10_dpp *dpp, +static enum lb_memory_config dpp1_dscl_find_lb_memory_config(struct dcn10_dpp *dpp, const struct scaler_data *scl_data) { int num_part_y, num_part_c; @@ -474,15 +474,15 @@ static enum lb_memory_config find_lb_memory_config(struct dcn10_dpp *dpp, dpp->base.caps->dscl_calc_lb_num_partitions( scl_data, LB_MEMORY_CONFIG_1, &num_part_y, &num_part_c); - if (is_lb_conf_valid(ceil_vratio, num_part_y, vtaps) - && is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c)) + if (dpp1_dscl_is_lb_conf_valid(ceil_vratio, num_part_y, vtaps) + && dpp1_dscl_is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c)) return LB_MEMORY_CONFIG_1; dpp->base.caps->dscl_calc_lb_num_partitions( scl_data, LB_MEMORY_CONFIG_2, &num_part_y, &num_part_c); - if (is_lb_conf_valid(ceil_vratio, num_part_y, vtaps) - && is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c)) + if (dpp1_dscl_is_lb_conf_valid(ceil_vratio, num_part_y, vtaps) + && dpp1_dscl_is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c)) return LB_MEMORY_CONFIG_2; if (scl_data->format == PIXEL_FORMAT_420BPP8 @@ -490,8 +490,8 @@ static enum lb_memory_config find_lb_memory_config(struct dcn10_dpp *dpp, dpp->base.caps->dscl_calc_lb_num_partitions( scl_data, LB_MEMORY_CONFIG_3, &num_part_y, &num_part_c); - if (is_lb_conf_valid(ceil_vratio, num_part_y, vtaps) - && is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c)) + if (dpp1_dscl_is_lb_conf_valid(ceil_vratio, num_part_y, vtaps) + && dpp1_dscl_is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c)) return LB_MEMORY_CONFIG_3; } @@ -499,34 +499,34 @@ static enum lb_memory_config find_lb_memory_config(struct dcn10_dpp *dpp, scl_data, LB_MEMORY_CONFIG_0, &num_part_y, &num_part_c); /*Ensure we can support the requested number of vtaps*/ - ASSERT(is_lb_conf_valid(ceil_vratio, num_part_y, vtaps) - && is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c)); + ASSERT(dpp1_dscl_is_lb_conf_valid(ceil_vratio, num_part_y, vtaps) + && dpp1_dscl_is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c)); return LB_MEMORY_CONFIG_0; } -void dpp_set_scaler_auto_scale( +void dpp1_dscl_set_scaler_auto_scale( struct dpp *dpp_base, const struct scaler_data *scl_data) { enum lb_memory_config lb_config; struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base); - enum dscl_mode_sel dscl_mode = get_dscl_mode( + enum dscl_mode_sel dscl_mode = dpp1_dscl_get_dscl_mode( dpp_base, scl_data, dpp_base->ctx->dc->debug.always_scale); bool ycbcr = scl_data->format >= PIXEL_FORMAT_VIDEO_BEGIN && scl_data->format <= PIXEL_FORMAT_VIDEO_END; - dpp_set_overscan(dpp, scl_data); + dpp1_dscl_set_overscan(dpp, scl_data); - dpp_set_otg_blank(dpp, scl_data); + dpp1_dscl_set_otg_blank(dpp, scl_data); REG_UPDATE(SCL_MODE, DSCL_MODE, dscl_mode); if (dscl_mode == DSCL_MODE_DSCL_BYPASS) return; - lb_config = find_lb_memory_config(dpp, scl_data); - dpp_set_lb(dpp, &scl_data->lb_params, lb_config); + lb_config = dpp1_dscl_find_lb_memory_config(dpp, scl_data); + dpp1_dscl_set_lb(dpp, &scl_data->lb_params, lb_config); if (dscl_mode == DSCL_MODE_SCALING_444_BYPASS) return; @@ -554,11 +554,11 @@ void dpp_set_scaler_auto_scale( SCL_V_NUM_TAPS_C, scl_data->taps.v_taps_c - 1, SCL_H_NUM_TAPS_C, scl_data->taps.h_taps_c - 1); - dpp_set_scl_filter(dpp, scl_data, ycbcr); + dpp1_dscl_set_scl_filter(dpp, scl_data, ycbcr); } -static void dpp_set_manual_ratio_init( +static void dpp1_dscl_set_manual_ratio_init( struct dcn10_dpp *dpp, const struct scaler_data *data) { uint32_t init_frac = 0; @@ -618,7 +618,7 @@ static void dpp_set_manual_ratio_init( -static void dpp_set_recout( +static void dpp1_dscl_set_recout( struct dcn10_dpp *dpp, const struct rect *recout) { REG_SET_2(RECOUT_START, 0, @@ -643,13 +643,13 @@ void dpp1_dscl_set_scaler_manual_scale( { enum lb_memory_config lb_config; struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base); - enum dscl_mode_sel dscl_mode = get_dscl_mode( + enum dscl_mode_sel dscl_mode = dpp1_dscl_get_dscl_mode( dpp_base, scl_data, dpp_base->ctx->dc->debug.always_scale); bool ycbcr = scl_data->format >= PIXEL_FORMAT_VIDEO_BEGIN && scl_data->format <= PIXEL_FORMAT_VIDEO_END; /* Recout */ - dpp_set_recout(dpp, &scl_data->recout); + dpp1_dscl_set_recout(dpp, &scl_data->recout); /* MPC Size */ REG_SET_2(MPC_SIZE, 0, @@ -665,8 +665,8 @@ void dpp1_dscl_set_scaler_manual_scale( return; /* LB */ - lb_config = find_lb_memory_config(dpp, scl_data); - dpp_set_lb(dpp, &scl_data->lb_params, lb_config); + lb_config = dpp1_dscl_find_lb_memory_config(dpp, scl_data); + dpp1_dscl_set_lb(dpp, &scl_data->lb_params, lb_config); if (dscl_mode == DSCL_MODE_SCALING_444_BYPASS) return; @@ -689,7 +689,7 @@ void dpp1_dscl_set_scaler_manual_scale( SCL_BLACK_OFFSET_CBCR, BLACK_OFFSET_RGB_Y); /* Manually calculate scale ratio and init values */ - dpp_set_manual_ratio_init(dpp, scl_data); + dpp1_dscl_set_manual_ratio_init(dpp, scl_data); /* HTaps/VTaps */ REG_SET_4(SCL_TAP_CONTROL, 0, @@ -698,5 +698,5 @@ void dpp1_dscl_set_scaler_manual_scale( SCL_V_NUM_TAPS_C, scl_data->taps.v_taps_c - 1, SCL_H_NUM_TAPS_C, scl_data->taps.h_taps_c - 1); - dpp_set_scl_filter(dpp, scl_data, ycbcr); + dpp1_dscl_set_scl_filter(dpp, scl_data, ycbcr); } From 6b29f4424e39d279fa1c7b465bc1b508ea6fc98e Mon Sep 17 00:00:00 2001 From: Tony Cheng Date: Thu, 12 Oct 2017 10:59:42 -0400 Subject: [PATCH 125/155] drm/amd/display: DAL 3.1.06 Raven bug fixes - RS3 MPO stability improvement - SLS fixes - AM4 fixes DAL 3.1 - merge in upstream patches from DRM maintainer Dave Arilie - hubp, dpp HW objects Signed-off-by: Tony Cheng Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 6c0de093a59e4..37a779ead4fba 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -38,7 +38,8 @@ #include "inc/compressor.h" #include "dml/display_mode_lib.h" -#define DC_VER "3.1.05" +#define DC_VER "3.1.06" + #define MAX_SURFACES 3 #define MAX_STREAMS 6 From b9b171fffc9358be9e98cbc2bc7ef3fbe029f170 Mon Sep 17 00:00:00 2001 From: Hersen Wu Date: Tue, 10 Oct 2017 16:28:02 -0400 Subject: [PATCH 126/155] drm/amd/display: LGD panel willl flash line under window Signed-off-by: Hersen Wu Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c index 5e5763c0ee94b..e8b8daeeed979 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c @@ -1399,6 +1399,15 @@ static void power_down_encoders(struct dc *dc) int i; enum connector_id connector_id; enum signal_type signal = SIGNAL_TYPE_NONE; + + /* do not know BIOS back-front mapping, simply blank all. It will not + * hurt for non-DP + */ + for (i = 0; i < dc->res_pool->stream_enc_count; i++) { + dc->res_pool->stream_enc[i]->funcs->dp_blank( + dc->res_pool->stream_enc[i]); + } + for (i = 0; i < dc->link_count; i++) { connector_id = dal_graphics_object_id_get_connector_id(dc->links[i]->link_id); if ((connector_id == CONNECTOR_ID_DISPLAY_PORT) || From 75e68891200e3404fb3283e47ed74184932a748a Mon Sep 17 00:00:00 2001 From: Harry Wentland Date: Thu, 12 Oct 2017 12:27:48 -0400 Subject: [PATCH 127/155] drm/amd/display: Move OS types to os_types.h Some of this stuff is not really dm_services Signed-off-by: Harry Wentland Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dm_services.h | 45 -------------------- drivers/gpu/drm/amd/display/dc/os_types.h | 40 +++++++++++++++++ 2 files changed, 40 insertions(+), 45 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dm_services.h b/drivers/gpu/drm/amd/display/dc/dm_services.h index d6b3b832986b5..c8190c38a6443 100644 --- a/drivers/gpu/drm/amd/display/dc/dm_services.h +++ b/drivers/gpu/drm/amd/display/dc/dm_services.h @@ -38,51 +38,6 @@ #undef DEPRECATED -/* - * - * general debug capabilities - * - */ -#if defined(CONFIG_DEBUG_KERNEL) || defined(CONFIG_DEBUG_DRIVER) - -#if defined(CONFIG_HAVE_KGDB) || defined(CONFIG_KGDB) -#define ASSERT_CRITICAL(expr) do { \ - if (WARN_ON(!(expr))) { \ - kgdb_breakpoint(); \ - } \ -} while (0) -#else -#define ASSERT_CRITICAL(expr) do { \ - if (WARN_ON(!(expr))) { \ - ; \ - } \ -} while (0) -#endif - -#if defined(CONFIG_DEBUG_KERNEL_DC) -#define ASSERT(expr) ASSERT_CRITICAL(expr) - -#else -#define ASSERT(expr) WARN_ON(!(expr)) -#endif - -#define BREAK_TO_DEBUGGER() ASSERT(0) - -#endif /* CONFIG_DEBUG_KERNEL || CONFIG_DEBUG_DRIVER */ - -#define DC_ERR(...) do { \ - dm_error(__VA_ARGS__); \ - BREAK_TO_DEBUGGER(); \ -} while (0) - -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) -#include -#endif - -#define dm_alloc(size) kzalloc(size, GFP_KERNEL) -#define dm_realloc(ptr, size) krealloc(ptr, size, GFP_KERNEL) -#define dm_free(ptr) kfree(ptr) - irq_handler_idx dm_register_interrupt( struct dc_context *ctx, struct dc_interrupt_params *int_params, diff --git a/drivers/gpu/drm/amd/display/dc/os_types.h b/drivers/gpu/drm/amd/display/dc/os_types.h index e0cd5278aae81..86170b40b5c5f 100644 --- a/drivers/gpu/drm/amd/display/dc/os_types.h +++ b/drivers/gpu/drm/amd/display/dc/os_types.h @@ -56,5 +56,45 @@ #endif +/* + * + * general debug capabilities + * + */ +#if defined(CONFIG_DEBUG_KERNEL) || defined(CONFIG_DEBUG_DRIVER) + +#if defined(CONFIG_HAVE_KGDB) || defined(CONFIG_KGDB) +#define ASSERT_CRITICAL(expr) do { \ + if (WARN_ON(!(expr))) { \ + kgdb_breakpoint(); \ + } \ +} while (0) +#else +#define ASSERT_CRITICAL(expr) do { \ + if (WARN_ON(!(expr))) { \ + ; \ + } \ +} while (0) +#endif + +#if defined(CONFIG_DEBUG_KERNEL_DC) +#define ASSERT(expr) ASSERT_CRITICAL(expr) + +#else +#define ASSERT(expr) WARN_ON(!(expr)) +#endif + +#define BREAK_TO_DEBUGGER() ASSERT(0) + +#endif /* CONFIG_DEBUG_KERNEL || CONFIG_DEBUG_DRIVER */ + +#define DC_ERR(...) do { \ + dm_error(__VA_ARGS__); \ + BREAK_TO_DEBUGGER(); \ +} while (0) + +#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#include +#endif #endif /* _OS_TYPES_H_ */ From 1bed4d09a4cc5a7d4449da86832d9bd816ae44ff Mon Sep 17 00:00:00 2001 From: Harry Wentland Date: Tue, 12 Sep 2017 17:10:25 +0100 Subject: [PATCH 128/155] drm/amd/display: Fix one more place for dc_stream_state leak One more thing that happened due to uneven applying of patches. This mirrors what Darren Salt fixed. Signed-off-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 0d1b41298990d..58143fe49e4a1 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -4484,7 +4484,7 @@ static int dm_update_crtcs_state(struct dc *dc, * TODO: need to dig out the root cause of that */ if (!aconnector || (!aconnector->dc_sink && aconnector->mst_port)) - continue; + goto next_crtc; if (modereset_required(new_crtc_state)) goto next_crtc; From bb16bee4b394bafd6168c7719b7b07e19d1f0ce1 Mon Sep 17 00:00:00 2001 From: Harry Wentland Date: Thu, 12 Oct 2017 14:15:26 -0400 Subject: [PATCH 129/155] drm/amd/display: Reduce stack size of commit_planes_to_stream This function likes to blow 1024 stack size when something is added to the addr struct. For now just dynamically allocate. Signed-off-by: Harry Wentland Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index ff6bd384aece1..7a0593d4ca62f 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -926,9 +926,9 @@ bool dc_commit_planes_to_stream( struct dc_state *state) { struct dc_surface_update updates[MAX_SURFACES]; - struct dc_flip_addrs flip_addr[MAX_SURFACES]; - struct dc_plane_info plane_info[MAX_SURFACES]; - struct dc_scaling_info scaling_info[MAX_SURFACES]; + struct dc_flip_addrs *flip_addr; + struct dc_plane_info *plane_info; + struct dc_scaling_info *scaling_info; int i; struct dc_stream_update *stream_update = kzalloc(sizeof(struct dc_stream_update), GFP_KERNEL); @@ -938,10 +938,14 @@ bool dc_commit_planes_to_stream( return false; } + flip_addr = kcalloc(MAX_SURFACES, sizeof(struct dc_flip_addrs), + GFP_KERNEL); + plane_info = kcalloc(MAX_SURFACES, sizeof(struct dc_plane_info), + GFP_KERNEL); + scaling_info = kcalloc(MAX_SURFACES, sizeof(struct dc_scaling_info), + GFP_KERNEL); + memset(updates, 0, sizeof(updates)); - memset(flip_addr, 0, sizeof(flip_addr)); - memset(plane_info, 0, sizeof(plane_info)); - memset(scaling_info, 0, sizeof(scaling_info)); stream_update->src = dc_stream->src; stream_update->dst = dc_stream->dst; @@ -980,6 +984,9 @@ bool dc_commit_planes_to_stream( new_plane_count, dc_stream, stream_update, plane_states, state); + kfree(flip_addr); + kfree(plane_info); + kfree(scaling_info); kfree(stream_update); return true; } From 9e7da3268aedd21d559f0f27406874cf92ff582a Mon Sep 17 00:00:00 2001 From: Tony Cheng Date: Thu, 12 Oct 2017 22:18:12 -0400 Subject: [PATCH 130/155] drm/amd/display: dal 3.1.07 - regression fixes in dal 3.1.06 - more linux upstream backport Signed-off-by: Tony Cheng Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 37a779ead4fba..9d8f4a55c74e9 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -38,8 +38,7 @@ #include "inc/compressor.h" #include "dml/display_mode_lib.h" -#define DC_VER "3.1.06" - +#define DC_VER "3.1.07" #define MAX_SURFACES 3 #define MAX_STREAMS 6 From be11749177d74b2e2c8a4cf2526e88355c40ad00 Mon Sep 17 00:00:00 2001 From: Harry Wentland Date: Fri, 13 Oct 2017 15:12:04 -0400 Subject: [PATCH 131/155] drm/amd/display: Remove redundant condition in dml vba Found by 0-day https://lists.freedesktop.org/archives/dri-devel/2017-October/154698.html Signed-off-by: Harry Wentland Reviewed-by: Dmytro Laktyushkin Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c index a11b37c50d960..117ec11ef304d 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c +++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c @@ -3463,7 +3463,7 @@ bool Calculate256BBlockSizes( unsigned int *BlockWidth256BytesC) { if ((SourcePixelFormat == dm_444_64 || SourcePixelFormat == dm_444_32 - || SourcePixelFormat == dm_444_16 || SourcePixelFormat == dm_444_16 + || SourcePixelFormat == dm_444_16 || SourcePixelFormat == dm_444_8)) { if (SurfaceTiling == dm_sw_linear) { *BlockHeight256BytesY = 1; From e92b44fdee3ec0b679bacdb9c7e95e55699167f0 Mon Sep 17 00:00:00 2001 From: Tony Cheng Date: Thu, 5 Oct 2017 14:38:46 -0400 Subject: [PATCH 132/155] drm/amd/display: default force_single_disp_pipe_split = 1 on RV 1080p idle, stutter efficiency goes up from 95.8% to 97.8% result in 5mW saving from APU and 8mW saving from DDR4 Signed-off-by: Tony Cheng Reviewed-by: Yongqiang Sun Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c index d47ff7e6a5257..d911590d08bc4 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c @@ -430,6 +430,7 @@ static const struct dc_debug debug_defaults_drv = { .disable_pplib_wm_range = false, .pplib_wm_report_mode = WM_REPORT_DEFAULT, .pipe_split_policy = MPC_SPLIT_AVOID_MULT_DISP, + .force_single_disp_pipe_split = true, .disable_dcc = DCC_ENABLE, .voltage_align_fclk = true, .disable_stereo_support = true, From f63d89066fb29a47ad3e9530214de7ea87e82e57 Mon Sep 17 00:00:00 2001 From: Dmytro Laktyushkin Date: Fri, 13 Oct 2017 12:53:38 -0400 Subject: [PATCH 133/155] drm/amd/display: change dml numdpp var to uint Signed-off-by: Dmytro Laktyushkin Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/dml/display_mode_vba.c | 14 +++++++------- .../gpu/drm/amd/display/dc/dml/display_mode_vba.h | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c index 117ec11ef304d..ffd1d8d10bdfd 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c +++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c @@ -1158,7 +1158,7 @@ static bool CalculatePrefetchSchedule( else if (PageTableLevels == 3) *Tno_bw = UrgentExtraLatency; else - Tno_bw = 0; + *Tno_bw = 0; } else if (DCCEnable) *Tno_bw = LineTime; else @@ -4721,14 +4721,14 @@ static void ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_ && mode_lib->vba.SwathWidthYSingleDPP[k] <= mode_lib->vba.MaximumSwathWidth[k] && mode_lib->vba.ODMCombineEnablePerState[i][k] == false) { - mode_lib->vba.NoOfDPP[i][k] = 1.0; + mode_lib->vba.NoOfDPP[i][k] = 1; mode_lib->vba.RequiredDPPCLK[i][k] = mode_lib->vba.MinDPPCLKUsingSingleDPP[k] * (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0); } else { - mode_lib->vba.NoOfDPP[i][k] = 2.0; + mode_lib->vba.NoOfDPP[i][k] = 2; mode_lib->vba.RequiredDPPCLK[i][k] = mode_lib->vba.MinDPPCLKUsingSingleDPP[k] * (1.0 @@ -4790,14 +4790,14 @@ static void ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_ <= mode_lib->vba.MaximumSwathWidth[k] && mode_lib->vba.ODMCombineEnablePerState[i][k] == false) { - mode_lib->vba.NoOfDPP[i][k] = 1.0; + mode_lib->vba.NoOfDPP[i][k] = 1; mode_lib->vba.RequiredDPPCLK[i][k] = mode_lib->vba.MinDPPCLKUsingSingleDPP[k] * (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0); } else { - mode_lib->vba.NoOfDPP[i][k] = 2.0; + mode_lib->vba.NoOfDPP[i][k] = 2; mode_lib->vba.RequiredDPPCLK[i][k] = mode_lib->vba.MinDPPCLKUsingSingleDPP[k] * (1.0 @@ -4833,14 +4833,14 @@ static void ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_ mode_lib->vba.ODMCombineEnablePerState[i][k] = false; if (mode_lib->vba.SwathWidthYSingleDPP[k] <= mode_lib->vba.MaximumSwathWidth[k]) { - mode_lib->vba.NoOfDPP[i][k] = 1.0; + mode_lib->vba.NoOfDPP[i][k] = 1; mode_lib->vba.RequiredDPPCLK[i][k] = mode_lib->vba.MinDPPCLKUsingSingleDPP[k] * (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0); } else { - mode_lib->vba.NoOfDPP[i][k] = 2.0; + mode_lib->vba.NoOfDPP[i][k] = 2; mode_lib->vba.RequiredDPPCLK[i][k] = mode_lib->vba.MinDPPCLKUsingSingleDPP[k] * (1.0 diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h index 63ad4a7bfeb51..4b8c1b911f178 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h +++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h @@ -489,7 +489,7 @@ struct vba_vars_st { double CursorBufferSize; double CursorChunkSize; unsigned int Mode; - double NoOfDPP[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX]; + unsigned int NoOfDPP[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX]; double OutputLinkDPLanes[DC__NUM_DPP__MAX]; double SwathWidthYPerState[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX]; double SwathHeightYPerState[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX]; From 3eea71e36fcd04d0a3e735ee3cf4dbbe9934e3c8 Mon Sep 17 00:00:00 2001 From: Dmytro Laktyushkin Date: Thu, 12 Oct 2017 22:45:25 -0400 Subject: [PATCH 134/155] drm/amd/display: Minor update to DML Signed-off-by: Dmytro Laktyushkin Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 3 ++- drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.c | 6 ------ drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.h | 1 - .../gpu/drm/amd/display/dc/dml/display_mode_structs.h | 7 ++----- drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c | 9 +-------- drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h | 1 - 6 files changed, 5 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index 741b5e06d3149..63c2f52661424 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -2015,10 +2015,11 @@ static void dcn10_power_on_fe( plane_state->dst_rect.height); dm_logger_write(dc->ctx->logger, LOG_DC, - "Pipe %d: width, height, x, y\n" + "Pipe %d: width, height, x, y format:%d\n" "viewport:%d, %d, %d, %d\n" "recout: %d, %d, %d, %d\n", pipe_ctx->pipe_idx, + plane_state->format, pipe_ctx->plane_res.scl_data.viewport.width, pipe_ctx->plane_res.scl_data.viewport.height, pipe_ctx->plane_res.scl_data.viewport.x, diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.c b/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.c index 09d232806de7c..4c31fa54af390 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.c +++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.c @@ -127,17 +127,11 @@ static void set_ip_params(struct _vcs_dpi_ip_params_st *ip, enum dml_project pro } } -static void set_mode_evaluation(struct _vcs_dpi_mode_evaluation_st *me, enum dml_project project) -{ - me->voltage_override = dm_vmin; -} - void dml_init_instance(struct display_mode_lib *lib, enum dml_project project) { if (lib->project != project) { set_soc_bounding_box(&lib->soc, project); set_ip_params(&lib->ip, project); - set_mode_evaluation(&lib->me, project); lib->project = project; } } diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.h index ed77f96016ddd..26f4f2a3d90d9 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.h +++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.h @@ -40,7 +40,6 @@ enum dml_project { struct display_mode_lib { struct _vcs_dpi_ip_params_st ip; struct _vcs_dpi_soc_bounding_box_st soc; - struct _vcs_dpi_mode_evaluation_st me; enum dml_project project; struct vba_vars_st vba; struct dal_logger *logger; diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h index 27e20460c71b5..baf182177736b 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h +++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h @@ -27,7 +27,6 @@ typedef struct _vcs_dpi_voltage_scaling_st voltage_scaling_st; typedef struct _vcs_dpi_soc_bounding_box_st soc_bounding_box_st; -typedef struct _vcs_dpi_mode_evaluation_st mode_evaluation_st; typedef struct _vcs_dpi_ip_params_st ip_params_st; typedef struct _vcs_dpi_display_pipe_source_params_st display_pipe_source_params_st; typedef struct _vcs_dpi_display_output_params_st display_output_params_st; @@ -60,10 +59,6 @@ typedef struct _vcs_dpi_display_dlg_prefetch_param_st display_dlg_prefetch_param typedef struct _vcs_dpi_display_pipe_clock_st display_pipe_clock_st; typedef struct _vcs_dpi_display_arb_params_st display_arb_params_st; -struct _vcs_dpi_mode_evaluation_st { - int voltage_override; -}; - struct _vcs_dpi_voltage_scaling_st { int state; double dscclk_mhz; @@ -96,6 +91,7 @@ struct _vcs_dpi_soc_bounding_box_st { double fabric_datapath_to_dcn_data_return_bytes; double dcn_downspread_percent; double dispclk_dppclk_vco_speed_mhz; + double dfs_vco_period_ps; unsigned int round_trip_ping_latency_dcfclk_cycles; unsigned int urgent_out_of_order_return_per_channel_bytes; unsigned int channel_interleave_bytes; @@ -105,6 +101,7 @@ struct _vcs_dpi_soc_bounding_box_st { double dram_clock_change_latency_us; double writeback_dram_clock_change_latency_us; unsigned int return_bus_width_bytes; + unsigned int voltage_override; double xfc_bus_transport_time_us; double xfc_xbuf_latency_tolerance_us; struct _vcs_dpi_voltage_scaling_st clock_limits[7]; diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c index ffd1d8d10bdfd..e337c2cf2c092 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c +++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c @@ -251,19 +251,14 @@ unsigned int dml_get_voltage_level( const display_e2e_pipe_params_st *pipes, unsigned int num_pipes) { - bool need_recalculate = memcmp( - &mode_lib->soc, - &mode_lib->vba.soc, - sizeof(mode_lib->vba.soc)) != 0 + bool need_recalculate = memcmp(&mode_lib->soc, &mode_lib->vba.soc, sizeof(mode_lib->vba.soc)) != 0 || memcmp(&mode_lib->ip, &mode_lib->vba.ip, sizeof(mode_lib->vba.ip)) != 0 - || memcmp(&mode_lib->me, &mode_lib->vba.me, sizeof(mode_lib->vba.me)) != 0 || num_pipes != mode_lib->vba.cache_num_pipes || memcmp(pipes, mode_lib->vba.cache_pipes, sizeof(display_e2e_pipe_params_st) * num_pipes) != 0; mode_lib->vba.soc = mode_lib->soc; mode_lib->vba.ip = mode_lib->ip; - mode_lib->vba.me = mode_lib->me; memcpy(mode_lib->vba.cache_pipes, pipes, sizeof(*pipes) * num_pipes); mode_lib->vba.cache_num_pipes = num_pipes; @@ -772,7 +767,6 @@ static void recalculate_params( // This is only safe to use memcmp because there are non-POD types in struct display_mode_lib if (memcmp(&mode_lib->soc, &mode_lib->vba.soc, sizeof(mode_lib->vba.soc)) != 0 || memcmp(&mode_lib->ip, &mode_lib->vba.ip, sizeof(mode_lib->vba.ip)) != 0 - || memcmp(&mode_lib->me, &mode_lib->vba.me, sizeof(mode_lib->vba.me)) != 0 || num_pipes != mode_lib->vba.cache_num_pipes || memcmp( pipes, @@ -780,7 +774,6 @@ static void recalculate_params( sizeof(display_e2e_pipe_params_st) * num_pipes) != 0) { mode_lib->vba.soc = mode_lib->soc; mode_lib->vba.ip = mode_lib->ip; - mode_lib->vba.me = mode_lib->me; memcpy(mode_lib->vba.cache_pipes, pipes, sizeof(*pipes) * num_pipes); mode_lib->vba.cache_num_pipes = num_pipes; recalculate(mode_lib); diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h index 4b8c1b911f178..c8d1a05395414 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h +++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h @@ -98,7 +98,6 @@ bool Calculate256BBlockSizes( struct vba_vars_st { ip_params_st ip; soc_bounding_box_st soc; - mode_evaluation_st me; unsigned int MaximumMaxVStartupLines; double cursor_bw[DC__NUM_DPP__MAX]; From 565f26a39d8e49745fda00d2303138aea831fd29 Mon Sep 17 00:00:00 2001 From: Harry Wentland Date: Mon, 16 Oct 2017 20:10:00 -0400 Subject: [PATCH 135/155] drm/amd/display: Small comment on dc_commit_planes_to_stream Having one struct on the stack was somewhat confusing. Also mention that the whole function should eventually go. Signed-off-by: Harry Wentland Reviewed-by: Andrey Grodzovsky Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 7a0593d4ca62f..a71392ffc46d5 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -918,6 +918,12 @@ bool dc_post_update_surfaces_to_stream(struct dc *dc) return true; } +/* + * TODO this whole function needs to go + * + * dc_surface_update is needlessly complex. See if we can just replace this + * with a dc_plane_state and follow the atomic model a bit more closely here. + */ bool dc_commit_planes_to_stream( struct dc *dc, struct dc_plane_state **plane_states, @@ -925,6 +931,7 @@ bool dc_commit_planes_to_stream( struct dc_stream_state *dc_stream, struct dc_state *state) { + /* no need to dynamically allocate this. it's pretty small */ struct dc_surface_update updates[MAX_SURFACES]; struct dc_flip_addrs *flip_addr; struct dc_plane_info *plane_info; From 16b2f2ed5f2ece5bf44d94883412048856ca2966 Mon Sep 17 00:00:00 2001 From: Harry Wentland Date: Thu, 28 Sep 2017 10:45:26 +1000 Subject: [PATCH 136/155] amdgpu/dc: inline a bunch of the dml wrappers. This reduces the code size. This is basically a redo of Dave's change with the same name on top of the latest DML. Signed-off-by: Harry Wentland Signed-off-by: Alex Deucher --- .../drm/amd/display/dc/dml/display_mode_vba.c | 2 + .../amd/display/dc/dml/display_rq_dlg_calc.c | 2 + .../display/dc/dml/dml1_display_rq_dlg_calc.c | 2 + .../drm/amd/display/dc/dml/dml_common_defs.c | 67 +----------- .../drm/amd/display/dc/dml/dml_common_defs.h | 14 --- .../drm/amd/display/dc/dml/dml_inline_defs.h | 102 ++++++++++++++++++ .../drm/amd/display/dc/dml/soc_bounding_box.c | 1 + 7 files changed, 110 insertions(+), 80 deletions(-) create mode 100644 drivers/gpu/drm/amd/display/dc/dml/dml_inline_defs.h diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c index e337c2cf2c092..f51a36449410b 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c +++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c @@ -1,6 +1,8 @@ #include "display_mode_lib.h" #include "display_mode_vba.h" +#include "dml_inline_defs.h" + static const unsigned int NumberOfStates = DC__VOLTAGE_STATES; static void fetch_socbb_params(struct display_mode_lib *mode_lib); diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_calc.c b/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_calc.c index 657b7386021d7..8ba962df42e60 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_calc.c +++ b/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_calc.c @@ -39,6 +39,8 @@ static void calculate_ttu_cursor(struct display_mode_lib *mode_lib, unsigned int cur_width, enum cursor_bpp cur_bpp); +#include "dml_inline_defs.h" + static unsigned int get_bytes_per_element(enum source_format_class source_format, bool is_chroma) { unsigned int ret_val = 0; diff --git a/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c b/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c index 8229f782260b6..1e4b1e3834012 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c @@ -26,6 +26,8 @@ #include "dml1_display_rq_dlg_calc.h" #include "display_mode_lib.h" +#include "dml_inline_defs.h" + static unsigned int get_bytes_per_element(enum source_format_class source_format, bool is_chroma) { unsigned int ret_val = 0; diff --git a/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.c b/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.c index 2af6d150cc463..101fb6f19c434 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.c @@ -26,37 +26,7 @@ #include "dml_common_defs.h" #include "../calcs/dcn_calc_math.h" -double dml_min(double a, double b) -{ - return (double) dcn_bw_min2(a, b); -} - -double dml_max(double a, double b) -{ - return (double) dcn_bw_max2(a, b); -} -double dml_max3(double a, double b, double c) -{ - return dml_max(dml_max(a, b), c); -} -double dml_max4(double a, double b, double c, double d) -{ - return dml_max(dml_max(a, b), dml_max(c, d)); -} -double dml_max5(double a, double b, double c, double d, double e) -{ - return dml_max(dml_max4(a, b, c, d), e); -} - -double dml_ceil(double a, double granularity) -{ - return (double) dcn_bw_ceil2(a, granularity); -} - -double dml_floor(double a, double granularity) -{ - return (double) dcn_bw_floor2(a, granularity); -} +#include "dml_inline_defs.h" double dml_round(double a) { @@ -70,16 +40,6 @@ double dml_round(double a) return floor; } -int dml_log2(double x) -{ - return dml_round((double)dcn_bw_log(x, 2)); -} - -double dml_pow(double a, int exp) -{ - return (double) dcn_bw_pow(a, exp); -} - unsigned int dml_round_to_multiple( unsigned int num, unsigned int multiple, @@ -101,16 +61,6 @@ unsigned int dml_round_to_multiple( return (num - remainder); } -double dml_fmod(double f, int val) -{ - return (double) dcn_bw_mod(f, val); -} - -double dml_ceil_2(double f) -{ - return (double) dcn_bw_ceil2(f, 2); -} - bool dml_util_is_420(enum source_format_class sorce_format) { bool val = false; @@ -143,18 +93,3 @@ bool dml_util_is_420(enum source_format_class sorce_format) return val; } - -double dml_ceil_ex(double x, double granularity) -{ - return (double) dcn_bw_ceil2(x, granularity); -} - -double dml_floor_ex(double x, double granularity) -{ - return (double) dcn_bw_floor2(x, granularity); -} - -double dml_log(double x, double base) -{ - return (double) dcn_bw_log(x, base); -} diff --git a/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.h b/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.h index ba01bbb007fc0..a55f4d5af36cf 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.h +++ b/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.h @@ -34,23 +34,9 @@ #define dml_print(str, ...) {dm_logger_write(mode_lib->logger, LOG_DML, str, ##__VA_ARGS__); } #define DTRACE(str, ...) {dm_logger_write(mode_lib->logger, LOG_DML, str, ##__VA_ARGS__); } -double dml_min(double a, double b); -double dml_max(double a, double b); -double dml_max3(double a, double b, double c); -double dml_max4(double a, double b, double c, double d); -double dml_max5(double a, double b, double c, double d, double e); bool dml_util_is_420(enum source_format_class sorce_format); -double dml_ceil_ex(double x, double granularity); -double dml_floor_ex(double x, double granularity); -double dml_log(double x, double base); -double dml_ceil(double a, double granularity); -double dml_floor(double a, double granularity); double dml_round(double a); -int dml_log2(double x); -double dml_pow(double a, int exp); unsigned int dml_round_to_multiple( unsigned int num, unsigned int multiple, bool up); -double dml_fmod(double f, int val); -double dml_ceil_2(double f); #endif /* __DC_COMMON_DEFS_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/dml/dml_inline_defs.h b/drivers/gpu/drm/amd/display/dc/dml/dml_inline_defs.h new file mode 100644 index 0000000000000..105c6721f9011 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/dml/dml_inline_defs.h @@ -0,0 +1,102 @@ +/* + * Copyright 2017 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: AMD + * + */ + +#ifndef __DML_INLINE_DEFS_H__ +#define __DML_INLINE_DEFS_H__ + +#include "dml_common_defs.h" +#include "../calcs/dcn_calc_math.h" + +static inline double dml_min(double a, double b) +{ + return (double) dcn_bw_min2(a, b); +} + +static inline double dml_max(double a, double b) +{ + return (double) dcn_bw_max2(a, b); +} + +static inline double dml_max3(double a, double b, double c) +{ + return dml_max(dml_max(a, b), c); +} + +static inline double dml_max4(double a, double b, double c, double d) +{ + return dml_max(dml_max(a, b), dml_max(c, d)); +} + +static inline double dml_max5(double a, double b, double c, double d, double e) +{ + return dml_max(dml_max4(a, b, c, d), e); +} + +static inline double dml_ceil(double a, double granularity) +{ + return (double) dcn_bw_ceil2(a, granularity); +} + +static inline double dml_floor(double a, double granularity) +{ + return (double) dcn_bw_floor2(a, granularity); +} + +static inline int dml_log2(double x) +{ + return dml_round((double)dcn_bw_log(x, 2)); +} + +static inline double dml_pow(double a, int exp) +{ + return (double) dcn_bw_pow(a, exp); +} + +static inline double dml_fmod(double f, int val) +{ + return (double) dcn_bw_mod(f, val); +} + +static inline double dml_ceil_2(double f) +{ + return (double) dcn_bw_ceil2(f, 2); +} + +static inline double dml_ceil_ex(double x, double granularity) +{ + return (double) dcn_bw_ceil2(x, granularity); +} + +static inline double dml_floor_ex(double x, double granularity) +{ + return (double) dcn_bw_floor2(x, granularity); +} + +static inline double dml_log(double x, double base) +{ + return (double) dcn_bw_log(x, base); +} + +#endif diff --git a/drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.c b/drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.c index 8b8512528af5d..bc7d8c7072211 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.c +++ b/drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.c @@ -26,6 +26,7 @@ #include "display_mode_lib.h" #include "dc_features.h" +#include "dml_inline_defs.h" void dml_socbb_set_latencies(soc_bounding_box_st *to_box, soc_bounding_box_st *from_box) { to_box->dram_clock_change_latency_us = from_box->dram_clock_change_latency_us; From c6ca4496177d89e3f6eef7d7b6200798b19250ee Mon Sep 17 00:00:00 2001 From: Harry Wentland Date: Mon, 16 Oct 2017 22:58:18 -0400 Subject: [PATCH 137/155] drm/amd/display: Add bunch of missing license headers in DML All files should have MIT headers. Signed-off-by: Harry Wentland Signed-off-by: Alex Deucher --- .../drm/amd/display/dc/dml/display_mode_vba.c | 25 +++++++++++++++++++ .../drm/amd/display/dc/dml/display_mode_vba.h | 24 +++++++++++++++--- 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c index f51a36449410b..ea661ee446741 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c +++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c @@ -1,3 +1,28 @@ +/* + * Copyright 2017 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: AMD + * + */ + #include "display_mode_lib.h" #include "display_mode_vba.h" diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h index c8d1a05395414..4112409cd9747 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h +++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h @@ -1,8 +1,26 @@ /* - * display_mode_vba.h + * Copyright 2017 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: AMD * - * Created on: Aug 18, 2017 - * Author: dlaktyus */ #ifndef __DML2_DISPLAY_MODE_VBA_H__ From b2484b6237ef3ed60af0400027c053ec973b60cc Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 28 Sep 2017 10:55:25 +1000 Subject: [PATCH 138/155] amdgpu/dc: drop dml_util_is_420 This is unused code. Signed-off-by: Dave Airlie Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher Signed-off-by: Alex Deucher --- .../drm/amd/display/dc/dml/dml_common_defs.c | 33 ------------------- .../drm/amd/display/dc/dml/dml_common_defs.h | 1 - 2 files changed, 34 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.c b/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.c index 101fb6f19c434..1683514ed0e37 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.c @@ -60,36 +60,3 @@ unsigned int dml_round_to_multiple( else return (num - remainder); } - -bool dml_util_is_420(enum source_format_class sorce_format) -{ - bool val = false; - - switch (sorce_format) { - case dm_444_16: - val = false; - break; - case dm_444_32: - val = false; - break; - case dm_444_64: - val = false; - break; - case dm_420_8: - val = true; - break; - case dm_420_10: - val = true; - break; - case dm_422_8: - val = false; - break; - case dm_422_10: - val = false; - break; - default: - BREAK_TO_DEBUGGER(); - } - - return val; -} diff --git a/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.h b/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.h index a55f4d5af36cf..e11d123ab8d9c 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.h +++ b/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.h @@ -34,7 +34,6 @@ #define dml_print(str, ...) {dm_logger_write(mode_lib->logger, LOG_DML, str, ##__VA_ARGS__); } #define DTRACE(str, ...) {dm_logger_write(mode_lib->logger, LOG_DML, str, ##__VA_ARGS__); } -bool dml_util_is_420(enum source_format_class sorce_format); double dml_round(double a); unsigned int dml_round_to_multiple( unsigned int num, unsigned int multiple, bool up); From 299f27fd370f34cb6e22e2ffb84b61e91dd6a4c1 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 29 Sep 2017 17:13:31 +1000 Subject: [PATCH 139/155] amdgpu/dc: inline dml_round_to_multiple turns out to be a win to inline this. Signed-off-by: Dave Airlie Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher --- .../drm/amd/display/dc/dml/dml_common_defs.c | 19 ------------------- .../drm/amd/display/dc/dml/dml_common_defs.h | 2 -- .../drm/amd/display/dc/dml/dml_inline_defs.h | 19 +++++++++++++++++++ 3 files changed, 19 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.c b/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.c index 1683514ed0e37..b953b02a15121 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.c @@ -40,23 +40,4 @@ double dml_round(double a) return floor; } -unsigned int dml_round_to_multiple( - unsigned int num, - unsigned int multiple, - bool up) -{ - unsigned int remainder; - - if (multiple == 0) - return num; - - remainder = num % multiple; - if (remainder == 0) - return num; - - if (up) - return (num + multiple - remainder); - else - return (num - remainder); -} diff --git a/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.h b/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.h index e11d123ab8d9c..b2847bc469fed 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.h +++ b/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.h @@ -35,7 +35,5 @@ #define DTRACE(str, ...) {dm_logger_write(mode_lib->logger, LOG_DML, str, ##__VA_ARGS__); } double dml_round(double a); -unsigned int dml_round_to_multiple( - unsigned int num, unsigned int multiple, bool up); #endif /* __DC_COMMON_DEFS_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/dml/dml_inline_defs.h b/drivers/gpu/drm/amd/display/dc/dml/dml_inline_defs.h index 105c6721f9011..e68086b8a22fe 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dml_inline_defs.h +++ b/drivers/gpu/drm/amd/display/dc/dml/dml_inline_defs.h @@ -99,4 +99,23 @@ static inline double dml_log(double x, double base) return (double) dcn_bw_log(x, base); } +static inline unsigned int dml_round_to_multiple(unsigned int num, + unsigned int multiple, + bool up) +{ + unsigned int remainder; + + if (multiple == 0) + return num; + + remainder = num % multiple; + + if (remainder == 0) + return num; + + if (up) + return (num + multiple - remainder); + else + return (num - remainder); +} #endif From 33be2785477e470087ea1c5b203881d644cdb0f3 Mon Sep 17 00:00:00 2001 From: Tom St Denis Date: Tue, 17 Oct 2017 08:47:25 -0400 Subject: [PATCH 140/155] drm/amd/display: Simplify dm_late_init() Signed-off-by: Tom St Denis Acked-by: Andrey Grodzovsky Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 58143fe49e4a1..d8fcf24a041ef 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -538,9 +538,8 @@ static int detect_mst_link_for_all_connectors(struct drm_device *dev) static int dm_late_init(void *handle) { struct drm_device *dev = ((struct amdgpu_device *)handle)->ddev; - int r = detect_mst_link_for_all_connectors(dev); - return r; + return detect_mst_link_for_all_connectors(dev); } static void s3_handle_mst(struct drm_device *dev, bool suspend) From 32f5062d1c7dc2a4d974bb10cf67a98043d9c901 Mon Sep 17 00:00:00 2001 From: Tom St Denis Date: Tue, 17 Oct 2017 08:48:44 -0400 Subject: [PATCH 141/155] drm/amd/display: Fix indentation in dm_suspend() Signed-off-by: Tom St Denis Acked-by: Andrey Grodzovsky Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index d8fcf24a041ef..893213b9c11ea 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -598,10 +598,7 @@ static int dm_suspend(void *handle) WARN_ON(adev->dm.cached_state); adev->dm.cached_state = drm_atomic_helper_suspend(adev->ddev); - dc_set_power_state( - dm->dc, - DC_ACPI_CM_POWER_STATE_D3 - ); + dc_set_power_state(dm->dc, DC_ACPI_CM_POWER_STATE_D3); return ret; } From 1fb0c9ccb311cdf16f6ec617fb30c249888c5f97 Mon Sep 17 00:00:00 2001 From: Tom St Denis Date: Tue, 17 Oct 2017 08:49:13 -0400 Subject: [PATCH 142/155] drm/amd/display: Fix indentation in dm_resume() Signed-off-by: Tom St Denis Acked-by: Andrey Grodzovsky Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 893213b9c11ea..a7bbd22e8f125 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -628,10 +628,7 @@ static int dm_resume(void *handle) struct amdgpu_display_manager *dm = &adev->dm; /* power on hardware */ - dc_set_power_state( - dm->dc, - DC_ACPI_CM_POWER_STATE_D0 - ); + dc_set_power_state(dm->dc, DC_ACPI_CM_POWER_STATE_D0); return 0; } From 900b3cb1833883de9be62e48ff748663c7b6ef96 Mon Sep 17 00:00:00 2001 From: Tom St Denis Date: Tue, 17 Oct 2017 08:59:18 -0400 Subject: [PATCH 143/155] drm/amd/display: Fix brace style in amdgpu_dm_update_connector_after_detect() Signed-off-by: Tom St Denis Acked-by: Andrey Grodzovsky Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index a7bbd22e8f125..7999eadddd75f 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -890,9 +890,9 @@ amdgpu_dm_update_connector_after_detect(struct amdgpu_dm_connector *aconnector) connector); aconnector->dc_sink = sink; - if (sink->dc_edid.length == 0) + if (sink->dc_edid.length == 0) { aconnector->edid = NULL; - else { + } else { aconnector->edid = (struct edid *) sink->dc_edid.raw_edid; From d4a6e8a90ffa281918d9ba75a08f1f917c7eb183 Mon Sep 17 00:00:00 2001 From: Tom St Denis Date: Tue, 17 Oct 2017 09:00:33 -0400 Subject: [PATCH 144/155] drm/amd/display: Fix brace style in dm_handle_hpd_rx_irq() Signed-off-by: Tom St Denis Acked-by: Andrey Grodzovsky Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 7999eadddd75f..2b57bfc8ec407 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -1010,8 +1010,9 @@ static void dm_handle_hpd_rx_irq(struct amdgpu_dm_connector *aconnector) dpcd_bytes_to_read); new_irq_handled = false; - } else + } else { break; + } } if (process_count == max_process_count) From 53cbf65c145450e35fbca50a33c56f5a066e3fe8 Mon Sep 17 00:00:00 2001 From: Tom St Denis Date: Tue, 17 Oct 2017 09:04:25 -0400 Subject: [PATCH 145/155] drm/amd/display: Simplify handle_hpd_rx_irq() There is a local reference to the dc_link that wasn't being used so we shorten references throughout the function. Signed-off-by: Tom St Denis Acked-by: Andrey Grodzovsky Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 2b57bfc8ec407..bb83da6fd31b0 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -1024,20 +1024,20 @@ static void handle_hpd_rx_irq(void *param) struct amdgpu_dm_connector *aconnector = (struct amdgpu_dm_connector *)param; struct drm_connector *connector = &aconnector->base; struct drm_device *dev = connector->dev; - const struct dc_link *dc_link = aconnector->dc_link; + struct dc_link *dc_link = aconnector->dc_link; bool is_mst_root_connector = aconnector->mst_mgr.mst_state; /* TODO:Temporary add mutex to protect hpd interrupt not have a gpio * conflict, after implement i2c helper, this mutex should be * retired. */ - if (aconnector->dc_link->type != dc_connection_mst_branch) + if (dc_link->type != dc_connection_mst_branch) mutex_lock(&aconnector->hpd_lock); - if (dc_link_handle_hpd_rx_irq(aconnector->dc_link, NULL) && + if (dc_link_handle_hpd_rx_irq(dc_link, NULL) && !is_mst_root_connector) { /* Downstream Port status changed. */ - if (dc_link_detect(aconnector->dc_link, DETECT_REASON_HPDRX)) { + if (dc_link_detect(dc_link, DETECT_REASON_HPDRX)) { amdgpu_dm_update_connector_after_detect(aconnector); @@ -1049,10 +1049,10 @@ static void handle_hpd_rx_irq(void *param) } } if ((dc_link->cur_link_settings.lane_count != LANE_COUNT_UNKNOWN) || - (dc_link->type == dc_connection_mst_branch)) + (dc_link->type == dc_connection_mst_branch)) dm_handle_hpd_rx_irq(aconnector); - if (aconnector->dc_link->type != dc_connection_mst_branch) + if (dc_link->type != dc_connection_mst_branch) mutex_unlock(&aconnector->hpd_lock); } From 8440c30463f3c6d312a5a65be634e6c6c1b6a5b3 Mon Sep 17 00:00:00 2001 From: Tom St Denis Date: Tue, 17 Oct 2017 09:09:42 -0400 Subject: [PATCH 146/155] drm/amd/display: Fix brace style in amdgpu_dm_initialize_drm_device() Signed-off-by: Tom St Denis Acked-by: Andrey Grodzovsky Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index bb83da6fd31b0..fb24ba69b2a6e 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -1412,9 +1412,8 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) goto fail_free_planes; aencoder = kzalloc(sizeof(*aencoder), GFP_KERNEL); - if (!aencoder) { + if (!aencoder) goto fail_free_connector; - } if (amdgpu_dm_encoder_init(dm->ddev, aencoder, i)) { DRM_ERROR("KMS: Failed to initialize encoder\n"); From d2b2562c23e5e2a122a73627b0c658c5cfedb01a Mon Sep 17 00:00:00 2001 From: Tom St Denis Date: Tue, 17 Oct 2017 09:46:54 -0400 Subject: [PATCH 147/155] drm/amd/display: Replace block with strncpy() in fill_audio_info() Replace inlined strncpy with library call. Signed-off-by: Tom St Denis Acked-by: Andrey Grodzovsky Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index fb24ba69b2a6e..3f405976f8820 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -2238,11 +2238,9 @@ static void fill_audio_info(struct audio_info *audio_info, cea_revision = drm_connector->display_info.cea_rev; - while (i < AUDIO_INFO_DISPLAY_NAME_SIZE_IN_CHARS && - edid_caps->display_name[i]) { - audio_info->display_name[i] = edid_caps->display_name[i]; - i++; - } + strncpy(audio_info->display_name, + edid_caps->display_name, + AUDIO_INFO_DISPLAY_NAME_SIZE_IN_CHARS - 1); if (cea_revision >= 3) { audio_info->mode_count = edid_caps->audio_mode_count; From a68d90e7aed55e274cb117bbca34913d5fb8afd2 Mon Sep 17 00:00:00 2001 From: Tom St Denis Date: Tue, 17 Oct 2017 10:15:12 -0400 Subject: [PATCH 148/155] drm/amd/display: Fix indentation in create_eml_sink() Signed-off-by: Tom St Denis Acked-by: Andrey Grodzovsky Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 3f405976f8820..ce975aef27a7f 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -2720,8 +2720,7 @@ static void create_eml_sink(struct amdgpu_dm_connector *aconnector) (edid->extensions + 1) * EDID_LENGTH, &init_params); - if (aconnector->base.force - == DRM_FORCE_ON) + if (aconnector->base.force == DRM_FORCE_ON) aconnector->dc_sink = aconnector->dc_link->local_sink ? aconnector->dc_link->local_sink : aconnector->dc_em_sink; From f922237daa7f2de4a8eae0ecdc99e944333fffc2 Mon Sep 17 00:00:00 2001 From: Tom St Denis Date: Tue, 17 Oct 2017 10:16:39 -0400 Subject: [PATCH 149/155] drm/amd/display: Tidy up dm_drm_plane_reset() Move WARN_ON higher up and in doing so fix brace style. Signed-off-by: Tom St Denis Acked-by: Andrey Grodzovsky Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index ce975aef27a7f..46fac2bccc574 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -2873,13 +2873,13 @@ static void dm_drm_plane_reset(struct drm_plane *plane) plane->funcs->atomic_destroy_state(plane, plane->state); amdgpu_state = kzalloc(sizeof(*amdgpu_state), GFP_KERNEL); - + WARN_ON(amdgpu_state == NULL); + if (amdgpu_state) { plane->state = &amdgpu_state->base; plane->state->plane = plane; plane->state->rotation = DRM_MODE_ROTATE_0; - } else - WARN_ON(1); + } } static struct drm_plane_state * From a8d8d3dc9ad8dc4ba6155bdd88f01e23bfc7dfbc Mon Sep 17 00:00:00 2001 From: Tom St Denis Date: Tue, 17 Oct 2017 10:38:27 -0400 Subject: [PATCH 150/155] drm/amd/display: Fix brace style in amdgpu_dm_connector_ddc_get_modes() Signed-off-by: Tom St Denis Acked-by: Andrey Grodzovsky Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 46fac2bccc574..d7fc237851c5c 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -3310,8 +3310,9 @@ static void amdgpu_dm_connector_ddc_get_modes(struct drm_connector *connector, drm_edid_to_eld(connector, edid); amdgpu_dm_get_native_mode(connector); - } else + } else { amdgpu_dm_connector->num_modes = 0; + } } static int amdgpu_dm_connector_get_modes(struct drm_connector *connector) From 9a227d263d44572583be5dd9e9f215cceb4297a1 Mon Sep 17 00:00:00 2001 From: Tom St Denis Date: Tue, 17 Oct 2017 10:40:08 -0400 Subject: [PATCH 151/155] drm/amd/display: Remove needless cast in amdgpu_dm_connector_init() The cast of dc_link is redundant. Signed-off-by: Tom St Denis Acked-by: Andrey Grodzovsky Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index d7fc237851c5c..6ef71e192845f 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -3460,7 +3460,8 @@ static int amdgpu_dm_connector_init(struct amdgpu_display_manager *dm, struct dc *dc = dm->dc; struct dc_link *link = dc_get_link_at_index(dc, link_index); struct amdgpu_i2c_adapter *i2c; - ((struct dc_link *)link)->priv = aconnector; + + link->priv = aconnector; DRM_DEBUG_DRIVER("%s()\n", __func__); From 634086b464ac92d215aeaa3653759b0fbcde1a02 Mon Sep 17 00:00:00 2001 From: Tom St Denis Date: Tue, 17 Oct 2017 12:13:39 -0400 Subject: [PATCH 152/155] drm/amd/display: Fix brace style Signed-off-by: Tom St Denis Acked-by: Andrey Grodzovsky Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c index b9e4d38310011..ca5d0d1581dc7 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c @@ -208,24 +208,21 @@ static void remove_timer_handler(struct amdgpu_device *adev, DM_IRQ_TABLE_LOCK(adev, irq_table_flags); } - if (handler_in == NULL) { - /* Remove ALL handlers. */ + /* Remove ALL handlers. */ + if (handler_in == NULL) continue; - } - if (handler_in == handler_temp) { - /* Remove a SPECIFIC handler. - * Found our handler - we can stop here. */ + /* Remove a SPECIFIC handler. + * Found our handler - we can stop here. */ + if (handler_in == handler_temp) break; - } } DM_IRQ_TABLE_UNLOCK(adev, irq_table_flags); - if (handler_in != NULL && handler_removed == false) { + if (handler_in != NULL && handler_removed == false) DRM_ERROR("DM_IRQ: handler: %p is not in the list!\n", handler_in); - } } static bool From fc9e9920b1d3a7a6af7eb993d531c36beb985570 Mon Sep 17 00:00:00 2001 From: Shirish S Date: Wed, 27 Sep 2017 15:15:38 +0530 Subject: [PATCH 153/155] drm/amd/display: add hardware_planes_only to list of affected planes For SoC's having software designed cursor plane, should be treated differently than hardware cursor planes. The DRM core initializes cursor plane by default with legacy_cursor_update set. Hence legacy_cursor_update can be use effectively to handle software cursor planes' update and atomicity functionalities. This patch uses this variable to decide in the atomic_check to whether add a requested plane to the list of affected planes or not, hence fixing the issue of co-existence of MPO, i.e, setting of available hardware planes like underlay and updation of cursor planes as well. Without this patch when underlay is set from user space, only blank screen with backlight is visible. Signed-off-by: Shirish S Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 30 +++++++++++++++---- 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 6ef71e192845f..51258d0451674 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -3982,6 +3982,8 @@ static int amdgpu_dm_atomic_commit(struct drm_device *dev, if (drm_atomic_crtc_needs_modeset(new_crtc_state) && dm_old_crtc_state->stream) manage_dm_interrupts(adev, acrtc, false); } + /* Add check here for SoC's that support hardware cursor plane, to + * unset legacy_cursor_update */ return drm_atomic_helper_commit(dev, state, nonblock); @@ -4647,7 +4649,7 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, struct drm_connector *connector; struct drm_connector_state *old_con_state, *new_con_state; struct drm_crtc *crtc; - struct drm_crtc_state *new_crtc_state; + struct drm_crtc_state *old_crtc_state, *new_crtc_state; /* * This bool will be set for true for any modeset/reset @@ -4656,18 +4658,34 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, bool lock_and_validation_needed = false; ret = drm_atomic_helper_check_modeset(dev, state); - if (ret) { DRM_ERROR("Atomic state validation failed with error :%d !\n", ret); return ret; } /* - * Hack: Commit needs planes right now, specifically for gamma - * TODO rework commit to check CRTC for gamma change + * legacy_cursor_update should be made false for SoC's having + * a dedicated hardware plane for cursor in amdgpu_dm_atomic_commit(), + * otherwise for software cursor plane, + * we should not add it to list of affected planes. */ - for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) { - if (new_crtc_state->color_mgmt_changed) { + if (state->legacy_cursor_update) { + for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) { + if (new_crtc_state->color_mgmt_changed) { + ret = drm_atomic_add_affected_planes(state, crtc); + if (ret) + goto fail; + } + } + } else { + for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { + if (!new_crtc_state->enable) + continue; + + ret = drm_atomic_add_affected_connectors(state, crtc); + if (ret) + return ret; + ret = drm_atomic_add_affected_planes(state, crtc); if (ret) goto fail; From af09e48aa52377eb807709e2a1cdc33e9fd1ac94 Mon Sep 17 00:00:00 2001 From: "Leo (Sunpeng) Li" Date: Fri, 20 Oct 2017 13:59:53 -0400 Subject: [PATCH 154/155] drm/amd/display: Fix memoryleak during S3 resume. Do not create dc_state within display_resume, since it's being constructed within atomic check. Reviewed-by: Harry Wentland Signed-off-by: Leo (Sunpeng) Li Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 51258d0451674..d0ee1b3b8b5c8 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -694,10 +694,6 @@ int amdgpu_dm_display_resume(struct amdgpu_device *adev) WARN_ON(kref_read(&cached_state->context->refcount) > 1); dc_release_state(cached_state->context); - cached_state->context = dc_create_state(); - ASSERT(cached_state->context); - dc_resource_state_copy_construct_current(adev->dm.dc, cached_state->context); - for_each_new_crtc_in_state(adev->dm.cached_state, crtc, new_crtc_state, i) { dm_crtc_state = to_dm_crtc_state(new_crtc_state); if (dm_crtc_state->stream) { From 9b38bd1b8f5c874c3d1f330e0dcf4e7d84137477 Mon Sep 17 00:00:00 2001 From: "Jerry (Fangzhi) Zuo" Date: Fri, 20 Oct 2017 16:45:53 -0400 Subject: [PATCH 155/155] drm/amd/display:: Fix NULL pointer in Raven hotplug MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Programming sequence to frontend and backend has been switched. In such case, program_scaler() is gettingĀ called when programming frontend, and should be removed from backend programming routine. Reviewed-by: Harry Wentland Signed-off-by: Jerry (Fangzhi) Zuo Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c index e8b8daeeed979..2a6d3ca129543 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c @@ -1369,13 +1369,6 @@ static enum dc_status apply_single_controller_ctx_to_hw( } pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != 0; - /* program_scaler and allocate_mem_input are not new asic */ - if ((!pipe_ctx_old || - memcmp(&pipe_ctx_old->plane_res.scl_data, &pipe_ctx->plane_res.scl_data, - sizeof(struct scaler_data)) != 0) && - pipe_ctx->plane_state) { - program_scaler(dc, pipe_ctx); - } /* mst support - use total stream count */ if (pipe_ctx->plane_res.mi != NULL) {