drm/amd/display: Update idle optimization handling
authorJoshua Aberback <joshua.aberback@amd.com>
Mon, 31 Aug 2020 05:58:03 +0000 (01:58 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 5 Jan 2021 16:34:35 +0000 (11:34 -0500)
[How]
 - use dc interface instead of hwss interface in cursor functions, to keep
dc->idle_optimizations_allowed updated
 - add dc interface to check if idle optimizations might apply to a plane

Signed-off-by: Joshua Aberback <joshua.aberback@amd.com>
Acked-by: Alex Deucher <alexander.deucher@amd.com>
Reviewed-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/core/dc.c
drivers/gpu/drm/amd/display/dc/dc.h
drivers/gpu/drm/amd/display/dc/dc_hw_types.h
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.h
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_init.c
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c
drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h

index cf0bcf674a9148f55e787b47f0fdee3b5a246aa4..8f1cadb823c7131eba7ec853de4c23e6d47c7762 100644 (file)
@@ -3138,9 +3138,11 @@ void dc_lock_memory_clock_frequency(struct dc *dc)
                        core_link_enable_stream(dc->current_state, &dc->current_state->res_ctx.pipe_ctx[i]);
 }
 
-bool dc_is_plane_eligible_for_idle_optimizaitons(struct dc *dc,
-                                                struct dc_plane_state *plane)
+bool dc_is_plane_eligible_for_idle_optimizaitons(struct dc *dc, struct dc_plane_state *plane)
 {
+       if (dc->hwss.does_plane_fit_in_mall && dc->hwss.does_plane_fit_in_mall(dc, plane))
+               return true;
+
        return false;
 }
 
index 3aedadb34548ef2be2f33ae6fed2a6a530047eda..90fdddb72e3b9de25648e37ea2bad418b6631de0 100644 (file)
@@ -171,6 +171,9 @@ struct dc_caps {
        bool dmcub_support;
        uint32_t num_of_internal_disp;
        enum dp_protocol_version max_dp_protocol_version;
+       unsigned int mall_size_per_mem_channel;
+       unsigned int mall_size_total;
+       unsigned int cursor_cache_size;
        struct dc_plane_cap planes[MAX_PLANES];
        struct dc_color_caps color;
 };
@@ -499,6 +502,7 @@ struct dc_debug_options {
        bool dmcub_emulation;
 #if defined(CONFIG_DRM_AMD_DC_DCN)
        bool disable_idle_power_optimizations;
+       unsigned int mall_size_override;
 #endif
        bool dmub_command_table; /* for testing only */
        struct dc_bw_validation_profile bw_val_profile;
index 701aa7178a896346809b1e6628544a3755184946..b41e6367b15ef967ad8e89c59dc8232e4df497de 100644 (file)
@@ -71,6 +71,7 @@ struct dc_plane_address {
        union {
                struct{
                        PHYSICAL_ADDRESS_LOC addr;
+                       PHYSICAL_ADDRESS_LOC cursor_cache_addr;
                        PHYSICAL_ADDRESS_LOC meta_addr;
                        union large_integer dcc_const_color;
                } grph;
index 3deb3fb1724dc3caaef08cda6252184f71be8cbf..b83c13d3d8b74c720870087ecea1d6ed4d7cf9e9 100644 (file)
@@ -814,6 +814,19 @@ bool dcn30_apply_idle_power_optimizations(struct dc *dc, bool enable)
        return true;
 }
 
+bool dcn30_does_plane_fit_in_mall(struct dc *dc, struct dc_plane_state *plane)
+{
+       // add meta size?
+       unsigned int surface_size = plane->plane_size.surface_pitch * plane->plane_size.surface_size.height *
+                       (plane->format >= SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616 ? 8 : 4);
+       unsigned int mall_size = dc->caps.mall_size_total;
+
+       if (dc->debug.mall_size_override)
+               mall_size = 1024 * 1024 * dc->debug.mall_size_override;
+
+       return (surface_size + dc->caps.cursor_cache_size) < mall_size;
+}
+
 void dcn30_hardware_release(struct dc *dc)
 {
        /* if pstate unsupported, force it supported */
index 7d32c43aafe0e65aa54a863b9f29fa612f2d89cf..bfc97e2ece61cbd703462950bab43e5f51a4b858 100644 (file)
@@ -65,6 +65,8 @@ void dcn30_set_avmute(struct pipe_ctx *pipe_ctx, bool enable);
 void dcn30_update_info_frame(struct pipe_ctx *pipe_ctx);
 void dcn30_program_dmdata_engine(struct pipe_ctx *pipe_ctx);
 
+bool dcn30_does_plane_fit_in_mall(struct dc *dc, struct dc_plane_state *plane);
+
 bool dcn30_apply_idle_power_optimizations(struct dc *dc, bool enable);
 
 void dcn30_hardware_release(struct dc *dc);
index 6125fe440ad0ee44d81efac972656478bf4b9d43..87c74aa844062435922baffa81a4d6eb2294501e 100644 (file)
@@ -91,6 +91,7 @@ static const struct hw_sequencer_funcs dcn30_funcs = {
        .get_vupdate_offset_from_vsync = dcn10_get_vupdate_offset_from_vsync,
        .calc_vupdate_position = dcn10_calc_vupdate_position,
        .apply_idle_power_optimizations = dcn30_apply_idle_power_optimizations,
+       .does_plane_fit_in_mall = dcn30_does_plane_fit_in_mall,
        .set_backlight_level = dcn21_set_backlight_level,
        .set_abm_immediate_disable = dcn21_set_abm_immediate_disable,
        .hardware_release = dcn30_hardware_release,
index 5e126fdf6ec105e0a5971d84e0a4b30b2f728eff..e5bb15d8487bd6710ab99468b42210c28ad7df8b 100644 (file)
@@ -2631,6 +2631,10 @@ static bool dcn30_resource_construct(
        dc->caps.max_cursor_size = 256;
        dc->caps.min_horizontal_blanking_period = 80;
        dc->caps.dmdata_alloc_size = 2048;
+       dc->caps.mall_size_per_mem_channel = 8;
+       /* total size = mall per channel * num channels * 1024 * 1024 */
+       dc->caps.mall_size_total = dc->caps.mall_size_per_mem_channel * dc->ctx->dc_bios->vram_info.num_chans * 1048576;
+       dc->caps.cursor_cache_size = dc->caps.max_cursor_size * dc->caps.max_cursor_size * 8;
 
        dc->caps.max_slave_planes = 1;
        dc->caps.post_blend_color_processing = true;
index 62804dc7b6981c0928c4b70b3a3baeb8e84c6c6b..7b12ffcdd4ec8c9e01f16240efa749dc2ac51b69 100644 (file)
@@ -217,6 +217,8 @@ struct hw_sequencer_funcs {
        /* Idle Optimization Related */
        bool (*apply_idle_power_optimizations)(struct dc *dc, bool enable);
 
+       bool (*does_plane_fit_in_mall)(struct dc *dc, struct dc_plane_state *plane);
+
        bool (*is_abm_supported)(struct dc *dc,
                        struct dc_state *context, struct dc_stream_state *stream);