drm/amd/display: adjust MALL size available for DCN32 and DCN321
authorjsg <jsg@openbsd.org>
Tue, 28 Mar 2023 00:34:04 +0000 (00:34 +0000)
committerjsg <jsg@openbsd.org>
Tue, 28 Mar 2023 00:34:04 +0000 (00:34 +0000)
From Samson Tam
38327b6cb1fa2bb098bca0db7dd25ee80a6d64b1 in linux-6.1.y/6.1.20
235fef6c7fd341026eee90cc546e6e8ff8b2c315 in mainline linux

sys/dev/pci/drm/amd/display/dc/dcn32/dcn32_resource.c
sys/dev/pci/drm/amd/display/dc/dcn32/dcn32_resource.h
sys/dev/pci/drm/amd/display/dc/dcn321/dcn321_resource.c
sys/dev/pci/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
sys/dev/pci/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c

index 9919c39..d70c64a 100644 (file)
@@ -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;
+       }
+}
index cf7633f..615244a 100644 (file)
@@ -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 */
index 6292ac5..d320e21 100644 (file)
@@ -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;
index 91a3839..e22b4b3 100644 (file)
@@ -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;
index 0ea4061..b80cef7 100644 (file)
@@ -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;