LCOV - code coverage report
Current view: top level - drivers/gpu/drm/amd/display/dc/dml/dcn20 - dcn20_fpu.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 95 870 10.9 %
Date: 2022-12-09 01:23:36 Functions: 3 24 12.5 %

          Line data    Source code
       1             : // SPDX-License-Identifier: MIT
       2             : /*
       3             :  * Copyright 2021 Advanced Micro Devices, Inc.
       4             :  *
       5             :  * Permission is hereby granted, free of charge, to any person obtaining a
       6             :  * copy of this software and associated documentation files (the "Software"),
       7             :  * to deal in the Software without restriction, including without limitation
       8             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
       9             :  * and/or sell copies of the Software, and to permit persons to whom the
      10             :  * Software is furnished to do so, subject to the following conditions:
      11             :  *
      12             :  * The above copyright notice and this permission notice shall be included in
      13             :  * all copies or substantial portions of the Software.
      14             :  *
      15             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      16             :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      17             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
      18             :  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
      19             :  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
      20             :  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
      21             :  * OTHER DEALINGS IN THE SOFTWARE.
      22             :  *
      23             :  * Authors: AMD
      24             :  *
      25             :  */
      26             : 
      27             : #include "resource.h"
      28             : #include "clk_mgr.h"
      29             : #include "dc_link_dp.h"
      30             : #include "dchubbub.h"
      31             : #include "dcn20/dcn20_resource.h"
      32             : #include "dcn21/dcn21_resource.h"
      33             : #include "clk_mgr/dcn21/rn_clk_mgr.h"
      34             : 
      35             : #include "dcn20_fpu.h"
      36             : 
      37             : #define DC_LOGGER_INIT(logger)
      38             : 
      39             : #ifndef MAX
      40             : #define MAX(X, Y) ((X) > (Y) ? (X) : (Y))
      41             : #endif
      42             : #ifndef MIN
      43             : #define MIN(X, Y) ((X) < (Y) ? (X) : (Y))
      44             : #endif
      45             : 
      46             : /* Constant */
      47             : #define LPDDR_MEM_RETRAIN_LATENCY 4.977 /* Number obtained from LPDDR4 Training Counter Requirement doc */
      48             : 
      49             : /**
      50             :  * DOC: DCN2x FPU manipulation Overview
      51             :  *
      52             :  * The DCN architecture relies on FPU operations, which require special
      53             :  * compilation flags and the use of kernel_fpu_begin/end functions; ideally, we
      54             :  * want to avoid spreading FPU access across multiple files. With this idea in
      55             :  * mind, this file aims to centralize all DCN20 and DCN2.1 (DCN2x) functions
      56             :  * that require FPU access in a single place. Code in this file follows the
      57             :  * following code pattern:
      58             :  *
      59             :  * 1. Functions that use FPU operations should be isolated in static functions.
      60             :  * 2. The FPU functions should have the noinline attribute to ensure anything
      61             :  *    that deals with FP register is contained within this call.
      62             :  * 3. All function that needs to be accessed outside this file requires a
      63             :  *    public interface that not uses any FPU reference.
      64             :  * 4. Developers **must not** use DC_FP_START/END in this file, but they need
      65             :  *    to ensure that the caller invokes it before access any function available
      66             :  *    in this file. For this reason, public functions in this file must invoke
      67             :  *    dc_assert_fp_enabled();
      68             :  *
      69             :  * Let's expand a little bit more the idea in the code pattern. To fully
      70             :  * isolate FPU operations in a single place, we must avoid situations where
      71             :  * compilers spill FP values to registers due to FP enable in a specific C
      72             :  * file. Note that even if we isolate all FPU functions in a single file and
      73             :  * call its interface from other files, the compiler might enable the use of
      74             :  * FPU before we call DC_FP_START. Nevertheless, it is the programmer's
      75             :  * responsibility to invoke DC_FP_START/END in the correct place. To highlight
      76             :  * situations where developers forgot to use the FP protection before calling
      77             :  * the DC FPU interface functions, we introduce a helper that checks if the
      78             :  * function is invoked under FP protection. If not, it will trigger a kernel
      79             :  * warning.
      80             :  */
      81             : 
      82             : struct _vcs_dpi_ip_params_st dcn2_0_ip = {
      83             :         .odm_capable = 1,
      84             :         .gpuvm_enable = 0,
      85             :         .hostvm_enable = 0,
      86             :         .gpuvm_max_page_table_levels = 4,
      87             :         .hostvm_max_page_table_levels = 4,
      88             :         .hostvm_cached_page_table_levels = 0,
      89             :         .pte_group_size_bytes = 2048,
      90             :         .num_dsc = 6,
      91             :         .rob_buffer_size_kbytes = 168,
      92             :         .det_buffer_size_kbytes = 164,
      93             :         .dpte_buffer_size_in_pte_reqs_luma = 84,
      94             :         .pde_proc_buffer_size_64k_reqs = 48,
      95             :         .dpp_output_buffer_pixels = 2560,
      96             :         .opp_output_buffer_lines = 1,
      97             :         .pixel_chunk_size_kbytes = 8,
      98             :         .pte_chunk_size_kbytes = 2,
      99             :         .meta_chunk_size_kbytes = 2,
     100             :         .writeback_chunk_size_kbytes = 2,
     101             :         .line_buffer_size_bits = 789504,
     102             :         .is_line_buffer_bpp_fixed = 0,
     103             :         .line_buffer_fixed_bpp = 0,
     104             :         .dcc_supported = true,
     105             :         .max_line_buffer_lines = 12,
     106             :         .writeback_luma_buffer_size_kbytes = 12,
     107             :         .writeback_chroma_buffer_size_kbytes = 8,
     108             :         .writeback_chroma_line_buffer_width_pixels = 4,
     109             :         .writeback_max_hscl_ratio = 1,
     110             :         .writeback_max_vscl_ratio = 1,
     111             :         .writeback_min_hscl_ratio = 1,
     112             :         .writeback_min_vscl_ratio = 1,
     113             :         .writeback_max_hscl_taps = 12,
     114             :         .writeback_max_vscl_taps = 12,
     115             :         .writeback_line_buffer_luma_buffer_size = 0,
     116             :         .writeback_line_buffer_chroma_buffer_size = 14643,
     117             :         .cursor_buffer_size = 8,
     118             :         .cursor_chunk_size = 2,
     119             :         .max_num_otg = 6,
     120             :         .max_num_dpp = 6,
     121             :         .max_num_wb = 1,
     122             :         .max_dchub_pscl_bw_pix_per_clk = 4,
     123             :         .max_pscl_lb_bw_pix_per_clk = 2,
     124             :         .max_lb_vscl_bw_pix_per_clk = 4,
     125             :         .max_vscl_hscl_bw_pix_per_clk = 4,
     126             :         .max_hscl_ratio = 8,
     127             :         .max_vscl_ratio = 8,
     128             :         .hscl_mults = 4,
     129             :         .vscl_mults = 4,
     130             :         .max_hscl_taps = 8,
     131             :         .max_vscl_taps = 8,
     132             :         .dispclk_ramp_margin_percent = 1,
     133             :         .underscan_factor = 1.10,
     134             :         .min_vblank_lines = 32, //
     135             :         .dppclk_delay_subtotal = 77, //
     136             :         .dppclk_delay_scl_lb_only = 16,
     137             :         .dppclk_delay_scl = 50,
     138             :         .dppclk_delay_cnvc_formatter = 8,
     139             :         .dppclk_delay_cnvc_cursor = 6,
     140             :         .dispclk_delay_subtotal = 87, //
     141             :         .dcfclk_cstate_latency = 10, // SRExitTime
     142             :         .max_inter_dcn_tile_repeaters = 8,
     143             :         .xfc_supported = true,
     144             :         .xfc_fill_bw_overhead_percent = 10.0,
     145             :         .xfc_fill_constant_bytes = 0,
     146             :         .number_of_cursors = 1,
     147             : };
     148             : 
     149             : struct _vcs_dpi_ip_params_st dcn2_0_nv14_ip = {
     150             :         .odm_capable = 1,
     151             :         .gpuvm_enable = 0,
     152             :         .hostvm_enable = 0,
     153             :         .gpuvm_max_page_table_levels = 4,
     154             :         .hostvm_max_page_table_levels = 4,
     155             :         .hostvm_cached_page_table_levels = 0,
     156             :         .num_dsc = 5,
     157             :         .rob_buffer_size_kbytes = 168,
     158             :         .det_buffer_size_kbytes = 164,
     159             :         .dpte_buffer_size_in_pte_reqs_luma = 84,
     160             :         .dpte_buffer_size_in_pte_reqs_chroma = 42,//todo
     161             :         .dpp_output_buffer_pixels = 2560,
     162             :         .opp_output_buffer_lines = 1,
     163             :         .pixel_chunk_size_kbytes = 8,
     164             :         .pte_enable = 1,
     165             :         .max_page_table_levels = 4,
     166             :         .pte_chunk_size_kbytes = 2,
     167             :         .meta_chunk_size_kbytes = 2,
     168             :         .writeback_chunk_size_kbytes = 2,
     169             :         .line_buffer_size_bits = 789504,
     170             :         .is_line_buffer_bpp_fixed = 0,
     171             :         .line_buffer_fixed_bpp = 0,
     172             :         .dcc_supported = true,
     173             :         .max_line_buffer_lines = 12,
     174             :         .writeback_luma_buffer_size_kbytes = 12,
     175             :         .writeback_chroma_buffer_size_kbytes = 8,
     176             :         .writeback_chroma_line_buffer_width_pixels = 4,
     177             :         .writeback_max_hscl_ratio = 1,
     178             :         .writeback_max_vscl_ratio = 1,
     179             :         .writeback_min_hscl_ratio = 1,
     180             :         .writeback_min_vscl_ratio = 1,
     181             :         .writeback_max_hscl_taps = 12,
     182             :         .writeback_max_vscl_taps = 12,
     183             :         .writeback_line_buffer_luma_buffer_size = 0,
     184             :         .writeback_line_buffer_chroma_buffer_size = 14643,
     185             :         .cursor_buffer_size = 8,
     186             :         .cursor_chunk_size = 2,
     187             :         .max_num_otg = 5,
     188             :         .max_num_dpp = 5,
     189             :         .max_num_wb = 1,
     190             :         .max_dchub_pscl_bw_pix_per_clk = 4,
     191             :         .max_pscl_lb_bw_pix_per_clk = 2,
     192             :         .max_lb_vscl_bw_pix_per_clk = 4,
     193             :         .max_vscl_hscl_bw_pix_per_clk = 4,
     194             :         .max_hscl_ratio = 8,
     195             :         .max_vscl_ratio = 8,
     196             :         .hscl_mults = 4,
     197             :         .vscl_mults = 4,
     198             :         .max_hscl_taps = 8,
     199             :         .max_vscl_taps = 8,
     200             :         .dispclk_ramp_margin_percent = 1,
     201             :         .underscan_factor = 1.10,
     202             :         .min_vblank_lines = 32, //
     203             :         .dppclk_delay_subtotal = 77, //
     204             :         .dppclk_delay_scl_lb_only = 16,
     205             :         .dppclk_delay_scl = 50,
     206             :         .dppclk_delay_cnvc_formatter = 8,
     207             :         .dppclk_delay_cnvc_cursor = 6,
     208             :         .dispclk_delay_subtotal = 87, //
     209             :         .dcfclk_cstate_latency = 10, // SRExitTime
     210             :         .max_inter_dcn_tile_repeaters = 8,
     211             :         .xfc_supported = true,
     212             :         .xfc_fill_bw_overhead_percent = 10.0,
     213             :         .xfc_fill_constant_bytes = 0,
     214             :         .ptoi_supported = 0,
     215             :         .number_of_cursors = 1,
     216             : };
     217             : 
     218             : struct _vcs_dpi_soc_bounding_box_st dcn2_0_soc = {
     219             :         /* Defaults that get patched on driver load from firmware. */
     220             :         .clock_limits = {
     221             :                         {
     222             :                                 .state = 0,
     223             :                                 .dcfclk_mhz = 560.0,
     224             :                                 .fabricclk_mhz = 560.0,
     225             :                                 .dispclk_mhz = 513.0,
     226             :                                 .dppclk_mhz = 513.0,
     227             :                                 .phyclk_mhz = 540.0,
     228             :                                 .socclk_mhz = 560.0,
     229             :                                 .dscclk_mhz = 171.0,
     230             :                                 .dram_speed_mts = 8960.0,
     231             :                         },
     232             :                         {
     233             :                                 .state = 1,
     234             :                                 .dcfclk_mhz = 694.0,
     235             :                                 .fabricclk_mhz = 694.0,
     236             :                                 .dispclk_mhz = 642.0,
     237             :                                 .dppclk_mhz = 642.0,
     238             :                                 .phyclk_mhz = 600.0,
     239             :                                 .socclk_mhz = 694.0,
     240             :                                 .dscclk_mhz = 214.0,
     241             :                                 .dram_speed_mts = 11104.0,
     242             :                         },
     243             :                         {
     244             :                                 .state = 2,
     245             :                                 .dcfclk_mhz = 875.0,
     246             :                                 .fabricclk_mhz = 875.0,
     247             :                                 .dispclk_mhz = 734.0,
     248             :                                 .dppclk_mhz = 734.0,
     249             :                                 .phyclk_mhz = 810.0,
     250             :                                 .socclk_mhz = 875.0,
     251             :                                 .dscclk_mhz = 245.0,
     252             :                                 .dram_speed_mts = 14000.0,
     253             :                         },
     254             :                         {
     255             :                                 .state = 3,
     256             :                                 .dcfclk_mhz = 1000.0,
     257             :                                 .fabricclk_mhz = 1000.0,
     258             :                                 .dispclk_mhz = 1100.0,
     259             :                                 .dppclk_mhz = 1100.0,
     260             :                                 .phyclk_mhz = 810.0,
     261             :                                 .socclk_mhz = 1000.0,
     262             :                                 .dscclk_mhz = 367.0,
     263             :                                 .dram_speed_mts = 16000.0,
     264             :                         },
     265             :                         {
     266             :                                 .state = 4,
     267             :                                 .dcfclk_mhz = 1200.0,
     268             :                                 .fabricclk_mhz = 1200.0,
     269             :                                 .dispclk_mhz = 1284.0,
     270             :                                 .dppclk_mhz = 1284.0,
     271             :                                 .phyclk_mhz = 810.0,
     272             :                                 .socclk_mhz = 1200.0,
     273             :                                 .dscclk_mhz = 428.0,
     274             :                                 .dram_speed_mts = 16000.0,
     275             :                         },
     276             :                         /*Extra state, no dispclk ramping*/
     277             :                         {
     278             :                                 .state = 5,
     279             :                                 .dcfclk_mhz = 1200.0,
     280             :                                 .fabricclk_mhz = 1200.0,
     281             :                                 .dispclk_mhz = 1284.0,
     282             :                                 .dppclk_mhz = 1284.0,
     283             :                                 .phyclk_mhz = 810.0,
     284             :                                 .socclk_mhz = 1200.0,
     285             :                                 .dscclk_mhz = 428.0,
     286             :                                 .dram_speed_mts = 16000.0,
     287             :                         },
     288             :                 },
     289             :         .num_states = 5,
     290             :         .sr_exit_time_us = 8.6,
     291             :         .sr_enter_plus_exit_time_us = 10.9,
     292             :         .urgent_latency_us = 4.0,
     293             :         .urgent_latency_pixel_data_only_us = 4.0,
     294             :         .urgent_latency_pixel_mixed_with_vm_data_us = 4.0,
     295             :         .urgent_latency_vm_data_only_us = 4.0,
     296             :         .urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096,
     297             :         .urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096,
     298             :         .urgent_out_of_order_return_per_channel_vm_only_bytes = 4096,
     299             :         .pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 40.0,
     300             :         .pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 40.0,
     301             :         .pct_ideal_dram_sdp_bw_after_urgent_vm_only = 40.0,
     302             :         .max_avg_sdp_bw_use_normal_percent = 40.0,
     303             :         .max_avg_dram_bw_use_normal_percent = 40.0,
     304             :         .writeback_latency_us = 12.0,
     305             :         .ideal_dram_bw_after_urgent_percent = 40.0,
     306             :         .max_request_size_bytes = 256,
     307             :         .dram_channel_width_bytes = 2,
     308             :         .fabric_datapath_to_dcn_data_return_bytes = 64,
     309             :         .dcn_downspread_percent = 0.5,
     310             :         .downspread_percent = 0.38,
     311             :         .dram_page_open_time_ns = 50.0,
     312             :         .dram_rw_turnaround_time_ns = 17.5,
     313             :         .dram_return_buffer_per_channel_bytes = 8192,
     314             :         .round_trip_ping_latency_dcfclk_cycles = 131,
     315             :         .urgent_out_of_order_return_per_channel_bytes = 256,
     316             :         .channel_interleave_bytes = 256,
     317             :         .num_banks = 8,
     318             :         .num_chans = 16,
     319             :         .vmm_page_size_bytes = 4096,
     320             :         .dram_clock_change_latency_us = 404.0,
     321             :         .dummy_pstate_latency_us = 5.0,
     322             :         .writeback_dram_clock_change_latency_us = 23.0,
     323             :         .return_bus_width_bytes = 64,
     324             :         .dispclk_dppclk_vco_speed_mhz = 3850,
     325             :         .xfc_bus_transport_time_us = 20,
     326             :         .xfc_xbuf_latency_tolerance_us = 4,
     327             :         .use_urgent_burst_bw = 0
     328             : };
     329             : 
     330             : struct _vcs_dpi_soc_bounding_box_st dcn2_0_nv14_soc = {
     331             :         .clock_limits = {
     332             :                         {
     333             :                                 .state = 0,
     334             :                                 .dcfclk_mhz = 560.0,
     335             :                                 .fabricclk_mhz = 560.0,
     336             :                                 .dispclk_mhz = 513.0,
     337             :                                 .dppclk_mhz = 513.0,
     338             :                                 .phyclk_mhz = 540.0,
     339             :                                 .socclk_mhz = 560.0,
     340             :                                 .dscclk_mhz = 171.0,
     341             :                                 .dram_speed_mts = 8960.0,
     342             :                         },
     343             :                         {
     344             :                                 .state = 1,
     345             :                                 .dcfclk_mhz = 694.0,
     346             :                                 .fabricclk_mhz = 694.0,
     347             :                                 .dispclk_mhz = 642.0,
     348             :                                 .dppclk_mhz = 642.0,
     349             :                                 .phyclk_mhz = 600.0,
     350             :                                 .socclk_mhz = 694.0,
     351             :                                 .dscclk_mhz = 214.0,
     352             :                                 .dram_speed_mts = 11104.0,
     353             :                         },
     354             :                         {
     355             :                                 .state = 2,
     356             :                                 .dcfclk_mhz = 875.0,
     357             :                                 .fabricclk_mhz = 875.0,
     358             :                                 .dispclk_mhz = 734.0,
     359             :                                 .dppclk_mhz = 734.0,
     360             :                                 .phyclk_mhz = 810.0,
     361             :                                 .socclk_mhz = 875.0,
     362             :                                 .dscclk_mhz = 245.0,
     363             :                                 .dram_speed_mts = 14000.0,
     364             :                         },
     365             :                         {
     366             :                                 .state = 3,
     367             :                                 .dcfclk_mhz = 1000.0,
     368             :                                 .fabricclk_mhz = 1000.0,
     369             :                                 .dispclk_mhz = 1100.0,
     370             :                                 .dppclk_mhz = 1100.0,
     371             :                                 .phyclk_mhz = 810.0,
     372             :                                 .socclk_mhz = 1000.0,
     373             :                                 .dscclk_mhz = 367.0,
     374             :                                 .dram_speed_mts = 16000.0,
     375             :                         },
     376             :                         {
     377             :                                 .state = 4,
     378             :                                 .dcfclk_mhz = 1200.0,
     379             :                                 .fabricclk_mhz = 1200.0,
     380             :                                 .dispclk_mhz = 1284.0,
     381             :                                 .dppclk_mhz = 1284.0,
     382             :                                 .phyclk_mhz = 810.0,
     383             :                                 .socclk_mhz = 1200.0,
     384             :                                 .dscclk_mhz = 428.0,
     385             :                                 .dram_speed_mts = 16000.0,
     386             :                         },
     387             :                         /*Extra state, no dispclk ramping*/
     388             :                         {
     389             :                                 .state = 5,
     390             :                                 .dcfclk_mhz = 1200.0,
     391             :                                 .fabricclk_mhz = 1200.0,
     392             :                                 .dispclk_mhz = 1284.0,
     393             :                                 .dppclk_mhz = 1284.0,
     394             :                                 .phyclk_mhz = 810.0,
     395             :                                 .socclk_mhz = 1200.0,
     396             :                                 .dscclk_mhz = 428.0,
     397             :                                 .dram_speed_mts = 16000.0,
     398             :                         },
     399             :                 },
     400             :         .num_states = 5,
     401             :         .sr_exit_time_us = 11.6,
     402             :         .sr_enter_plus_exit_time_us = 13.9,
     403             :         .urgent_latency_us = 4.0,
     404             :         .urgent_latency_pixel_data_only_us = 4.0,
     405             :         .urgent_latency_pixel_mixed_with_vm_data_us = 4.0,
     406             :         .urgent_latency_vm_data_only_us = 4.0,
     407             :         .urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096,
     408             :         .urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096,
     409             :         .urgent_out_of_order_return_per_channel_vm_only_bytes = 4096,
     410             :         .pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 40.0,
     411             :         .pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 40.0,
     412             :         .pct_ideal_dram_sdp_bw_after_urgent_vm_only = 40.0,
     413             :         .max_avg_sdp_bw_use_normal_percent = 40.0,
     414             :         .max_avg_dram_bw_use_normal_percent = 40.0,
     415             :         .writeback_latency_us = 12.0,
     416             :         .ideal_dram_bw_after_urgent_percent = 40.0,
     417             :         .max_request_size_bytes = 256,
     418             :         .dram_channel_width_bytes = 2,
     419             :         .fabric_datapath_to_dcn_data_return_bytes = 64,
     420             :         .dcn_downspread_percent = 0.5,
     421             :         .downspread_percent = 0.38,
     422             :         .dram_page_open_time_ns = 50.0,
     423             :         .dram_rw_turnaround_time_ns = 17.5,
     424             :         .dram_return_buffer_per_channel_bytes = 8192,
     425             :         .round_trip_ping_latency_dcfclk_cycles = 131,
     426             :         .urgent_out_of_order_return_per_channel_bytes = 256,
     427             :         .channel_interleave_bytes = 256,
     428             :         .num_banks = 8,
     429             :         .num_chans = 8,
     430             :         .vmm_page_size_bytes = 4096,
     431             :         .dram_clock_change_latency_us = 404.0,
     432             :         .dummy_pstate_latency_us = 5.0,
     433             :         .writeback_dram_clock_change_latency_us = 23.0,
     434             :         .return_bus_width_bytes = 64,
     435             :         .dispclk_dppclk_vco_speed_mhz = 3850,
     436             :         .xfc_bus_transport_time_us = 20,
     437             :         .xfc_xbuf_latency_tolerance_us = 4,
     438             :         .use_urgent_burst_bw = 0
     439             : };
     440             : 
     441             : struct _vcs_dpi_soc_bounding_box_st dcn2_0_nv12_soc = { 0 };
     442             : 
     443             : struct _vcs_dpi_ip_params_st dcn2_1_ip = {
     444             :         .odm_capable = 1,
     445             :         .gpuvm_enable = 1,
     446             :         .hostvm_enable = 1,
     447             :         .gpuvm_max_page_table_levels = 1,
     448             :         .hostvm_max_page_table_levels = 4,
     449             :         .hostvm_cached_page_table_levels = 2,
     450             :         .num_dsc = 3,
     451             :         .rob_buffer_size_kbytes = 168,
     452             :         .det_buffer_size_kbytes = 164,
     453             :         .dpte_buffer_size_in_pte_reqs_luma = 44,
     454             :         .dpte_buffer_size_in_pte_reqs_chroma = 42,//todo
     455             :         .dpp_output_buffer_pixels = 2560,
     456             :         .opp_output_buffer_lines = 1,
     457             :         .pixel_chunk_size_kbytes = 8,
     458             :         .pte_enable = 1,
     459             :         .max_page_table_levels = 4,
     460             :         .pte_chunk_size_kbytes = 2,
     461             :         .meta_chunk_size_kbytes = 2,
     462             :         .min_meta_chunk_size_bytes = 256,
     463             :         .writeback_chunk_size_kbytes = 2,
     464             :         .line_buffer_size_bits = 789504,
     465             :         .is_line_buffer_bpp_fixed = 0,
     466             :         .line_buffer_fixed_bpp = 0,
     467             :         .dcc_supported = true,
     468             :         .max_line_buffer_lines = 12,
     469             :         .writeback_luma_buffer_size_kbytes = 12,
     470             :         .writeback_chroma_buffer_size_kbytes = 8,
     471             :         .writeback_chroma_line_buffer_width_pixels = 4,
     472             :         .writeback_max_hscl_ratio = 1,
     473             :         .writeback_max_vscl_ratio = 1,
     474             :         .writeback_min_hscl_ratio = 1,
     475             :         .writeback_min_vscl_ratio = 1,
     476             :         .writeback_max_hscl_taps = 12,
     477             :         .writeback_max_vscl_taps = 12,
     478             :         .writeback_line_buffer_luma_buffer_size = 0,
     479             :         .writeback_line_buffer_chroma_buffer_size = 14643,
     480             :         .cursor_buffer_size = 8,
     481             :         .cursor_chunk_size = 2,
     482             :         .max_num_otg = 4,
     483             :         .max_num_dpp = 4,
     484             :         .max_num_wb = 1,
     485             :         .max_dchub_pscl_bw_pix_per_clk = 4,
     486             :         .max_pscl_lb_bw_pix_per_clk = 2,
     487             :         .max_lb_vscl_bw_pix_per_clk = 4,
     488             :         .max_vscl_hscl_bw_pix_per_clk = 4,
     489             :         .max_hscl_ratio = 4,
     490             :         .max_vscl_ratio = 4,
     491             :         .hscl_mults = 4,
     492             :         .vscl_mults = 4,
     493             :         .max_hscl_taps = 8,
     494             :         .max_vscl_taps = 8,
     495             :         .dispclk_ramp_margin_percent = 1,
     496             :         .underscan_factor = 1.10,
     497             :         .min_vblank_lines = 32, //
     498             :         .dppclk_delay_subtotal = 77, //
     499             :         .dppclk_delay_scl_lb_only = 16,
     500             :         .dppclk_delay_scl = 50,
     501             :         .dppclk_delay_cnvc_formatter = 8,
     502             :         .dppclk_delay_cnvc_cursor = 6,
     503             :         .dispclk_delay_subtotal = 87, //
     504             :         .dcfclk_cstate_latency = 10, // SRExitTime
     505             :         .max_inter_dcn_tile_repeaters = 8,
     506             : 
     507             :         .xfc_supported = false,
     508             :         .xfc_fill_bw_overhead_percent = 10.0,
     509             :         .xfc_fill_constant_bytes = 0,
     510             :         .ptoi_supported = 0,
     511             :         .number_of_cursors = 1,
     512             : };
     513             : 
     514             : struct _vcs_dpi_soc_bounding_box_st dcn2_1_soc = {
     515             :         .clock_limits = {
     516             :                         {
     517             :                                 .state = 0,
     518             :                                 .dcfclk_mhz = 400.0,
     519             :                                 .fabricclk_mhz = 400.0,
     520             :                                 .dispclk_mhz = 600.0,
     521             :                                 .dppclk_mhz = 400.00,
     522             :                                 .phyclk_mhz = 600.0,
     523             :                                 .socclk_mhz = 278.0,
     524             :                                 .dscclk_mhz = 205.67,
     525             :                                 .dram_speed_mts = 1600.0,
     526             :                         },
     527             :                         {
     528             :                                 .state = 1,
     529             :                                 .dcfclk_mhz = 464.52,
     530             :                                 .fabricclk_mhz = 800.0,
     531             :                                 .dispclk_mhz = 654.55,
     532             :                                 .dppclk_mhz = 626.09,
     533             :                                 .phyclk_mhz = 600.0,
     534             :                                 .socclk_mhz = 278.0,
     535             :                                 .dscclk_mhz = 205.67,
     536             :                                 .dram_speed_mts = 1600.0,
     537             :                         },
     538             :                         {
     539             :                                 .state = 2,
     540             :                                 .dcfclk_mhz = 514.29,
     541             :                                 .fabricclk_mhz = 933.0,
     542             :                                 .dispclk_mhz = 757.89,
     543             :                                 .dppclk_mhz = 685.71,
     544             :                                 .phyclk_mhz = 600.0,
     545             :                                 .socclk_mhz = 278.0,
     546             :                                 .dscclk_mhz = 287.67,
     547             :                                 .dram_speed_mts = 1866.0,
     548             :                         },
     549             :                         {
     550             :                                 .state = 3,
     551             :                                 .dcfclk_mhz = 576.00,
     552             :                                 .fabricclk_mhz = 1067.0,
     553             :                                 .dispclk_mhz = 847.06,
     554             :                                 .dppclk_mhz = 757.89,
     555             :                                 .phyclk_mhz = 600.0,
     556             :                                 .socclk_mhz = 715.0,
     557             :                                 .dscclk_mhz = 318.334,
     558             :                                 .dram_speed_mts = 2134.0,
     559             :                         },
     560             :                         {
     561             :                                 .state = 4,
     562             :                                 .dcfclk_mhz = 626.09,
     563             :                                 .fabricclk_mhz = 1200.0,
     564             :                                 .dispclk_mhz = 900.00,
     565             :                                 .dppclk_mhz = 847.06,
     566             :                                 .phyclk_mhz = 810.0,
     567             :                                 .socclk_mhz = 953.0,
     568             :                                 .dscclk_mhz = 489.0,
     569             :                                 .dram_speed_mts = 2400.0,
     570             :                         },
     571             :                         {
     572             :                                 .state = 5,
     573             :                                 .dcfclk_mhz = 685.71,
     574             :                                 .fabricclk_mhz = 1333.0,
     575             :                                 .dispclk_mhz = 1028.57,
     576             :                                 .dppclk_mhz = 960.00,
     577             :                                 .phyclk_mhz = 810.0,
     578             :                                 .socclk_mhz = 278.0,
     579             :                                 .dscclk_mhz = 287.67,
     580             :                                 .dram_speed_mts = 2666.0,
     581             :                         },
     582             :                         {
     583             :                                 .state = 6,
     584             :                                 .dcfclk_mhz = 757.89,
     585             :                                 .fabricclk_mhz = 1467.0,
     586             :                                 .dispclk_mhz = 1107.69,
     587             :                                 .dppclk_mhz = 1028.57,
     588             :                                 .phyclk_mhz = 810.0,
     589             :                                 .socclk_mhz = 715.0,
     590             :                                 .dscclk_mhz = 318.334,
     591             :                                 .dram_speed_mts = 3200.0,
     592             :                         },
     593             :                         {
     594             :                                 .state = 7,
     595             :                                 .dcfclk_mhz = 847.06,
     596             :                                 .fabricclk_mhz = 1600.0,
     597             :                                 .dispclk_mhz = 1395.0,
     598             :                                 .dppclk_mhz = 1285.00,
     599             :                                 .phyclk_mhz = 1325.0,
     600             :                                 .socclk_mhz = 953.0,
     601             :                                 .dscclk_mhz = 489.0,
     602             :                                 .dram_speed_mts = 4266.0,
     603             :                         },
     604             :                         /*Extra state, no dispclk ramping*/
     605             :                         {
     606             :                                 .state = 8,
     607             :                                 .dcfclk_mhz = 847.06,
     608             :                                 .fabricclk_mhz = 1600.0,
     609             :                                 .dispclk_mhz = 1395.0,
     610             :                                 .dppclk_mhz = 1285.0,
     611             :                                 .phyclk_mhz = 1325.0,
     612             :                                 .socclk_mhz = 953.0,
     613             :                                 .dscclk_mhz = 489.0,
     614             :                                 .dram_speed_mts = 4266.0,
     615             :                         },
     616             : 
     617             :                 },
     618             : 
     619             :         .sr_exit_time_us = 12.5,
     620             :         .sr_enter_plus_exit_time_us = 17.0,
     621             :         .urgent_latency_us = 4.0,
     622             :         .urgent_latency_pixel_data_only_us = 4.0,
     623             :         .urgent_latency_pixel_mixed_with_vm_data_us = 4.0,
     624             :         .urgent_latency_vm_data_only_us = 4.0,
     625             :         .urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096,
     626             :         .urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096,
     627             :         .urgent_out_of_order_return_per_channel_vm_only_bytes = 4096,
     628             :         .pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 80.0,
     629             :         .pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 75.0,
     630             :         .pct_ideal_dram_sdp_bw_after_urgent_vm_only = 40.0,
     631             :         .max_avg_sdp_bw_use_normal_percent = 60.0,
     632             :         .max_avg_dram_bw_use_normal_percent = 100.0,
     633             :         .writeback_latency_us = 12.0,
     634             :         .max_request_size_bytes = 256,
     635             :         .dram_channel_width_bytes = 4,
     636             :         .fabric_datapath_to_dcn_data_return_bytes = 32,
     637             :         .dcn_downspread_percent = 0.5,
     638             :         .downspread_percent = 0.38,
     639             :         .dram_page_open_time_ns = 50.0,
     640             :         .dram_rw_turnaround_time_ns = 17.5,
     641             :         .dram_return_buffer_per_channel_bytes = 8192,
     642             :         .round_trip_ping_latency_dcfclk_cycles = 128,
     643             :         .urgent_out_of_order_return_per_channel_bytes = 4096,
     644             :         .channel_interleave_bytes = 256,
     645             :         .num_banks = 8,
     646             :         .num_chans = 4,
     647             :         .vmm_page_size_bytes = 4096,
     648             :         .dram_clock_change_latency_us = 23.84,
     649             :         .return_bus_width_bytes = 64,
     650             :         .dispclk_dppclk_vco_speed_mhz = 3600,
     651             :         .xfc_bus_transport_time_us = 4,
     652             :         .xfc_xbuf_latency_tolerance_us = 4,
     653             :         .use_urgent_burst_bw = 1,
     654             :         .num_states = 8
     655             : };
     656             : 
     657             : struct wm_table ddr4_wm_table_gs = {
     658             :         .entries = {
     659             :                 {
     660             :                         .wm_inst = WM_A,
     661             :                         .wm_type = WM_TYPE_PSTATE_CHG,
     662             :                         .pstate_latency_us = 11.72,
     663             :                         .sr_exit_time_us = 7.09,
     664             :                         .sr_enter_plus_exit_time_us = 8.14,
     665             :                         .valid = true,
     666             :                 },
     667             :                 {
     668             :                         .wm_inst = WM_B,
     669             :                         .wm_type = WM_TYPE_PSTATE_CHG,
     670             :                         .pstate_latency_us = 11.72,
     671             :                         .sr_exit_time_us = 10.12,
     672             :                         .sr_enter_plus_exit_time_us = 11.48,
     673             :                         .valid = true,
     674             :                 },
     675             :                 {
     676             :                         .wm_inst = WM_C,
     677             :                         .wm_type = WM_TYPE_PSTATE_CHG,
     678             :                         .pstate_latency_us = 11.72,
     679             :                         .sr_exit_time_us = 10.12,
     680             :                         .sr_enter_plus_exit_time_us = 11.48,
     681             :                         .valid = true,
     682             :                 },
     683             :                 {
     684             :                         .wm_inst = WM_D,
     685             :                         .wm_type = WM_TYPE_PSTATE_CHG,
     686             :                         .pstate_latency_us = 11.72,
     687             :                         .sr_exit_time_us = 10.12,
     688             :                         .sr_enter_plus_exit_time_us = 11.48,
     689             :                         .valid = true,
     690             :                 },
     691             :         }
     692             : };
     693             : 
     694             : struct wm_table lpddr4_wm_table_gs = {
     695             :         .entries = {
     696             :                 {
     697             :                         .wm_inst = WM_A,
     698             :                         .wm_type = WM_TYPE_PSTATE_CHG,
     699             :                         .pstate_latency_us = 11.65333,
     700             :                         .sr_exit_time_us = 5.32,
     701             :                         .sr_enter_plus_exit_time_us = 6.38,
     702             :                         .valid = true,
     703             :                 },
     704             :                 {
     705             :                         .wm_inst = WM_B,
     706             :                         .wm_type = WM_TYPE_PSTATE_CHG,
     707             :                         .pstate_latency_us = 11.65333,
     708             :                         .sr_exit_time_us = 9.82,
     709             :                         .sr_enter_plus_exit_time_us = 11.196,
     710             :                         .valid = true,
     711             :                 },
     712             :                 {
     713             :                         .wm_inst = WM_C,
     714             :                         .wm_type = WM_TYPE_PSTATE_CHG,
     715             :                         .pstate_latency_us = 11.65333,
     716             :                         .sr_exit_time_us = 9.89,
     717             :                         .sr_enter_plus_exit_time_us = 11.24,
     718             :                         .valid = true,
     719             :                 },
     720             :                 {
     721             :                         .wm_inst = WM_D,
     722             :                         .wm_type = WM_TYPE_PSTATE_CHG,
     723             :                         .pstate_latency_us = 11.65333,
     724             :                         .sr_exit_time_us = 9.748,
     725             :                         .sr_enter_plus_exit_time_us = 11.102,
     726             :                         .valid = true,
     727             :                 },
     728             :         }
     729             : };
     730             : 
     731             : struct wm_table lpddr4_wm_table_with_disabled_ppt = {
     732             :         .entries = {
     733             :                 {
     734             :                         .wm_inst = WM_A,
     735             :                         .wm_type = WM_TYPE_PSTATE_CHG,
     736             :                         .pstate_latency_us = 11.65333,
     737             :                         .sr_exit_time_us = 8.32,
     738             :                         .sr_enter_plus_exit_time_us = 9.38,
     739             :                         .valid = true,
     740             :                 },
     741             :                 {
     742             :                         .wm_inst = WM_B,
     743             :                         .wm_type = WM_TYPE_PSTATE_CHG,
     744             :                         .pstate_latency_us = 11.65333,
     745             :                         .sr_exit_time_us = 9.82,
     746             :                         .sr_enter_plus_exit_time_us = 11.196,
     747             :                         .valid = true,
     748             :                 },
     749             :                 {
     750             :                         .wm_inst = WM_C,
     751             :                         .wm_type = WM_TYPE_PSTATE_CHG,
     752             :                         .pstate_latency_us = 11.65333,
     753             :                         .sr_exit_time_us = 9.89,
     754             :                         .sr_enter_plus_exit_time_us = 11.24,
     755             :                         .valid = true,
     756             :                 },
     757             :                 {
     758             :                         .wm_inst = WM_D,
     759             :                         .wm_type = WM_TYPE_PSTATE_CHG,
     760             :                         .pstate_latency_us = 11.65333,
     761             :                         .sr_exit_time_us = 9.748,
     762             :                         .sr_enter_plus_exit_time_us = 11.102,
     763             :                         .valid = true,
     764             :                 },
     765             :         }
     766             : };
     767             : 
     768             : struct wm_table ddr4_wm_table_rn = {
     769             :         .entries = {
     770             :                 {
     771             :                         .wm_inst = WM_A,
     772             :                         .wm_type = WM_TYPE_PSTATE_CHG,
     773             :                         .pstate_latency_us = 11.72,
     774             :                         .sr_exit_time_us = 11.90,
     775             :                         .sr_enter_plus_exit_time_us = 12.80,
     776             :                         .valid = true,
     777             :                 },
     778             :                 {
     779             :                         .wm_inst = WM_B,
     780             :                         .wm_type = WM_TYPE_PSTATE_CHG,
     781             :                         .pstate_latency_us = 11.72,
     782             :                         .sr_exit_time_us = 13.18,
     783             :                         .sr_enter_plus_exit_time_us = 14.30,
     784             :                         .valid = true,
     785             :                 },
     786             :                 {
     787             :                         .wm_inst = WM_C,
     788             :                         .wm_type = WM_TYPE_PSTATE_CHG,
     789             :                         .pstate_latency_us = 11.72,
     790             :                         .sr_exit_time_us = 13.18,
     791             :                         .sr_enter_plus_exit_time_us = 14.30,
     792             :                         .valid = true,
     793             :                 },
     794             :                 {
     795             :                         .wm_inst = WM_D,
     796             :                         .wm_type = WM_TYPE_PSTATE_CHG,
     797             :                         .pstate_latency_us = 11.72,
     798             :                         .sr_exit_time_us = 13.18,
     799             :                         .sr_enter_plus_exit_time_us = 14.30,
     800             :                         .valid = true,
     801             :                 },
     802             :         }
     803             : };
     804             : 
     805             : struct wm_table ddr4_1R_wm_table_rn = {
     806             :         .entries = {
     807             :                 {
     808             :                         .wm_inst = WM_A,
     809             :                         .wm_type = WM_TYPE_PSTATE_CHG,
     810             :                         .pstate_latency_us = 11.72,
     811             :                         .sr_exit_time_us = 13.90,
     812             :                         .sr_enter_plus_exit_time_us = 14.80,
     813             :                         .valid = true,
     814             :                 },
     815             :                 {
     816             :                         .wm_inst = WM_B,
     817             :                         .wm_type = WM_TYPE_PSTATE_CHG,
     818             :                         .pstate_latency_us = 11.72,
     819             :                         .sr_exit_time_us = 13.90,
     820             :                         .sr_enter_plus_exit_time_us = 14.80,
     821             :                         .valid = true,
     822             :                 },
     823             :                 {
     824             :                         .wm_inst = WM_C,
     825             :                         .wm_type = WM_TYPE_PSTATE_CHG,
     826             :                         .pstate_latency_us = 11.72,
     827             :                         .sr_exit_time_us = 13.90,
     828             :                         .sr_enter_plus_exit_time_us = 14.80,
     829             :                         .valid = true,
     830             :                 },
     831             :                 {
     832             :                         .wm_inst = WM_D,
     833             :                         .wm_type = WM_TYPE_PSTATE_CHG,
     834             :                         .pstate_latency_us = 11.72,
     835             :                         .sr_exit_time_us = 13.90,
     836             :                         .sr_enter_plus_exit_time_us = 14.80,
     837             :                         .valid = true,
     838             :                 },
     839             :         }
     840             : };
     841             : 
     842             : struct wm_table lpddr4_wm_table_rn = {
     843             :         .entries = {
     844             :                 {
     845             :                         .wm_inst = WM_A,
     846             :                         .wm_type = WM_TYPE_PSTATE_CHG,
     847             :                         .pstate_latency_us = 11.65333,
     848             :                         .sr_exit_time_us = 7.32,
     849             :                         .sr_enter_plus_exit_time_us = 8.38,
     850             :                         .valid = true,
     851             :                 },
     852             :                 {
     853             :                         .wm_inst = WM_B,
     854             :                         .wm_type = WM_TYPE_PSTATE_CHG,
     855             :                         .pstate_latency_us = 11.65333,
     856             :                         .sr_exit_time_us = 9.82,
     857             :                         .sr_enter_plus_exit_time_us = 11.196,
     858             :                         .valid = true,
     859             :                 },
     860             :                 {
     861             :                         .wm_inst = WM_C,
     862             :                         .wm_type = WM_TYPE_PSTATE_CHG,
     863             :                         .pstate_latency_us = 11.65333,
     864             :                         .sr_exit_time_us = 9.89,
     865             :                         .sr_enter_plus_exit_time_us = 11.24,
     866             :                         .valid = true,
     867             :                 },
     868             :                 {
     869             :                         .wm_inst = WM_D,
     870             :                         .wm_type = WM_TYPE_PSTATE_CHG,
     871             :                         .pstate_latency_us = 11.65333,
     872             :                         .sr_exit_time_us = 9.748,
     873             :                         .sr_enter_plus_exit_time_us = 11.102,
     874             :                         .valid = true,
     875             :                 },
     876             :         }
     877             : };
     878             : 
     879           0 : void dcn20_populate_dml_writeback_from_context(struct dc *dc,
     880             :                                                struct resource_context *res_ctx,
     881             :                                                display_e2e_pipe_params_st *pipes)
     882             : {
     883             :         int pipe_cnt, i;
     884             : 
     885           0 :         dc_assert_fp_enabled();
     886             : 
     887           0 :         for (i = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {
     888           0 :                 struct dc_writeback_info *wb_info = &res_ctx->pipe_ctx[i].stream->writeback_info[0];
     889             : 
     890           0 :                 if (!res_ctx->pipe_ctx[i].stream)
     891           0 :                         continue;
     892             : 
     893             :                 /* Set writeback information */
     894           0 :                 pipes[pipe_cnt].dout.wb_enable = (wb_info->wb_enabled == true) ? 1 : 0;
     895           0 :                 pipes[pipe_cnt].dout.num_active_wb++;
     896           0 :                 pipes[pipe_cnt].dout.wb.wb_src_height = wb_info->dwb_params.cnv_params.crop_height;
     897           0 :                 pipes[pipe_cnt].dout.wb.wb_src_width = wb_info->dwb_params.cnv_params.crop_width;
     898           0 :                 pipes[pipe_cnt].dout.wb.wb_dst_width = wb_info->dwb_params.dest_width;
     899           0 :                 pipes[pipe_cnt].dout.wb.wb_dst_height = wb_info->dwb_params.dest_height;
     900           0 :                 pipes[pipe_cnt].dout.wb.wb_htaps_luma = 1;
     901           0 :                 pipes[pipe_cnt].dout.wb.wb_vtaps_luma = 1;
     902           0 :                 pipes[pipe_cnt].dout.wb.wb_htaps_chroma = wb_info->dwb_params.scaler_taps.h_taps_c;
     903           0 :                 pipes[pipe_cnt].dout.wb.wb_vtaps_chroma = wb_info->dwb_params.scaler_taps.v_taps_c;
     904           0 :                 pipes[pipe_cnt].dout.wb.wb_hratio = 1.0;
     905           0 :                 pipes[pipe_cnt].dout.wb.wb_vratio = 1.0;
     906           0 :                 if (wb_info->dwb_params.out_format == dwb_scaler_mode_yuv420) {
     907           0 :                         if (wb_info->dwb_params.output_depth == DWB_OUTPUT_PIXEL_DEPTH_8BPC)
     908           0 :                                 pipes[pipe_cnt].dout.wb.wb_pixel_format = dm_420_8;
     909             :                         else
     910           0 :                                 pipes[pipe_cnt].dout.wb.wb_pixel_format = dm_420_10;
     911             :                 } else {
     912           0 :                         pipes[pipe_cnt].dout.wb.wb_pixel_format = dm_444_32;
     913             :                 }
     914             : 
     915           0 :                 pipe_cnt++;
     916             :         }
     917           0 : }
     918             : 
     919           0 : void dcn20_fpu_set_wb_arb_params(struct mcif_arb_params *wb_arb_params,
     920             :                                 struct dc_state *context,
     921             :                                 display_e2e_pipe_params_st *pipes,
     922             :                                 int pipe_cnt, int i)
     923             : {
     924             :        int k;
     925             : 
     926           0 :        dc_assert_fp_enabled();
     927             : 
     928           0 :        for (k = 0; k < sizeof(wb_arb_params->cli_watermark)/sizeof(wb_arb_params->cli_watermark[0]); k++) {
     929           0 :                wb_arb_params->cli_watermark[k] = get_wm_writeback_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
     930           0 :                wb_arb_params->pstate_watermark[k] = get_wm_writeback_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
     931             :        }
     932           0 :        wb_arb_params->time_per_pixel = 16.0 * 1000 / (context->res_ctx.pipe_ctx[i].stream->phy_pix_clk / 1000); /* 4 bit fraction, ms */
     933           0 : }
     934             : 
     935           0 : static bool is_dtbclk_required(struct dc *dc, struct dc_state *context)
     936             : {
     937             :         int i;
     938           0 :         for (i = 0; i < dc->res_pool->pipe_count; i++) {
     939           0 :                 if (!context->res_ctx.pipe_ctx[i].stream)
     940           0 :                         continue;
     941           0 :                 if (is_dp_128b_132b_signal(&context->res_ctx.pipe_ctx[i]))
     942             :                         return true;
     943             :         }
     944             :         return false;
     945             : }
     946             : 
     947           0 : static enum dcn_zstate_support_state  decide_zstate_support(struct dc *dc, struct dc_state *context)
     948             : {
     949             :         int plane_count;
     950             :         int i;
     951             :         unsigned int optimized_min_dst_y_next_start_us;
     952             : 
     953           0 :         plane_count = 0;
     954           0 :         optimized_min_dst_y_next_start_us = 0;
     955           0 :         for (i = 0; i < dc->res_pool->pipe_count; i++) {
     956           0 :                 if (context->res_ctx.pipe_ctx[i].plane_state)
     957           0 :                         plane_count++;
     958             :         }
     959             : 
     960             :         /*
     961             :          * Z9 and Z10 allowed cases:
     962             :          *      1. 0 Planes enabled
     963             :          *      2. single eDP, on link 0, 1 plane and stutter period > 5ms
     964             :          * Z10 only cases:
     965             :          *      1. single eDP, on link 0, 1 plane and stutter period >= 5ms
     966             :          * Zstate not allowed cases:
     967             :          *      1. Everything else
     968             :          */
     969           0 :         if (plane_count == 0)
     970             :                 return DCN_ZSTATE_SUPPORT_ALLOW;
     971           0 :         else if (context->stream_count == 1 &&  context->streams[0]->signal == SIGNAL_TYPE_EDP) {
     972           0 :                 struct dc_link *link = context->streams[0]->sink->link;
     973           0 :                 struct dc_stream_status *stream_status = &context->stream_status[0];
     974             : 
     975           0 :                 if (dc_extended_blank_supported(dc)) {
     976           0 :                         for (i = 0; i < dc->res_pool->pipe_count; i++) {
     977           0 :                                 if (context->res_ctx.pipe_ctx[i].stream == context->streams[0]
     978           0 :                                         && context->res_ctx.pipe_ctx[i].stream->adjust.v_total_min == context->res_ctx.pipe_ctx[i].stream->adjust.v_total_max
     979           0 :                                         && context->res_ctx.pipe_ctx[i].stream->adjust.v_total_min > context->res_ctx.pipe_ctx[i].stream->timing.v_total) {
     980           0 :                                                 optimized_min_dst_y_next_start_us =
     981             :                                                         context->res_ctx.pipe_ctx[i].dlg_regs.optimized_min_dst_y_next_start_us;
     982           0 :                                                 break;
     983             :                                 }
     984             :                         }
     985             :                 }
     986             :                 /* zstate only supported on PWRSEQ0  and when there's <2 planes*/
     987           0 :                 if (link->link_index != 0 || stream_status->plane_count > 1)
     988             :                         return DCN_ZSTATE_SUPPORT_DISALLOW;
     989             : 
     990           0 :                 if (context->bw_ctx.dml.vba.StutterPeriod > 5000.0 || optimized_min_dst_y_next_start_us > 5000)
     991             :                         return DCN_ZSTATE_SUPPORT_ALLOW;
     992           0 :                 else if (link->psr_settings.psr_version == DC_PSR_VERSION_1 && !dc->debug.disable_psr)
     993             :                         return DCN_ZSTATE_SUPPORT_ALLOW_Z10_ONLY;
     994             :                 else
     995           0 :                         return DCN_ZSTATE_SUPPORT_DISALLOW;
     996             :         } else
     997             :                 return DCN_ZSTATE_SUPPORT_DISALLOW;
     998             : }
     999             : 
    1000           0 : void dcn20_calculate_dlg_params(
    1001             :                 struct dc *dc, struct dc_state *context,
    1002             :                 display_e2e_pipe_params_st *pipes,
    1003             :                 int pipe_cnt,
    1004             :                 int vlevel)
    1005             : {
    1006             :         int i, pipe_idx;
    1007             : 
    1008           0 :         dc_assert_fp_enabled();
    1009             : 
    1010             :         /* Writeback MCIF_WB arbitration parameters */
    1011           0 :         dc->res_pool->funcs->set_mcif_arb_params(dc, context, pipes, pipe_cnt);
    1012             : 
    1013           0 :         context->bw_ctx.bw.dcn.clk.dispclk_khz = context->bw_ctx.dml.vba.DISPCLK * 1000;
    1014           0 :         context->bw_ctx.bw.dcn.clk.dcfclk_khz = context->bw_ctx.dml.vba.DCFCLK * 1000;
    1015           0 :         context->bw_ctx.bw.dcn.clk.socclk_khz = context->bw_ctx.dml.vba.SOCCLK * 1000;
    1016           0 :         context->bw_ctx.bw.dcn.clk.dramclk_khz = context->bw_ctx.dml.vba.DRAMSpeed * 1000 / 16;
    1017             : 
    1018           0 :         if (dc->debug.min_dram_clk_khz > context->bw_ctx.bw.dcn.clk.dramclk_khz)
    1019           0 :                 context->bw_ctx.bw.dcn.clk.dramclk_khz = dc->debug.min_dram_clk_khz;
    1020             : 
    1021           0 :         context->bw_ctx.bw.dcn.clk.dcfclk_deep_sleep_khz = context->bw_ctx.dml.vba.DCFCLKDeepSleep * 1000;
    1022           0 :         context->bw_ctx.bw.dcn.clk.fclk_khz = context->bw_ctx.dml.vba.FabricClock * 1000;
    1023             :         context->bw_ctx.bw.dcn.clk.p_state_change_support =
    1024           0 :                 context->bw_ctx.dml.vba.DRAMClockChangeSupport[vlevel][context->bw_ctx.dml.vba.maxMpcComb]
    1025           0 :                                                         != dm_dram_clock_change_unsupported;
    1026             : 
    1027             :         /* Pstate change might not be supported by hardware, but it might be
    1028             :          * possible with firmware driven vertical blank stretching.
    1029             :          */
    1030           0 :         context->bw_ctx.bw.dcn.clk.p_state_change_support |= context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching;
    1031             : 
    1032           0 :         context->bw_ctx.bw.dcn.clk.dppclk_khz = 0;
    1033             : 
    1034           0 :         context->bw_ctx.bw.dcn.clk.dtbclk_en = is_dtbclk_required(dc, context);
    1035             : 
    1036           0 :         if (context->bw_ctx.bw.dcn.clk.dispclk_khz < dc->debug.min_disp_clk_khz)
    1037           0 :                 context->bw_ctx.bw.dcn.clk.dispclk_khz = dc->debug.min_disp_clk_khz;
    1038             : 
    1039           0 :         for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) {
    1040           0 :                 if (!context->res_ctx.pipe_ctx[i].stream)
    1041           0 :                         continue;
    1042           0 :                 pipes[pipe_idx].pipe.dest.vstartup_start = get_vstartup(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx);
    1043           0 :                 pipes[pipe_idx].pipe.dest.vupdate_offset = get_vupdate_offset(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx);
    1044           0 :                 pipes[pipe_idx].pipe.dest.vupdate_width = get_vupdate_width(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx);
    1045           0 :                 pipes[pipe_idx].pipe.dest.vready_offset = get_vready_offset(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx);
    1046           0 :                 if (context->res_ctx.pipe_ctx[i].stream->mall_stream_config.type == SUBVP_PHANTOM) {
    1047             :                         // Phantom pipe requires that DET_SIZE = 0 and no unbounded requests
    1048           0 :                         context->res_ctx.pipe_ctx[i].det_buffer_size_kb = 0;
    1049           0 :                         context->res_ctx.pipe_ctx[i].unbounded_req = false;
    1050             :                 } else {
    1051           0 :                         context->res_ctx.pipe_ctx[i].det_buffer_size_kb = context->bw_ctx.dml.ip.det_buffer_size_kbytes;
    1052           0 :                         context->res_ctx.pipe_ctx[i].unbounded_req = pipes[pipe_idx].pipe.src.unbounded_req_mode;
    1053             :                 }
    1054           0 :                 if (context->bw_ctx.bw.dcn.clk.dppclk_khz < pipes[pipe_idx].clks_cfg.dppclk_mhz * 1000)
    1055           0 :                         context->bw_ctx.bw.dcn.clk.dppclk_khz = pipes[pipe_idx].clks_cfg.dppclk_mhz * 1000;
    1056           0 :                 context->res_ctx.pipe_ctx[i].plane_res.bw.dppclk_khz =
    1057           0 :                                                 pipes[pipe_idx].clks_cfg.dppclk_mhz * 1000;
    1058           0 :                 context->res_ctx.pipe_ctx[i].pipe_dlg_param = pipes[pipe_idx].pipe.dest;
    1059           0 :                 pipe_idx++;
    1060             :         }
    1061             :         /*save a original dppclock copy*/
    1062           0 :         context->bw_ctx.bw.dcn.clk.bw_dppclk_khz = context->bw_ctx.bw.dcn.clk.dppclk_khz;
    1063           0 :         context->bw_ctx.bw.dcn.clk.bw_dispclk_khz = context->bw_ctx.bw.dcn.clk.dispclk_khz;
    1064           0 :         context->bw_ctx.bw.dcn.clk.max_supported_dppclk_khz = context->bw_ctx.dml.soc.clock_limits[vlevel].dppclk_mhz * 1000;
    1065           0 :         context->bw_ctx.bw.dcn.clk.max_supported_dispclk_khz = context->bw_ctx.dml.soc.clock_limits[vlevel].dispclk_mhz * 1000;
    1066             : 
    1067           0 :         context->bw_ctx.bw.dcn.compbuf_size_kb = context->bw_ctx.dml.ip.config_return_buffer_size_in_kbytes
    1068           0 :                                                 - context->bw_ctx.dml.ip.det_buffer_size_kbytes * pipe_idx;
    1069             : 
    1070           0 :         for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) {
    1071           0 :                 bool cstate_en = context->bw_ctx.dml.vba.PrefetchMode[vlevel][context->bw_ctx.dml.vba.maxMpcComb] != 2;
    1072             : 
    1073           0 :                 if (!context->res_ctx.pipe_ctx[i].stream)
    1074           0 :                         continue;
    1075             : 
    1076           0 :                 if (dc->ctx->dce_version == DCN_VERSION_2_01)
    1077           0 :                         cstate_en = false;
    1078             : 
    1079           0 :                 context->bw_ctx.dml.funcs.rq_dlg_get_dlg_reg(&context->bw_ctx.dml,
    1080           0 :                                 &context->res_ctx.pipe_ctx[i].dlg_regs,
    1081           0 :                                 &context->res_ctx.pipe_ctx[i].ttu_regs,
    1082             :                                 pipes,
    1083             :                                 pipe_cnt,
    1084             :                                 pipe_idx,
    1085             :                                 cstate_en,
    1086           0 :                                 context->bw_ctx.bw.dcn.clk.p_state_change_support,
    1087             :                                 false, false, true);
    1088             : 
    1089           0 :                 context->bw_ctx.dml.funcs.rq_dlg_get_rq_reg(&context->bw_ctx.dml,
    1090           0 :                                 &context->res_ctx.pipe_ctx[i].rq_regs,
    1091           0 :                                 &pipes[pipe_idx].pipe);
    1092           0 :                 pipe_idx++;
    1093             :         }
    1094           0 :         context->bw_ctx.bw.dcn.clk.zstate_support = decide_zstate_support(dc, context);
    1095           0 : }
    1096             : 
    1097           0 : static void swizzle_to_dml_params(
    1098             :                 enum swizzle_mode_values swizzle,
    1099             :                 unsigned int *sw_mode)
    1100             : {
    1101           0 :         switch (swizzle) {
    1102             :         case DC_SW_LINEAR:
    1103           0 :                 *sw_mode = dm_sw_linear;
    1104           0 :                 break;
    1105             :         case DC_SW_4KB_S:
    1106           0 :                 *sw_mode = dm_sw_4kb_s;
    1107           0 :                 break;
    1108             :         case DC_SW_4KB_S_X:
    1109           0 :                 *sw_mode = dm_sw_4kb_s_x;
    1110           0 :                 break;
    1111             :         case DC_SW_4KB_D:
    1112           0 :                 *sw_mode = dm_sw_4kb_d;
    1113           0 :                 break;
    1114             :         case DC_SW_4KB_D_X:
    1115           0 :                 *sw_mode = dm_sw_4kb_d_x;
    1116           0 :                 break;
    1117             :         case DC_SW_64KB_S:
    1118           0 :                 *sw_mode = dm_sw_64kb_s;
    1119           0 :                 break;
    1120             :         case DC_SW_64KB_S_X:
    1121           0 :                 *sw_mode = dm_sw_64kb_s_x;
    1122           0 :                 break;
    1123             :         case DC_SW_64KB_S_T:
    1124           0 :                 *sw_mode = dm_sw_64kb_s_t;
    1125           0 :                 break;
    1126             :         case DC_SW_64KB_D:
    1127           0 :                 *sw_mode = dm_sw_64kb_d;
    1128           0 :                 break;
    1129             :         case DC_SW_64KB_D_X:
    1130           0 :                 *sw_mode = dm_sw_64kb_d_x;
    1131           0 :                 break;
    1132             :         case DC_SW_64KB_D_T:
    1133           0 :                 *sw_mode = dm_sw_64kb_d_t;
    1134           0 :                 break;
    1135             :         case DC_SW_64KB_R_X:
    1136           0 :                 *sw_mode = dm_sw_64kb_r_x;
    1137           0 :                 break;
    1138             :         case DC_SW_VAR_S:
    1139           0 :                 *sw_mode = dm_sw_var_s;
    1140           0 :                 break;
    1141             :         case DC_SW_VAR_S_X:
    1142           0 :                 *sw_mode = dm_sw_var_s_x;
    1143           0 :                 break;
    1144             :         case DC_SW_VAR_D:
    1145           0 :                 *sw_mode = dm_sw_var_d;
    1146           0 :                 break;
    1147             :         case DC_SW_VAR_D_X:
    1148           0 :                 *sw_mode = dm_sw_var_d_x;
    1149           0 :                 break;
    1150             :         case DC_SW_VAR_R_X:
    1151           0 :                 *sw_mode = dm_sw_var_r_x;
    1152           0 :                 break;
    1153             :         default:
    1154           0 :                 ASSERT(0); /* Not supported */
    1155             :                 break;
    1156             :         }
    1157           0 : }
    1158             : 
    1159           0 : int dcn20_populate_dml_pipes_from_context(
    1160             :                 struct dc *dc,
    1161             :                 struct dc_state *context,
    1162             :                 display_e2e_pipe_params_st *pipes,
    1163             :                 bool fast_validate)
    1164             : {
    1165             :         int pipe_cnt, i;
    1166           0 :         bool synchronized_vblank = true;
    1167           0 :         struct resource_context *res_ctx = &context->res_ctx;
    1168             : 
    1169           0 :         dc_assert_fp_enabled();
    1170             : 
    1171           0 :         for (i = 0, pipe_cnt = -1; i < dc->res_pool->pipe_count; i++) {
    1172           0 :                 if (!res_ctx->pipe_ctx[i].stream)
    1173           0 :                         continue;
    1174             : 
    1175           0 :                 if (pipe_cnt < 0) {
    1176           0 :                         pipe_cnt = i;
    1177           0 :                         continue;
    1178             :                 }
    1179             : 
    1180           0 :                 if (res_ctx->pipe_ctx[pipe_cnt].stream == res_ctx->pipe_ctx[i].stream)
    1181           0 :                         continue;
    1182             : 
    1183           0 :                 if (dc->debug.disable_timing_sync ||
    1184           0 :                         (!resource_are_streams_timing_synchronizable(
    1185             :                                 res_ctx->pipe_ctx[pipe_cnt].stream,
    1186           0 :                                 res_ctx->pipe_ctx[i].stream) &&
    1187           0 :                         !resource_are_vblanks_synchronizable(
    1188             :                                 res_ctx->pipe_ctx[pipe_cnt].stream,
    1189             :                                 res_ctx->pipe_ctx[i].stream))) {
    1190             :                         synchronized_vblank = false;
    1191             :                         break;
    1192             :                 }
    1193             :         }
    1194             : 
    1195           0 :         for (i = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {
    1196           0 :                 struct dc_crtc_timing *timing = &res_ctx->pipe_ctx[i].stream->timing;
    1197             :                 unsigned int v_total;
    1198             :                 unsigned int front_porch;
    1199             :                 int output_bpc;
    1200           0 :                 struct audio_check aud_check = {0};
    1201             : 
    1202           0 :                 if (!res_ctx->pipe_ctx[i].stream)
    1203           0 :                         continue;
    1204             : 
    1205           0 :                 v_total = timing->v_total;
    1206           0 :                 front_porch = timing->v_front_porch;
    1207             : 
    1208             :                 /* todo:
    1209             :                 pipes[pipe_cnt].pipe.src.dynamic_metadata_enable = 0;
    1210             :                 pipes[pipe_cnt].pipe.src.dcc = 0;
    1211             :                 pipes[pipe_cnt].pipe.src.vm = 0;*/
    1212             : 
    1213           0 :                 pipes[pipe_cnt].clks_cfg.refclk_mhz = dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000.0;
    1214             : 
    1215           0 :                 pipes[pipe_cnt].dout.dsc_enable = res_ctx->pipe_ctx[i].stream->timing.flags.DSC;
    1216             :                 /* todo: rotation?*/
    1217           0 :                 pipes[pipe_cnt].dout.dsc_slices = res_ctx->pipe_ctx[i].stream->timing.dsc_cfg.num_slices_h;
    1218           0 :                 if (res_ctx->pipe_ctx[i].stream->use_dynamic_meta) {
    1219           0 :                         pipes[pipe_cnt].pipe.src.dynamic_metadata_enable = true;
    1220             :                         /* 1/2 vblank */
    1221           0 :                         pipes[pipe_cnt].pipe.src.dynamic_metadata_lines_before_active =
    1222           0 :                                 (v_total - timing->v_addressable
    1223           0 :                                         - timing->v_border_top - timing->v_border_bottom) / 2;
    1224             :                         /* 36 bytes dp, 32 hdmi */
    1225           0 :                         pipes[pipe_cnt].pipe.src.dynamic_metadata_xmit_bytes =
    1226           0 :                                 dc_is_dp_signal(res_ctx->pipe_ctx[i].stream->signal) ? 36 : 32;
    1227             :                 }
    1228           0 :                 pipes[pipe_cnt].pipe.src.dcc = false;
    1229           0 :                 pipes[pipe_cnt].pipe.src.dcc_rate = 1;
    1230           0 :                 pipes[pipe_cnt].pipe.dest.synchronized_vblank_all_planes = synchronized_vblank;
    1231           0 :                 pipes[pipe_cnt].pipe.dest.hblank_start = timing->h_total - timing->h_front_porch;
    1232           0 :                 pipes[pipe_cnt].pipe.dest.hblank_end = pipes[pipe_cnt].pipe.dest.hblank_start
    1233           0 :                                 - timing->h_addressable
    1234           0 :                                 - timing->h_border_left
    1235           0 :                                 - timing->h_border_right;
    1236           0 :                 pipes[pipe_cnt].pipe.dest.vblank_start = v_total - front_porch;
    1237           0 :                 pipes[pipe_cnt].pipe.dest.vblank_end = pipes[pipe_cnt].pipe.dest.vblank_start
    1238           0 :                                 - timing->v_addressable
    1239           0 :                                 - timing->v_border_top
    1240           0 :                                 - timing->v_border_bottom;
    1241           0 :                 pipes[pipe_cnt].pipe.dest.htotal = timing->h_total;
    1242           0 :                 pipes[pipe_cnt].pipe.dest.vtotal = v_total;
    1243           0 :                 pipes[pipe_cnt].pipe.dest.hactive =
    1244           0 :                         timing->h_addressable + timing->h_border_left + timing->h_border_right;
    1245           0 :                 pipes[pipe_cnt].pipe.dest.vactive =
    1246           0 :                         timing->v_addressable + timing->v_border_top + timing->v_border_bottom;
    1247           0 :                 pipes[pipe_cnt].pipe.dest.interlaced = timing->flags.INTERLACE;
    1248           0 :                 pipes[pipe_cnt].pipe.dest.pixel_rate_mhz = timing->pix_clk_100hz/10000.0;
    1249           0 :                 if (timing->timing_3d_format == TIMING_3D_FORMAT_HW_FRAME_PACKING)
    1250           0 :                         pipes[pipe_cnt].pipe.dest.pixel_rate_mhz *= 2;
    1251           0 :                 pipes[pipe_cnt].pipe.dest.otg_inst = res_ctx->pipe_ctx[i].stream_res.tg->inst;
    1252           0 :                 pipes[pipe_cnt].dout.dp_lanes = 4;
    1253           0 :                 if (res_ctx->pipe_ctx[i].stream->link)
    1254           0 :                         pipes[pipe_cnt].dout.dp_rate = dm_dp_rate_na;
    1255           0 :                 pipes[pipe_cnt].dout.is_virtual = 0;
    1256           0 :                 pipes[pipe_cnt].pipe.dest.vtotal_min = res_ctx->pipe_ctx[i].stream->adjust.v_total_min;
    1257           0 :                 pipes[pipe_cnt].pipe.dest.vtotal_max = res_ctx->pipe_ctx[i].stream->adjust.v_total_max;
    1258           0 :                 switch (get_num_odm_splits(&res_ctx->pipe_ctx[i])) {
    1259             :                 case 1:
    1260           0 :                         pipes[pipe_cnt].pipe.dest.odm_combine = dm_odm_combine_mode_2to1;
    1261           0 :                         break;
    1262             :                 case 3:
    1263           0 :                         pipes[pipe_cnt].pipe.dest.odm_combine = dm_odm_combine_mode_4to1;
    1264           0 :                         break;
    1265             :                 default:
    1266           0 :                         pipes[pipe_cnt].pipe.dest.odm_combine = dm_odm_combine_mode_disabled;
    1267             :                 }
    1268           0 :                 pipes[pipe_cnt].pipe.src.hsplit_grp = res_ctx->pipe_ctx[i].pipe_idx;
    1269           0 :                 if (res_ctx->pipe_ctx[i].top_pipe && res_ctx->pipe_ctx[i].top_pipe->plane_state
    1270           0 :                                 == res_ctx->pipe_ctx[i].plane_state) {
    1271             :                         struct pipe_ctx *first_pipe = res_ctx->pipe_ctx[i].top_pipe;
    1272             :                         int split_idx = 0;
    1273             : 
    1274           0 :                         while (first_pipe->top_pipe && first_pipe->top_pipe->plane_state
    1275             :                                         == res_ctx->pipe_ctx[i].plane_state) {
    1276           0 :                                 first_pipe = first_pipe->top_pipe;
    1277           0 :                                 split_idx++;
    1278             :                         }
    1279             :                         /* Treat 4to1 mpc combine as an mpo of 2 2-to-1 combines */
    1280           0 :                         if (split_idx == 0)
    1281           0 :                                 pipes[pipe_cnt].pipe.src.hsplit_grp = first_pipe->pipe_idx;
    1282           0 :                         else if (split_idx == 1)
    1283           0 :                                 pipes[pipe_cnt].pipe.src.hsplit_grp = res_ctx->pipe_ctx[i].pipe_idx;
    1284           0 :                         else if (split_idx == 2)
    1285           0 :                                 pipes[pipe_cnt].pipe.src.hsplit_grp = res_ctx->pipe_ctx[i].top_pipe->pipe_idx;
    1286           0 :                 } else if (res_ctx->pipe_ctx[i].prev_odm_pipe) {
    1287             :                         struct pipe_ctx *first_pipe = res_ctx->pipe_ctx[i].prev_odm_pipe;
    1288             : 
    1289           0 :                         while (first_pipe->prev_odm_pipe)
    1290             :                                 first_pipe = first_pipe->prev_odm_pipe;
    1291           0 :                         pipes[pipe_cnt].pipe.src.hsplit_grp = first_pipe->pipe_idx;
    1292             :                 }
    1293             : 
    1294           0 :                 switch (res_ctx->pipe_ctx[i].stream->signal) {
    1295             :                 case SIGNAL_TYPE_DISPLAY_PORT_MST:
    1296             :                 case SIGNAL_TYPE_DISPLAY_PORT:
    1297           0 :                         pipes[pipe_cnt].dout.output_type = dm_dp;
    1298           0 :                         break;
    1299             :                 case SIGNAL_TYPE_EDP:
    1300           0 :                         pipes[pipe_cnt].dout.output_type = dm_edp;
    1301           0 :                         break;
    1302             :                 case SIGNAL_TYPE_HDMI_TYPE_A:
    1303             :                 case SIGNAL_TYPE_DVI_SINGLE_LINK:
    1304             :                 case SIGNAL_TYPE_DVI_DUAL_LINK:
    1305           0 :                         pipes[pipe_cnt].dout.output_type = dm_hdmi;
    1306           0 :                         break;
    1307             :                 default:
    1308             :                         /* In case there is no signal, set dp with 4 lanes to allow max config */
    1309           0 :                         pipes[pipe_cnt].dout.is_virtual = 1;
    1310           0 :                         pipes[pipe_cnt].dout.output_type = dm_dp;
    1311           0 :                         pipes[pipe_cnt].dout.dp_lanes = 4;
    1312           0 :                         pipes[pipe_cnt].dout.dp_rate = dm_dp_rate_hbr2;
    1313             :                 }
    1314             : 
    1315           0 :                 switch (res_ctx->pipe_ctx[i].stream->timing.display_color_depth) {
    1316             :                 case COLOR_DEPTH_666:
    1317             :                         output_bpc = 6;
    1318             :                         break;
    1319             :                 case COLOR_DEPTH_888:
    1320             :                         output_bpc = 8;
    1321             :                         break;
    1322             :                 case COLOR_DEPTH_101010:
    1323             :                         output_bpc = 10;
    1324             :                         break;
    1325             :                 case COLOR_DEPTH_121212:
    1326             :                         output_bpc = 12;
    1327             :                         break;
    1328             :                 case COLOR_DEPTH_141414:
    1329             :                         output_bpc = 14;
    1330             :                         break;
    1331             :                 case COLOR_DEPTH_161616:
    1332             :                         output_bpc = 16;
    1333             :                         break;
    1334             :                 case COLOR_DEPTH_999:
    1335             :                         output_bpc = 9;
    1336             :                         break;
    1337             :                 case COLOR_DEPTH_111111:
    1338             :                         output_bpc = 11;
    1339             :                         break;
    1340             :                 default:
    1341             :                         output_bpc = 8;
    1342             :                         break;
    1343             :                 }
    1344             : 
    1345           0 :                 switch (res_ctx->pipe_ctx[i].stream->timing.pixel_encoding) {
    1346             :                 case PIXEL_ENCODING_RGB:
    1347             :                 case PIXEL_ENCODING_YCBCR444:
    1348           0 :                         pipes[pipe_cnt].dout.output_format = dm_444;
    1349           0 :                         pipes[pipe_cnt].dout.output_bpp = output_bpc * 3;
    1350           0 :                         break;
    1351             :                 case PIXEL_ENCODING_YCBCR420:
    1352           0 :                         pipes[pipe_cnt].dout.output_format = dm_420;
    1353           0 :                         pipes[pipe_cnt].dout.output_bpp = (output_bpc * 3.0) / 2;
    1354           0 :                         break;
    1355             :                 case PIXEL_ENCODING_YCBCR422:
    1356           0 :                         if (res_ctx->pipe_ctx[i].stream->timing.flags.DSC &&
    1357           0 :                             !res_ctx->pipe_ctx[i].stream->timing.dsc_cfg.ycbcr422_simple)
    1358           0 :                                 pipes[pipe_cnt].dout.output_format = dm_n422;
    1359             :                         else
    1360           0 :                                 pipes[pipe_cnt].dout.output_format = dm_s422;
    1361           0 :                         pipes[pipe_cnt].dout.output_bpp = output_bpc * 2;
    1362           0 :                         break;
    1363             :                 default:
    1364           0 :                         pipes[pipe_cnt].dout.output_format = dm_444;
    1365           0 :                         pipes[pipe_cnt].dout.output_bpp = output_bpc * 3;
    1366             :                 }
    1367             : 
    1368           0 :                 if (res_ctx->pipe_ctx[i].stream->timing.flags.DSC)
    1369           0 :                         pipes[pipe_cnt].dout.output_bpp = res_ctx->pipe_ctx[i].stream->timing.dsc_cfg.bits_per_pixel / 16.0;
    1370             : 
    1371             :                 /* todo: default max for now, until there is logic reflecting this in dc*/
    1372           0 :                 pipes[pipe_cnt].dout.dsc_input_bpc = 12;
    1373             :                 /*fill up the audio sample rate (unit in kHz)*/
    1374           0 :                 get_audio_check(&res_ctx->pipe_ctx[i].stream->audio_info, &aud_check);
    1375           0 :                 pipes[pipe_cnt].dout.max_audio_sample_rate = aud_check.max_audiosample_rate / 1000;
    1376             :                 /*
    1377             :                  * For graphic plane, cursor number is 1, nv12 is 0
    1378             :                  * bw calculations due to cursor on/off
    1379             :                  */
    1380           0 :                 if (res_ctx->pipe_ctx[i].plane_state &&
    1381           0 :                                 (res_ctx->pipe_ctx[i].plane_state->address.type == PLN_ADDR_TYPE_VIDEO_PROGRESSIVE ||
    1382           0 :                                  res_ctx->pipe_ctx[i].stream->mall_stream_config.type == SUBVP_PHANTOM))
    1383           0 :                         pipes[pipe_cnt].pipe.src.num_cursors = 0;
    1384             :                 else
    1385           0 :                         pipes[pipe_cnt].pipe.src.num_cursors = dc->dml.ip.number_of_cursors;
    1386             : 
    1387           0 :                 pipes[pipe_cnt].pipe.src.cur0_src_width = 256;
    1388           0 :                 pipes[pipe_cnt].pipe.src.cur0_bpp = dm_cur_32bit;
    1389             : 
    1390           0 :                 if (!res_ctx->pipe_ctx[i].plane_state) {
    1391           0 :                         pipes[pipe_cnt].pipe.src.is_hsplit = pipes[pipe_cnt].pipe.dest.odm_combine != dm_odm_combine_mode_disabled;
    1392           0 :                         pipes[pipe_cnt].pipe.src.source_scan = dm_horz;
    1393           0 :                         pipes[pipe_cnt].pipe.src.source_rotation = dm_rotation_0;
    1394           0 :                         pipes[pipe_cnt].pipe.src.sw_mode = dm_sw_4kb_s;
    1395           0 :                         pipes[pipe_cnt].pipe.src.macro_tile_size = dm_64k_tile;
    1396           0 :                         pipes[pipe_cnt].pipe.src.viewport_width = timing->h_addressable;
    1397           0 :                         if (pipes[pipe_cnt].pipe.src.viewport_width > 1920)
    1398           0 :                                 pipes[pipe_cnt].pipe.src.viewport_width = 1920;
    1399           0 :                         pipes[pipe_cnt].pipe.src.viewport_height = timing->v_addressable;
    1400           0 :                         if (pipes[pipe_cnt].pipe.src.viewport_height > 1080)
    1401           0 :                                 pipes[pipe_cnt].pipe.src.viewport_height = 1080;
    1402           0 :                         pipes[pipe_cnt].pipe.src.surface_height_y = pipes[pipe_cnt].pipe.src.viewport_height;
    1403           0 :                         pipes[pipe_cnt].pipe.src.surface_width_y = pipes[pipe_cnt].pipe.src.viewport_width;
    1404           0 :                         pipes[pipe_cnt].pipe.src.surface_height_c = pipes[pipe_cnt].pipe.src.viewport_height;
    1405           0 :                         pipes[pipe_cnt].pipe.src.surface_width_c = pipes[pipe_cnt].pipe.src.viewport_width;
    1406           0 :                         pipes[pipe_cnt].pipe.src.data_pitch = ((pipes[pipe_cnt].pipe.src.viewport_width + 255) / 256) * 256;
    1407           0 :                         pipes[pipe_cnt].pipe.src.source_format = dm_444_32;
    1408           0 :                         pipes[pipe_cnt].pipe.dest.recout_width = pipes[pipe_cnt].pipe.src.viewport_width; /*vp_width/hratio*/
    1409           0 :                         pipes[pipe_cnt].pipe.dest.recout_height = pipes[pipe_cnt].pipe.src.viewport_height; /*vp_height/vratio*/
    1410           0 :                         pipes[pipe_cnt].pipe.dest.full_recout_width = pipes[pipe_cnt].pipe.dest.recout_width;  /*when is_hsplit != 1*/
    1411           0 :                         pipes[pipe_cnt].pipe.dest.full_recout_height = pipes[pipe_cnt].pipe.dest.recout_height; /*when is_hsplit != 1*/
    1412           0 :                         pipes[pipe_cnt].pipe.scale_ratio_depth.lb_depth = dm_lb_16;
    1413           0 :                         pipes[pipe_cnt].pipe.scale_ratio_depth.hscl_ratio = 1.0;
    1414           0 :                         pipes[pipe_cnt].pipe.scale_ratio_depth.vscl_ratio = 1.0;
    1415           0 :                         pipes[pipe_cnt].pipe.scale_ratio_depth.scl_enable = 0; /*Lb only or Full scl*/
    1416           0 :                         pipes[pipe_cnt].pipe.scale_taps.htaps = 1;
    1417           0 :                         pipes[pipe_cnt].pipe.scale_taps.vtaps = 1;
    1418           0 :                         pipes[pipe_cnt].pipe.dest.vtotal_min = v_total;
    1419           0 :                         pipes[pipe_cnt].pipe.dest.vtotal_max = v_total;
    1420             : 
    1421           0 :                         if (pipes[pipe_cnt].pipe.dest.odm_combine == dm_odm_combine_mode_2to1) {
    1422           0 :                                 pipes[pipe_cnt].pipe.src.viewport_width /= 2;
    1423           0 :                                 pipes[pipe_cnt].pipe.dest.recout_width /= 2;
    1424           0 :                         } else if (pipes[pipe_cnt].pipe.dest.odm_combine == dm_odm_combine_mode_4to1) {
    1425           0 :                                 pipes[pipe_cnt].pipe.src.viewport_width /= 4;
    1426           0 :                                 pipes[pipe_cnt].pipe.dest.recout_width /= 4;
    1427             :                         }
    1428             :                 } else {
    1429           0 :                         struct dc_plane_state *pln = res_ctx->pipe_ctx[i].plane_state;
    1430           0 :                         struct scaler_data *scl = &res_ctx->pipe_ctx[i].plane_res.scl_data;
    1431             : 
    1432           0 :                         pipes[pipe_cnt].pipe.src.immediate_flip = pln->flip_immediate;
    1433           0 :                         pipes[pipe_cnt].pipe.src.is_hsplit = (res_ctx->pipe_ctx[i].bottom_pipe && res_ctx->pipe_ctx[i].bottom_pipe->plane_state == pln)
    1434           0 :                                         || (res_ctx->pipe_ctx[i].top_pipe && res_ctx->pipe_ctx[i].top_pipe->plane_state == pln)
    1435           0 :                                         || pipes[pipe_cnt].pipe.dest.odm_combine != dm_odm_combine_mode_disabled;
    1436             : 
    1437             :                         /* stereo is not split */
    1438           0 :                         if (pln->stereo_format == PLANE_STEREO_FORMAT_SIDE_BY_SIDE ||
    1439             :                             pln->stereo_format == PLANE_STEREO_FORMAT_TOP_AND_BOTTOM) {
    1440           0 :                                 pipes[pipe_cnt].pipe.src.is_hsplit = false;
    1441           0 :                                 pipes[pipe_cnt].pipe.src.hsplit_grp = res_ctx->pipe_ctx[i].pipe_idx;
    1442             :                         }
    1443             : 
    1444           0 :                         pipes[pipe_cnt].pipe.src.source_scan = pln->rotation == ROTATION_ANGLE_90
    1445           0 :                                         || pln->rotation == ROTATION_ANGLE_270 ? dm_vert : dm_horz;
    1446           0 :                         switch (pln->rotation) {
    1447             :                         case ROTATION_ANGLE_0:
    1448           0 :                                 pipes[pipe_cnt].pipe.src.source_rotation = dm_rotation_0;
    1449           0 :                                 break;
    1450             :                         case ROTATION_ANGLE_90:
    1451           0 :                                 pipes[pipe_cnt].pipe.src.source_rotation = dm_rotation_90;
    1452           0 :                                 break;
    1453             :                         case ROTATION_ANGLE_180:
    1454           0 :                                 pipes[pipe_cnt].pipe.src.source_rotation = dm_rotation_180;
    1455           0 :                                 break;
    1456             :                         case ROTATION_ANGLE_270:
    1457           0 :                                 pipes[pipe_cnt].pipe.src.source_rotation = dm_rotation_270;
    1458           0 :                                 break;
    1459             :                         default:
    1460             :                                 break;
    1461             :                         }
    1462           0 :                         pipes[pipe_cnt].pipe.src.viewport_y_y = scl->viewport.y;
    1463           0 :                         pipes[pipe_cnt].pipe.src.viewport_y_c = scl->viewport_c.y;
    1464           0 :                         pipes[pipe_cnt].pipe.src.viewport_x_y = scl->viewport.x;
    1465           0 :                         pipes[pipe_cnt].pipe.src.viewport_x_c = scl->viewport_c.x;
    1466           0 :                         pipes[pipe_cnt].pipe.src.viewport_width = scl->viewport.width;
    1467           0 :                         pipes[pipe_cnt].pipe.src.viewport_width_c = scl->viewport_c.width;
    1468           0 :                         pipes[pipe_cnt].pipe.src.viewport_height = scl->viewport.height;
    1469           0 :                         pipes[pipe_cnt].pipe.src.viewport_height_c = scl->viewport_c.height;
    1470           0 :                         pipes[pipe_cnt].pipe.src.viewport_width_max = pln->src_rect.width;
    1471           0 :                         pipes[pipe_cnt].pipe.src.viewport_height_max = pln->src_rect.height;
    1472           0 :                         pipes[pipe_cnt].pipe.src.surface_width_y = pln->plane_size.surface_size.width;
    1473           0 :                         pipes[pipe_cnt].pipe.src.surface_height_y = pln->plane_size.surface_size.height;
    1474           0 :                         pipes[pipe_cnt].pipe.src.surface_width_c = pln->plane_size.chroma_size.width;
    1475           0 :                         pipes[pipe_cnt].pipe.src.surface_height_c = pln->plane_size.chroma_size.height;
    1476           0 :                         if (pln->format == SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA
    1477             :                                         || pln->format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) {
    1478           0 :                                 pipes[pipe_cnt].pipe.src.data_pitch = pln->plane_size.surface_pitch;
    1479           0 :                                 pipes[pipe_cnt].pipe.src.data_pitch_c = pln->plane_size.chroma_pitch;
    1480           0 :                                 pipes[pipe_cnt].pipe.src.meta_pitch = pln->dcc.meta_pitch;
    1481           0 :                                 pipes[pipe_cnt].pipe.src.meta_pitch_c = pln->dcc.meta_pitch_c;
    1482             :                         } else {
    1483           0 :                                 pipes[pipe_cnt].pipe.src.data_pitch = pln->plane_size.surface_pitch;
    1484           0 :                                 pipes[pipe_cnt].pipe.src.meta_pitch = pln->dcc.meta_pitch;
    1485             :                         }
    1486           0 :                         pipes[pipe_cnt].pipe.src.dcc = pln->dcc.enable;
    1487           0 :                         pipes[pipe_cnt].pipe.dest.recout_width = scl->recout.width;
    1488           0 :                         pipes[pipe_cnt].pipe.dest.recout_height = scl->recout.height;
    1489           0 :                         pipes[pipe_cnt].pipe.dest.full_recout_height = scl->recout.height;
    1490           0 :                         pipes[pipe_cnt].pipe.dest.full_recout_width = scl->recout.width;
    1491           0 :                         if (pipes[pipe_cnt].pipe.dest.odm_combine == dm_odm_combine_mode_2to1)
    1492           0 :                                 pipes[pipe_cnt].pipe.dest.full_recout_width *= 2;
    1493           0 :                         else if (pipes[pipe_cnt].pipe.dest.odm_combine == dm_odm_combine_mode_4to1)
    1494           0 :                                 pipes[pipe_cnt].pipe.dest.full_recout_width *= 4;
    1495             :                         else {
    1496           0 :                                 struct pipe_ctx *split_pipe = res_ctx->pipe_ctx[i].bottom_pipe;
    1497             : 
    1498           0 :                                 while (split_pipe && split_pipe->plane_state == pln) {
    1499           0 :                                         pipes[pipe_cnt].pipe.dest.full_recout_width += split_pipe->plane_res.scl_data.recout.width;
    1500           0 :                                         split_pipe = split_pipe->bottom_pipe;
    1501             :                                 }
    1502           0 :                                 split_pipe = res_ctx->pipe_ctx[i].top_pipe;
    1503           0 :                                 while (split_pipe && split_pipe->plane_state == pln) {
    1504           0 :                                         pipes[pipe_cnt].pipe.dest.full_recout_width += split_pipe->plane_res.scl_data.recout.width;
    1505           0 :                                         split_pipe = split_pipe->top_pipe;
    1506             :                                 }
    1507             :                         }
    1508             : 
    1509           0 :                         pipes[pipe_cnt].pipe.scale_ratio_depth.lb_depth = dm_lb_16;
    1510           0 :                         pipes[pipe_cnt].pipe.scale_ratio_depth.hscl_ratio = (double) scl->ratios.horz.value / (1ULL<<32);
    1511           0 :                         pipes[pipe_cnt].pipe.scale_ratio_depth.hscl_ratio_c = (double) scl->ratios.horz_c.value / (1ULL<<32);
    1512           0 :                         pipes[pipe_cnt].pipe.scale_ratio_depth.vscl_ratio = (double) scl->ratios.vert.value / (1ULL<<32);
    1513           0 :                         pipes[pipe_cnt].pipe.scale_ratio_depth.vscl_ratio_c = (double) scl->ratios.vert_c.value / (1ULL<<32);
    1514           0 :                         pipes[pipe_cnt].pipe.scale_ratio_depth.scl_enable =
    1515           0 :                                         scl->ratios.vert.value != dc_fixpt_one.value
    1516           0 :                                         || scl->ratios.horz.value != dc_fixpt_one.value
    1517           0 :                                         || scl->ratios.vert_c.value != dc_fixpt_one.value
    1518           0 :                                         || scl->ratios.horz_c.value != dc_fixpt_one.value /*Lb only or Full scl*/
    1519           0 :                                         || dc->debug.always_scale; /*support always scale*/
    1520           0 :                         pipes[pipe_cnt].pipe.scale_taps.htaps = scl->taps.h_taps;
    1521           0 :                         pipes[pipe_cnt].pipe.scale_taps.htaps_c = scl->taps.h_taps_c;
    1522           0 :                         pipes[pipe_cnt].pipe.scale_taps.vtaps = scl->taps.v_taps;
    1523           0 :                         pipes[pipe_cnt].pipe.scale_taps.vtaps_c = scl->taps.v_taps_c;
    1524             : 
    1525           0 :                         pipes[pipe_cnt].pipe.src.macro_tile_size =
    1526           0 :                                         swizzle_mode_to_macro_tile_size(pln->tiling_info.gfx9.swizzle);
    1527           0 :                         swizzle_to_dml_params(pln->tiling_info.gfx9.swizzle,
    1528           0 :                                         &pipes[pipe_cnt].pipe.src.sw_mode);
    1529             : 
    1530           0 :                         switch (pln->format) {
    1531             :                         case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
    1532             :                         case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
    1533           0 :                                 pipes[pipe_cnt].pipe.src.source_format = dm_420_8;
    1534           0 :                                 break;
    1535             :                         case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr:
    1536             :                         case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb:
    1537           0 :                                 pipes[pipe_cnt].pipe.src.source_format = dm_420_10;
    1538           0 :                                 break;
    1539             :                         case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
    1540             :                         case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
    1541             :                         case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
    1542             :                         case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
    1543           0 :                                 pipes[pipe_cnt].pipe.src.source_format = dm_444_64;
    1544           0 :                                 break;
    1545             :                         case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555:
    1546             :                         case SURFACE_PIXEL_FORMAT_GRPH_RGB565:
    1547           0 :                                 pipes[pipe_cnt].pipe.src.source_format = dm_444_16;
    1548           0 :                                 break;
    1549             :                         case SURFACE_PIXEL_FORMAT_GRPH_PALETA_256_COLORS:
    1550           0 :                                 pipes[pipe_cnt].pipe.src.source_format = dm_444_8;
    1551           0 :                                 break;
    1552             :                         case SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA:
    1553           0 :                                 pipes[pipe_cnt].pipe.src.source_format = dm_rgbe_alpha;
    1554           0 :                                 break;
    1555             :                         default:
    1556           0 :                                 pipes[pipe_cnt].pipe.src.source_format = dm_444_32;
    1557           0 :                                 break;
    1558             :                         }
    1559             :                 }
    1560             : 
    1561           0 :                 pipe_cnt++;
    1562             :         }
    1563             : 
    1564             :         /* populate writeback information */
    1565           0 :         dc->res_pool->funcs->populate_dml_writeback_from_context(dc, res_ctx, pipes);
    1566             : 
    1567           0 :         return pipe_cnt;
    1568             : }
    1569             : 
    1570           0 : void dcn20_calculate_wm(
    1571             :                 struct dc *dc, struct dc_state *context,
    1572             :                 display_e2e_pipe_params_st *pipes,
    1573             :                 int *out_pipe_cnt,
    1574             :                 int *pipe_split_from,
    1575             :                 int vlevel,
    1576             :                 bool fast_validate)
    1577             : {
    1578             :         int pipe_cnt, i, pipe_idx;
    1579             : 
    1580           0 :         dc_assert_fp_enabled();
    1581             : 
    1582           0 :         for (i = 0, pipe_idx = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {
    1583           0 :                 if (!context->res_ctx.pipe_ctx[i].stream)
    1584           0 :                         continue;
    1585             : 
    1586           0 :                 pipes[pipe_cnt].clks_cfg.refclk_mhz = dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000.0;
    1587           0 :                 pipes[pipe_cnt].clks_cfg.dispclk_mhz = context->bw_ctx.dml.vba.RequiredDISPCLK[vlevel][context->bw_ctx.dml.vba.maxMpcComb];
    1588             : 
    1589           0 :                 if (pipe_split_from[i] < 0) {
    1590           0 :                         pipes[pipe_cnt].clks_cfg.dppclk_mhz =
    1591           0 :                                         context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx];
    1592           0 :                         if (context->bw_ctx.dml.vba.BlendingAndTiming[pipe_idx] == pipe_idx)
    1593           0 :                                 pipes[pipe_cnt].pipe.dest.odm_combine =
    1594           0 :                                                 context->bw_ctx.dml.vba.ODMCombineEnabled[pipe_idx];
    1595             :                         else
    1596           0 :                                 pipes[pipe_cnt].pipe.dest.odm_combine = 0;
    1597           0 :                         pipe_idx++;
    1598             :                 } else {
    1599           0 :                         pipes[pipe_cnt].clks_cfg.dppclk_mhz =
    1600           0 :                                         context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_split_from[i]];
    1601           0 :                         if (context->bw_ctx.dml.vba.BlendingAndTiming[pipe_split_from[i]] == pipe_split_from[i])
    1602           0 :                                 pipes[pipe_cnt].pipe.dest.odm_combine =
    1603           0 :                                                 context->bw_ctx.dml.vba.ODMCombineEnabled[pipe_split_from[i]];
    1604             :                         else
    1605           0 :                                 pipes[pipe_cnt].pipe.dest.odm_combine = 0;
    1606             :                 }
    1607             : 
    1608           0 :                 if (dc->config.forced_clocks) {
    1609           0 :                         pipes[pipe_cnt].clks_cfg.dispclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dispclk_mhz;
    1610           0 :                         pipes[pipe_cnt].clks_cfg.dppclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dppclk_mhz;
    1611             :                 }
    1612           0 :                 if (dc->debug.min_disp_clk_khz > pipes[pipe_cnt].clks_cfg.dispclk_mhz * 1000)
    1613           0 :                         pipes[pipe_cnt].clks_cfg.dispclk_mhz = dc->debug.min_disp_clk_khz / 1000.0;
    1614           0 :                 if (dc->debug.min_dpp_clk_khz > pipes[pipe_cnt].clks_cfg.dppclk_mhz * 1000)
    1615           0 :                         pipes[pipe_cnt].clks_cfg.dppclk_mhz = dc->debug.min_dpp_clk_khz / 1000.0;
    1616             : 
    1617           0 :                 pipe_cnt++;
    1618             :         }
    1619             : 
    1620           0 :         if (pipe_cnt != pipe_idx) {
    1621           0 :                 if (dc->res_pool->funcs->populate_dml_pipes)
    1622           0 :                         pipe_cnt = dc->res_pool->funcs->populate_dml_pipes(dc,
    1623             :                                 context, pipes, fast_validate);
    1624             :                 else
    1625           0 :                         pipe_cnt = dcn20_populate_dml_pipes_from_context(dc,
    1626             :                                 context, pipes, fast_validate);
    1627             :         }
    1628             : 
    1629           0 :         *out_pipe_cnt = pipe_cnt;
    1630             : 
    1631           0 :         pipes[0].clks_cfg.voltage = vlevel;
    1632           0 :         pipes[0].clks_cfg.dcfclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel].dcfclk_mhz;
    1633           0 :         pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel].socclk_mhz;
    1634             : 
    1635             :         /* only pipe 0 is read for voltage and dcf/soc clocks */
    1636           0 :         if (vlevel < 1) {
    1637           0 :                 pipes[0].clks_cfg.voltage = 1;
    1638           0 :                 pipes[0].clks_cfg.dcfclk_mhz = context->bw_ctx.dml.soc.clock_limits[1].dcfclk_mhz;
    1639           0 :                 pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[1].socclk_mhz;
    1640             :         }
    1641           0 :         context->bw_ctx.bw.dcn.watermarks.b.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
    1642           0 :         context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
    1643           0 :         context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
    1644           0 :         context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
    1645           0 :         context->bw_ctx.bw.dcn.watermarks.b.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
    1646           0 :         context->bw_ctx.bw.dcn.watermarks.b.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
    1647           0 :         context->bw_ctx.bw.dcn.watermarks.b.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
    1648           0 :         context->bw_ctx.bw.dcn.watermarks.b.urgent_latency_ns = get_urgent_latency(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
    1649             : 
    1650           0 :         if (vlevel < 2) {
    1651           0 :                 pipes[0].clks_cfg.voltage = 2;
    1652           0 :                 pipes[0].clks_cfg.dcfclk_mhz = context->bw_ctx.dml.soc.clock_limits[2].dcfclk_mhz;
    1653           0 :                 pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[2].socclk_mhz;
    1654             :         }
    1655           0 :         context->bw_ctx.bw.dcn.watermarks.c.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
    1656           0 :         context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
    1657           0 :         context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
    1658           0 :         context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
    1659           0 :         context->bw_ctx.bw.dcn.watermarks.c.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
    1660           0 :         context->bw_ctx.bw.dcn.watermarks.c.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
    1661           0 :         context->bw_ctx.bw.dcn.watermarks.c.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
    1662             : 
    1663           0 :         if (vlevel < 3) {
    1664           0 :                 pipes[0].clks_cfg.voltage = 3;
    1665           0 :                 pipes[0].clks_cfg.dcfclk_mhz = context->bw_ctx.dml.soc.clock_limits[2].dcfclk_mhz;
    1666           0 :                 pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[2].socclk_mhz;
    1667             :         }
    1668           0 :         context->bw_ctx.bw.dcn.watermarks.d.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
    1669           0 :         context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
    1670           0 :         context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
    1671           0 :         context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
    1672           0 :         context->bw_ctx.bw.dcn.watermarks.d.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
    1673           0 :         context->bw_ctx.bw.dcn.watermarks.d.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
    1674           0 :         context->bw_ctx.bw.dcn.watermarks.d.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
    1675             : 
    1676           0 :         pipes[0].clks_cfg.voltage = vlevel;
    1677           0 :         pipes[0].clks_cfg.dcfclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel].dcfclk_mhz;
    1678           0 :         pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel].socclk_mhz;
    1679           0 :         context->bw_ctx.bw.dcn.watermarks.a.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
    1680           0 :         context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
    1681           0 :         context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
    1682           0 :         context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
    1683           0 :         context->bw_ctx.bw.dcn.watermarks.a.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
    1684           0 :         context->bw_ctx.bw.dcn.watermarks.a.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
    1685           0 :         context->bw_ctx.bw.dcn.watermarks.a.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
    1686           0 : }
    1687             : 
    1688           0 : void dcn20_update_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_st *bb,
    1689             :                 struct pp_smu_nv_clock_table *max_clocks, unsigned int *uclk_states, unsigned int num_states)
    1690             : {
    1691           0 :         int num_calculated_states = 0;
    1692           0 :         int min_dcfclk = 0;
    1693             :         int i;
    1694             : 
    1695           0 :         dc_assert_fp_enabled();
    1696             : 
    1697           0 :         if (num_states == 0)
    1698             :                 return;
    1699             : 
    1700           0 :         memset(bb->clock_limits, 0, sizeof(bb->clock_limits));
    1701             : 
    1702           0 :         if (dc->bb_overrides.min_dcfclk_mhz > 0) {
    1703             :                 min_dcfclk = dc->bb_overrides.min_dcfclk_mhz;
    1704             :         } else {
    1705           0 :                 if (ASICREV_IS_NAVI12_P(dc->ctx->asic_id.hw_internal_rev))
    1706             :                         min_dcfclk = 310;
    1707             :                 else
    1708             :                         // Accounting for SOC/DCF relationship, we can go as high as
    1709             :                         // 506Mhz in Vmin.
    1710           0 :                         min_dcfclk = 506;
    1711             :         }
    1712             : 
    1713           0 :         for (i = 0; i < num_states; i++) {
    1714             :                 int min_fclk_required_by_uclk;
    1715           0 :                 bb->clock_limits[i].state = i;
    1716           0 :                 bb->clock_limits[i].dram_speed_mts = uclk_states[i] * 16 / 1000;
    1717             : 
    1718             :                 // FCLK:UCLK ratio is 1.08
    1719           0 :                 min_fclk_required_by_uclk = div_u64(((unsigned long long)uclk_states[i]) * 1080,
    1720             :                         1000000);
    1721             : 
    1722           0 :                 bb->clock_limits[i].fabricclk_mhz = (min_fclk_required_by_uclk < min_dcfclk) ?
    1723           0 :                                 min_dcfclk : min_fclk_required_by_uclk;
    1724             : 
    1725           0 :                 bb->clock_limits[i].socclk_mhz = (bb->clock_limits[i].fabricclk_mhz > max_clocks->socClockInKhz / 1000) ?
    1726           0 :                                 max_clocks->socClockInKhz / 1000 : bb->clock_limits[i].fabricclk_mhz;
    1727             : 
    1728           0 :                 bb->clock_limits[i].dcfclk_mhz = (bb->clock_limits[i].fabricclk_mhz > max_clocks->dcfClockInKhz / 1000) ?
    1729           0 :                                 max_clocks->dcfClockInKhz / 1000 : bb->clock_limits[i].fabricclk_mhz;
    1730             : 
    1731           0 :                 bb->clock_limits[i].dispclk_mhz = max_clocks->displayClockInKhz / 1000;
    1732           0 :                 bb->clock_limits[i].dppclk_mhz = max_clocks->displayClockInKhz / 1000;
    1733           0 :                 bb->clock_limits[i].dscclk_mhz = max_clocks->displayClockInKhz / (1000 * 3);
    1734             : 
    1735           0 :                 bb->clock_limits[i].phyclk_mhz = max_clocks->phyClockInKhz / 1000;
    1736             : 
    1737           0 :                 num_calculated_states++;
    1738             :         }
    1739             : 
    1740           0 :         bb->clock_limits[num_calculated_states - 1].socclk_mhz = max_clocks->socClockInKhz / 1000;
    1741           0 :         bb->clock_limits[num_calculated_states - 1].fabricclk_mhz = max_clocks->socClockInKhz / 1000;
    1742           0 :         bb->clock_limits[num_calculated_states - 1].dcfclk_mhz = max_clocks->dcfClockInKhz / 1000;
    1743             : 
    1744           0 :         bb->num_states = num_calculated_states;
    1745             : 
    1746             :         // Duplicate the last state, DML always an extra state identical to max state to work
    1747           0 :         memcpy(&bb->clock_limits[num_calculated_states], &bb->clock_limits[num_calculated_states - 1], sizeof(struct _vcs_dpi_voltage_scaling_st));
    1748           0 :         bb->clock_limits[num_calculated_states].state = bb->num_states;
    1749             : }
    1750             : 
    1751           3 : void dcn20_cap_soc_clocks(
    1752             :                 struct _vcs_dpi_soc_bounding_box_st *bb,
    1753             :                 struct pp_smu_nv_clock_table max_clocks)
    1754             : {
    1755             :         int i;
    1756             : 
    1757           3 :         dc_assert_fp_enabled();
    1758             : 
    1759             :         // First pass - cap all clocks higher than the reported max
    1760          12 :         for (i = 0; i < bb->num_states; i++) {
    1761           9 :                 if ((bb->clock_limits[i].dcfclk_mhz > (max_clocks.dcfClockInKhz / 1000))
    1762           1 :                                 && max_clocks.dcfClockInKhz != 0)
    1763           0 :                         bb->clock_limits[i].dcfclk_mhz = (max_clocks.dcfClockInKhz / 1000);
    1764             : 
    1765           9 :                 if ((bb->clock_limits[i].dram_speed_mts > (max_clocks.uClockInKhz / 1000) * 16)
    1766           3 :                                                 && max_clocks.uClockInKhz != 0)
    1767           2 :                         bb->clock_limits[i].dram_speed_mts = (max_clocks.uClockInKhz / 1000) * 16;
    1768             : 
    1769           9 :                 if ((bb->clock_limits[i].fabricclk_mhz > (max_clocks.fabricClockInKhz / 1000))
    1770           9 :                                                 && max_clocks.fabricClockInKhz != 0)
    1771           0 :                         bb->clock_limits[i].fabricclk_mhz = (max_clocks.fabricClockInKhz / 1000);
    1772             : 
    1773           9 :                 if ((bb->clock_limits[i].dispclk_mhz > (max_clocks.displayClockInKhz / 1000))
    1774           1 :                                                 && max_clocks.displayClockInKhz != 0)
    1775           0 :                         bb->clock_limits[i].dispclk_mhz = (max_clocks.displayClockInKhz / 1000);
    1776             : 
    1777           9 :                 if ((bb->clock_limits[i].dppclk_mhz > (max_clocks.dppClockInKhz / 1000))
    1778           9 :                                                 && max_clocks.dppClockInKhz != 0)
    1779           0 :                         bb->clock_limits[i].dppclk_mhz = (max_clocks.dppClockInKhz / 1000);
    1780             : 
    1781           9 :                 if ((bb->clock_limits[i].phyclk_mhz > (max_clocks.phyClockInKhz / 1000))
    1782           1 :                                                 && max_clocks.phyClockInKhz != 0)
    1783           0 :                         bb->clock_limits[i].phyclk_mhz = (max_clocks.phyClockInKhz / 1000);
    1784             : 
    1785           9 :                 if ((bb->clock_limits[i].socclk_mhz > (max_clocks.socClockInKhz / 1000))
    1786           1 :                                                 && max_clocks.socClockInKhz != 0)
    1787           0 :                         bb->clock_limits[i].socclk_mhz = (max_clocks.socClockInKhz / 1000);
    1788             : 
    1789           9 :                 if ((bb->clock_limits[i].dscclk_mhz > (max_clocks.dscClockInKhz / 1000))
    1790           9 :                                                 && max_clocks.dscClockInKhz != 0)
    1791           0 :                         bb->clock_limits[i].dscclk_mhz = (max_clocks.dscClockInKhz / 1000);
    1792             :         }
    1793             : 
    1794             :         // Second pass - remove all duplicate clock states
    1795          10 :         for (i = bb->num_states - 1; i > 1; i--) {
    1796           4 :                 bool duplicate = true;
    1797             : 
    1798           4 :                 if (bb->clock_limits[i-1].dcfclk_mhz != bb->clock_limits[i].dcfclk_mhz)
    1799           3 :                         duplicate = false;
    1800           4 :                 if (bb->clock_limits[i-1].dispclk_mhz != bb->clock_limits[i].dispclk_mhz)
    1801           0 :                         duplicate = false;
    1802           4 :                 if (bb->clock_limits[i-1].dppclk_mhz != bb->clock_limits[i].dppclk_mhz)
    1803           0 :                         duplicate = false;
    1804           4 :                 if (bb->clock_limits[i-1].dram_speed_mts != bb->clock_limits[i].dram_speed_mts)
    1805           3 :                         duplicate = false;
    1806           4 :                 if (bb->clock_limits[i-1].dscclk_mhz != bb->clock_limits[i].dscclk_mhz)
    1807           0 :                         duplicate = false;
    1808           4 :                 if (bb->clock_limits[i-1].fabricclk_mhz != bb->clock_limits[i].fabricclk_mhz)
    1809           3 :                         duplicate = false;
    1810           4 :                 if (bb->clock_limits[i-1].phyclk_mhz != bb->clock_limits[i].phyclk_mhz)
    1811           0 :                         duplicate = false;
    1812           4 :                 if (bb->clock_limits[i-1].socclk_mhz != bb->clock_limits[i].socclk_mhz)
    1813           3 :                         duplicate = false;
    1814             : 
    1815           4 :                 if (duplicate)
    1816           1 :                         bb->num_states--;
    1817             :         }
    1818           3 : }
    1819             : 
    1820           0 : void dcn20_patch_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_st *bb)
    1821             : {
    1822           0 :         dc_assert_fp_enabled();
    1823             : 
    1824           0 :         if ((int)(bb->sr_exit_time_us * 1000) != dc->bb_overrides.sr_exit_time_ns
    1825           0 :                         && dc->bb_overrides.sr_exit_time_ns) {
    1826           0 :                 bb->sr_exit_time_us = dc->bb_overrides.sr_exit_time_ns / 1000.0;
    1827             :         }
    1828             : 
    1829           0 :         if ((int)(bb->sr_enter_plus_exit_time_us * 1000)
    1830           0 :                                 != dc->bb_overrides.sr_enter_plus_exit_time_ns
    1831           0 :                         && dc->bb_overrides.sr_enter_plus_exit_time_ns) {
    1832           0 :                 bb->sr_enter_plus_exit_time_us =
    1833           0 :                                 dc->bb_overrides.sr_enter_plus_exit_time_ns / 1000.0;
    1834             :         }
    1835             : 
    1836           0 :         if ((int)(bb->urgent_latency_us * 1000) != dc->bb_overrides.urgent_latency_ns
    1837           0 :                         && dc->bb_overrides.urgent_latency_ns) {
    1838           0 :                 bb->urgent_latency_us = dc->bb_overrides.urgent_latency_ns / 1000.0;
    1839             :         }
    1840             : 
    1841           0 :         if ((int)(bb->dram_clock_change_latency_us * 1000)
    1842           0 :                                 != dc->bb_overrides.dram_clock_change_latency_ns
    1843           0 :                         && dc->bb_overrides.dram_clock_change_latency_ns) {
    1844           0 :                 bb->dram_clock_change_latency_us =
    1845           0 :                                 dc->bb_overrides.dram_clock_change_latency_ns / 1000.0;
    1846             :         }
    1847             : 
    1848           0 :         if ((int)(bb->dummy_pstate_latency_us * 1000)
    1849           0 :                                 != dc->bb_overrides.dummy_clock_change_latency_ns
    1850           0 :                         && dc->bb_overrides.dummy_clock_change_latency_ns) {
    1851           0 :                 bb->dummy_pstate_latency_us =
    1852           0 :                                 dc->bb_overrides.dummy_clock_change_latency_ns / 1000.0;
    1853             :         }
    1854           0 : }
    1855             : 
    1856           0 : static bool dcn20_validate_bandwidth_internal(struct dc *dc, struct dc_state *context,
    1857             :                 bool fast_validate)
    1858             : {
    1859           0 :         bool out = false;
    1860             : 
    1861           0 :         BW_VAL_TRACE_SETUP();
    1862             : 
    1863           0 :         int vlevel = 0;
    1864             :         int pipe_split_from[MAX_PIPES];
    1865           0 :         int pipe_cnt = 0;
    1866           0 :         display_e2e_pipe_params_st *pipes = kzalloc(dc->res_pool->pipe_count * sizeof(display_e2e_pipe_params_st), GFP_ATOMIC);
    1867             :         DC_LOGGER_INIT(dc->ctx->logger);
    1868             : 
    1869           0 :         BW_VAL_TRACE_COUNT();
    1870             : 
    1871           0 :         out = dcn20_fast_validate_bw(dc, context, pipes, &pipe_cnt, pipe_split_from, &vlevel, fast_validate);
    1872             : 
    1873           0 :         if (pipe_cnt == 0)
    1874             :                 goto validate_out;
    1875             : 
    1876           0 :         if (!out)
    1877             :                 goto validate_fail;
    1878             : 
    1879           0 :         BW_VAL_TRACE_END_VOLTAGE_LEVEL();
    1880             : 
    1881           0 :         if (fast_validate) {
    1882           0 :                 BW_VAL_TRACE_SKIP(fast);
    1883             :                 goto validate_out;
    1884             :         }
    1885             : 
    1886           0 :         dcn20_calculate_wm(dc, context, pipes, &pipe_cnt, pipe_split_from, vlevel, fast_validate);
    1887           0 :         dcn20_calculate_dlg_params(dc, context, pipes, pipe_cnt, vlevel);
    1888             : 
    1889           0 :         BW_VAL_TRACE_END_WATERMARKS();
    1890             : 
    1891             :         goto validate_out;
    1892             : 
    1893             : validate_fail:
    1894           0 :         DC_LOG_WARNING("Mode Validation Warning: %s failed validation.\n",
    1895             :                 dml_get_status_message(context->bw_ctx.dml.vba.ValidationStatus[context->bw_ctx.dml.vba.soc.num_states]));
    1896             : 
    1897           0 :         BW_VAL_TRACE_SKIP(fail);
    1898             :         out = false;
    1899             : 
    1900             : validate_out:
    1901           0 :         kfree(pipes);
    1902             : 
    1903           0 :         BW_VAL_TRACE_FINISH();
    1904             : 
    1905           0 :         return out;
    1906             : }
    1907             : 
    1908           0 : bool dcn20_validate_bandwidth_fp(struct dc *dc,
    1909             :                                 struct dc_state *context,
    1910             :                                 bool fast_validate)
    1911             : {
    1912           0 :        bool voltage_supported = false;
    1913           0 :        bool full_pstate_supported = false;
    1914           0 :        bool dummy_pstate_supported = false;
    1915             :        double p_state_latency_us;
    1916             : 
    1917           0 :        dc_assert_fp_enabled();
    1918             : 
    1919           0 :        p_state_latency_us = context->bw_ctx.dml.soc.dram_clock_change_latency_us;
    1920           0 :        context->bw_ctx.dml.soc.disable_dram_clock_change_vactive_support =
    1921           0 :                dc->debug.disable_dram_clock_change_vactive_support;
    1922           0 :        context->bw_ctx.dml.soc.allow_dram_clock_one_display_vactive =
    1923           0 :                dc->debug.enable_dram_clock_change_one_display_vactive;
    1924             : 
    1925             :        /*Unsafe due to current pipe merge and split logic*/
    1926           0 :        ASSERT(context != dc->current_state);
    1927             : 
    1928           0 :        if (fast_validate) {
    1929           0 :                return dcn20_validate_bandwidth_internal(dc, context, true);
    1930             :        }
    1931             : 
    1932             :        // Best case, we support full UCLK switch latency
    1933           0 :        voltage_supported = dcn20_validate_bandwidth_internal(dc, context, false);
    1934           0 :        full_pstate_supported = context->bw_ctx.bw.dcn.clk.p_state_change_support;
    1935             : 
    1936           0 :        if (context->bw_ctx.dml.soc.dummy_pstate_latency_us == 0 ||
    1937           0 :                (voltage_supported && full_pstate_supported)) {
    1938             :                context->bw_ctx.bw.dcn.clk.p_state_change_support = full_pstate_supported;
    1939             :                goto restore_dml_state;
    1940             :        }
    1941             : 
    1942             :        // Fallback: Try to only support G6 temperature read latency
    1943           0 :        context->bw_ctx.dml.soc.dram_clock_change_latency_us = context->bw_ctx.dml.soc.dummy_pstate_latency_us;
    1944             : 
    1945           0 :        voltage_supported = dcn20_validate_bandwidth_internal(dc, context, false);
    1946           0 :        dummy_pstate_supported = context->bw_ctx.bw.dcn.clk.p_state_change_support;
    1947             : 
    1948           0 :        if (voltage_supported && (dummy_pstate_supported || !(context->stream_count))) {
    1949           0 :                context->bw_ctx.bw.dcn.clk.p_state_change_support = false;
    1950           0 :                goto restore_dml_state;
    1951             :        }
    1952             : 
    1953             :        // ERROR: fallback is supposed to always work.
    1954           0 :        ASSERT(false);
    1955             : 
    1956             : restore_dml_state:
    1957           0 :        context->bw_ctx.dml.soc.dram_clock_change_latency_us = p_state_latency_us;
    1958           0 :        return voltage_supported;
    1959             : }
    1960             : 
    1961           0 : void dcn20_fpu_set_wm_ranges(int i,
    1962             :                             struct pp_smu_wm_range_sets *ranges,
    1963             :                             struct _vcs_dpi_soc_bounding_box_st *loaded_bb)
    1964             : {
    1965           0 :        dc_assert_fp_enabled();
    1966             : 
    1967           0 :        ranges->reader_wm_sets[i].min_fill_clk_mhz = (i > 0) ? (loaded_bb->clock_limits[i - 1].dram_speed_mts / 16) + 1 : 0;
    1968           0 :        ranges->reader_wm_sets[i].max_fill_clk_mhz = loaded_bb->clock_limits[i].dram_speed_mts / 16;
    1969           0 : }
    1970             : 
    1971           0 : void dcn20_fpu_adjust_dppclk(struct vba_vars_st *v,
    1972             :                             int vlevel,
    1973             :                             int max_mpc_comb,
    1974             :                             int pipe_idx,
    1975             :                             bool is_validating_bw)
    1976             : {
    1977           0 :        dc_assert_fp_enabled();
    1978             : 
    1979           0 :        if (is_validating_bw)
    1980           0 :                v->RequiredDPPCLK[vlevel][max_mpc_comb][pipe_idx] *= 2;
    1981             :        else
    1982           0 :                v->RequiredDPPCLK[vlevel][max_mpc_comb][pipe_idx] /= 2;
    1983           0 : }
    1984             : 
    1985           0 : int dcn21_populate_dml_pipes_from_context(struct dc *dc,
    1986             :                                           struct dc_state *context,
    1987             :                                           display_e2e_pipe_params_st *pipes,
    1988             :                                           bool fast_validate)
    1989             : {
    1990             :         uint32_t pipe_cnt;
    1991             :         int i;
    1992             : 
    1993           0 :         dc_assert_fp_enabled();
    1994             : 
    1995           0 :         pipe_cnt = dcn20_populate_dml_pipes_from_context(dc, context, pipes, fast_validate);
    1996             : 
    1997           0 :         for (i = 0; i < pipe_cnt; i++) {
    1998             : 
    1999           0 :                 pipes[i].pipe.src.hostvm = dc->res_pool->hubbub->riommu_active;
    2000           0 :                 pipes[i].pipe.src.gpuvm = 1;
    2001             :         }
    2002             : 
    2003           0 :         return pipe_cnt;
    2004             : }
    2005             : 
    2006           0 : static void patch_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_st *bb)
    2007             : {
    2008             :         int i;
    2009             : 
    2010           0 :         if (dc->bb_overrides.sr_exit_time_ns) {
    2011           0 :                 for (i = 0; i < WM_SET_COUNT; i++) {
    2012           0 :                           dc->clk_mgr->bw_params->wm_table.entries[i].sr_exit_time_us =
    2013           0 :                                           dc->bb_overrides.sr_exit_time_ns / 1000.0;
    2014             :                 }
    2015             :         }
    2016             : 
    2017           0 :         if (dc->bb_overrides.sr_enter_plus_exit_time_ns) {
    2018           0 :                 for (i = 0; i < WM_SET_COUNT; i++) {
    2019           0 :                           dc->clk_mgr->bw_params->wm_table.entries[i].sr_enter_plus_exit_time_us =
    2020           0 :                                           dc->bb_overrides.sr_enter_plus_exit_time_ns / 1000.0;
    2021             :                 }
    2022             :         }
    2023             : 
    2024           0 :         if (dc->bb_overrides.urgent_latency_ns) {
    2025           0 :                 bb->urgent_latency_us = dc->bb_overrides.urgent_latency_ns / 1000.0;
    2026             :         }
    2027             : 
    2028           0 :         if (dc->bb_overrides.dram_clock_change_latency_ns) {
    2029           0 :                 for (i = 0; i < WM_SET_COUNT; i++) {
    2030           0 :                         dc->clk_mgr->bw_params->wm_table.entries[i].pstate_latency_us =
    2031           0 :                                 dc->bb_overrides.dram_clock_change_latency_ns / 1000.0;
    2032             :                 }
    2033             :         }
    2034           0 : }
    2035             : 
    2036           0 : static void calculate_wm_set_for_vlevel(int vlevel,
    2037             :                                         struct wm_range_table_entry *table_entry,
    2038             :                                         struct dcn_watermarks *wm_set,
    2039             :                                         struct display_mode_lib *dml,
    2040             :                                         display_e2e_pipe_params_st *pipes,
    2041             :                                         int pipe_cnt)
    2042             : {
    2043           0 :         double dram_clock_change_latency_cached = dml->soc.dram_clock_change_latency_us;
    2044             : 
    2045           0 :         ASSERT(vlevel < dml->soc.num_states);
    2046             :         /* only pipe 0 is read for voltage and dcf/soc clocks */
    2047           0 :         pipes[0].clks_cfg.voltage = vlevel;
    2048           0 :         pipes[0].clks_cfg.dcfclk_mhz = dml->soc.clock_limits[vlevel].dcfclk_mhz;
    2049           0 :         pipes[0].clks_cfg.socclk_mhz = dml->soc.clock_limits[vlevel].socclk_mhz;
    2050             : 
    2051           0 :         dml->soc.dram_clock_change_latency_us = table_entry->pstate_latency_us;
    2052           0 :         dml->soc.sr_exit_time_us = table_entry->sr_exit_time_us;
    2053           0 :         dml->soc.sr_enter_plus_exit_time_us = table_entry->sr_enter_plus_exit_time_us;
    2054             : 
    2055           0 :         wm_set->urgent_ns = get_wm_urgent(dml, pipes, pipe_cnt) * 1000;
    2056           0 :         wm_set->cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(dml, pipes, pipe_cnt) * 1000;
    2057           0 :         wm_set->cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(dml, pipes, pipe_cnt) * 1000;
    2058           0 :         wm_set->cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(dml, pipes, pipe_cnt) * 1000;
    2059           0 :         wm_set->pte_meta_urgent_ns = get_wm_memory_trip(dml, pipes, pipe_cnt) * 1000;
    2060           0 :         wm_set->frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(dml, pipes, pipe_cnt) * 1000;
    2061           0 :         wm_set->frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(dml, pipes, pipe_cnt) * 1000;
    2062           0 :         wm_set->urgent_latency_ns = get_urgent_latency(dml, pipes, pipe_cnt) * 1000;
    2063           0 :         dml->soc.dram_clock_change_latency_us = dram_clock_change_latency_cached;
    2064           0 : }
    2065             : 
    2066           0 : static void dcn21_calculate_wm(struct dc *dc, struct dc_state *context,
    2067             :                         display_e2e_pipe_params_st *pipes,
    2068             :                         int *out_pipe_cnt,
    2069             :                         int *pipe_split_from,
    2070             :                         int vlevel_req,
    2071             :                         bool fast_validate)
    2072             : {
    2073             :         int pipe_cnt, i, pipe_idx;
    2074             :         int vlevel, vlevel_max;
    2075             :         struct wm_range_table_entry *table_entry;
    2076           0 :         struct clk_bw_params *bw_params = dc->clk_mgr->bw_params;
    2077             : 
    2078           0 :         ASSERT(bw_params);
    2079             : 
    2080           0 :         patch_bounding_box(dc, &context->bw_ctx.dml.soc);
    2081             : 
    2082           0 :         for (i = 0, pipe_idx = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {
    2083           0 :                         if (!context->res_ctx.pipe_ctx[i].stream)
    2084           0 :                                 continue;
    2085             : 
    2086           0 :                         pipes[pipe_cnt].clks_cfg.refclk_mhz = dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000.0;
    2087           0 :                         pipes[pipe_cnt].clks_cfg.dispclk_mhz = context->bw_ctx.dml.vba.RequiredDISPCLK[vlevel_req][context->bw_ctx.dml.vba.maxMpcComb];
    2088             : 
    2089           0 :                         if (pipe_split_from[i] < 0) {
    2090           0 :                                 pipes[pipe_cnt].clks_cfg.dppclk_mhz =
    2091           0 :                                                 context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel_req][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx];
    2092           0 :                                 if (context->bw_ctx.dml.vba.BlendingAndTiming[pipe_idx] == pipe_idx)
    2093           0 :                                         pipes[pipe_cnt].pipe.dest.odm_combine =
    2094           0 :                                                         context->bw_ctx.dml.vba.ODMCombineEnablePerState[vlevel_req][pipe_idx];
    2095             :                                 else
    2096           0 :                                         pipes[pipe_cnt].pipe.dest.odm_combine = 0;
    2097           0 :                                 pipe_idx++;
    2098             :                         } else {
    2099           0 :                                 pipes[pipe_cnt].clks_cfg.dppclk_mhz =
    2100           0 :                                                 context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel_req][context->bw_ctx.dml.vba.maxMpcComb][pipe_split_from[i]];
    2101           0 :                                 if (context->bw_ctx.dml.vba.BlendingAndTiming[pipe_split_from[i]] == pipe_split_from[i])
    2102           0 :                                         pipes[pipe_cnt].pipe.dest.odm_combine =
    2103           0 :                                                         context->bw_ctx.dml.vba.ODMCombineEnablePerState[vlevel_req][pipe_split_from[i]];
    2104             :                                 else
    2105           0 :                                         pipes[pipe_cnt].pipe.dest.odm_combine = 0;
    2106             :                         }
    2107           0 :                         pipe_cnt++;
    2108             :         }
    2109             : 
    2110           0 :         if (pipe_cnt != pipe_idx) {
    2111           0 :                 if (dc->res_pool->funcs->populate_dml_pipes)
    2112           0 :                         pipe_cnt = dc->res_pool->funcs->populate_dml_pipes(dc,
    2113             :                                 context, pipes, fast_validate);
    2114             :                 else
    2115           0 :                         pipe_cnt = dcn21_populate_dml_pipes_from_context(dc,
    2116             :                                 context, pipes, fast_validate);
    2117             :         }
    2118             : 
    2119           0 :         *out_pipe_cnt = pipe_cnt;
    2120             : 
    2121           0 :         vlevel_max = bw_params->clk_table.num_entries - 1;
    2122             : 
    2123             : 
    2124             :         /* WM Set D */
    2125           0 :         table_entry = &bw_params->wm_table.entries[WM_D];
    2126           0 :         if (table_entry->wm_type == WM_TYPE_RETRAINING)
    2127             :                 vlevel = 0;
    2128             :         else
    2129           0 :                 vlevel = vlevel_max;
    2130           0 :         calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.d,
    2131             :                                                 &context->bw_ctx.dml, pipes, pipe_cnt);
    2132             :         /* WM Set C */
    2133           0 :         table_entry = &bw_params->wm_table.entries[WM_C];
    2134           0 :         vlevel = MIN(MAX(vlevel_req, 3), vlevel_max);
    2135           0 :         calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.c,
    2136             :                                                 &context->bw_ctx.dml, pipes, pipe_cnt);
    2137             :         /* WM Set B */
    2138           0 :         table_entry = &bw_params->wm_table.entries[WM_B];
    2139           0 :         vlevel = MIN(MAX(vlevel_req, 2), vlevel_max);
    2140           0 :         calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.b,
    2141             :                                                 &context->bw_ctx.dml, pipes, pipe_cnt);
    2142             : 
    2143             :         /* WM Set A */
    2144           0 :         table_entry = &bw_params->wm_table.entries[WM_A];
    2145           0 :         vlevel = MIN(vlevel_req, vlevel_max);
    2146           0 :         calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.a,
    2147             :                                                 &context->bw_ctx.dml, pipes, pipe_cnt);
    2148           0 : }
    2149             : 
    2150           0 : bool dcn21_validate_bandwidth_fp(struct dc *dc,
    2151             :                                  struct dc_state *context,
    2152             :                                  bool fast_validate)
    2153             : {
    2154           0 :         bool out = false;
    2155             : 
    2156           0 :         BW_VAL_TRACE_SETUP();
    2157             : 
    2158           0 :         int vlevel = 0;
    2159             :         int pipe_split_from[MAX_PIPES];
    2160           0 :         int pipe_cnt = 0;
    2161           0 :         display_e2e_pipe_params_st *pipes = kzalloc(dc->res_pool->pipe_count * sizeof(display_e2e_pipe_params_st), GFP_ATOMIC);
    2162             :         DC_LOGGER_INIT(dc->ctx->logger);
    2163             : 
    2164           0 :         BW_VAL_TRACE_COUNT();
    2165             : 
    2166           0 :         dc_assert_fp_enabled();
    2167             : 
    2168             :         /*Unsafe due to current pipe merge and split logic*/
    2169           0 :         ASSERT(context != dc->current_state);
    2170             : 
    2171           0 :         out = dcn21_fast_validate_bw(dc, context, pipes, &pipe_cnt, pipe_split_from, &vlevel, fast_validate);
    2172             : 
    2173           0 :         if (pipe_cnt == 0)
    2174             :                 goto validate_out;
    2175             : 
    2176           0 :         if (!out)
    2177             :                 goto validate_fail;
    2178             : 
    2179           0 :         BW_VAL_TRACE_END_VOLTAGE_LEVEL();
    2180             : 
    2181           0 :         if (fast_validate) {
    2182           0 :                 BW_VAL_TRACE_SKIP(fast);
    2183             :                 goto validate_out;
    2184             :         }
    2185             : 
    2186           0 :         dcn21_calculate_wm(dc, context, pipes, &pipe_cnt, pipe_split_from, vlevel, fast_validate);
    2187           0 :         dcn20_calculate_dlg_params(dc, context, pipes, pipe_cnt, vlevel);
    2188             : 
    2189           0 :         BW_VAL_TRACE_END_WATERMARKS();
    2190             : 
    2191             :         goto validate_out;
    2192             : 
    2193             : validate_fail:
    2194           0 :         DC_LOG_WARNING("Mode Validation Warning: %s failed validation.\n",
    2195             :                         dml_get_status_message(context->bw_ctx.dml.vba.ValidationStatus[context->bw_ctx.dml.vba.soc.num_states]));
    2196             : 
    2197           0 :         BW_VAL_TRACE_SKIP(fail);
    2198             :         out = false;
    2199             : 
    2200             : validate_out:
    2201           0 :         kfree(pipes);
    2202             : 
    2203           0 :         BW_VAL_TRACE_FINISH();
    2204             : 
    2205           0 :         return out;
    2206             : }
    2207             : 
    2208           1 : static struct _vcs_dpi_voltage_scaling_st construct_low_pstate_lvl(struct clk_limit_table *clk_table, unsigned int high_voltage_lvl)
    2209             : {
    2210             :         struct _vcs_dpi_voltage_scaling_st low_pstate_lvl;
    2211             :         int i;
    2212             : 
    2213           1 :         low_pstate_lvl.state = 1;
    2214           1 :         low_pstate_lvl.dcfclk_mhz = clk_table->entries[0].dcfclk_mhz;
    2215           1 :         low_pstate_lvl.fabricclk_mhz = clk_table->entries[0].fclk_mhz;
    2216           1 :         low_pstate_lvl.socclk_mhz = clk_table->entries[0].socclk_mhz;
    2217           1 :         low_pstate_lvl.dram_speed_mts = clk_table->entries[0].memclk_mhz * 2;
    2218             : 
    2219           1 :         low_pstate_lvl.dispclk_mhz = dcn2_1_soc.clock_limits[high_voltage_lvl].dispclk_mhz;
    2220           1 :         low_pstate_lvl.dppclk_mhz = dcn2_1_soc.clock_limits[high_voltage_lvl].dppclk_mhz;
    2221           1 :         low_pstate_lvl.dram_bw_per_chan_gbps = dcn2_1_soc.clock_limits[high_voltage_lvl].dram_bw_per_chan_gbps;
    2222           1 :         low_pstate_lvl.dscclk_mhz = dcn2_1_soc.clock_limits[high_voltage_lvl].dscclk_mhz;
    2223           1 :         low_pstate_lvl.dtbclk_mhz = dcn2_1_soc.clock_limits[high_voltage_lvl].dtbclk_mhz;
    2224           1 :         low_pstate_lvl.phyclk_d18_mhz = dcn2_1_soc.clock_limits[high_voltage_lvl].phyclk_d18_mhz;
    2225           1 :         low_pstate_lvl.phyclk_mhz = dcn2_1_soc.clock_limits[high_voltage_lvl].phyclk_mhz;
    2226             : 
    2227           5 :         for (i = clk_table->num_entries; i > 1; i--)
    2228           4 :                 clk_table->entries[i] = clk_table->entries[i-1];
    2229           1 :         clk_table->entries[1] = clk_table->entries[0];
    2230           1 :         clk_table->num_entries++;
    2231             : 
    2232           1 :         return low_pstate_lvl;
    2233             : }
    2234             : 
    2235           1 : void dcn21_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params)
    2236             : {
    2237           1 :         struct _vcs_dpi_voltage_scaling_st *s = dc->scratch.update_bw_bounding_box.clock_limits;
    2238           1 :         struct dcn21_resource_pool *pool = TO_DCN21_RES_POOL(dc->res_pool);
    2239           1 :         struct clk_limit_table *clk_table = &bw_params->clk_table;
    2240           1 :         unsigned int i, closest_clk_lvl = 0, k = 0;
    2241             :         int j;
    2242             : 
    2243           1 :         dc_assert_fp_enabled();
    2244             : 
    2245           1 :         dcn2_1_ip.max_num_otg = pool->base.res_cap->num_timing_generator;
    2246           1 :         dcn2_1_ip.max_num_dpp = pool->base.pipe_count;
    2247           1 :         dcn2_1_soc.num_chans = bw_params->num_channels;
    2248             : 
    2249           1 :         ASSERT(clk_table->num_entries);
    2250             :         /* Copy dcn2_1_soc.clock_limits to clock_limits to avoid copying over null states later */
    2251           1 :         memcpy(s, dcn2_1_soc.clock_limits, sizeof(dcn2_1_soc.clock_limits));
    2252             : 
    2253           6 :         for (i = 0; i < clk_table->num_entries; i++) {
    2254             :                 /* loop backwards*/
    2255          38 :                 for (closest_clk_lvl = 0, j = dcn2_1_soc.num_states - 1; j >= 0; j--) {
    2256          35 :                         if ((unsigned int) dcn2_1_soc.clock_limits[j].dcfclk_mhz <= clk_table->entries[i].dcfclk_mhz) {
    2257           2 :                                 closest_clk_lvl = j;
    2258           2 :                                 break;
    2259             :                         }
    2260             :                 }
    2261             : 
    2262             :                 /* clk_table[1] is reserved for min DF PState.  skip here to fill in later. */
    2263           5 :                 if (i == 1)
    2264           1 :                         k++;
    2265             : 
    2266           5 :                 s[k].state = k;
    2267           5 :                 s[k].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz;
    2268           5 :                 s[k].fabricclk_mhz = clk_table->entries[i].fclk_mhz;
    2269           5 :                 s[k].socclk_mhz = clk_table->entries[i].socclk_mhz;
    2270           5 :                 s[k].dram_speed_mts = clk_table->entries[i].memclk_mhz * 2;
    2271             : 
    2272           5 :                 s[k].dispclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dispclk_mhz;
    2273           5 :                 s[k].dppclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dppclk_mhz;
    2274           5 :                 s[k].dram_bw_per_chan_gbps =
    2275           5 :                         dcn2_1_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps;
    2276           5 :                 s[k].dscclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dscclk_mhz;
    2277           5 :                 s[k].dtbclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dtbclk_mhz;
    2278           5 :                 s[k].phyclk_d18_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].phyclk_d18_mhz;
    2279           5 :                 s[k].phyclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].phyclk_mhz;
    2280             : 
    2281           5 :                 k++;
    2282             :         }
    2283             : 
    2284           1 :         memcpy(dcn2_1_soc.clock_limits, s, sizeof(dcn2_1_soc.clock_limits));
    2285             : 
    2286           1 :         if (clk_table->num_entries) {
    2287           1 :                 dcn2_1_soc.num_states = clk_table->num_entries + 1;
    2288             :                 /* fill in min DF PState */
    2289           1 :                 dcn2_1_soc.clock_limits[1] = construct_low_pstate_lvl(clk_table, closest_clk_lvl);
    2290             :                 /* duplicate last level */
    2291           1 :                 dcn2_1_soc.clock_limits[dcn2_1_soc.num_states] = dcn2_1_soc.clock_limits[dcn2_1_soc.num_states - 1];
    2292           1 :                 dcn2_1_soc.clock_limits[dcn2_1_soc.num_states].state = dcn2_1_soc.num_states;
    2293             :         }
    2294             : 
    2295           1 :         dml_init_instance(&dc->dml, &dcn2_1_soc, &dcn2_1_ip, DML_PROJECT_DCN21);
    2296           1 : }
    2297             : 
    2298           0 : void dcn21_clk_mgr_set_bw_params_wm_table(struct clk_bw_params *bw_params)
    2299             : {
    2300           0 :         dc_assert_fp_enabled();
    2301             : 
    2302           0 :         bw_params->wm_table.entries[WM_D].pstate_latency_us = LPDDR_MEM_RETRAIN_LATENCY;
    2303           0 :         bw_params->wm_table.entries[WM_D].wm_inst = WM_D;
    2304           0 :         bw_params->wm_table.entries[WM_D].wm_type = WM_TYPE_RETRAINING;
    2305           0 :         bw_params->wm_table.entries[WM_D].valid = true;
    2306           0 : }
    2307             : 
    2308           0 : void dcn201_populate_dml_writeback_from_context_fpu(struct dc *dc,
    2309             :                                                     struct resource_context *res_ctx,
    2310             :                                                     display_e2e_pipe_params_st *pipes)
    2311             : {
    2312             :         int pipe_cnt, i, j;
    2313             :         double max_calc_writeback_dispclk;
    2314             :         double writeback_dispclk;
    2315             :         struct writeback_st dout_wb;
    2316             : 
    2317           0 :         dc_assert_fp_enabled();
    2318             : 
    2319           0 :         for (i = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {
    2320           0 :                 struct dc_stream_state *stream = res_ctx->pipe_ctx[i].stream;
    2321             : 
    2322           0 :                 if (!stream)
    2323           0 :                         continue;
    2324           0 :                 max_calc_writeback_dispclk = 0;
    2325             : 
    2326             :                 /* Set writeback information */
    2327           0 :                 pipes[pipe_cnt].dout.wb_enable = 0;
    2328           0 :                 pipes[pipe_cnt].dout.num_active_wb = 0;
    2329           0 :                 for (j = 0; j < stream->num_wb_info; j++) {
    2330           0 :                         struct dc_writeback_info *wb_info = &stream->writeback_info[j];
    2331             : 
    2332           0 :                         if (wb_info->wb_enabled && wb_info->writeback_source_plane &&
    2333           0 :                                         (wb_info->writeback_source_plane == res_ctx->pipe_ctx[i].plane_state)) {
    2334           0 :                                 pipes[pipe_cnt].dout.wb_enable = 1;
    2335           0 :                                 pipes[pipe_cnt].dout.num_active_wb++;
    2336           0 :                                 dout_wb.wb_src_height = wb_info->dwb_params.cnv_params.crop_en ?
    2337           0 :                                         wb_info->dwb_params.cnv_params.crop_height :
    2338           0 :                                         wb_info->dwb_params.cnv_params.src_height;
    2339           0 :                                 dout_wb.wb_src_width = wb_info->dwb_params.cnv_params.crop_en ?
    2340           0 :                                         wb_info->dwb_params.cnv_params.crop_width :
    2341           0 :                                         wb_info->dwb_params.cnv_params.src_width;
    2342           0 :                                 dout_wb.wb_dst_width = wb_info->dwb_params.dest_width;
    2343           0 :                                 dout_wb.wb_dst_height = wb_info->dwb_params.dest_height;
    2344           0 :                                 dout_wb.wb_htaps_luma = wb_info->dwb_params.scaler_taps.h_taps;
    2345           0 :                                 dout_wb.wb_vtaps_luma = wb_info->dwb_params.scaler_taps.v_taps;
    2346           0 :                                 dout_wb.wb_htaps_chroma = wb_info->dwb_params.scaler_taps.h_taps_c;
    2347           0 :                                 dout_wb.wb_vtaps_chroma = wb_info->dwb_params.scaler_taps.v_taps_c;
    2348           0 :                                 dout_wb.wb_hratio = wb_info->dwb_params.cnv_params.crop_en ?
    2349           0 :                                         (double)wb_info->dwb_params.cnv_params.crop_width /
    2350           0 :                                                 (double)wb_info->dwb_params.dest_width :
    2351           0 :                                         (double)wb_info->dwb_params.cnv_params.src_width /
    2352           0 :                                                 (double)wb_info->dwb_params.dest_width;
    2353           0 :                                 dout_wb.wb_vratio = wb_info->dwb_params.cnv_params.crop_en ?
    2354           0 :                                         (double)wb_info->dwb_params.cnv_params.crop_height /
    2355           0 :                                                 (double)wb_info->dwb_params.dest_height :
    2356           0 :                                         (double)wb_info->dwb_params.cnv_params.src_height /
    2357           0 :                                                 (double)wb_info->dwb_params.dest_height;
    2358           0 :                                 if (wb_info->dwb_params.out_format == dwb_scaler_mode_yuv420) {
    2359           0 :                                         if (wb_info->dwb_params.output_depth == DWB_OUTPUT_PIXEL_DEPTH_8BPC)
    2360             :                                                 dout_wb.wb_pixel_format = dm_420_8;
    2361             :                                         else
    2362           0 :                                                 dout_wb.wb_pixel_format = dm_420_10;
    2363             :                                 } else
    2364             :                                         dout_wb.wb_pixel_format = dm_444_32;
    2365             : 
    2366             :                                 /* Workaround for cases where multiple writebacks are connected to same plane
    2367             :                                  * In which case, need to compute worst case and set the associated writeback parameters
    2368             :                                  * This workaround is necessary due to DML computation assuming only 1 set of writeback
    2369             :                                  * parameters per pipe */
    2370           0 :                                 writeback_dispclk = CalculateWriteBackDISPCLK(
    2371             :                                                 dout_wb.wb_pixel_format,
    2372             :                                                 pipes[pipe_cnt].pipe.dest.pixel_rate_mhz,
    2373             :                                                 dout_wb.wb_hratio,
    2374             :                                                 dout_wb.wb_vratio,
    2375             :                                                 dout_wb.wb_htaps_luma,
    2376             :                                                 dout_wb.wb_vtaps_luma,
    2377             :                                                 dout_wb.wb_htaps_chroma,
    2378             :                                                 dout_wb.wb_vtaps_chroma,
    2379             :                                                 dout_wb.wb_dst_width,
    2380             :                                                 pipes[pipe_cnt].pipe.dest.htotal,
    2381             :                                                 2);
    2382             : 
    2383           0 :                                 if (writeback_dispclk > max_calc_writeback_dispclk) {
    2384           0 :                                         max_calc_writeback_dispclk = writeback_dispclk;
    2385           0 :                                         pipes[pipe_cnt].dout.wb = dout_wb;
    2386             :                                 }
    2387             :                         }
    2388             :                 }
    2389             : 
    2390           0 :                 pipe_cnt++;
    2391             :         }
    2392             : 
    2393           0 : }

Generated by: LCOV version 1.14