From cadf119f701f0e4799eb4461b609a5ec04f5ee94 Mon Sep 17 00:00:00 2001 From: jsg Date: Tue, 28 Mar 2023 00:34:04 +0000 Subject: [PATCH] drm/amd/display: adjust MALL size available for DCN32 and DCN321 From Samson Tam 38327b6cb1fa2bb098bca0db7dd25ee80a6d64b1 in linux-6.1.y/6.1.20 235fef6c7fd341026eee90cc546e6e8ff8b2c315 in mainline linux --- .../drm/amd/display/dc/dcn32/dcn32_resource.c | 62 ++++++++++++++++++- .../drm/amd/display/dc/dcn32/dcn32_resource.h | 2 + .../amd/display/dc/dcn321/dcn321_resource.c | 9 ++- .../drm/amd/display/dc/dml/dcn32/dcn32_fpu.c | 5 +- .../amd/display/dc/dml/dcn321/dcn321_fpu.c | 5 +- 5 files changed, 78 insertions(+), 5 deletions(-) diff --git a/sys/dev/pci/drm/amd/display/dc/dcn32/dcn32_resource.c b/sys/dev/pci/drm/amd/display/dc/dcn32/dcn32_resource.c index 9919c39f7ea..d70c64a9fcb 100644 --- a/sys/dev/pci/drm/amd/display/dc/dcn32/dcn32_resource.c +++ b/sys/dev/pci/drm/amd/display/dc/dcn32/dcn32_resource.c @@ -2109,13 +2109,19 @@ static bool dcn32_resource_construct( dc->caps.max_cursor_size = 64; dc->caps.min_horizontal_blanking_period = 80; dc->caps.dmdata_alloc_size = 2048; - dc->caps.mall_size_per_mem_channel = 0; + dc->caps.mall_size_per_mem_channel = 4; dc->caps.mall_size_total = 0; dc->caps.cursor_cache_size = dc->caps.max_cursor_size * dc->caps.max_cursor_size * 8; dc->caps.cache_line_size = 64; dc->caps.cache_num_ways = 16; - dc->caps.max_cab_allocation_bytes = 67108864; // 64MB = 1024 * 1024 * 64 + + /* Calculate the available MALL space */ + dc->caps.max_cab_allocation_bytes = dcn32_calc_num_avail_chans_for_mall( + dc, dc->ctx->dc_bios->vram_info.num_chans) * + dc->caps.mall_size_per_mem_channel * 1024 * 1024; + dc->caps.mall_size_total = dc->caps.max_cab_allocation_bytes; + dc->caps.subvp_fw_processing_delay_us = 15; dc->caps.subvp_prefetch_end_to_mall_start_us = 15; dc->caps.subvp_swath_height_margin_lines = 16; @@ -2545,3 +2551,55 @@ struct pipe_ctx *dcn32_acquire_idle_pipe_for_head_pipe_in_layer( return idle_pipe; } + +unsigned int dcn32_calc_num_avail_chans_for_mall(struct dc *dc, int num_chans) +{ + /* + * DCN32 and DCN321 SKUs may have different sizes for MALL + * but we may not be able to access all the MALL space. + * If the num_chans is power of 2, then we can access all + * of the available MALL space. Otherwise, we can only + * access: + * + * max_cab_size_in_bytes = total_cache_size_in_bytes * + * ((2^floor(log2(num_chans)))/num_chans) + * + * Calculating the MALL sizes for all available SKUs, we + * have come up with the follow simplified check. + * - we have max_chans which provides the max MALL size. + * Each chans supports 4MB of MALL so: + * + * total_cache_size_in_bytes = max_chans * 4 MB + * + * - we have avail_chans which shows the number of channels + * we can use if we can't access the entire MALL space. + * It is generally half of max_chans + * - so we use the following checks: + * + * if (num_chans == max_chans), return max_chans + * if (num_chans < max_chans), return avail_chans + * + * - exception is GC_11_0_0 where we can't access max_chans, + * so we define max_avail_chans as the maximum available + * MALL space + * + */ + int gc_11_0_0_max_chans = 48; + int gc_11_0_0_max_avail_chans = 32; + int gc_11_0_0_avail_chans = 16; + int gc_11_0_3_max_chans = 16; + int gc_11_0_3_avail_chans = 8; + int gc_11_0_2_max_chans = 8; + int gc_11_0_2_avail_chans = 4; + + if (ASICREV_IS_GC_11_0_0(dc->ctx->asic_id.hw_internal_rev)) { + return (num_chans == gc_11_0_0_max_chans) ? + gc_11_0_0_max_avail_chans : gc_11_0_0_avail_chans; + } else if (ASICREV_IS_GC_11_0_2(dc->ctx->asic_id.hw_internal_rev)) { + return (num_chans == gc_11_0_2_max_chans) ? + gc_11_0_2_max_chans : gc_11_0_2_avail_chans; + } else { // if (ASICREV_IS_GC_11_0_3(dc->ctx->asic_id.hw_internal_rev)) { + return (num_chans == gc_11_0_3_max_chans) ? + gc_11_0_3_max_chans : gc_11_0_3_avail_chans; + } +} diff --git a/sys/dev/pci/drm/amd/display/dc/dcn32/dcn32_resource.h b/sys/dev/pci/drm/amd/display/dc/dcn32/dcn32_resource.h index cf7633fab09..615244a1f95 100644 --- a/sys/dev/pci/drm/amd/display/dc/dcn32/dcn32_resource.h +++ b/sys/dev/pci/drm/amd/display/dc/dcn32/dcn32_resource.h @@ -144,6 +144,8 @@ void dcn32_restore_mall_state(struct dc *dc, bool dcn32_allow_subvp_with_active_margin(struct pipe_ctx *pipe); +unsigned int dcn32_calc_num_avail_chans_for_mall(struct dc *dc, int num_chans); + /* definitions for run time init of reg offsets */ /* CLK SRC */ diff --git a/sys/dev/pci/drm/amd/display/dc/dcn321/dcn321_resource.c b/sys/dev/pci/drm/amd/display/dc/dcn321/dcn321_resource.c index 6292ac515d1..d320e21680d 100644 --- a/sys/dev/pci/drm/amd/display/dc/dcn321/dcn321_resource.c +++ b/sys/dev/pci/drm/amd/display/dc/dcn321/dcn321_resource.c @@ -1697,11 +1697,18 @@ static bool dcn321_resource_construct( dc->caps.max_cursor_size = 64; dc->caps.min_horizontal_blanking_period = 80; dc->caps.dmdata_alloc_size = 2048; - dc->caps.mall_size_per_mem_channel = 0; + dc->caps.mall_size_per_mem_channel = 4; dc->caps.mall_size_total = 0; dc->caps.cursor_cache_size = dc->caps.max_cursor_size * dc->caps.max_cursor_size * 8; dc->caps.cache_line_size = 64; dc->caps.cache_num_ways = 16; + + /* Calculate the available MALL space */ + dc->caps.max_cab_allocation_bytes = dcn32_calc_num_avail_chans_for_mall( + dc, dc->ctx->dc_bios->vram_info.num_chans) * + dc->caps.mall_size_per_mem_channel * 1024 * 1024; + dc->caps.mall_size_total = dc->caps.max_cab_allocation_bytes; + dc->caps.max_cab_allocation_bytes = 33554432; // 32MB = 1024 * 1024 * 32 dc->caps.subvp_fw_processing_delay_us = 15; dc->caps.subvp_prefetch_end_to_mall_start_us = 15; diff --git a/sys/dev/pci/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c b/sys/dev/pci/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c index 91a3839bc29..e22b4b3880a 100644 --- a/sys/dev/pci/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c +++ b/sys/dev/pci/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c @@ -2381,8 +2381,11 @@ void dcn32_update_bw_bounding_box_fpu(struct dc *dc, struct clk_bw_params *bw_pa } /* Override from VBIOS for num_chan */ - if (dc->ctx->dc_bios->vram_info.num_chans) + if (dc->ctx->dc_bios->vram_info.num_chans) { dcn3_2_soc.num_chans = dc->ctx->dc_bios->vram_info.num_chans; + dcn3_2_soc.mall_allocated_for_dcn_mbytes = (double)(dcn32_calc_num_avail_chans_for_mall(dc, + dc->ctx->dc_bios->vram_info.num_chans) * dc->caps.mall_size_per_mem_channel); + } if (dc->ctx->dc_bios->vram_info.dram_channel_width_bytes) dcn3_2_soc.dram_channel_width_bytes = dc->ctx->dc_bios->vram_info.dram_channel_width_bytes; diff --git a/sys/dev/pci/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c b/sys/dev/pci/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c index 0ea406145c1..b80cef70fa6 100644 --- a/sys/dev/pci/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c +++ b/sys/dev/pci/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c @@ -534,8 +534,11 @@ void dcn321_update_bw_bounding_box_fpu(struct dc *dc, struct clk_bw_params *bw_p } /* Override from VBIOS for num_chan */ - if (dc->ctx->dc_bios->vram_info.num_chans) + if (dc->ctx->dc_bios->vram_info.num_chans) { dcn3_21_soc.num_chans = dc->ctx->dc_bios->vram_info.num_chans; + dcn3_21_soc.mall_allocated_for_dcn_mbytes = (double)(dcn32_calc_num_avail_chans_for_mall(dc, + dc->ctx->dc_bios->vram_info.num_chans) * dc->caps.mall_size_per_mem_channel); + } if (dc->ctx->dc_bios->vram_info.dram_channel_width_bytes) dcn3_21_soc.dram_channel_width_bytes = dc->ctx->dc_bios->vram_info.dram_channel_width_bytes; -- 2.20.1