Home | History | Annotate | Line # | Download | only in dcn20
      1 /*	$NetBSD: amdgpu_dcn20_resource.c,v 1.5 2023/07/20 21:48:49 riastradh Exp $	*/
      2 
      3 /*
      4 * Copyright 2016 Advanced Micro Devices, Inc.
      5  * Copyright 2019 Raptor Engineering, LLC
      6  *
      7  * Permission is hereby granted, free of charge, to any person obtaining a
      8  * copy of this software and associated documentation files (the "Software"),
      9  * to deal in the Software without restriction, including without limitation
     10  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     11  * and/or sell copies of the Software, and to permit persons to whom the
     12  * Software is furnished to do so, subject to the following conditions:
     13  *
     14  * The above copyright notice and this permission notice shall be included in
     15  * all copies or substantial portions of the Software.
     16  *
     17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     20  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
     21  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     22  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     23  * OTHER DEALINGS IN THE SOFTWARE.
     24  *
     25  * Authors: AMD
     26  *
     27  */
     28 
     29 #include <sys/cdefs.h>
     30 __KERNEL_RCSID(0, "$NetBSD: amdgpu_dcn20_resource.c,v 1.5 2023/07/20 21:48:49 riastradh Exp $");
     31 
     32 #include <linux/slab.h>
     33 
     34 #include "dm_services.h"
     35 #include "dc.h"
     36 
     37 #include "dcn20_init.h"
     38 
     39 #include "resource.h"
     40 #include "include/irq_service_interface.h"
     41 #include "dcn20/dcn20_resource.h"
     42 
     43 #include "dcn10/dcn10_hubp.h"
     44 #include "dcn10/dcn10_ipp.h"
     45 #include "dcn20_hubbub.h"
     46 #include "dcn20_mpc.h"
     47 #include "dcn20_hubp.h"
     48 #include "irq/dcn20/irq_service_dcn20.h"
     49 #include "dcn20_dpp.h"
     50 #include "dcn20_optc.h"
     51 #include "dcn20_hwseq.h"
     52 #include "dce110/dce110_hw_sequencer.h"
     53 #include "dcn10/dcn10_resource.h"
     54 #include "dcn20_opp.h"
     55 
     56 #include "dcn20_dsc.h"
     57 
     58 #include "dcn20_link_encoder.h"
     59 #include "dcn20_stream_encoder.h"
     60 #include "dce/dce_clock_source.h"
     61 #include "dce/dce_audio.h"
     62 #include "dce/dce_hwseq.h"
     63 #include "virtual/virtual_stream_encoder.h"
     64 #include "dce110/dce110_resource.h"
     65 #include "dml/display_mode_vba.h"
     66 #include "dcn20_dccg.h"
     67 #include "dcn20_vmid.h"
     68 #include "dc_link_ddc.h"
     69 
     70 #include "navi10_ip_offset.h"
     71 
     72 #include "dcn/dcn_2_0_0_offset.h"
     73 #include "dcn/dcn_2_0_0_sh_mask.h"
     74 #include "dpcs/dpcs_2_0_0_offset.h"
     75 #include "dpcs/dpcs_2_0_0_sh_mask.h"
     76 
     77 #include "nbio/nbio_2_3_offset.h"
     78 
     79 #include "dcn20/dcn20_dwb.h"
     80 #include "dcn20/dcn20_mmhubbub.h"
     81 
     82 #include "mmhub/mmhub_2_0_0_offset.h"
     83 #include "mmhub/mmhub_2_0_0_sh_mask.h"
     84 
     85 #include "reg_helper.h"
     86 #include "dce/dce_abm.h"
     87 #include "dce/dce_dmcu.h"
     88 #include "dce/dce_aux.h"
     89 #include "dce/dce_i2c.h"
     90 #include "vm_helper.h"
     91 
     92 #include "amdgpu_socbb.h"
     93 
     94 #define DC_LOGGER_INIT(logger)
     95 
     96 struct _vcs_dpi_ip_params_st dcn2_0_ip = {
     97 	.odm_capable = 1,
     98 	.gpuvm_enable = 0,
     99 	.hostvm_enable = 0,
    100 	.gpuvm_max_page_table_levels = 4,
    101 	.hostvm_max_page_table_levels = 4,
    102 	.hostvm_cached_page_table_levels = 0,
    103 	.pte_group_size_bytes = 2048,
    104 	.num_dsc = 6,
    105 	.rob_buffer_size_kbytes = 168,
    106 	.det_buffer_size_kbytes = 164,
    107 	.dpte_buffer_size_in_pte_reqs_luma = 84,
    108 	.pde_proc_buffer_size_64k_reqs = 48,
    109 	.dpp_output_buffer_pixels = 2560,
    110 	.opp_output_buffer_lines = 1,
    111 	.pixel_chunk_size_kbytes = 8,
    112 	.pte_chunk_size_kbytes = 2,
    113 	.meta_chunk_size_kbytes = 2,
    114 	.writeback_chunk_size_kbytes = 2,
    115 	.line_buffer_size_bits = 789504,
    116 	.is_line_buffer_bpp_fixed = 0,
    117 	.line_buffer_fixed_bpp = 0,
    118 	.dcc_supported = true,
    119 	.max_line_buffer_lines = 12,
    120 	.writeback_luma_buffer_size_kbytes = 12,
    121 	.writeback_chroma_buffer_size_kbytes = 8,
    122 	.writeback_chroma_line_buffer_width_pixels = 4,
    123 	.writeback_max_hscl_ratio = 1,
    124 	.writeback_max_vscl_ratio = 1,
    125 	.writeback_min_hscl_ratio = 1,
    126 	.writeback_min_vscl_ratio = 1,
    127 	.writeback_max_hscl_taps = 12,
    128 	.writeback_max_vscl_taps = 12,
    129 	.writeback_line_buffer_luma_buffer_size = 0,
    130 	.writeback_line_buffer_chroma_buffer_size = 14643,
    131 	.cursor_buffer_size = 8,
    132 	.cursor_chunk_size = 2,
    133 	.max_num_otg = 6,
    134 	.max_num_dpp = 6,
    135 	.max_num_wb = 1,
    136 	.max_dchub_pscl_bw_pix_per_clk = 4,
    137 	.max_pscl_lb_bw_pix_per_clk = 2,
    138 	.max_lb_vscl_bw_pix_per_clk = 4,
    139 	.max_vscl_hscl_bw_pix_per_clk = 4,
    140 	.max_hscl_ratio = 8,
    141 	.max_vscl_ratio = 8,
    142 	.hscl_mults = 4,
    143 	.vscl_mults = 4,
    144 	.max_hscl_taps = 8,
    145 	.max_vscl_taps = 8,
    146 	.dispclk_ramp_margin_percent = 1,
    147 	.underscan_factor = 1.10,
    148 	.min_vblank_lines = 32, //
    149 	.dppclk_delay_subtotal = 77, //
    150 	.dppclk_delay_scl_lb_only = 16,
    151 	.dppclk_delay_scl = 50,
    152 	.dppclk_delay_cnvc_formatter = 8,
    153 	.dppclk_delay_cnvc_cursor = 6,
    154 	.dispclk_delay_subtotal = 87, //
    155 	.dcfclk_cstate_latency = 10, // SRExitTime
    156 	.max_inter_dcn_tile_repeaters = 8,
    157 
    158 	.xfc_supported = true,
    159 	.xfc_fill_bw_overhead_percent = 10.0,
    160 	.xfc_fill_constant_bytes = 0,
    161 };
    162 
    163 struct _vcs_dpi_ip_params_st dcn2_0_nv14_ip = {
    164 	.odm_capable = 1,
    165 	.gpuvm_enable = 0,
    166 	.hostvm_enable = 0,
    167 	.gpuvm_max_page_table_levels = 4,
    168 	.hostvm_max_page_table_levels = 4,
    169 	.hostvm_cached_page_table_levels = 0,
    170 	.num_dsc = 5,
    171 	.rob_buffer_size_kbytes = 168,
    172 	.det_buffer_size_kbytes = 164,
    173 	.dpte_buffer_size_in_pte_reqs_luma = 84,
    174 	.dpte_buffer_size_in_pte_reqs_chroma = 42,//todo
    175 	.dpp_output_buffer_pixels = 2560,
    176 	.opp_output_buffer_lines = 1,
    177 	.pixel_chunk_size_kbytes = 8,
    178 	.pte_enable = 1,
    179 	.max_page_table_levels = 4,
    180 	.pte_chunk_size_kbytes = 2,
    181 	.meta_chunk_size_kbytes = 2,
    182 	.writeback_chunk_size_kbytes = 2,
    183 	.line_buffer_size_bits = 789504,
    184 	.is_line_buffer_bpp_fixed = 0,
    185 	.line_buffer_fixed_bpp = 0,
    186 	.dcc_supported = true,
    187 	.max_line_buffer_lines = 12,
    188 	.writeback_luma_buffer_size_kbytes = 12,
    189 	.writeback_chroma_buffer_size_kbytes = 8,
    190 	.writeback_chroma_line_buffer_width_pixels = 4,
    191 	.writeback_max_hscl_ratio = 1,
    192 	.writeback_max_vscl_ratio = 1,
    193 	.writeback_min_hscl_ratio = 1,
    194 	.writeback_min_vscl_ratio = 1,
    195 	.writeback_max_hscl_taps = 12,
    196 	.writeback_max_vscl_taps = 12,
    197 	.writeback_line_buffer_luma_buffer_size = 0,
    198 	.writeback_line_buffer_chroma_buffer_size = 14643,
    199 	.cursor_buffer_size = 8,
    200 	.cursor_chunk_size = 2,
    201 	.max_num_otg = 5,
    202 	.max_num_dpp = 5,
    203 	.max_num_wb = 1,
    204 	.max_dchub_pscl_bw_pix_per_clk = 4,
    205 	.max_pscl_lb_bw_pix_per_clk = 2,
    206 	.max_lb_vscl_bw_pix_per_clk = 4,
    207 	.max_vscl_hscl_bw_pix_per_clk = 4,
    208 	.max_hscl_ratio = 8,
    209 	.max_vscl_ratio = 8,
    210 	.hscl_mults = 4,
    211 	.vscl_mults = 4,
    212 	.max_hscl_taps = 8,
    213 	.max_vscl_taps = 8,
    214 	.dispclk_ramp_margin_percent = 1,
    215 	.underscan_factor = 1.10,
    216 	.min_vblank_lines = 32, //
    217 	.dppclk_delay_subtotal = 77, //
    218 	.dppclk_delay_scl_lb_only = 16,
    219 	.dppclk_delay_scl = 50,
    220 	.dppclk_delay_cnvc_formatter = 8,
    221 	.dppclk_delay_cnvc_cursor = 6,
    222 	.dispclk_delay_subtotal = 87, //
    223 	.dcfclk_cstate_latency = 10, // SRExitTime
    224 	.max_inter_dcn_tile_repeaters = 8,
    225 	.xfc_supported = true,
    226 	.xfc_fill_bw_overhead_percent = 10.0,
    227 	.xfc_fill_constant_bytes = 0,
    228 	.ptoi_supported = 0
    229 };
    230 
    231 struct _vcs_dpi_soc_bounding_box_st dcn2_0_soc = {
    232 	/* Defaults that get patched on driver load from firmware. */
    233 	.clock_limits = {
    234 			{
    235 				.state = 0,
    236 				.dcfclk_mhz = 560.0,
    237 				.fabricclk_mhz = 560.0,
    238 				.dispclk_mhz = 513.0,
    239 				.dppclk_mhz = 513.0,
    240 				.phyclk_mhz = 540.0,
    241 				.socclk_mhz = 560.0,
    242 				.dscclk_mhz = 171.0,
    243 				.dram_speed_mts = 8960.0,
    244 			},
    245 			{
    246 				.state = 1,
    247 				.dcfclk_mhz = 694.0,
    248 				.fabricclk_mhz = 694.0,
    249 				.dispclk_mhz = 642.0,
    250 				.dppclk_mhz = 642.0,
    251 				.phyclk_mhz = 600.0,
    252 				.socclk_mhz = 694.0,
    253 				.dscclk_mhz = 214.0,
    254 				.dram_speed_mts = 11104.0,
    255 			},
    256 			{
    257 				.state = 2,
    258 				.dcfclk_mhz = 875.0,
    259 				.fabricclk_mhz = 875.0,
    260 				.dispclk_mhz = 734.0,
    261 				.dppclk_mhz = 734.0,
    262 				.phyclk_mhz = 810.0,
    263 				.socclk_mhz = 875.0,
    264 				.dscclk_mhz = 245.0,
    265 				.dram_speed_mts = 14000.0,
    266 			},
    267 			{
    268 				.state = 3,
    269 				.dcfclk_mhz = 1000.0,
    270 				.fabricclk_mhz = 1000.0,
    271 				.dispclk_mhz = 1100.0,
    272 				.dppclk_mhz = 1100.0,
    273 				.phyclk_mhz = 810.0,
    274 				.socclk_mhz = 1000.0,
    275 				.dscclk_mhz = 367.0,
    276 				.dram_speed_mts = 16000.0,
    277 			},
    278 			{
    279 				.state = 4,
    280 				.dcfclk_mhz = 1200.0,
    281 				.fabricclk_mhz = 1200.0,
    282 				.dispclk_mhz = 1284.0,
    283 				.dppclk_mhz = 1284.0,
    284 				.phyclk_mhz = 810.0,
    285 				.socclk_mhz = 1200.0,
    286 				.dscclk_mhz = 428.0,
    287 				.dram_speed_mts = 16000.0,
    288 			},
    289 			/*Extra state, no dispclk ramping*/
    290 			{
    291 				.state = 5,
    292 				.dcfclk_mhz = 1200.0,
    293 				.fabricclk_mhz = 1200.0,
    294 				.dispclk_mhz = 1284.0,
    295 				.dppclk_mhz = 1284.0,
    296 				.phyclk_mhz = 810.0,
    297 				.socclk_mhz = 1200.0,
    298 				.dscclk_mhz = 428.0,
    299 				.dram_speed_mts = 16000.0,
    300 			},
    301 		},
    302 	.num_states = 5,
    303 	.sr_exit_time_us = 8.6,
    304 	.sr_enter_plus_exit_time_us = 10.9,
    305 	.urgent_latency_us = 4.0,
    306 	.urgent_latency_pixel_data_only_us = 4.0,
    307 	.urgent_latency_pixel_mixed_with_vm_data_us = 4.0,
    308 	.urgent_latency_vm_data_only_us = 4.0,
    309 	.urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096,
    310 	.urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096,
    311 	.urgent_out_of_order_return_per_channel_vm_only_bytes = 4096,
    312 	.pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 40.0,
    313 	.pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 40.0,
    314 	.pct_ideal_dram_sdp_bw_after_urgent_vm_only = 40.0,
    315 	.max_avg_sdp_bw_use_normal_percent = 40.0,
    316 	.max_avg_dram_bw_use_normal_percent = 40.0,
    317 	.writeback_latency_us = 12.0,
    318 	.ideal_dram_bw_after_urgent_percent = 40.0,
    319 	.max_request_size_bytes = 256,
    320 	.dram_channel_width_bytes = 2,
    321 	.fabric_datapath_to_dcn_data_return_bytes = 64,
    322 	.dcn_downspread_percent = 0.5,
    323 	.downspread_percent = 0.38,
    324 	.dram_page_open_time_ns = 50.0,
    325 	.dram_rw_turnaround_time_ns = 17.5,
    326 	.dram_return_buffer_per_channel_bytes = 8192,
    327 	.round_trip_ping_latency_dcfclk_cycles = 131,
    328 	.urgent_out_of_order_return_per_channel_bytes = 256,
    329 	.channel_interleave_bytes = 256,
    330 	.num_banks = 8,
    331 	.num_chans = 16,
    332 	.vmm_page_size_bytes = 4096,
    333 	.dram_clock_change_latency_us = 404.0,
    334 	.dummy_pstate_latency_us = 5.0,
    335 	.writeback_dram_clock_change_latency_us = 23.0,
    336 	.return_bus_width_bytes = 64,
    337 	.dispclk_dppclk_vco_speed_mhz = 3850,
    338 	.xfc_bus_transport_time_us = 20,
    339 	.xfc_xbuf_latency_tolerance_us = 4,
    340 	.use_urgent_burst_bw = 0
    341 };
    342 
    343 struct _vcs_dpi_soc_bounding_box_st dcn2_0_nv12_soc = { 0 };
    344 
    345 #ifndef mmDP0_DP_DPHY_INTERNAL_CTRL
    346 	#define mmDP0_DP_DPHY_INTERNAL_CTRL		0x210f
    347 	#define mmDP0_DP_DPHY_INTERNAL_CTRL_BASE_IDX	2
    348 	#define mmDP1_DP_DPHY_INTERNAL_CTRL		0x220f
    349 	#define mmDP1_DP_DPHY_INTERNAL_CTRL_BASE_IDX	2
    350 	#define mmDP2_DP_DPHY_INTERNAL_CTRL		0x230f
    351 	#define mmDP2_DP_DPHY_INTERNAL_CTRL_BASE_IDX	2
    352 	#define mmDP3_DP_DPHY_INTERNAL_CTRL		0x240f
    353 	#define mmDP3_DP_DPHY_INTERNAL_CTRL_BASE_IDX	2
    354 	#define mmDP4_DP_DPHY_INTERNAL_CTRL		0x250f
    355 	#define mmDP4_DP_DPHY_INTERNAL_CTRL_BASE_IDX	2
    356 	#define mmDP5_DP_DPHY_INTERNAL_CTRL		0x260f
    357 	#define mmDP5_DP_DPHY_INTERNAL_CTRL_BASE_IDX	2
    358 	#define mmDP6_DP_DPHY_INTERNAL_CTRL		0x270f
    359 	#define mmDP6_DP_DPHY_INTERNAL_CTRL_BASE_IDX	2
    360 #endif
    361 
    362 
    363 enum dcn20_clk_src_array_id {
    364 	DCN20_CLK_SRC_PLL0,
    365 	DCN20_CLK_SRC_PLL1,
    366 	DCN20_CLK_SRC_PLL2,
    367 	DCN20_CLK_SRC_PLL3,
    368 	DCN20_CLK_SRC_PLL4,
    369 	DCN20_CLK_SRC_PLL5,
    370 	DCN20_CLK_SRC_TOTAL
    371 };
    372 
    373 /* begin *********************
    374  * macros to expend register list macro defined in HW object header file */
    375 
    376 /* DCN */
    377 /* TODO awful hack. fixup dcn20_dwb.h */
    378 #undef BASE_INNER
    379 #define BASE_INNER(seg) DCN_BASE__INST0_SEG ## seg
    380 
    381 #define BASE(seg) BASE_INNER(seg)
    382 
    383 #define SR(reg_name)\
    384 		.reg_name = BASE(mm ## reg_name ## _BASE_IDX) +  \
    385 					mm ## reg_name
    386 
    387 #define SRI(reg_name, block, id)\
    388 	.reg_name = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
    389 					mm ## block ## id ## _ ## reg_name
    390 
    391 #define SRIR(var_name, reg_name, block, id)\
    392 	.var_name = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
    393 					mm ## block ## id ## _ ## reg_name
    394 
    395 #define SRII(reg_name, block, id)\
    396 	.reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
    397 					mm ## block ## id ## _ ## reg_name
    398 
    399 #define DCCG_SRII(reg_name, block, id)\
    400 	.block ## _ ## reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
    401 					mm ## block ## id ## _ ## reg_name
    402 
    403 /* NBIO */
    404 #define NBIO_BASE_INNER(seg) \
    405 	NBIO_BASE__INST0_SEG ## seg
    406 
    407 #define NBIO_BASE(seg) \
    408 	NBIO_BASE_INNER(seg)
    409 
    410 #define NBIO_SR(reg_name)\
    411 		.reg_name = NBIO_BASE(mm ## reg_name ## _BASE_IDX) + \
    412 					mm ## reg_name
    413 
    414 /* MMHUB */
    415 #define MMHUB_BASE_INNER(seg) \
    416 	MMHUB_BASE__INST0_SEG ## seg
    417 
    418 #define MMHUB_BASE(seg) \
    419 	MMHUB_BASE_INNER(seg)
    420 
    421 #define MMHUB_SR(reg_name)\
    422 		.reg_name = MMHUB_BASE(mmMM ## reg_name ## _BASE_IDX) + \
    423 					mmMM ## reg_name
    424 
    425 static const struct bios_registers bios_regs = {
    426 		NBIO_SR(BIOS_SCRATCH_3),
    427 		NBIO_SR(BIOS_SCRATCH_6)
    428 };
    429 
    430 #define clk_src_regs(index, pllid)\
    431 [index] = {\
    432 	CS_COMMON_REG_LIST_DCN2_0(index, pllid),\
    433 }
    434 
    435 static const struct dce110_clk_src_regs clk_src_regs[] = {
    436 	clk_src_regs(0, A),
    437 	clk_src_regs(1, B),
    438 	clk_src_regs(2, C),
    439 	clk_src_regs(3, D),
    440 	clk_src_regs(4, E),
    441 	clk_src_regs(5, F)
    442 };
    443 
    444 static const struct dce110_clk_src_shift cs_shift = {
    445 		CS_COMMON_MASK_SH_LIST_DCN2_0(__SHIFT)
    446 };
    447 
    448 static const struct dce110_clk_src_mask cs_mask = {
    449 		CS_COMMON_MASK_SH_LIST_DCN2_0(_MASK)
    450 };
    451 
    452 static const struct dce_dmcu_registers dmcu_regs = {
    453 		DMCU_DCN10_REG_LIST()
    454 };
    455 
    456 static const struct dce_dmcu_shift dmcu_shift = {
    457 		DMCU_MASK_SH_LIST_DCN10(__SHIFT)
    458 };
    459 
    460 static const struct dce_dmcu_mask dmcu_mask = {
    461 		DMCU_MASK_SH_LIST_DCN10(_MASK)
    462 };
    463 
    464 static const struct dce_abm_registers abm_regs = {
    465 		ABM_DCN20_REG_LIST()
    466 };
    467 
    468 static const struct dce_abm_shift abm_shift = {
    469 		ABM_MASK_SH_LIST_DCN20(__SHIFT)
    470 };
    471 
    472 static const struct dce_abm_mask abm_mask = {
    473 		ABM_MASK_SH_LIST_DCN20(_MASK)
    474 };
    475 
    476 #define audio_regs(id)\
    477 [id] = {\
    478 		AUD_COMMON_REG_LIST(id)\
    479 }
    480 
    481 static const struct dce_audio_registers audio_regs[] = {
    482 	audio_regs(0),
    483 	audio_regs(1),
    484 	audio_regs(2),
    485 	audio_regs(3),
    486 	audio_regs(4),
    487 	audio_regs(5),
    488 	audio_regs(6),
    489 };
    490 
    491 #define DCE120_AUD_COMMON_MASK_SH_LIST(mask_sh)\
    492 		SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_INDEX, AZALIA_ENDPOINT_REG_INDEX, mask_sh),\
    493 		SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_DATA, AZALIA_ENDPOINT_REG_DATA, mask_sh),\
    494 		AUD_COMMON_MASK_SH_LIST_BASE(mask_sh)
    495 
    496 static const struct dce_audio_shift audio_shift = {
    497 		DCE120_AUD_COMMON_MASK_SH_LIST(__SHIFT)
    498 };
    499 
    500 static const struct dce_audio_mask audio_mask = {
    501 		DCE120_AUD_COMMON_MASK_SH_LIST(_MASK)
    502 };
    503 
    504 #define stream_enc_regs(id)\
    505 [id] = {\
    506 	SE_DCN2_REG_LIST(id)\
    507 }
    508 
    509 static const struct dcn10_stream_enc_registers stream_enc_regs[] = {
    510 	stream_enc_regs(0),
    511 	stream_enc_regs(1),
    512 	stream_enc_regs(2),
    513 	stream_enc_regs(3),
    514 	stream_enc_regs(4),
    515 	stream_enc_regs(5),
    516 };
    517 
    518 static const struct dcn10_stream_encoder_shift se_shift = {
    519 		SE_COMMON_MASK_SH_LIST_DCN20(__SHIFT)
    520 };
    521 
    522 static const struct dcn10_stream_encoder_mask se_mask = {
    523 		SE_COMMON_MASK_SH_LIST_DCN20(_MASK)
    524 };
    525 
    526 
    527 #define aux_regs(id)\
    528 [id] = {\
    529 	DCN2_AUX_REG_LIST(id)\
    530 }
    531 
    532 static const struct dcn10_link_enc_aux_registers link_enc_aux_regs[] = {
    533 		aux_regs(0),
    534 		aux_regs(1),
    535 		aux_regs(2),
    536 		aux_regs(3),
    537 		aux_regs(4),
    538 		aux_regs(5)
    539 };
    540 
    541 #define hpd_regs(id)\
    542 [id] = {\
    543 	HPD_REG_LIST(id)\
    544 }
    545 
    546 static const struct dcn10_link_enc_hpd_registers link_enc_hpd_regs[] = {
    547 		hpd_regs(0),
    548 		hpd_regs(1),
    549 		hpd_regs(2),
    550 		hpd_regs(3),
    551 		hpd_regs(4),
    552 		hpd_regs(5)
    553 };
    554 
    555 #define link_regs(id, phyid)\
    556 [id] = {\
    557 	LE_DCN10_REG_LIST(id), \
    558 	UNIPHY_DCN2_REG_LIST(phyid), \
    559 	DPCS_DCN2_REG_LIST(id), \
    560 	SRI(DP_DPHY_INTERNAL_CTRL, DP, id) \
    561 }
    562 
    563 static const struct dcn10_link_enc_registers link_enc_regs[] = {
    564 	link_regs(0, A),
    565 	link_regs(1, B),
    566 	link_regs(2, C),
    567 	link_regs(3, D),
    568 	link_regs(4, E),
    569 	link_regs(5, F)
    570 };
    571 
    572 static const struct dcn10_link_enc_shift le_shift = {
    573 	LINK_ENCODER_MASK_SH_LIST_DCN20(__SHIFT),\
    574 	DPCS_DCN2_MASK_SH_LIST(__SHIFT)
    575 };
    576 
    577 static const struct dcn10_link_enc_mask le_mask = {
    578 	LINK_ENCODER_MASK_SH_LIST_DCN20(_MASK),\
    579 	DPCS_DCN2_MASK_SH_LIST(_MASK)
    580 };
    581 
    582 #define ipp_regs(id)\
    583 [id] = {\
    584 	IPP_REG_LIST_DCN20(id),\
    585 }
    586 
    587 static const struct dcn10_ipp_registers ipp_regs[] = {
    588 	ipp_regs(0),
    589 	ipp_regs(1),
    590 	ipp_regs(2),
    591 	ipp_regs(3),
    592 	ipp_regs(4),
    593 	ipp_regs(5),
    594 };
    595 
    596 static const struct dcn10_ipp_shift ipp_shift = {
    597 		IPP_MASK_SH_LIST_DCN20(__SHIFT)
    598 };
    599 
    600 static const struct dcn10_ipp_mask ipp_mask = {
    601 		IPP_MASK_SH_LIST_DCN20(_MASK),
    602 };
    603 
    604 #define opp_regs(id)\
    605 [id] = {\
    606 	OPP_REG_LIST_DCN20(id),\
    607 }
    608 
    609 static const struct dcn20_opp_registers opp_regs[] = {
    610 	opp_regs(0),
    611 	opp_regs(1),
    612 	opp_regs(2),
    613 	opp_regs(3),
    614 	opp_regs(4),
    615 	opp_regs(5),
    616 };
    617 
    618 static const struct dcn20_opp_shift opp_shift = {
    619 		OPP_MASK_SH_LIST_DCN20(__SHIFT)
    620 };
    621 
    622 static const struct dcn20_opp_mask opp_mask = {
    623 		OPP_MASK_SH_LIST_DCN20(_MASK)
    624 };
    625 
    626 #define aux_engine_regs(id)\
    627 [id] = {\
    628 	AUX_COMMON_REG_LIST0(id), \
    629 	.AUXN_IMPCAL = 0, \
    630 	.AUXP_IMPCAL = 0, \
    631 	.AUX_RESET_MASK = DP_AUX0_AUX_CONTROL__AUX_RESET_MASK, \
    632 }
    633 
    634 static const struct dce110_aux_registers aux_engine_regs[] = {
    635 		aux_engine_regs(0),
    636 		aux_engine_regs(1),
    637 		aux_engine_regs(2),
    638 		aux_engine_regs(3),
    639 		aux_engine_regs(4),
    640 		aux_engine_regs(5)
    641 };
    642 
    643 #define tf_regs(id)\
    644 [id] = {\
    645 	TF_REG_LIST_DCN20(id),\
    646 	TF_REG_LIST_DCN20_COMMON_APPEND(id),\
    647 }
    648 
    649 static const struct dcn2_dpp_registers tf_regs[] = {
    650 	tf_regs(0),
    651 	tf_regs(1),
    652 	tf_regs(2),
    653 	tf_regs(3),
    654 	tf_regs(4),
    655 	tf_regs(5),
    656 };
    657 
    658 static const struct dcn2_dpp_shift tf_shift = {
    659 		TF_REG_LIST_SH_MASK_DCN20(__SHIFT),
    660 		TF_DEBUG_REG_LIST_SH_DCN20
    661 };
    662 
    663 static const struct dcn2_dpp_mask tf_mask = {
    664 		TF_REG_LIST_SH_MASK_DCN20(_MASK),
    665 		TF_DEBUG_REG_LIST_MASK_DCN20
    666 };
    667 
    668 #define dwbc_regs_dcn2(id)\
    669 [id] = {\
    670 	DWBC_COMMON_REG_LIST_DCN2_0(id),\
    671 		}
    672 
    673 static const struct dcn20_dwbc_registers dwbc20_regs[] = {
    674 	dwbc_regs_dcn2(0),
    675 };
    676 
    677 static const struct dcn20_dwbc_shift dwbc20_shift = {
    678 	DWBC_COMMON_MASK_SH_LIST_DCN2_0(__SHIFT)
    679 };
    680 
    681 static const struct dcn20_dwbc_mask dwbc20_mask = {
    682 	DWBC_COMMON_MASK_SH_LIST_DCN2_0(_MASK)
    683 };
    684 
    685 #define mcif_wb_regs_dcn2(id)\
    686 [id] = {\
    687 	MCIF_WB_COMMON_REG_LIST_DCN2_0(id),\
    688 		}
    689 
    690 static const struct dcn20_mmhubbub_registers mcif_wb20_regs[] = {
    691 	mcif_wb_regs_dcn2(0),
    692 };
    693 
    694 static const struct dcn20_mmhubbub_shift mcif_wb20_shift = {
    695 	MCIF_WB_COMMON_MASK_SH_LIST_DCN2_0(__SHIFT)
    696 };
    697 
    698 static const struct dcn20_mmhubbub_mask mcif_wb20_mask = {
    699 	MCIF_WB_COMMON_MASK_SH_LIST_DCN2_0(_MASK)
    700 };
    701 
    702 static const struct dcn20_mpc_registers mpc_regs = {
    703 		MPC_REG_LIST_DCN2_0(0),
    704 		MPC_REG_LIST_DCN2_0(1),
    705 		MPC_REG_LIST_DCN2_0(2),
    706 		MPC_REG_LIST_DCN2_0(3),
    707 		MPC_REG_LIST_DCN2_0(4),
    708 		MPC_REG_LIST_DCN2_0(5),
    709 		MPC_OUT_MUX_REG_LIST_DCN2_0(0),
    710 		MPC_OUT_MUX_REG_LIST_DCN2_0(1),
    711 		MPC_OUT_MUX_REG_LIST_DCN2_0(2),
    712 		MPC_OUT_MUX_REG_LIST_DCN2_0(3),
    713 		MPC_OUT_MUX_REG_LIST_DCN2_0(4),
    714 		MPC_OUT_MUX_REG_LIST_DCN2_0(5),
    715 		MPC_DBG_REG_LIST_DCN2_0()
    716 };
    717 
    718 static const struct dcn20_mpc_shift mpc_shift = {
    719 	MPC_COMMON_MASK_SH_LIST_DCN2_0(__SHIFT),
    720 	MPC_DEBUG_REG_LIST_SH_DCN20
    721 };
    722 
    723 static const struct dcn20_mpc_mask mpc_mask = {
    724 	MPC_COMMON_MASK_SH_LIST_DCN2_0(_MASK),
    725 	MPC_DEBUG_REG_LIST_MASK_DCN20
    726 };
    727 
    728 #define tg_regs(id)\
    729 [id] = {TG_COMMON_REG_LIST_DCN2_0(id)}
    730 
    731 
    732 static const struct dcn_optc_registers tg_regs[] = {
    733 	tg_regs(0),
    734 	tg_regs(1),
    735 	tg_regs(2),
    736 	tg_regs(3),
    737 	tg_regs(4),
    738 	tg_regs(5)
    739 };
    740 
    741 static const struct dcn_optc_shift tg_shift = {
    742 	TG_COMMON_MASK_SH_LIST_DCN2_0(__SHIFT)
    743 };
    744 
    745 static const struct dcn_optc_mask tg_mask = {
    746 	TG_COMMON_MASK_SH_LIST_DCN2_0(_MASK)
    747 };
    748 
    749 #define hubp_regs(id)\
    750 [id] = {\
    751 	HUBP_REG_LIST_DCN20(id)\
    752 }
    753 
    754 static const struct dcn_hubp2_registers hubp_regs[] = {
    755 		hubp_regs(0),
    756 		hubp_regs(1),
    757 		hubp_regs(2),
    758 		hubp_regs(3),
    759 		hubp_regs(4),
    760 		hubp_regs(5)
    761 };
    762 
    763 static const struct dcn_hubp2_shift hubp_shift = {
    764 		HUBP_MASK_SH_LIST_DCN20(__SHIFT)
    765 };
    766 
    767 static const struct dcn_hubp2_mask hubp_mask = {
    768 		HUBP_MASK_SH_LIST_DCN20(_MASK)
    769 };
    770 
    771 static const struct dcn_hubbub_registers hubbub_reg = {
    772 		HUBBUB_REG_LIST_DCN20(0)
    773 };
    774 
    775 static const struct dcn_hubbub_shift hubbub_shift = {
    776 		HUBBUB_MASK_SH_LIST_DCN20(__SHIFT)
    777 };
    778 
    779 static const struct dcn_hubbub_mask hubbub_mask = {
    780 		HUBBUB_MASK_SH_LIST_DCN20(_MASK)
    781 };
    782 
    783 #define vmid_regs(id)\
    784 [id] = {\
    785 		DCN20_VMID_REG_LIST(id)\
    786 }
    787 
    788 static const struct dcn_vmid_registers vmid_regs[] = {
    789 	vmid_regs(0),
    790 	vmid_regs(1),
    791 	vmid_regs(2),
    792 	vmid_regs(3),
    793 	vmid_regs(4),
    794 	vmid_regs(5),
    795 	vmid_regs(6),
    796 	vmid_regs(7),
    797 	vmid_regs(8),
    798 	vmid_regs(9),
    799 	vmid_regs(10),
    800 	vmid_regs(11),
    801 	vmid_regs(12),
    802 	vmid_regs(13),
    803 	vmid_regs(14),
    804 	vmid_regs(15)
    805 };
    806 
    807 static const struct dcn20_vmid_shift vmid_shifts = {
    808 		DCN20_VMID_MASK_SH_LIST(__SHIFT)
    809 };
    810 
    811 static const struct dcn20_vmid_mask vmid_masks = {
    812 		DCN20_VMID_MASK_SH_LIST(_MASK)
    813 };
    814 
    815 static const struct dce110_aux_registers_shift aux_shift = {
    816 		DCN_AUX_MASK_SH_LIST(__SHIFT)
    817 };
    818 
    819 static const struct dce110_aux_registers_mask aux_mask = {
    820 		DCN_AUX_MASK_SH_LIST(_MASK)
    821 };
    822 
    823 static int map_transmitter_id_to_phy_instance(
    824 	enum transmitter transmitter)
    825 {
    826 	switch (transmitter) {
    827 	case TRANSMITTER_UNIPHY_A:
    828 		return 0;
    829 	break;
    830 	case TRANSMITTER_UNIPHY_B:
    831 		return 1;
    832 	break;
    833 	case TRANSMITTER_UNIPHY_C:
    834 		return 2;
    835 	break;
    836 	case TRANSMITTER_UNIPHY_D:
    837 		return 3;
    838 	break;
    839 	case TRANSMITTER_UNIPHY_E:
    840 		return 4;
    841 	break;
    842 	case TRANSMITTER_UNIPHY_F:
    843 		return 5;
    844 	break;
    845 	default:
    846 		ASSERT(0);
    847 		return 0;
    848 	}
    849 }
    850 
    851 #define dsc_regsDCN20(id)\
    852 [id] = {\
    853 	DSC_REG_LIST_DCN20(id)\
    854 }
    855 
    856 static const struct dcn20_dsc_registers dsc_regs[] = {
    857 	dsc_regsDCN20(0),
    858 	dsc_regsDCN20(1),
    859 	dsc_regsDCN20(2),
    860 	dsc_regsDCN20(3),
    861 	dsc_regsDCN20(4),
    862 	dsc_regsDCN20(5)
    863 };
    864 
    865 static const struct dcn20_dsc_shift dsc_shift = {
    866 	DSC_REG_LIST_SH_MASK_DCN20(__SHIFT)
    867 };
    868 
    869 static const struct dcn20_dsc_mask dsc_mask = {
    870 	DSC_REG_LIST_SH_MASK_DCN20(_MASK)
    871 };
    872 
    873 static const struct dccg_registers dccg_regs = {
    874 		DCCG_REG_LIST_DCN2()
    875 };
    876 
    877 static const struct dccg_shift dccg_shift = {
    878 		DCCG_MASK_SH_LIST_DCN2(__SHIFT)
    879 };
    880 
    881 static const struct dccg_mask dccg_mask = {
    882 		DCCG_MASK_SH_LIST_DCN2(_MASK)
    883 };
    884 
    885 static const struct resource_caps res_cap_nv10 = {
    886 		.num_timing_generator = 6,
    887 		.num_opp = 6,
    888 		.num_video_plane = 6,
    889 		.num_audio = 7,
    890 		.num_stream_encoder = 6,
    891 		.num_pll = 6,
    892 		.num_dwb = 1,
    893 		.num_ddc = 6,
    894 		.num_vmid = 16,
    895 		.num_dsc = 6,
    896 };
    897 
    898 static const struct dc_plane_cap plane_cap = {
    899 	.type = DC_PLANE_TYPE_DCN_UNIVERSAL,
    900 	.blends_with_above = true,
    901 	.blends_with_below = true,
    902 	.per_pixel_alpha = true,
    903 
    904 	.pixel_format_support = {
    905 			.argb8888 = true,
    906 			.nv12 = true,
    907 			.fp16 = true
    908 	},
    909 
    910 	.max_upscale_factor = {
    911 			.argb8888 = 16000,
    912 			.nv12 = 16000,
    913 			.fp16 = 1
    914 	},
    915 
    916 	.max_downscale_factor = {
    917 			.argb8888 = 250,
    918 			.nv12 = 250,
    919 			.fp16 = 1
    920 	}
    921 };
    922 static const struct resource_caps res_cap_nv14 = {
    923 		.num_timing_generator = 5,
    924 		.num_opp = 5,
    925 		.num_video_plane = 5,
    926 		.num_audio = 6,
    927 		.num_stream_encoder = 5,
    928 		.num_pll = 5,
    929 		.num_dwb = 1,
    930 		.num_ddc = 5,
    931 		.num_vmid = 16,
    932 		.num_dsc = 5,
    933 };
    934 
    935 static const struct dc_debug_options debug_defaults_drv = {
    936 		.disable_dmcu = true,
    937 		.force_abm_enable = false,
    938 		.timing_trace = false,
    939 		.clock_trace = true,
    940 		.disable_pplib_clock_request = true,
    941 		.pipe_split_policy = MPC_SPLIT_DYNAMIC,
    942 		.force_single_disp_pipe_split = false,
    943 		.disable_dcc = DCC_ENABLE,
    944 		.vsr_support = true,
    945 		.performance_trace = false,
    946 		.max_downscale_src_width = 5120,/*upto 5K*/
    947 		.disable_pplib_wm_range = false,
    948 		.scl_reset_length10 = true,
    949 		.sanity_checks = false,
    950 		.disable_tri_buf = true,
    951 		.underflow_assert_delay_us = 0xFFFFFFFF,
    952 };
    953 
    954 static const struct dc_debug_options debug_defaults_diags = {
    955 		.disable_dmcu = true,
    956 		.force_abm_enable = false,
    957 		.timing_trace = true,
    958 		.clock_trace = true,
    959 		.disable_dpp_power_gate = true,
    960 		.disable_hubp_power_gate = true,
    961 		.disable_clock_gate = true,
    962 		.disable_pplib_clock_request = true,
    963 		.disable_pplib_wm_range = true,
    964 		.disable_stutter = true,
    965 		.scl_reset_length10 = true,
    966 		.underflow_assert_delay_us = 0xFFFFFFFF,
    967 };
    968 
    969 void dcn20_dpp_destroy(struct dpp **dpp)
    970 {
    971 	kfree(TO_DCN20_DPP(*dpp));
    972 	*dpp = NULL;
    973 }
    974 
    975 struct dpp *dcn20_dpp_create(
    976 	struct dc_context *ctx,
    977 	uint32_t inst)
    978 {
    979 	struct dcn20_dpp *dpp =
    980 		kzalloc(sizeof(struct dcn20_dpp), GFP_KERNEL);
    981 
    982 	if (!dpp)
    983 		return NULL;
    984 
    985 	if (dpp2_construct(dpp, ctx, inst,
    986 			&tf_regs[inst], &tf_shift, &tf_mask))
    987 		return &dpp->base;
    988 
    989 	BREAK_TO_DEBUGGER();
    990 	kfree(dpp);
    991 	return NULL;
    992 }
    993 
    994 struct input_pixel_processor *dcn20_ipp_create(
    995 	struct dc_context *ctx, uint32_t inst)
    996 {
    997 	struct dcn10_ipp *ipp =
    998 		kzalloc(sizeof(struct dcn10_ipp), GFP_KERNEL);
    999 
   1000 	if (!ipp) {
   1001 		BREAK_TO_DEBUGGER();
   1002 		return NULL;
   1003 	}
   1004 
   1005 	dcn20_ipp_construct(ipp, ctx, inst,
   1006 			&ipp_regs[inst], &ipp_shift, &ipp_mask);
   1007 	return &ipp->base;
   1008 }
   1009 
   1010 
   1011 struct output_pixel_processor *dcn20_opp_create(
   1012 	struct dc_context *ctx, uint32_t inst)
   1013 {
   1014 	struct dcn20_opp *opp =
   1015 		kzalloc(sizeof(struct dcn20_opp), GFP_KERNEL);
   1016 
   1017 	if (!opp) {
   1018 		BREAK_TO_DEBUGGER();
   1019 		return NULL;
   1020 	}
   1021 
   1022 	dcn20_opp_construct(opp, ctx, inst,
   1023 			&opp_regs[inst], &opp_shift, &opp_mask);
   1024 	return &opp->base;
   1025 }
   1026 
   1027 struct dce_aux *dcn20_aux_engine_create(
   1028 	struct dc_context *ctx,
   1029 	uint32_t inst)
   1030 {
   1031 	struct aux_engine_dce110 *aux_engine =
   1032 		kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL);
   1033 
   1034 	if (!aux_engine)
   1035 		return NULL;
   1036 
   1037 	dce110_aux_engine_construct(aux_engine, ctx, inst,
   1038 				    SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD,
   1039 				    &aux_engine_regs[inst],
   1040 					&aux_mask,
   1041 					&aux_shift,
   1042 					ctx->dc->caps.extended_aux_timeout_support);
   1043 
   1044 	return &aux_engine->base;
   1045 }
   1046 #define i2c_inst_regs(id) { I2C_HW_ENGINE_COMMON_REG_LIST(id) }
   1047 
   1048 static const struct dce_i2c_registers i2c_hw_regs[] = {
   1049 		i2c_inst_regs(1),
   1050 		i2c_inst_regs(2),
   1051 		i2c_inst_regs(3),
   1052 		i2c_inst_regs(4),
   1053 		i2c_inst_regs(5),
   1054 		i2c_inst_regs(6),
   1055 };
   1056 
   1057 static const struct dce_i2c_shift i2c_shifts = {
   1058 		I2C_COMMON_MASK_SH_LIST_DCN2(__SHIFT)
   1059 };
   1060 
   1061 static const struct dce_i2c_mask i2c_masks = {
   1062 		I2C_COMMON_MASK_SH_LIST_DCN2(_MASK)
   1063 };
   1064 
   1065 struct dce_i2c_hw *dcn20_i2c_hw_create(
   1066 	struct dc_context *ctx,
   1067 	uint32_t inst)
   1068 {
   1069 	struct dce_i2c_hw *dce_i2c_hw =
   1070 		kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL);
   1071 
   1072 	if (!dce_i2c_hw)
   1073 		return NULL;
   1074 
   1075 	dcn2_i2c_hw_construct(dce_i2c_hw, ctx, inst,
   1076 				    &i2c_hw_regs[inst], &i2c_shifts, &i2c_masks);
   1077 
   1078 	return dce_i2c_hw;
   1079 }
   1080 struct mpc *dcn20_mpc_create(struct dc_context *ctx)
   1081 {
   1082 	struct dcn20_mpc *mpc20 = kzalloc(sizeof(struct dcn20_mpc),
   1083 					  GFP_KERNEL);
   1084 
   1085 	if (!mpc20)
   1086 		return NULL;
   1087 
   1088 	dcn20_mpc_construct(mpc20, ctx,
   1089 			&mpc_regs,
   1090 			&mpc_shift,
   1091 			&mpc_mask,
   1092 			6);
   1093 
   1094 	return &mpc20->base;
   1095 }
   1096 
   1097 struct hubbub *dcn20_hubbub_create(struct dc_context *ctx)
   1098 {
   1099 	int i;
   1100 	struct dcn20_hubbub *hubbub = kzalloc(sizeof(struct dcn20_hubbub),
   1101 					  GFP_KERNEL);
   1102 
   1103 	if (!hubbub)
   1104 		return NULL;
   1105 
   1106 	hubbub2_construct(hubbub, ctx,
   1107 			&hubbub_reg,
   1108 			&hubbub_shift,
   1109 			&hubbub_mask);
   1110 
   1111 	for (i = 0; i < res_cap_nv10.num_vmid; i++) {
   1112 		struct dcn20_vmid *vmid = &hubbub->vmid[i];
   1113 
   1114 		vmid->ctx = ctx;
   1115 
   1116 		vmid->regs = &vmid_regs[i];
   1117 		vmid->shifts = &vmid_shifts;
   1118 		vmid->masks = &vmid_masks;
   1119 	}
   1120 
   1121 	return &hubbub->base;
   1122 }
   1123 
   1124 struct timing_generator *dcn20_timing_generator_create(
   1125 		struct dc_context *ctx,
   1126 		uint32_t instance)
   1127 {
   1128 	struct optc *tgn10 =
   1129 		kzalloc(sizeof(struct optc), GFP_KERNEL);
   1130 
   1131 	if (!tgn10)
   1132 		return NULL;
   1133 
   1134 	tgn10->base.inst = instance;
   1135 	tgn10->base.ctx = ctx;
   1136 
   1137 	tgn10->tg_regs = &tg_regs[instance];
   1138 	tgn10->tg_shift = &tg_shift;
   1139 	tgn10->tg_mask = &tg_mask;
   1140 
   1141 	dcn20_timing_generator_init(tgn10);
   1142 
   1143 	return &tgn10->base;
   1144 }
   1145 
   1146 static const struct encoder_feature_support link_enc_feature = {
   1147 		.max_hdmi_deep_color = COLOR_DEPTH_121212,
   1148 		.max_hdmi_pixel_clock = 600000,
   1149 		.hdmi_ycbcr420_supported = true,
   1150 		.dp_ycbcr420_supported = true,
   1151 		.flags.bits.IS_HBR2_CAPABLE = true,
   1152 		.flags.bits.IS_HBR3_CAPABLE = true,
   1153 		.flags.bits.IS_TPS3_CAPABLE = true,
   1154 		.flags.bits.IS_TPS4_CAPABLE = true
   1155 };
   1156 
   1157 struct link_encoder *dcn20_link_encoder_create(
   1158 	const struct encoder_init_data *enc_init_data)
   1159 {
   1160 	struct dcn20_link_encoder *enc20 =
   1161 		kzalloc(sizeof(struct dcn20_link_encoder), GFP_KERNEL);
   1162 	int link_regs_id;
   1163 
   1164 	if (!enc20)
   1165 		return NULL;
   1166 
   1167 	link_regs_id =
   1168 		map_transmitter_id_to_phy_instance(enc_init_data->transmitter);
   1169 
   1170 	dcn20_link_encoder_construct(enc20,
   1171 				      enc_init_data,
   1172 				      &link_enc_feature,
   1173 				      &link_enc_regs[link_regs_id],
   1174 				      &link_enc_aux_regs[enc_init_data->channel - 1],
   1175 				      &link_enc_hpd_regs[enc_init_data->hpd_source],
   1176 				      &le_shift,
   1177 				      &le_mask);
   1178 
   1179 	return &enc20->enc10.base;
   1180 }
   1181 
   1182 struct clock_source *dcn20_clock_source_create(
   1183 	struct dc_context *ctx,
   1184 	struct dc_bios *bios,
   1185 	enum clock_source_id id,
   1186 	const struct dce110_clk_src_regs *regs,
   1187 	bool dp_clk_src)
   1188 {
   1189 	struct dce110_clk_src *clk_src =
   1190 		kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL);
   1191 
   1192 	if (!clk_src)
   1193 		return NULL;
   1194 
   1195 	if (dcn20_clk_src_construct(clk_src, ctx, bios, id,
   1196 			regs, &cs_shift, &cs_mask)) {
   1197 		clk_src->base.dp_clk_src = dp_clk_src;
   1198 		return &clk_src->base;
   1199 	}
   1200 
   1201 	kfree(clk_src);
   1202 	BREAK_TO_DEBUGGER();
   1203 	return NULL;
   1204 }
   1205 
   1206 static void read_dce_straps(
   1207 	struct dc_context *ctx,
   1208 	struct resource_straps *straps)
   1209 {
   1210 	generic_reg_get(ctx, mmDC_PINSTRAPS + BASE(mmDC_PINSTRAPS_BASE_IDX),
   1211 		FN(DC_PINSTRAPS, DC_PINSTRAPS_AUDIO), &straps->dc_pinstraps_audio);
   1212 }
   1213 
   1214 static struct audio *dcn20_create_audio(
   1215 		struct dc_context *ctx, unsigned int inst)
   1216 {
   1217 	return dce_audio_create(ctx, inst,
   1218 			&audio_regs[inst], &audio_shift, &audio_mask);
   1219 }
   1220 
   1221 struct stream_encoder *dcn20_stream_encoder_create(
   1222 	enum engine_id eng_id,
   1223 	struct dc_context *ctx)
   1224 {
   1225 	struct dcn10_stream_encoder *enc1 =
   1226 		kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL);
   1227 
   1228 	if (!enc1)
   1229 		return NULL;
   1230 
   1231 	if (ASICREV_IS_NAVI14_M(ctx->asic_id.hw_internal_rev)) {
   1232 		if (eng_id >= ENGINE_ID_DIGD)
   1233 			eng_id++;
   1234 	}
   1235 
   1236 	dcn20_stream_encoder_construct(enc1, ctx, ctx->dc_bios, eng_id,
   1237 					&stream_enc_regs[eng_id],
   1238 					&se_shift, &se_mask);
   1239 
   1240 	return &enc1->base;
   1241 }
   1242 
   1243 static const struct dce_hwseq_registers hwseq_reg = {
   1244 		HWSEQ_DCN2_REG_LIST()
   1245 };
   1246 
   1247 static const struct dce_hwseq_shift hwseq_shift = {
   1248 		HWSEQ_DCN2_MASK_SH_LIST(__SHIFT)
   1249 };
   1250 
   1251 static const struct dce_hwseq_mask hwseq_mask = {
   1252 		HWSEQ_DCN2_MASK_SH_LIST(_MASK)
   1253 };
   1254 
   1255 struct dce_hwseq *dcn20_hwseq_create(
   1256 	struct dc_context *ctx)
   1257 {
   1258 	struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL);
   1259 
   1260 	if (hws) {
   1261 		hws->ctx = ctx;
   1262 		hws->regs = &hwseq_reg;
   1263 		hws->shifts = &hwseq_shift;
   1264 		hws->masks = &hwseq_mask;
   1265 	}
   1266 	return hws;
   1267 }
   1268 
   1269 static const struct resource_create_funcs res_create_funcs = {
   1270 	.read_dce_straps = read_dce_straps,
   1271 	.create_audio = dcn20_create_audio,
   1272 	.create_stream_encoder = dcn20_stream_encoder_create,
   1273 	.create_hwseq = dcn20_hwseq_create,
   1274 };
   1275 
   1276 static const struct resource_create_funcs res_create_maximus_funcs = {
   1277 	.read_dce_straps = NULL,
   1278 	.create_audio = NULL,
   1279 	.create_stream_encoder = NULL,
   1280 	.create_hwseq = dcn20_hwseq_create,
   1281 };
   1282 
   1283 static void dcn20_pp_smu_destroy(struct pp_smu_funcs **pp_smu);
   1284 
   1285 void dcn20_clock_source_destroy(struct clock_source **clk_src)
   1286 {
   1287 	kfree(TO_DCE110_CLK_SRC(*clk_src));
   1288 	*clk_src = NULL;
   1289 }
   1290 
   1291 
   1292 struct display_stream_compressor *dcn20_dsc_create(
   1293 	struct dc_context *ctx, uint32_t inst)
   1294 {
   1295 	struct dcn20_dsc *dsc =
   1296 		kzalloc(sizeof(struct dcn20_dsc), GFP_KERNEL);
   1297 
   1298 	if (!dsc) {
   1299 		BREAK_TO_DEBUGGER();
   1300 		return NULL;
   1301 	}
   1302 
   1303 	dsc2_construct(dsc, ctx, inst, &dsc_regs[inst], &dsc_shift, &dsc_mask);
   1304 	return &dsc->base;
   1305 }
   1306 
   1307 void dcn20_dsc_destroy(struct display_stream_compressor **dsc)
   1308 {
   1309 	kfree(container_of(*dsc, struct dcn20_dsc, base));
   1310 	*dsc = NULL;
   1311 }
   1312 
   1313 
   1314 static void dcn20_resource_destruct(struct dcn20_resource_pool *pool)
   1315 {
   1316 	unsigned int i;
   1317 
   1318 	for (i = 0; i < pool->base.stream_enc_count; i++) {
   1319 		if (pool->base.stream_enc[i] != NULL) {
   1320 			kfree(DCN10STRENC_FROM_STRENC(pool->base.stream_enc[i]));
   1321 			pool->base.stream_enc[i] = NULL;
   1322 		}
   1323 	}
   1324 
   1325 	for (i = 0; i < pool->base.res_cap->num_dsc; i++) {
   1326 		if (pool->base.dscs[i] != NULL)
   1327 			dcn20_dsc_destroy(&pool->base.dscs[i]);
   1328 	}
   1329 
   1330 	if (pool->base.mpc != NULL) {
   1331 		kfree(TO_DCN20_MPC(pool->base.mpc));
   1332 		pool->base.mpc = NULL;
   1333 	}
   1334 	if (pool->base.hubbub != NULL) {
   1335 		kfree(pool->base.hubbub);
   1336 		pool->base.hubbub = NULL;
   1337 	}
   1338 	for (i = 0; i < pool->base.pipe_count; i++) {
   1339 		if (pool->base.dpps[i] != NULL)
   1340 			dcn20_dpp_destroy(&pool->base.dpps[i]);
   1341 
   1342 		if (pool->base.ipps[i] != NULL)
   1343 			pool->base.ipps[i]->funcs->ipp_destroy(&pool->base.ipps[i]);
   1344 
   1345 		if (pool->base.hubps[i] != NULL) {
   1346 			kfree(TO_DCN20_HUBP(pool->base.hubps[i]));
   1347 			pool->base.hubps[i] = NULL;
   1348 		}
   1349 
   1350 		if (pool->base.irqs != NULL) {
   1351 			dal_irq_service_destroy(&pool->base.irqs);
   1352 		}
   1353 	}
   1354 
   1355 	for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
   1356 		if (pool->base.engines[i] != NULL)
   1357 			dce110_engine_destroy(&pool->base.engines[i]);
   1358 		if (pool->base.hw_i2cs[i] != NULL) {
   1359 			kfree(pool->base.hw_i2cs[i]);
   1360 			pool->base.hw_i2cs[i] = NULL;
   1361 		}
   1362 		if (pool->base.sw_i2cs[i] != NULL) {
   1363 			kfree(pool->base.sw_i2cs[i]);
   1364 			pool->base.sw_i2cs[i] = NULL;
   1365 		}
   1366 	}
   1367 
   1368 	for (i = 0; i < pool->base.res_cap->num_opp; i++) {
   1369 		if (pool->base.opps[i] != NULL)
   1370 			pool->base.opps[i]->funcs->opp_destroy(&pool->base.opps[i]);
   1371 	}
   1372 
   1373 	for (i = 0; i < pool->base.res_cap->num_timing_generator; i++) {
   1374 		if (pool->base.timing_generators[i] != NULL)	{
   1375 			kfree(DCN10TG_FROM_TG(pool->base.timing_generators[i]));
   1376 			pool->base.timing_generators[i] = NULL;
   1377 		}
   1378 	}
   1379 
   1380 	for (i = 0; i < pool->base.res_cap->num_dwb; i++) {
   1381 		if (pool->base.dwbc[i] != NULL) {
   1382 			kfree(TO_DCN20_DWBC(pool->base.dwbc[i]));
   1383 			pool->base.dwbc[i] = NULL;
   1384 		}
   1385 		if (pool->base.mcif_wb[i] != NULL) {
   1386 			kfree(TO_DCN20_MMHUBBUB(pool->base.mcif_wb[i]));
   1387 			pool->base.mcif_wb[i] = NULL;
   1388 		}
   1389 	}
   1390 
   1391 	for (i = 0; i < pool->base.audio_count; i++) {
   1392 		if (pool->base.audios[i])
   1393 			dce_aud_destroy(&pool->base.audios[i]);
   1394 	}
   1395 
   1396 	for (i = 0; i < pool->base.clk_src_count; i++) {
   1397 		if (pool->base.clock_sources[i] != NULL) {
   1398 			dcn20_clock_source_destroy(&pool->base.clock_sources[i]);
   1399 			pool->base.clock_sources[i] = NULL;
   1400 		}
   1401 	}
   1402 
   1403 	if (pool->base.dp_clock_source != NULL) {
   1404 		dcn20_clock_source_destroy(&pool->base.dp_clock_source);
   1405 		pool->base.dp_clock_source = NULL;
   1406 	}
   1407 
   1408 
   1409 	if (pool->base.abm != NULL)
   1410 		dce_abm_destroy(&pool->base.abm);
   1411 
   1412 	if (pool->base.dmcu != NULL)
   1413 		dce_dmcu_destroy(&pool->base.dmcu);
   1414 
   1415 	if (pool->base.dccg != NULL)
   1416 		dcn_dccg_destroy(&pool->base.dccg);
   1417 
   1418 	if (pool->base.pp_smu != NULL)
   1419 		dcn20_pp_smu_destroy(&pool->base.pp_smu);
   1420 
   1421 	if (pool->base.oem_device != NULL)
   1422 		dal_ddc_service_destroy(&pool->base.oem_device);
   1423 }
   1424 
   1425 struct hubp *dcn20_hubp_create(
   1426 	struct dc_context *ctx,
   1427 	uint32_t inst)
   1428 {
   1429 	struct dcn20_hubp *hubp2 =
   1430 		kzalloc(sizeof(struct dcn20_hubp), GFP_KERNEL);
   1431 
   1432 	if (!hubp2)
   1433 		return NULL;
   1434 
   1435 	if (hubp2_construct(hubp2, ctx, inst,
   1436 			&hubp_regs[inst], &hubp_shift, &hubp_mask))
   1437 		return &hubp2->base;
   1438 
   1439 	BREAK_TO_DEBUGGER();
   1440 	kfree(hubp2);
   1441 	return NULL;
   1442 }
   1443 
   1444 static void get_pixel_clock_parameters(
   1445 	struct pipe_ctx *pipe_ctx,
   1446 	struct pixel_clk_params *pixel_clk_params)
   1447 {
   1448 	const struct dc_stream_state *stream = pipe_ctx->stream;
   1449 	struct pipe_ctx *odm_pipe;
   1450 	int opp_cnt = 1;
   1451 
   1452 	for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
   1453 		opp_cnt++;
   1454 
   1455 	pixel_clk_params->requested_pix_clk_100hz = stream->timing.pix_clk_100hz;
   1456 	pixel_clk_params->encoder_object_id = stream->link->link_enc->id;
   1457 	pixel_clk_params->signal_type = pipe_ctx->stream->signal;
   1458 	pixel_clk_params->controller_id = pipe_ctx->stream_res.tg->inst + 1;
   1459 	/* TODO: un-hardcode*/
   1460 	pixel_clk_params->requested_sym_clk = LINK_RATE_LOW *
   1461 		LINK_RATE_REF_FREQ_IN_KHZ;
   1462 	pixel_clk_params->flags.ENABLE_SS = 0;
   1463 	pixel_clk_params->color_depth =
   1464 		stream->timing.display_color_depth;
   1465 	pixel_clk_params->flags.DISPLAY_BLANKED = 1;
   1466 	pixel_clk_params->pixel_encoding = stream->timing.pixel_encoding;
   1467 
   1468 	if (stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR422)
   1469 		pixel_clk_params->color_depth = COLOR_DEPTH_888;
   1470 
   1471 	if (opp_cnt == 4)
   1472 		pixel_clk_params->requested_pix_clk_100hz /= 4;
   1473 	else if (optc2_is_two_pixels_per_containter(&stream->timing) || opp_cnt == 2)
   1474 		pixel_clk_params->requested_pix_clk_100hz /= 2;
   1475 
   1476 	if (stream->timing.timing_3d_format == TIMING_3D_FORMAT_HW_FRAME_PACKING)
   1477 		pixel_clk_params->requested_pix_clk_100hz *= 2;
   1478 
   1479 }
   1480 
   1481 static void build_clamping_params(struct dc_stream_state *stream)
   1482 {
   1483 	stream->clamping.clamping_level = CLAMPING_FULL_RANGE;
   1484 	stream->clamping.c_depth = stream->timing.display_color_depth;
   1485 	stream->clamping.pixel_encoding = stream->timing.pixel_encoding;
   1486 }
   1487 
   1488 static enum dc_status build_pipe_hw_param(struct pipe_ctx *pipe_ctx)
   1489 {
   1490 
   1491 	get_pixel_clock_parameters(pipe_ctx, &pipe_ctx->stream_res.pix_clk_params);
   1492 
   1493 	pipe_ctx->clock_source->funcs->get_pix_clk_dividers(
   1494 		pipe_ctx->clock_source,
   1495 		&pipe_ctx->stream_res.pix_clk_params,
   1496 		&pipe_ctx->pll_settings);
   1497 
   1498 	pipe_ctx->stream->clamping.pixel_encoding = pipe_ctx->stream->timing.pixel_encoding;
   1499 
   1500 	resource_build_bit_depth_reduction_params(pipe_ctx->stream,
   1501 					&pipe_ctx->stream->bit_depth_params);
   1502 	build_clamping_params(pipe_ctx->stream);
   1503 
   1504 	return DC_OK;
   1505 }
   1506 
   1507 enum dc_status dcn20_build_mapped_resource(const struct dc *dc, struct dc_state *context, struct dc_stream_state *stream)
   1508 {
   1509 	enum dc_status status = DC_OK;
   1510 	struct pipe_ctx *pipe_ctx = resource_get_head_pipe_for_stream(&context->res_ctx, stream);
   1511 
   1512 	/*TODO Seems unneeded anymore */
   1513 	/*	if (old_context && resource_is_stream_unchanged(old_context, stream)) {
   1514 			if (stream != NULL && old_context->streams[i] != NULL) {
   1515 				 todo: shouldn't have to copy missing parameter here
   1516 				resource_build_bit_depth_reduction_params(stream,
   1517 						&stream->bit_depth_params);
   1518 				stream->clamping.pixel_encoding =
   1519 						stream->timing.pixel_encoding;
   1520 
   1521 				resource_build_bit_depth_reduction_params(stream,
   1522 								&stream->bit_depth_params);
   1523 				build_clamping_params(stream);
   1524 
   1525 				continue;
   1526 			}
   1527 		}
   1528 	*/
   1529 
   1530 	if (!pipe_ctx)
   1531 		return DC_ERROR_UNEXPECTED;
   1532 
   1533 
   1534 	status = build_pipe_hw_param(pipe_ctx);
   1535 
   1536 	return status;
   1537 }
   1538 
   1539 
   1540 static void acquire_dsc(struct resource_context *res_ctx,
   1541 			const struct resource_pool *pool,
   1542 			struct display_stream_compressor **dsc,
   1543 			int pipe_idx)
   1544 {
   1545 	int i;
   1546 
   1547 	ASSERT(*dsc == NULL);
   1548 	*dsc = NULL;
   1549 
   1550 	if (pool->res_cap->num_dsc == pool->res_cap->num_opp) {
   1551 		*dsc = pool->dscs[pipe_idx];
   1552 		res_ctx->is_dsc_acquired[pipe_idx] = true;
   1553 		return;
   1554 	}
   1555 
   1556 	/* Find first free DSC */
   1557 	for (i = 0; i < pool->res_cap->num_dsc; i++)
   1558 		if (!res_ctx->is_dsc_acquired[i]) {
   1559 			*dsc = pool->dscs[i];
   1560 			res_ctx->is_dsc_acquired[i] = true;
   1561 			break;
   1562 		}
   1563 }
   1564 
   1565 static void release_dsc(struct resource_context *res_ctx,
   1566 			const struct resource_pool *pool,
   1567 			struct display_stream_compressor **dsc)
   1568 {
   1569 	int i;
   1570 
   1571 	for (i = 0; i < pool->res_cap->num_dsc; i++)
   1572 		if (pool->dscs[i] == *dsc) {
   1573 			res_ctx->is_dsc_acquired[i] = false;
   1574 			*dsc = NULL;
   1575 			break;
   1576 		}
   1577 }
   1578 
   1579 
   1580 
   1581 enum dc_status dcn20_add_dsc_to_stream_resource(struct dc *dc,
   1582 		struct dc_state *dc_ctx,
   1583 		struct dc_stream_state *dc_stream)
   1584 {
   1585 	enum dc_status result = DC_OK;
   1586 	int i;
   1587 	const struct resource_pool *pool = dc->res_pool;
   1588 
   1589 	/* Get a DSC if required and available */
   1590 	for (i = 0; i < dc->res_pool->pipe_count; i++) {
   1591 		struct pipe_ctx *pipe_ctx = &dc_ctx->res_ctx.pipe_ctx[i];
   1592 
   1593 		if (pipe_ctx->stream != dc_stream)
   1594 			continue;
   1595 
   1596 		if (pipe_ctx->stream_res.dsc)
   1597 			continue;
   1598 
   1599 		acquire_dsc(&dc_ctx->res_ctx, pool, &pipe_ctx->stream_res.dsc, i);
   1600 
   1601 		/* The number of DSCs can be less than the number of pipes */
   1602 		if (!pipe_ctx->stream_res.dsc) {
   1603 			result = DC_NO_DSC_RESOURCE;
   1604 		}
   1605 
   1606 		break;
   1607 	}
   1608 
   1609 	return result;
   1610 }
   1611 
   1612 
   1613 static enum dc_status remove_dsc_from_stream_resource(struct dc *dc,
   1614 		struct dc_state *new_ctx,
   1615 		struct dc_stream_state *dc_stream)
   1616 {
   1617 	struct pipe_ctx *pipe_ctx = NULL;
   1618 	int i;
   1619 
   1620 	for (i = 0; i < MAX_PIPES; i++) {
   1621 		if (new_ctx->res_ctx.pipe_ctx[i].stream == dc_stream && !new_ctx->res_ctx.pipe_ctx[i].top_pipe) {
   1622 			pipe_ctx = &new_ctx->res_ctx.pipe_ctx[i];
   1623 
   1624 			if (pipe_ctx->stream_res.dsc)
   1625 				release_dsc(&new_ctx->res_ctx, dc->res_pool, &pipe_ctx->stream_res.dsc);
   1626 		}
   1627 	}
   1628 
   1629 	if (!pipe_ctx)
   1630 		return DC_ERROR_UNEXPECTED;
   1631 	else
   1632 		return DC_OK;
   1633 }
   1634 
   1635 
   1636 enum dc_status dcn20_add_stream_to_ctx(struct dc *dc, struct dc_state *new_ctx, struct dc_stream_state *dc_stream)
   1637 {
   1638 	enum dc_status result = DC_ERROR_UNEXPECTED;
   1639 
   1640 	result = resource_map_pool_resources(dc, new_ctx, dc_stream);
   1641 
   1642 	if (result == DC_OK)
   1643 		result = resource_map_phy_clock_resources(dc, new_ctx, dc_stream);
   1644 
   1645 	/* Get a DSC if required and available */
   1646 	if (result == DC_OK && dc_stream->timing.flags.DSC)
   1647 		result = dcn20_add_dsc_to_stream_resource(dc, new_ctx, dc_stream);
   1648 
   1649 	if (result == DC_OK)
   1650 		result = dcn20_build_mapped_resource(dc, new_ctx, dc_stream);
   1651 
   1652 	return result;
   1653 }
   1654 
   1655 
   1656 enum dc_status dcn20_remove_stream_from_ctx(struct dc *dc, struct dc_state *new_ctx, struct dc_stream_state *dc_stream)
   1657 {
   1658 	enum dc_status result = DC_OK;
   1659 
   1660 	result = remove_dsc_from_stream_resource(dc, new_ctx, dc_stream);
   1661 
   1662 	return result;
   1663 }
   1664 
   1665 
   1666 static void swizzle_to_dml_params(
   1667 		enum swizzle_mode_values swizzle,
   1668 		unsigned int *sw_mode)
   1669 {
   1670 	switch (swizzle) {
   1671 	case DC_SW_LINEAR:
   1672 		*sw_mode = dm_sw_linear;
   1673 		break;
   1674 	case DC_SW_4KB_S:
   1675 		*sw_mode = dm_sw_4kb_s;
   1676 		break;
   1677 	case DC_SW_4KB_S_X:
   1678 		*sw_mode = dm_sw_4kb_s_x;
   1679 		break;
   1680 	case DC_SW_4KB_D:
   1681 		*sw_mode = dm_sw_4kb_d;
   1682 		break;
   1683 	case DC_SW_4KB_D_X:
   1684 		*sw_mode = dm_sw_4kb_d_x;
   1685 		break;
   1686 	case DC_SW_64KB_S:
   1687 		*sw_mode = dm_sw_64kb_s;
   1688 		break;
   1689 	case DC_SW_64KB_S_X:
   1690 		*sw_mode = dm_sw_64kb_s_x;
   1691 		break;
   1692 	case DC_SW_64KB_S_T:
   1693 		*sw_mode = dm_sw_64kb_s_t;
   1694 		break;
   1695 	case DC_SW_64KB_D:
   1696 		*sw_mode = dm_sw_64kb_d;
   1697 		break;
   1698 	case DC_SW_64KB_D_X:
   1699 		*sw_mode = dm_sw_64kb_d_x;
   1700 		break;
   1701 	case DC_SW_64KB_D_T:
   1702 		*sw_mode = dm_sw_64kb_d_t;
   1703 		break;
   1704 	case DC_SW_64KB_R_X:
   1705 		*sw_mode = dm_sw_64kb_r_x;
   1706 		break;
   1707 	case DC_SW_VAR_S:
   1708 		*sw_mode = dm_sw_var_s;
   1709 		break;
   1710 	case DC_SW_VAR_S_X:
   1711 		*sw_mode = dm_sw_var_s_x;
   1712 		break;
   1713 	case DC_SW_VAR_D:
   1714 		*sw_mode = dm_sw_var_d;
   1715 		break;
   1716 	case DC_SW_VAR_D_X:
   1717 		*sw_mode = dm_sw_var_d_x;
   1718 		break;
   1719 
   1720 	default:
   1721 		ASSERT(0); /* Not supported */
   1722 		break;
   1723 	}
   1724 }
   1725 
   1726 bool dcn20_split_stream_for_odm(
   1727 		struct resource_context *res_ctx,
   1728 		const struct resource_pool *pool,
   1729 		struct pipe_ctx *prev_odm_pipe,
   1730 		struct pipe_ctx *next_odm_pipe)
   1731 {
   1732 	int pipe_idx = next_odm_pipe->pipe_idx;
   1733 
   1734 	*next_odm_pipe = *prev_odm_pipe;
   1735 
   1736 	next_odm_pipe->pipe_idx = pipe_idx;
   1737 	next_odm_pipe->plane_res.mi = pool->mis[next_odm_pipe->pipe_idx];
   1738 	next_odm_pipe->plane_res.hubp = pool->hubps[next_odm_pipe->pipe_idx];
   1739 	next_odm_pipe->plane_res.ipp = pool->ipps[next_odm_pipe->pipe_idx];
   1740 	next_odm_pipe->plane_res.xfm = pool->transforms[next_odm_pipe->pipe_idx];
   1741 	next_odm_pipe->plane_res.dpp = pool->dpps[next_odm_pipe->pipe_idx];
   1742 	next_odm_pipe->plane_res.mpcc_inst = pool->dpps[next_odm_pipe->pipe_idx]->inst;
   1743 	next_odm_pipe->stream_res.dsc = NULL;
   1744 	if (prev_odm_pipe->next_odm_pipe && prev_odm_pipe->next_odm_pipe != next_odm_pipe) {
   1745 		next_odm_pipe->next_odm_pipe = prev_odm_pipe->next_odm_pipe;
   1746 		next_odm_pipe->next_odm_pipe->prev_odm_pipe = next_odm_pipe;
   1747 	}
   1748 	prev_odm_pipe->next_odm_pipe = next_odm_pipe;
   1749 	next_odm_pipe->prev_odm_pipe = prev_odm_pipe;
   1750 	ASSERT(next_odm_pipe->top_pipe == NULL);
   1751 
   1752 	if (prev_odm_pipe->plane_state) {
   1753 		struct scaler_data *sd = &prev_odm_pipe->plane_res.scl_data;
   1754 		int new_width;
   1755 
   1756 		/* HACTIVE halved for odm combine */
   1757 		sd->h_active /= 2;
   1758 		/* Calculate new vp and recout for left pipe */
   1759 		/* Need at least 16 pixels width per side */
   1760 		if (sd->recout.x + 16 >= sd->h_active)
   1761 			return false;
   1762 		new_width = sd->h_active - sd->recout.x;
   1763 		sd->viewport.width -= dc_fixpt_floor(dc_fixpt_mul_int(
   1764 				sd->ratios.horz, sd->recout.width - new_width));
   1765 		sd->viewport_c.width -= dc_fixpt_floor(dc_fixpt_mul_int(
   1766 				sd->ratios.horz_c, sd->recout.width - new_width));
   1767 		sd->recout.width = new_width;
   1768 
   1769 		/* Calculate new vp and recout for right pipe */
   1770 		sd = &next_odm_pipe->plane_res.scl_data;
   1771 		/* HACTIVE halved for odm combine */
   1772 		sd->h_active /= 2;
   1773 		/* Need at least 16 pixels width per side */
   1774 		if (new_width <= 16)
   1775 			return false;
   1776 		new_width = sd->recout.width + sd->recout.x - sd->h_active;
   1777 		sd->viewport.width -= dc_fixpt_floor(dc_fixpt_mul_int(
   1778 				sd->ratios.horz, sd->recout.width - new_width));
   1779 		sd->viewport_c.width -= dc_fixpt_floor(dc_fixpt_mul_int(
   1780 				sd->ratios.horz_c, sd->recout.width - new_width));
   1781 		sd->recout.width = new_width;
   1782 		sd->viewport.x += dc_fixpt_floor(dc_fixpt_mul_int(
   1783 				sd->ratios.horz, sd->h_active - sd->recout.x));
   1784 		sd->viewport_c.x += dc_fixpt_floor(dc_fixpt_mul_int(
   1785 				sd->ratios.horz_c, sd->h_active - sd->recout.x));
   1786 		sd->recout.x = 0;
   1787 	}
   1788 	next_odm_pipe->stream_res.opp = pool->opps[next_odm_pipe->pipe_idx];
   1789 	if (next_odm_pipe->stream->timing.flags.DSC == 1) {
   1790 		acquire_dsc(res_ctx, pool, &next_odm_pipe->stream_res.dsc, next_odm_pipe->pipe_idx);
   1791 		ASSERT(next_odm_pipe->stream_res.dsc);
   1792 		if (next_odm_pipe->stream_res.dsc == NULL)
   1793 			return false;
   1794 	}
   1795 
   1796 	return true;
   1797 }
   1798 
   1799 void dcn20_split_stream_for_mpc(
   1800 		struct resource_context *res_ctx,
   1801 		const struct resource_pool *pool,
   1802 		struct pipe_ctx *primary_pipe,
   1803 		struct pipe_ctx *secondary_pipe)
   1804 {
   1805 	int pipe_idx = secondary_pipe->pipe_idx;
   1806 	struct pipe_ctx *sec_bot_pipe = secondary_pipe->bottom_pipe;
   1807 
   1808 	*secondary_pipe = *primary_pipe;
   1809 	secondary_pipe->bottom_pipe = sec_bot_pipe;
   1810 
   1811 	secondary_pipe->pipe_idx = pipe_idx;
   1812 	secondary_pipe->plane_res.mi = pool->mis[secondary_pipe->pipe_idx];
   1813 	secondary_pipe->plane_res.hubp = pool->hubps[secondary_pipe->pipe_idx];
   1814 	secondary_pipe->plane_res.ipp = pool->ipps[secondary_pipe->pipe_idx];
   1815 	secondary_pipe->plane_res.xfm = pool->transforms[secondary_pipe->pipe_idx];
   1816 	secondary_pipe->plane_res.dpp = pool->dpps[secondary_pipe->pipe_idx];
   1817 	secondary_pipe->plane_res.mpcc_inst = pool->dpps[secondary_pipe->pipe_idx]->inst;
   1818 	secondary_pipe->stream_res.dsc = NULL;
   1819 	if (primary_pipe->bottom_pipe && primary_pipe->bottom_pipe != secondary_pipe) {
   1820 		ASSERT(!secondary_pipe->bottom_pipe);
   1821 		secondary_pipe->bottom_pipe = primary_pipe->bottom_pipe;
   1822 		secondary_pipe->bottom_pipe->top_pipe = secondary_pipe;
   1823 	}
   1824 	primary_pipe->bottom_pipe = secondary_pipe;
   1825 	secondary_pipe->top_pipe = primary_pipe;
   1826 
   1827 	ASSERT(primary_pipe->plane_state);
   1828 	resource_build_scaling_params(primary_pipe);
   1829 	resource_build_scaling_params(secondary_pipe);
   1830 }
   1831 
   1832 void dcn20_populate_dml_writeback_from_context(
   1833 		struct dc *dc, struct resource_context *res_ctx, display_e2e_pipe_params_st *pipes)
   1834 {
   1835 	int pipe_cnt, i;
   1836 
   1837 	for (i = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {
   1838 		struct dc_writeback_info *wb_info = &res_ctx->pipe_ctx[i].stream->writeback_info[0];
   1839 
   1840 		if (!res_ctx->pipe_ctx[i].stream)
   1841 			continue;
   1842 
   1843 		/* Set writeback information */
   1844 		pipes[pipe_cnt].dout.wb_enable = (wb_info->wb_enabled == true) ? 1 : 0;
   1845 		pipes[pipe_cnt].dout.num_active_wb++;
   1846 		pipes[pipe_cnt].dout.wb.wb_src_height = wb_info->dwb_params.cnv_params.crop_height;
   1847 		pipes[pipe_cnt].dout.wb.wb_src_width = wb_info->dwb_params.cnv_params.crop_width;
   1848 		pipes[pipe_cnt].dout.wb.wb_dst_width = wb_info->dwb_params.dest_width;
   1849 		pipes[pipe_cnt].dout.wb.wb_dst_height = wb_info->dwb_params.dest_height;
   1850 		pipes[pipe_cnt].dout.wb.wb_htaps_luma = 1;
   1851 		pipes[pipe_cnt].dout.wb.wb_vtaps_luma = 1;
   1852 		pipes[pipe_cnt].dout.wb.wb_htaps_chroma = wb_info->dwb_params.scaler_taps.h_taps_c;
   1853 		pipes[pipe_cnt].dout.wb.wb_vtaps_chroma = wb_info->dwb_params.scaler_taps.v_taps_c;
   1854 		pipes[pipe_cnt].dout.wb.wb_hratio = 1.0;
   1855 		pipes[pipe_cnt].dout.wb.wb_vratio = 1.0;
   1856 		if (wb_info->dwb_params.out_format == dwb_scaler_mode_yuv420) {
   1857 			if (wb_info->dwb_params.output_depth == DWB_OUTPUT_PIXEL_DEPTH_8BPC)
   1858 				pipes[pipe_cnt].dout.wb.wb_pixel_format = dm_420_8;
   1859 			else
   1860 				pipes[pipe_cnt].dout.wb.wb_pixel_format = dm_420_10;
   1861 		} else
   1862 			pipes[pipe_cnt].dout.wb.wb_pixel_format = dm_444_32;
   1863 
   1864 		pipe_cnt++;
   1865 	}
   1866 
   1867 }
   1868 
   1869 static int get_num_odm_heads(struct pipe_ctx *pipe)
   1870 {
   1871 	int odm_head_count = 0;
   1872 	struct pipe_ctx *next_pipe = pipe->next_odm_pipe;
   1873 	while (next_pipe) {
   1874 		odm_head_count++;
   1875 		next_pipe = next_pipe->next_odm_pipe;
   1876 	}
   1877 	pipe = pipe->prev_odm_pipe;
   1878 	while (pipe) {
   1879 		odm_head_count++;
   1880 		pipe = pipe->prev_odm_pipe;
   1881 	}
   1882 	return odm_head_count ? odm_head_count + 1 : 0;
   1883 }
   1884 
   1885 int dcn20_populate_dml_pipes_from_context(
   1886 		struct dc *dc, struct dc_state *context, display_e2e_pipe_params_st *pipes)
   1887 {
   1888 	int pipe_cnt, i;
   1889 	bool synchronized_vblank = true;
   1890 	struct resource_context *res_ctx = &context->res_ctx;
   1891 
   1892 	for (i = 0, pipe_cnt = -1; i < dc->res_pool->pipe_count; i++) {
   1893 		if (!res_ctx->pipe_ctx[i].stream)
   1894 			continue;
   1895 
   1896 		if (pipe_cnt < 0) {
   1897 			pipe_cnt = i;
   1898 			continue;
   1899 		}
   1900 		if (dc->debug.disable_timing_sync || !resource_are_streams_timing_synchronizable(
   1901 				res_ctx->pipe_ctx[pipe_cnt].stream,
   1902 				res_ctx->pipe_ctx[i].stream)) {
   1903 			synchronized_vblank = false;
   1904 			break;
   1905 		}
   1906 	}
   1907 
   1908 	for (i = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {
   1909 		struct dc_crtc_timing *timing = &res_ctx->pipe_ctx[i].stream->timing;
   1910 		unsigned int v_total;
   1911 		unsigned int front_porch;
   1912 		int output_bpc;
   1913 
   1914 		if (!res_ctx->pipe_ctx[i].stream)
   1915 			continue;
   1916 
   1917 		v_total = timing->v_total;
   1918 		front_porch = timing->v_front_porch;
   1919 		/* todo:
   1920 		pipes[pipe_cnt].pipe.src.dynamic_metadata_enable = 0;
   1921 		pipes[pipe_cnt].pipe.src.dcc = 0;
   1922 		pipes[pipe_cnt].pipe.src.vm = 0;*/
   1923 
   1924 		pipes[pipe_cnt].clks_cfg.refclk_mhz = dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000.0;
   1925 
   1926 		pipes[pipe_cnt].dout.dsc_enable = res_ctx->pipe_ctx[i].stream->timing.flags.DSC;
   1927 		/* todo: rotation?*/
   1928 		pipes[pipe_cnt].dout.dsc_slices = res_ctx->pipe_ctx[i].stream->timing.dsc_cfg.num_slices_h;
   1929 		if (res_ctx->pipe_ctx[i].stream->use_dynamic_meta) {
   1930 			pipes[pipe_cnt].pipe.src.dynamic_metadata_enable = true;
   1931 			/* 1/2 vblank */
   1932 			pipes[pipe_cnt].pipe.src.dynamic_metadata_lines_before_active =
   1933 				(v_total - timing->v_addressable
   1934 					- timing->v_border_top - timing->v_border_bottom) / 2;
   1935 			/* 36 bytes dp, 32 hdmi */
   1936 			pipes[pipe_cnt].pipe.src.dynamic_metadata_xmit_bytes =
   1937 				dc_is_dp_signal(res_ctx->pipe_ctx[i].stream->signal) ? 36 : 32;
   1938 		}
   1939 		pipes[pipe_cnt].pipe.src.dcc = false;
   1940 		pipes[pipe_cnt].pipe.src.dcc_rate = 1;
   1941 		pipes[pipe_cnt].pipe.dest.synchronized_vblank_all_planes = synchronized_vblank;
   1942 		pipes[pipe_cnt].pipe.dest.hblank_start = timing->h_total - timing->h_front_porch;
   1943 		pipes[pipe_cnt].pipe.dest.hblank_end = pipes[pipe_cnt].pipe.dest.hblank_start
   1944 				- timing->h_addressable
   1945 				- timing->h_border_left
   1946 				- timing->h_border_right;
   1947 		pipes[pipe_cnt].pipe.dest.vblank_start = v_total - front_porch;
   1948 		pipes[pipe_cnt].pipe.dest.vblank_end = pipes[pipe_cnt].pipe.dest.vblank_start
   1949 				- timing->v_addressable
   1950 				- timing->v_border_top
   1951 				- timing->v_border_bottom;
   1952 		pipes[pipe_cnt].pipe.dest.htotal = timing->h_total;
   1953 		pipes[pipe_cnt].pipe.dest.vtotal = v_total;
   1954 		pipes[pipe_cnt].pipe.dest.hactive = timing->h_addressable;
   1955 		pipes[pipe_cnt].pipe.dest.vactive = timing->v_addressable;
   1956 		pipes[pipe_cnt].pipe.dest.interlaced = timing->flags.INTERLACE;
   1957 		pipes[pipe_cnt].pipe.dest.pixel_rate_mhz = timing->pix_clk_100hz/10000.0;
   1958 		if (timing->timing_3d_format == TIMING_3D_FORMAT_HW_FRAME_PACKING)
   1959 			pipes[pipe_cnt].pipe.dest.pixel_rate_mhz *= 2;
   1960 		pipes[pipe_cnt].pipe.dest.otg_inst = res_ctx->pipe_ctx[i].stream_res.tg->inst;
   1961 		pipes[pipe_cnt].dout.dp_lanes = 4;
   1962 		pipes[pipe_cnt].pipe.dest.vtotal_min = res_ctx->pipe_ctx[i].stream->adjust.v_total_min;
   1963 		pipes[pipe_cnt].pipe.dest.vtotal_max = res_ctx->pipe_ctx[i].stream->adjust.v_total_max;
   1964 		switch (get_num_odm_heads(&res_ctx->pipe_ctx[i])) {
   1965 		case 2:
   1966 			pipes[pipe_cnt].pipe.dest.odm_combine = dm_odm_combine_mode_2to1;
   1967 			break;
   1968 		default:
   1969 			pipes[pipe_cnt].pipe.dest.odm_combine = dm_odm_combine_mode_disabled;
   1970 		}
   1971 		pipes[pipe_cnt].pipe.src.hsplit_grp = res_ctx->pipe_ctx[i].pipe_idx;
   1972 		if (res_ctx->pipe_ctx[i].top_pipe && res_ctx->pipe_ctx[i].top_pipe->plane_state
   1973 				== res_ctx->pipe_ctx[i].plane_state)
   1974 			pipes[pipe_cnt].pipe.src.hsplit_grp = res_ctx->pipe_ctx[i].top_pipe->pipe_idx;
   1975 		else if (res_ctx->pipe_ctx[i].prev_odm_pipe) {
   1976 			struct pipe_ctx *first_pipe = res_ctx->pipe_ctx[i].prev_odm_pipe;
   1977 
   1978 			while (first_pipe->prev_odm_pipe)
   1979 				first_pipe = first_pipe->prev_odm_pipe;
   1980 			pipes[pipe_cnt].pipe.src.hsplit_grp = first_pipe->pipe_idx;
   1981 		}
   1982 
   1983 		switch (res_ctx->pipe_ctx[i].stream->signal) {
   1984 		case SIGNAL_TYPE_DISPLAY_PORT_MST:
   1985 		case SIGNAL_TYPE_DISPLAY_PORT:
   1986 			pipes[pipe_cnt].dout.output_type = dm_dp;
   1987 			break;
   1988 		case SIGNAL_TYPE_EDP:
   1989 			pipes[pipe_cnt].dout.output_type = dm_edp;
   1990 			break;
   1991 		case SIGNAL_TYPE_HDMI_TYPE_A:
   1992 		case SIGNAL_TYPE_DVI_SINGLE_LINK:
   1993 		case SIGNAL_TYPE_DVI_DUAL_LINK:
   1994 			pipes[pipe_cnt].dout.output_type = dm_hdmi;
   1995 			break;
   1996 		default:
   1997 			/* In case there is no signal, set dp with 4 lanes to allow max config */
   1998 			pipes[pipe_cnt].dout.output_type = dm_dp;
   1999 			pipes[pipe_cnt].dout.dp_lanes = 4;
   2000 		}
   2001 
   2002 		switch (res_ctx->pipe_ctx[i].stream->timing.display_color_depth) {
   2003 		case COLOR_DEPTH_666:
   2004 			output_bpc = 6;
   2005 			break;
   2006 		case COLOR_DEPTH_888:
   2007 			output_bpc = 8;
   2008 			break;
   2009 		case COLOR_DEPTH_101010:
   2010 			output_bpc = 10;
   2011 			break;
   2012 		case COLOR_DEPTH_121212:
   2013 			output_bpc = 12;
   2014 			break;
   2015 		case COLOR_DEPTH_141414:
   2016 			output_bpc = 14;
   2017 			break;
   2018 		case COLOR_DEPTH_161616:
   2019 			output_bpc = 16;
   2020 			break;
   2021 		case COLOR_DEPTH_999:
   2022 			output_bpc = 9;
   2023 			break;
   2024 		case COLOR_DEPTH_111111:
   2025 			output_bpc = 11;
   2026 			break;
   2027 		default:
   2028 			output_bpc = 8;
   2029 			break;
   2030 		}
   2031 
   2032 		switch (res_ctx->pipe_ctx[i].stream->timing.pixel_encoding) {
   2033 		case PIXEL_ENCODING_RGB:
   2034 		case PIXEL_ENCODING_YCBCR444:
   2035 			pipes[pipe_cnt].dout.output_format = dm_444;
   2036 			pipes[pipe_cnt].dout.output_bpp = output_bpc * 3;
   2037 			break;
   2038 		case PIXEL_ENCODING_YCBCR420:
   2039 			pipes[pipe_cnt].dout.output_format = dm_420;
   2040 			pipes[pipe_cnt].dout.output_bpp = (output_bpc * 3.0) / 2;
   2041 			break;
   2042 		case PIXEL_ENCODING_YCBCR422:
   2043 			if (true) /* todo */
   2044 				pipes[pipe_cnt].dout.output_format = dm_s422;
   2045 			else
   2046 				pipes[pipe_cnt].dout.output_format = dm_n422;
   2047 			pipes[pipe_cnt].dout.output_bpp = output_bpc * 2;
   2048 			break;
   2049 		default:
   2050 			pipes[pipe_cnt].dout.output_format = dm_444;
   2051 			pipes[pipe_cnt].dout.output_bpp = output_bpc * 3;
   2052 		}
   2053 
   2054 		if (res_ctx->pipe_ctx[i].stream->timing.flags.DSC)
   2055 			pipes[pipe_cnt].dout.output_bpp = res_ctx->pipe_ctx[i].stream->timing.dsc_cfg.bits_per_pixel / 16.0;
   2056 
   2057 		/* todo: default max for now, until there is logic reflecting this in dc*/
   2058 		pipes[pipe_cnt].dout.output_bpc = 12;
   2059 		/*
   2060 		 * Use max cursor settings for calculations to minimize
   2061 		 * bw calculations due to cursor on/off
   2062 		 */
   2063 		pipes[pipe_cnt].pipe.src.num_cursors = 2;
   2064 		pipes[pipe_cnt].pipe.src.cur0_src_width = 256;
   2065 		pipes[pipe_cnt].pipe.src.cur0_bpp = dm_cur_32bit;
   2066 		pipes[pipe_cnt].pipe.src.cur1_src_width = 256;
   2067 		pipes[pipe_cnt].pipe.src.cur1_bpp = dm_cur_32bit;
   2068 
   2069 		if (!res_ctx->pipe_ctx[i].plane_state) {
   2070 			pipes[pipe_cnt].pipe.src.source_scan = dm_horz;
   2071 			pipes[pipe_cnt].pipe.src.sw_mode = dm_sw_linear;
   2072 			pipes[pipe_cnt].pipe.src.macro_tile_size = dm_64k_tile;
   2073 			pipes[pipe_cnt].pipe.src.viewport_width = timing->h_addressable;
   2074 			if (pipes[pipe_cnt].pipe.src.viewport_width > 1920)
   2075 				pipes[pipe_cnt].pipe.src.viewport_width = 1920;
   2076 			pipes[pipe_cnt].pipe.src.viewport_height = timing->v_addressable;
   2077 			if (pipes[pipe_cnt].pipe.src.viewport_height > 1080)
   2078 				pipes[pipe_cnt].pipe.src.viewport_height = 1080;
   2079 			pipes[pipe_cnt].pipe.src.surface_height_y = pipes[pipe_cnt].pipe.src.viewport_height;
   2080 			pipes[pipe_cnt].pipe.src.surface_width_y = pipes[pipe_cnt].pipe.src.viewport_width;
   2081 			pipes[pipe_cnt].pipe.src.surface_height_c = pipes[pipe_cnt].pipe.src.viewport_height;
   2082 			pipes[pipe_cnt].pipe.src.surface_width_c = pipes[pipe_cnt].pipe.src.viewport_width;
   2083 			pipes[pipe_cnt].pipe.src.data_pitch = ((pipes[pipe_cnt].pipe.src.viewport_width + 63) / 64) * 64; /* linear sw only */
   2084 			pipes[pipe_cnt].pipe.src.source_format = dm_444_32;
   2085 			pipes[pipe_cnt].pipe.dest.recout_width = pipes[pipe_cnt].pipe.src.viewport_width; /*vp_width/hratio*/
   2086 			pipes[pipe_cnt].pipe.dest.recout_height = pipes[pipe_cnt].pipe.src.viewport_height; /*vp_height/vratio*/
   2087 			pipes[pipe_cnt].pipe.dest.full_recout_width = pipes[pipe_cnt].pipe.dest.recout_width;  /*when is_hsplit != 1*/
   2088 			pipes[pipe_cnt].pipe.dest.full_recout_height = pipes[pipe_cnt].pipe.dest.recout_height; /*when is_hsplit != 1*/
   2089 			pipes[pipe_cnt].pipe.scale_ratio_depth.lb_depth = dm_lb_16;
   2090 			pipes[pipe_cnt].pipe.scale_ratio_depth.hscl_ratio = 1.0;
   2091 			pipes[pipe_cnt].pipe.scale_ratio_depth.vscl_ratio = 1.0;
   2092 			pipes[pipe_cnt].pipe.scale_ratio_depth.scl_enable = 0; /*Lb only or Full scl*/
   2093 			pipes[pipe_cnt].pipe.scale_taps.htaps = 1;
   2094 			pipes[pipe_cnt].pipe.scale_taps.vtaps = 1;
   2095 			pipes[pipe_cnt].pipe.src.is_hsplit = 0;
   2096 			pipes[pipe_cnt].pipe.dest.odm_combine = 0;
   2097 			pipes[pipe_cnt].pipe.dest.vtotal_min = v_total;
   2098 			pipes[pipe_cnt].pipe.dest.vtotal_max = v_total;
   2099 		} else {
   2100 			struct dc_plane_state *pln = res_ctx->pipe_ctx[i].plane_state;
   2101 			struct scaler_data *scl = &res_ctx->pipe_ctx[i].plane_res.scl_data;
   2102 
   2103 			pipes[pipe_cnt].pipe.src.immediate_flip = pln->flip_immediate;
   2104 			pipes[pipe_cnt].pipe.src.is_hsplit = (res_ctx->pipe_ctx[i].bottom_pipe
   2105 					&& res_ctx->pipe_ctx[i].bottom_pipe->plane_state == pln)
   2106 					|| (res_ctx->pipe_ctx[i].top_pipe
   2107 					&& res_ctx->pipe_ctx[i].top_pipe->plane_state == pln);
   2108 			pipes[pipe_cnt].pipe.src.source_scan = pln->rotation == ROTATION_ANGLE_90
   2109 					|| pln->rotation == ROTATION_ANGLE_270 ? dm_vert : dm_horz;
   2110 			pipes[pipe_cnt].pipe.src.viewport_y_y = scl->viewport.y;
   2111 			pipes[pipe_cnt].pipe.src.viewport_y_c = scl->viewport_c.y;
   2112 			pipes[pipe_cnt].pipe.src.viewport_width = scl->viewport.width;
   2113 			pipes[pipe_cnt].pipe.src.viewport_width_c = scl->viewport_c.width;
   2114 			pipes[pipe_cnt].pipe.src.viewport_height = scl->viewport.height;
   2115 			pipes[pipe_cnt].pipe.src.viewport_height_c = scl->viewport_c.height;
   2116 			pipes[pipe_cnt].pipe.src.surface_width_y = pln->plane_size.surface_size.width;
   2117 			pipes[pipe_cnt].pipe.src.surface_height_y = pln->plane_size.surface_size.height;
   2118 			pipes[pipe_cnt].pipe.src.surface_width_c = pln->plane_size.chroma_size.width;
   2119 			pipes[pipe_cnt].pipe.src.surface_height_c = pln->plane_size.chroma_size.height;
   2120 			if (pln->format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) {
   2121 				pipes[pipe_cnt].pipe.src.data_pitch = pln->plane_size.surface_pitch;
   2122 				pipes[pipe_cnt].pipe.src.data_pitch_c = pln->plane_size.chroma_pitch;
   2123 				pipes[pipe_cnt].pipe.src.meta_pitch = pln->dcc.meta_pitch;
   2124 				pipes[pipe_cnt].pipe.src.meta_pitch_c = pln->dcc.meta_pitch_c;
   2125 			} else {
   2126 				pipes[pipe_cnt].pipe.src.data_pitch = pln->plane_size.surface_pitch;
   2127 				pipes[pipe_cnt].pipe.src.meta_pitch = pln->dcc.meta_pitch;
   2128 			}
   2129 			pipes[pipe_cnt].pipe.src.dcc = pln->dcc.enable;
   2130 			pipes[pipe_cnt].pipe.dest.recout_width = scl->recout.width;
   2131 			pipes[pipe_cnt].pipe.dest.recout_height = scl->recout.height;
   2132 			pipes[pipe_cnt].pipe.dest.full_recout_width = scl->recout.width;
   2133 			pipes[pipe_cnt].pipe.dest.full_recout_height = scl->recout.height;
   2134 			if (res_ctx->pipe_ctx[i].bottom_pipe && res_ctx->pipe_ctx[i].bottom_pipe->plane_state == pln) {
   2135 				pipes[pipe_cnt].pipe.dest.full_recout_width +=
   2136 						res_ctx->pipe_ctx[i].bottom_pipe->plane_res.scl_data.recout.width;
   2137 				pipes[pipe_cnt].pipe.dest.full_recout_height +=
   2138 						res_ctx->pipe_ctx[i].bottom_pipe->plane_res.scl_data.recout.height;
   2139 			} else if (res_ctx->pipe_ctx[i].top_pipe && res_ctx->pipe_ctx[i].top_pipe->plane_state == pln) {
   2140 				pipes[pipe_cnt].pipe.dest.full_recout_width +=
   2141 						res_ctx->pipe_ctx[i].top_pipe->plane_res.scl_data.recout.width;
   2142 				pipes[pipe_cnt].pipe.dest.full_recout_height +=
   2143 						res_ctx->pipe_ctx[i].top_pipe->plane_res.scl_data.recout.height;
   2144 			}
   2145 
   2146 			pipes[pipe_cnt].pipe.scale_ratio_depth.lb_depth = dm_lb_16;
   2147 			pipes[pipe_cnt].pipe.scale_ratio_depth.hscl_ratio = (double) scl->ratios.horz.value / (1ULL<<32);
   2148 			pipes[pipe_cnt].pipe.scale_ratio_depth.hscl_ratio_c = (double) scl->ratios.horz_c.value / (1ULL<<32);
   2149 			pipes[pipe_cnt].pipe.scale_ratio_depth.vscl_ratio = (double) scl->ratios.vert.value / (1ULL<<32);
   2150 			pipes[pipe_cnt].pipe.scale_ratio_depth.vscl_ratio_c = (double) scl->ratios.vert_c.value / (1ULL<<32);
   2151 			pipes[pipe_cnt].pipe.scale_ratio_depth.scl_enable =
   2152 					scl->ratios.vert.value != dc_fixpt_one.value
   2153 					|| scl->ratios.horz.value != dc_fixpt_one.value
   2154 					|| scl->ratios.vert_c.value != dc_fixpt_one.value
   2155 					|| scl->ratios.horz_c.value != dc_fixpt_one.value /*Lb only or Full scl*/
   2156 					|| dc->debug.always_scale; /*support always scale*/
   2157 			pipes[pipe_cnt].pipe.scale_taps.htaps = scl->taps.h_taps;
   2158 			pipes[pipe_cnt].pipe.scale_taps.htaps_c = scl->taps.h_taps_c;
   2159 			pipes[pipe_cnt].pipe.scale_taps.vtaps = scl->taps.v_taps;
   2160 			pipes[pipe_cnt].pipe.scale_taps.vtaps_c = scl->taps.v_taps_c;
   2161 
   2162 			pipes[pipe_cnt].pipe.src.macro_tile_size =
   2163 					swizzle_mode_to_macro_tile_size(pln->tiling_info.gfx9.swizzle);
   2164 			swizzle_to_dml_params(pln->tiling_info.gfx9.swizzle,
   2165 					&pipes[pipe_cnt].pipe.src.sw_mode);
   2166 
   2167 			switch (pln->format) {
   2168 			case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
   2169 			case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
   2170 				pipes[pipe_cnt].pipe.src.source_format = dm_420_8;
   2171 				break;
   2172 			case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr:
   2173 			case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb:
   2174 				pipes[pipe_cnt].pipe.src.source_format = dm_420_10;
   2175 				break;
   2176 			case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
   2177 			case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
   2178 			case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
   2179 				pipes[pipe_cnt].pipe.src.source_format = dm_444_64;
   2180 				break;
   2181 			case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555:
   2182 			case SURFACE_PIXEL_FORMAT_GRPH_RGB565:
   2183 				pipes[pipe_cnt].pipe.src.source_format = dm_444_16;
   2184 				break;
   2185 			case SURFACE_PIXEL_FORMAT_GRPH_PALETA_256_COLORS:
   2186 				pipes[pipe_cnt].pipe.src.source_format = dm_444_8;
   2187 				break;
   2188 			default:
   2189 				pipes[pipe_cnt].pipe.src.source_format = dm_444_32;
   2190 				break;
   2191 			}
   2192 		}
   2193 
   2194 		pipe_cnt++;
   2195 	}
   2196 
   2197 	/* populate writeback information */
   2198 	dc->res_pool->funcs->populate_dml_writeback_from_context(dc, res_ctx, pipes);
   2199 
   2200 	return pipe_cnt;
   2201 }
   2202 
   2203 unsigned int dcn20_calc_max_scaled_time(
   2204 		unsigned int time_per_pixel,
   2205 		enum mmhubbub_wbif_mode mode,
   2206 		unsigned int urgent_watermark)
   2207 {
   2208 	unsigned int time_per_byte = 0;
   2209 	unsigned int total_y_free_entry = 0x200; /* two memory piece for luma */
   2210 	unsigned int total_c_free_entry = 0x140; /* two memory piece for chroma */
   2211 	unsigned int small_free_entry, max_free_entry;
   2212 	unsigned int buf_lh_capability;
   2213 	unsigned int max_scaled_time;
   2214 
   2215 	if (mode == PACKED_444) /* packed mode */
   2216 		time_per_byte = time_per_pixel/4;
   2217 	else if (mode == PLANAR_420_8BPC)
   2218 		time_per_byte  = time_per_pixel;
   2219 	else if (mode == PLANAR_420_10BPC) /* p010 */
   2220 		time_per_byte  = time_per_pixel * 819/1024;
   2221 
   2222 	if (time_per_byte == 0)
   2223 		time_per_byte = 1;
   2224 
   2225 	small_free_entry  = (total_y_free_entry > total_c_free_entry) ? total_c_free_entry : total_y_free_entry;
   2226 	max_free_entry    = (mode == PACKED_444) ? total_y_free_entry + total_c_free_entry : small_free_entry;
   2227 	buf_lh_capability = max_free_entry*time_per_byte*32/16; /* there is 4bit fraction */
   2228 	max_scaled_time   = buf_lh_capability - urgent_watermark;
   2229 	return max_scaled_time;
   2230 }
   2231 
   2232 void dcn20_set_mcif_arb_params(
   2233 		struct dc *dc,
   2234 		struct dc_state *context,
   2235 		display_e2e_pipe_params_st *pipes,
   2236 		int pipe_cnt)
   2237 {
   2238 	enum mmhubbub_wbif_mode wbif_mode;
   2239 	struct mcif_arb_params *wb_arb_params;
   2240 	int i, j, k, dwb_pipe;
   2241 
   2242 	/* Writeback MCIF_WB arbitration parameters */
   2243 	dwb_pipe = 0;
   2244 	for (i = 0; i < dc->res_pool->pipe_count; i++) {
   2245 
   2246 		if (!context->res_ctx.pipe_ctx[i].stream)
   2247 			continue;
   2248 
   2249 		for (j = 0; j < MAX_DWB_PIPES; j++) {
   2250 			if (context->res_ctx.pipe_ctx[i].stream->writeback_info[j].wb_enabled == false)
   2251 				continue;
   2252 
   2253 			//wb_arb_params = &context->res_ctx.pipe_ctx[i].stream->writeback_info[j].mcif_arb_params;
   2254 			wb_arb_params = &context->bw_ctx.bw.dcn.bw_writeback.mcif_wb_arb[dwb_pipe];
   2255 
   2256 			if (context->res_ctx.pipe_ctx[i].stream->writeback_info[j].dwb_params.out_format == dwb_scaler_mode_yuv420) {
   2257 				if (context->res_ctx.pipe_ctx[i].stream->writeback_info[j].dwb_params.output_depth == DWB_OUTPUT_PIXEL_DEPTH_8BPC)
   2258 					wbif_mode = PLANAR_420_8BPC;
   2259 				else
   2260 					wbif_mode = PLANAR_420_10BPC;
   2261 			} else
   2262 				wbif_mode = PACKED_444;
   2263 
   2264 			for (k = 0; k < sizeof(wb_arb_params->cli_watermark)/sizeof(wb_arb_params->cli_watermark[0]); k++) {
   2265 				wb_arb_params->cli_watermark[k] = get_wm_writeback_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
   2266 				wb_arb_params->pstate_watermark[k] = get_wm_writeback_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
   2267 			}
   2268 			wb_arb_params->time_per_pixel = 16.0 / context->res_ctx.pipe_ctx[i].stream->phy_pix_clk; /* 4 bit fraction, ms */
   2269 			wb_arb_params->slice_lines = 32;
   2270 			wb_arb_params->arbitration_slice = 2;
   2271 			wb_arb_params->max_scaled_time = dcn20_calc_max_scaled_time(wb_arb_params->time_per_pixel,
   2272 				wbif_mode,
   2273 				wb_arb_params->cli_watermark[0]); /* assume 4 watermark sets have the same value */
   2274 
   2275 			dwb_pipe++;
   2276 
   2277 			if (dwb_pipe >= MAX_DWB_PIPES)
   2278 				return;
   2279 		}
   2280 		if (dwb_pipe >= MAX_DWB_PIPES)
   2281 			return;
   2282 	}
   2283 }
   2284 
   2285 bool dcn20_validate_dsc(struct dc *dc, struct dc_state *new_ctx)
   2286 {
   2287 	int i;
   2288 
   2289 	/* Validate DSC config, dsc count validation is already done */
   2290 	for (i = 0; i < dc->res_pool->pipe_count; i++) {
   2291 		struct pipe_ctx *pipe_ctx = &new_ctx->res_ctx.pipe_ctx[i];
   2292 		struct dc_stream_state *stream = pipe_ctx->stream;
   2293 		struct dsc_config dsc_cfg;
   2294 		struct pipe_ctx *odm_pipe;
   2295 		int opp_cnt = 1;
   2296 
   2297 		for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
   2298 			opp_cnt++;
   2299 
   2300 		/* Only need to validate top pipe */
   2301 		if (pipe_ctx->top_pipe || pipe_ctx->prev_odm_pipe || !stream || !stream->timing.flags.DSC)
   2302 			continue;
   2303 
   2304 		dsc_cfg.pic_width = (stream->timing.h_addressable + stream->timing.h_border_left
   2305 				+ stream->timing.h_border_right) / opp_cnt;
   2306 		dsc_cfg.pic_height = stream->timing.v_addressable + stream->timing.v_border_top
   2307 				+ stream->timing.v_border_bottom;
   2308 		dsc_cfg.pixel_encoding = stream->timing.pixel_encoding;
   2309 		dsc_cfg.color_depth = stream->timing.display_color_depth;
   2310 		dsc_cfg.dc_dsc_cfg = stream->timing.dsc_cfg;
   2311 		dsc_cfg.dc_dsc_cfg.num_slices_h /= opp_cnt;
   2312 
   2313 		if (!pipe_ctx->stream_res.dsc->funcs->dsc_validate_stream(pipe_ctx->stream_res.dsc, &dsc_cfg))
   2314 			return false;
   2315 	}
   2316 	return true;
   2317 }
   2318 
   2319 struct pipe_ctx *dcn20_find_secondary_pipe(struct dc *dc,
   2320 		struct resource_context *res_ctx,
   2321 		const struct resource_pool *pool,
   2322 		const struct pipe_ctx *primary_pipe)
   2323 {
   2324 	struct pipe_ctx *secondary_pipe = NULL;
   2325 
   2326 	if (dc && primary_pipe) {
   2327 		int j;
   2328 		int preferred_pipe_idx = 0;
   2329 
   2330 		/* first check the prev dc state:
   2331 		 * if this primary pipe has a bottom pipe in prev. state
   2332 		 * and if the bottom pipe is still available (which it should be),
   2333 		 * pick that pipe as secondary
   2334 		 * Same logic applies for ODM pipes. Since mpo is not allowed with odm
   2335 		 * check in else case.
   2336 		 */
   2337 		if (dc->current_state->res_ctx.pipe_ctx[primary_pipe->pipe_idx].bottom_pipe) {
   2338 			preferred_pipe_idx = dc->current_state->res_ctx.pipe_ctx[primary_pipe->pipe_idx].bottom_pipe->pipe_idx;
   2339 			if (res_ctx->pipe_ctx[preferred_pipe_idx].stream == NULL) {
   2340 				secondary_pipe = &res_ctx->pipe_ctx[preferred_pipe_idx];
   2341 				secondary_pipe->pipe_idx = preferred_pipe_idx;
   2342 			}
   2343 		} else if (dc->current_state->res_ctx.pipe_ctx[primary_pipe->pipe_idx].next_odm_pipe) {
   2344 			preferred_pipe_idx = dc->current_state->res_ctx.pipe_ctx[primary_pipe->pipe_idx].next_odm_pipe->pipe_idx;
   2345 			if (res_ctx->pipe_ctx[preferred_pipe_idx].stream == NULL) {
   2346 				secondary_pipe = &res_ctx->pipe_ctx[preferred_pipe_idx];
   2347 				secondary_pipe->pipe_idx = preferred_pipe_idx;
   2348 			}
   2349 		}
   2350 
   2351 		/*
   2352 		 * if this primary pipe does not have a bottom pipe in prev. state
   2353 		 * start backward and find a pipe that did not used to be a bottom pipe in
   2354 		 * prev. dc state. This way we make sure we keep the same assignment as
   2355 		 * last state and will not have to reprogram every pipe
   2356 		 */
   2357 		if (secondary_pipe == NULL) {
   2358 			for (j = dc->res_pool->pipe_count - 1; j >= 0; j--) {
   2359 				if (dc->current_state->res_ctx.pipe_ctx[j].top_pipe == NULL
   2360 						&& dc->current_state->res_ctx.pipe_ctx[j].prev_odm_pipe == NULL) {
   2361 					preferred_pipe_idx = j;
   2362 
   2363 					if (res_ctx->pipe_ctx[preferred_pipe_idx].stream == NULL) {
   2364 						secondary_pipe = &res_ctx->pipe_ctx[preferred_pipe_idx];
   2365 						secondary_pipe->pipe_idx = preferred_pipe_idx;
   2366 						break;
   2367 					}
   2368 				}
   2369 			}
   2370 		}
   2371 		/*
   2372 		 * We should never hit this assert unless assignments are shuffled around
   2373 		 * if this happens we will prob. hit a vsync tdr
   2374 		 */
   2375 		ASSERT(secondary_pipe);
   2376 		/*
   2377 		 * search backwards for the second pipe to keep pipe
   2378 		 * assignment more consistent
   2379 		 */
   2380 		if (secondary_pipe == NULL) {
   2381 			for (j = dc->res_pool->pipe_count - 1; j >= 0; j--) {
   2382 				preferred_pipe_idx = j;
   2383 
   2384 				if (res_ctx->pipe_ctx[preferred_pipe_idx].stream == NULL) {
   2385 					secondary_pipe = &res_ctx->pipe_ctx[preferred_pipe_idx];
   2386 					secondary_pipe->pipe_idx = preferred_pipe_idx;
   2387 					break;
   2388 				}
   2389 			}
   2390 		}
   2391 	}
   2392 
   2393 	return secondary_pipe;
   2394 }
   2395 
   2396 void dcn20_merge_pipes_for_validate(
   2397 		struct dc *dc,
   2398 		struct dc_state *context)
   2399 {
   2400 	int i;
   2401 
   2402 	/* merge previously split odm pipes since mode support needs to make the decision */
   2403 	for (i = 0; i < dc->res_pool->pipe_count; i++) {
   2404 		struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
   2405 		struct pipe_ctx *odm_pipe = pipe->next_odm_pipe;
   2406 
   2407 		if (pipe->prev_odm_pipe)
   2408 			continue;
   2409 
   2410 		pipe->next_odm_pipe = NULL;
   2411 		while (odm_pipe) {
   2412 			struct pipe_ctx *next_odm_pipe = odm_pipe->next_odm_pipe;
   2413 
   2414 			odm_pipe->plane_state = NULL;
   2415 			odm_pipe->stream = NULL;
   2416 			odm_pipe->top_pipe = NULL;
   2417 			odm_pipe->bottom_pipe = NULL;
   2418 			odm_pipe->prev_odm_pipe = NULL;
   2419 			odm_pipe->next_odm_pipe = NULL;
   2420 			if (odm_pipe->stream_res.dsc)
   2421 				release_dsc(&context->res_ctx, dc->res_pool, &odm_pipe->stream_res.dsc);
   2422 			/* Clear plane_res and stream_res */
   2423 			memset(&odm_pipe->plane_res, 0, sizeof(odm_pipe->plane_res));
   2424 			memset(&odm_pipe->stream_res, 0, sizeof(odm_pipe->stream_res));
   2425 			odm_pipe = next_odm_pipe;
   2426 		}
   2427 		if (pipe->plane_state)
   2428 			resource_build_scaling_params(pipe);
   2429 	}
   2430 
   2431 	/* merge previously mpc split pipes since mode support needs to make the decision */
   2432 	for (i = 0; i < dc->res_pool->pipe_count; i++) {
   2433 		struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
   2434 		struct pipe_ctx *hsplit_pipe = pipe->bottom_pipe;
   2435 
   2436 		if (!hsplit_pipe || hsplit_pipe->plane_state != pipe->plane_state)
   2437 			continue;
   2438 
   2439 		pipe->bottom_pipe = hsplit_pipe->bottom_pipe;
   2440 		if (hsplit_pipe->bottom_pipe)
   2441 			hsplit_pipe->bottom_pipe->top_pipe = pipe;
   2442 		hsplit_pipe->plane_state = NULL;
   2443 		hsplit_pipe->stream = NULL;
   2444 		hsplit_pipe->top_pipe = NULL;
   2445 		hsplit_pipe->bottom_pipe = NULL;
   2446 
   2447 		/* Clear plane_res and stream_res */
   2448 		memset(&hsplit_pipe->plane_res, 0, sizeof(hsplit_pipe->plane_res));
   2449 		memset(&hsplit_pipe->stream_res, 0, sizeof(hsplit_pipe->stream_res));
   2450 		if (pipe->plane_state)
   2451 			resource_build_scaling_params(pipe);
   2452 	}
   2453 }
   2454 
   2455 int dcn20_validate_apply_pipe_split_flags(
   2456 		struct dc *dc,
   2457 		struct dc_state *context,
   2458 		int vlevel,
   2459 		bool *split)
   2460 {
   2461 	int i, pipe_idx, vlevel_split;
   2462 	bool force_split = false;
   2463 	bool avoid_split = dc->debug.pipe_split_policy != MPC_SPLIT_DYNAMIC;
   2464 
   2465 	/* Single display loop, exits if there is more than one display */
   2466 	for (i = 0; i < dc->res_pool->pipe_count; i++) {
   2467 		struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
   2468 		bool exit_loop = false;
   2469 
   2470 		if (!pipe->stream || pipe->top_pipe)
   2471 			continue;
   2472 
   2473 		if (dc->debug.force_single_disp_pipe_split) {
   2474 			if (!force_split)
   2475 				force_split = true;
   2476 			else {
   2477 				force_split = false;
   2478 				exit_loop = true;
   2479 			}
   2480 		}
   2481 		if (dc->debug.pipe_split_policy == MPC_SPLIT_AVOID_MULT_DISP) {
   2482 			if (avoid_split)
   2483 				avoid_split = false;
   2484 			else {
   2485 				avoid_split = true;
   2486 				exit_loop = true;
   2487 			}
   2488 		}
   2489 		if (exit_loop)
   2490 			break;
   2491 	}
   2492 	/* TODO: fix dc bugs and remove this split threshold thing */
   2493 	if (context->stream_count > dc->res_pool->pipe_count / 2)
   2494 		avoid_split = true;
   2495 
   2496 	/* Avoid split loop looks for lowest voltage level that allows most unsplit pipes possible */
   2497 	if (avoid_split) {
   2498 		for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) {
   2499 			if (!context->res_ctx.pipe_ctx[i].stream)
   2500 				continue;
   2501 
   2502 			for (vlevel_split = vlevel; vlevel <= context->bw_ctx.dml.soc.num_states; vlevel++)
   2503 				if (context->bw_ctx.dml.vba.NoOfDPP[vlevel][0][pipe_idx] == 1)
   2504 					break;
   2505 			/* Impossible to not split this pipe */
   2506 			if (vlevel > context->bw_ctx.dml.soc.num_states)
   2507 				vlevel = vlevel_split;
   2508 			pipe_idx++;
   2509 		}
   2510 		context->bw_ctx.dml.vba.maxMpcComb = 0;
   2511 	}
   2512 
   2513 	/* Split loop sets which pipe should be split based on dml outputs and dc flags */
   2514 	for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) {
   2515 		struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
   2516 
   2517 		if (!context->res_ctx.pipe_ctx[i].stream)
   2518 			continue;
   2519 
   2520 		if (force_split || context->bw_ctx.dml.vba.NoOfDPP[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx] > 1)
   2521 			split[i] = true;
   2522 		if ((pipe->stream->view_format ==
   2523 				VIEW_3D_FORMAT_SIDE_BY_SIDE ||
   2524 				pipe->stream->view_format ==
   2525 				VIEW_3D_FORMAT_TOP_AND_BOTTOM) &&
   2526 				(pipe->stream->timing.timing_3d_format ==
   2527 				TIMING_3D_FORMAT_TOP_AND_BOTTOM ||
   2528 				 pipe->stream->timing.timing_3d_format ==
   2529 				TIMING_3D_FORMAT_SIDE_BY_SIDE))
   2530 			split[i] = true;
   2531 		if (dc->debug.force_odm_combine & (1 << pipe->stream_res.tg->inst)) {
   2532 			split[i] = true;
   2533 			context->bw_ctx.dml.vba.ODMCombineEnablePerState[vlevel][pipe_idx] = dm_odm_combine_mode_2to1;
   2534 		}
   2535 		context->bw_ctx.dml.vba.ODMCombineEnabled[pipe_idx] =
   2536 			context->bw_ctx.dml.vba.ODMCombineEnablePerState[vlevel][pipe_idx];
   2537 		/* Adjust dppclk when split is forced, do not bother with dispclk */
   2538 		if (split[i] && context->bw_ctx.dml.vba.NoOfDPP[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx] == 1)
   2539 			context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx] /= 2;
   2540 		pipe_idx++;
   2541 	}
   2542 
   2543 	return vlevel;
   2544 }
   2545 
   2546 bool dcn20_fast_validate_bw(
   2547 		struct dc *dc,
   2548 		struct dc_state *context,
   2549 		display_e2e_pipe_params_st *pipes,
   2550 		int *pipe_cnt_out,
   2551 		int *pipe_split_from,
   2552 		int *vlevel_out)
   2553 {
   2554 	bool out = false;
   2555 	bool split[MAX_PIPES] = { false };
   2556 	int pipe_cnt, i, pipe_idx, vlevel;
   2557 
   2558 	ASSERT(pipes);
   2559 	if (!pipes)
   2560 		return false;
   2561 
   2562 	dcn20_merge_pipes_for_validate(dc, context);
   2563 
   2564 	pipe_cnt = dc->res_pool->funcs->populate_dml_pipes(dc, context, pipes);
   2565 
   2566 	*pipe_cnt_out = pipe_cnt;
   2567 
   2568 	if (!pipe_cnt) {
   2569 		out = true;
   2570 		goto validate_out;
   2571 	}
   2572 
   2573 	vlevel = dml_get_voltage_level(&context->bw_ctx.dml, pipes, pipe_cnt);
   2574 
   2575 	if (vlevel > context->bw_ctx.dml.soc.num_states)
   2576 		goto validate_fail;
   2577 
   2578 	vlevel = dcn20_validate_apply_pipe_split_flags(dc, context, vlevel, split);
   2579 
   2580 	/*initialize pipe_just_split_from to invalid idx*/
   2581 	for (i = 0; i < MAX_PIPES; i++)
   2582 		pipe_split_from[i] = -1;
   2583 
   2584 	for (i = 0, pipe_idx = -1; i < dc->res_pool->pipe_count; i++) {
   2585 		struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
   2586 		struct pipe_ctx *hsplit_pipe = pipe->bottom_pipe;
   2587 
   2588 		if (!pipe->stream || pipe_split_from[i] >= 0)
   2589 			continue;
   2590 
   2591 		pipe_idx++;
   2592 
   2593 		if (!pipe->top_pipe && !pipe->plane_state && context->bw_ctx.dml.vba.ODMCombineEnabled[pipe_idx]) {
   2594 			hsplit_pipe = dcn20_find_secondary_pipe(dc, &context->res_ctx, dc->res_pool, pipe);
   2595 			ASSERT(hsplit_pipe);
   2596 			if (!dcn20_split_stream_for_odm(
   2597 					&context->res_ctx, dc->res_pool,
   2598 					pipe, hsplit_pipe))
   2599 				goto validate_fail;
   2600 			pipe_split_from[hsplit_pipe->pipe_idx] = pipe_idx;
   2601 			dcn20_build_mapped_resource(dc, context, pipe->stream);
   2602 		}
   2603 
   2604 		if (!pipe->plane_state)
   2605 			continue;
   2606 		/* Skip 2nd half of already split pipe */
   2607 		if (pipe->top_pipe && pipe->plane_state == pipe->top_pipe->plane_state)
   2608 			continue;
   2609 
   2610 		/* We do not support mpo + odm at the moment */
   2611 		if (hsplit_pipe && hsplit_pipe->plane_state != pipe->plane_state
   2612 				&& context->bw_ctx.dml.vba.ODMCombineEnabled[pipe_idx])
   2613 			goto validate_fail;
   2614 
   2615 		if (split[i]) {
   2616 			if (!hsplit_pipe || hsplit_pipe->plane_state != pipe->plane_state) {
   2617 				/* pipe not split previously needs split */
   2618 				hsplit_pipe = dcn20_find_secondary_pipe(dc, &context->res_ctx, dc->res_pool, pipe);
   2619 				ASSERT(hsplit_pipe);
   2620 				if (!hsplit_pipe) {
   2621 					context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx] *= 2;
   2622 					continue;
   2623 				}
   2624 				if (context->bw_ctx.dml.vba.ODMCombineEnabled[pipe_idx]) {
   2625 					if (!dcn20_split_stream_for_odm(
   2626 							&context->res_ctx, dc->res_pool,
   2627 							pipe, hsplit_pipe))
   2628 						goto validate_fail;
   2629 					dcn20_build_mapped_resource(dc, context, pipe->stream);
   2630 				} else
   2631 					dcn20_split_stream_for_mpc(
   2632 						&context->res_ctx, dc->res_pool,
   2633 						pipe, hsplit_pipe);
   2634 				pipe_split_from[hsplit_pipe->pipe_idx] = pipe_idx;
   2635 			}
   2636 		} else if (hsplit_pipe && hsplit_pipe->plane_state == pipe->plane_state) {
   2637 			/* merge should already have been done */
   2638 			ASSERT(0);
   2639 		}
   2640 	}
   2641 	/* Actual dsc count per stream dsc validation*/
   2642 	if (!dcn20_validate_dsc(dc, context)) {
   2643 		context->bw_ctx.dml.vba.ValidationStatus[context->bw_ctx.dml.vba.soc.num_states] =
   2644 				DML_FAIL_DSC_VALIDATION_FAILURE;
   2645 		goto validate_fail;
   2646 	}
   2647 
   2648 	*vlevel_out = vlevel;
   2649 
   2650 	out = true;
   2651 	goto validate_out;
   2652 
   2653 validate_fail:
   2654 	out = false;
   2655 
   2656 validate_out:
   2657 	return out;
   2658 }
   2659 
   2660 static void dcn20_calculate_wm(
   2661 		struct dc *dc, struct dc_state *context,
   2662 		display_e2e_pipe_params_st *pipes,
   2663 		int *out_pipe_cnt,
   2664 		int *pipe_split_from,
   2665 		int vlevel)
   2666 {
   2667 	int pipe_cnt, i, pipe_idx;
   2668 
   2669 	for (i = 0, pipe_idx = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {
   2670 		if (!context->res_ctx.pipe_ctx[i].stream)
   2671 			continue;
   2672 
   2673 		pipes[pipe_cnt].clks_cfg.refclk_mhz = dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000.0;
   2674 		pipes[pipe_cnt].clks_cfg.dispclk_mhz = context->bw_ctx.dml.vba.RequiredDISPCLK[vlevel][context->bw_ctx.dml.vba.maxMpcComb];
   2675 
   2676 		if (pipe_split_from[i] < 0) {
   2677 			pipes[pipe_cnt].clks_cfg.dppclk_mhz =
   2678 					context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx];
   2679 			if (context->bw_ctx.dml.vba.BlendingAndTiming[pipe_idx] == pipe_idx)
   2680 				pipes[pipe_cnt].pipe.dest.odm_combine =
   2681 						context->bw_ctx.dml.vba.ODMCombineEnabled[pipe_idx];
   2682 			else
   2683 				pipes[pipe_cnt].pipe.dest.odm_combine = 0;
   2684 			pipe_idx++;
   2685 		} else {
   2686 			pipes[pipe_cnt].clks_cfg.dppclk_mhz =
   2687 					context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_split_from[i]];
   2688 			if (context->bw_ctx.dml.vba.BlendingAndTiming[pipe_split_from[i]] == pipe_split_from[i])
   2689 				pipes[pipe_cnt].pipe.dest.odm_combine =
   2690 						context->bw_ctx.dml.vba.ODMCombineEnabled[pipe_split_from[i]];
   2691 			else
   2692 				pipes[pipe_cnt].pipe.dest.odm_combine = 0;
   2693 		}
   2694 
   2695 		if (dc->config.forced_clocks) {
   2696 			pipes[pipe_cnt].clks_cfg.dispclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dispclk_mhz;
   2697 			pipes[pipe_cnt].clks_cfg.dppclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dppclk_mhz;
   2698 		}
   2699 		if (dc->debug.min_disp_clk_khz > pipes[pipe_cnt].clks_cfg.dispclk_mhz * 1000)
   2700 			pipes[pipe_cnt].clks_cfg.dispclk_mhz = dc->debug.min_disp_clk_khz / 1000.0;
   2701 		if (dc->debug.min_dpp_clk_khz > pipes[pipe_cnt].clks_cfg.dppclk_mhz * 1000)
   2702 			pipes[pipe_cnt].clks_cfg.dppclk_mhz = dc->debug.min_dpp_clk_khz / 1000.0;
   2703 
   2704 		pipe_cnt++;
   2705 	}
   2706 
   2707 	if (pipe_cnt != pipe_idx) {
   2708 		if (dc->res_pool->funcs->populate_dml_pipes)
   2709 			pipe_cnt = dc->res_pool->funcs->populate_dml_pipes(dc,
   2710 				context, pipes);
   2711 		else
   2712 			pipe_cnt = dcn20_populate_dml_pipes_from_context(dc,
   2713 				context, pipes);
   2714 	}
   2715 
   2716 	*out_pipe_cnt = pipe_cnt;
   2717 
   2718 	pipes[0].clks_cfg.voltage = vlevel;
   2719 	pipes[0].clks_cfg.dcfclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel].dcfclk_mhz;
   2720 	pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel].socclk_mhz;
   2721 
   2722 	/* only pipe 0 is read for voltage and dcf/soc clocks */
   2723 	if (vlevel < 1) {
   2724 		pipes[0].clks_cfg.voltage = 1;
   2725 		pipes[0].clks_cfg.dcfclk_mhz = context->bw_ctx.dml.soc.clock_limits[1].dcfclk_mhz;
   2726 		pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[1].socclk_mhz;
   2727 	}
   2728 	context->bw_ctx.bw.dcn.watermarks.b.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
   2729 	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;
   2730 	context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
   2731 	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;
   2732 	context->bw_ctx.bw.dcn.watermarks.b.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
   2733 	context->bw_ctx.bw.dcn.watermarks.b.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
   2734 	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;
   2735 	context->bw_ctx.bw.dcn.watermarks.b.urgent_latency_ns = get_urgent_latency(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
   2736 
   2737 	if (vlevel < 2) {
   2738 		pipes[0].clks_cfg.voltage = 2;
   2739 		pipes[0].clks_cfg.dcfclk_mhz = context->bw_ctx.dml.soc.clock_limits[2].dcfclk_mhz;
   2740 		pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[2].socclk_mhz;
   2741 	}
   2742 	context->bw_ctx.bw.dcn.watermarks.c.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
   2743 	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;
   2744 	context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
   2745 	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;
   2746 	context->bw_ctx.bw.dcn.watermarks.c.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
   2747 	context->bw_ctx.bw.dcn.watermarks.c.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
   2748 	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;
   2749 
   2750 	if (vlevel < 3) {
   2751 		pipes[0].clks_cfg.voltage = 3;
   2752 		pipes[0].clks_cfg.dcfclk_mhz = context->bw_ctx.dml.soc.clock_limits[2].dcfclk_mhz;
   2753 		pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[2].socclk_mhz;
   2754 	}
   2755 	context->bw_ctx.bw.dcn.watermarks.d.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
   2756 	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;
   2757 	context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
   2758 	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;
   2759 	context->bw_ctx.bw.dcn.watermarks.d.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
   2760 	context->bw_ctx.bw.dcn.watermarks.d.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
   2761 	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;
   2762 
   2763 	pipes[0].clks_cfg.voltage = vlevel;
   2764 	pipes[0].clks_cfg.dcfclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel].dcfclk_mhz;
   2765 	pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel].socclk_mhz;
   2766 	context->bw_ctx.bw.dcn.watermarks.a.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
   2767 	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;
   2768 	context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
   2769 	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;
   2770 	context->bw_ctx.bw.dcn.watermarks.a.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
   2771 	context->bw_ctx.bw.dcn.watermarks.a.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
   2772 	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;
   2773 }
   2774 
   2775 void dcn20_calculate_dlg_params(
   2776 		struct dc *dc, struct dc_state *context,
   2777 		display_e2e_pipe_params_st *pipes,
   2778 		int pipe_cnt,
   2779 		int vlevel)
   2780 {
   2781 	int i, j, pipe_idx, pipe_idx_unsplit;
   2782 	bool visited[MAX_PIPES] = { 0 };
   2783 
   2784 	/* Writeback MCIF_WB arbitration parameters */
   2785 	dc->res_pool->funcs->set_mcif_arb_params(dc, context, pipes, pipe_cnt);
   2786 
   2787 	context->bw_ctx.bw.dcn.clk.dispclk_khz = context->bw_ctx.dml.vba.DISPCLK * 1000;
   2788 	context->bw_ctx.bw.dcn.clk.dcfclk_khz = context->bw_ctx.dml.vba.DCFCLK * 1000;
   2789 	context->bw_ctx.bw.dcn.clk.socclk_khz = context->bw_ctx.dml.vba.SOCCLK * 1000;
   2790 	context->bw_ctx.bw.dcn.clk.dramclk_khz = context->bw_ctx.dml.vba.DRAMSpeed * 1000 / 16;
   2791 	context->bw_ctx.bw.dcn.clk.dcfclk_deep_sleep_khz = context->bw_ctx.dml.vba.DCFCLKDeepSleep * 1000;
   2792 	context->bw_ctx.bw.dcn.clk.fclk_khz = context->bw_ctx.dml.vba.FabricClock * 1000;
   2793 	context->bw_ctx.bw.dcn.clk.p_state_change_support =
   2794 		context->bw_ctx.dml.vba.DRAMClockChangeSupport[vlevel][context->bw_ctx.dml.vba.maxMpcComb]
   2795 							!= dm_dram_clock_change_unsupported;
   2796 	context->bw_ctx.bw.dcn.clk.dppclk_khz = 0;
   2797 
   2798 	/*
   2799 	 * An artifact of dml pipe split/odm is that pipes get merged back together for
   2800 	 * calculation. Therefore we need to only extract for first pipe in ascending index order
   2801 	 * and copy into the other split half.
   2802 	 */
   2803 	for (i = 0, pipe_idx = 0, pipe_idx_unsplit = 0; i < dc->res_pool->pipe_count; i++) {
   2804 		if (!context->res_ctx.pipe_ctx[i].stream)
   2805 			continue;
   2806 
   2807 		if (!visited[pipe_idx]) {
   2808 			display_pipe_source_params_st *src = &pipes[pipe_idx].pipe.src;
   2809 			display_pipe_dest_params_st *dst = &pipes[pipe_idx].pipe.dest;
   2810 
   2811 			dst->vstartup_start = context->bw_ctx.dml.vba.VStartup[pipe_idx_unsplit];
   2812 			dst->vupdate_offset = context->bw_ctx.dml.vba.VUpdateOffsetPix[pipe_idx_unsplit];
   2813 			dst->vupdate_width = context->bw_ctx.dml.vba.VUpdateWidthPix[pipe_idx_unsplit];
   2814 			dst->vready_offset = context->bw_ctx.dml.vba.VReadyOffsetPix[pipe_idx_unsplit];
   2815 			/*
   2816 			 * j iterates inside pipes array, unlike i which iterates inside
   2817 			 * pipe_ctx array
   2818 			 */
   2819 			if (src->is_hsplit)
   2820 				for (j = pipe_idx + 1; j < pipe_cnt; j++) {
   2821 					display_pipe_source_params_st *src_j = &pipes[j].pipe.src;
   2822 					display_pipe_dest_params_st *dst_j = &pipes[j].pipe.dest;
   2823 
   2824 					if (src_j->is_hsplit && !visited[j]
   2825 							&& src->hsplit_grp == src_j->hsplit_grp) {
   2826 						dst_j->vstartup_start = context->bw_ctx.dml.vba.VStartup[pipe_idx_unsplit];
   2827 						dst_j->vupdate_offset = context->bw_ctx.dml.vba.VUpdateOffsetPix[pipe_idx_unsplit];
   2828 						dst_j->vupdate_width = context->bw_ctx.dml.vba.VUpdateWidthPix[pipe_idx_unsplit];
   2829 						dst_j->vready_offset = context->bw_ctx.dml.vba.VReadyOffsetPix[pipe_idx_unsplit];
   2830 						visited[j] = true;
   2831 					}
   2832 				}
   2833 			visited[pipe_idx] = true;
   2834 			pipe_idx_unsplit++;
   2835 		}
   2836 		pipe_idx++;
   2837 	}
   2838 
   2839 	for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) {
   2840 		if (!context->res_ctx.pipe_ctx[i].stream)
   2841 			continue;
   2842 		if (context->bw_ctx.bw.dcn.clk.dppclk_khz < pipes[pipe_idx].clks_cfg.dppclk_mhz * 1000)
   2843 			context->bw_ctx.bw.dcn.clk.dppclk_khz = pipes[pipe_idx].clks_cfg.dppclk_mhz * 1000;
   2844 		context->res_ctx.pipe_ctx[i].plane_res.bw.dppclk_khz =
   2845 						pipes[pipe_idx].clks_cfg.dppclk_mhz * 1000;
   2846 		ASSERT(visited[pipe_idx]);
   2847 		context->res_ctx.pipe_ctx[i].pipe_dlg_param = pipes[pipe_idx].pipe.dest;
   2848 		pipe_idx++;
   2849 	}
   2850 	/*save a original dppclock copy*/
   2851 	context->bw_ctx.bw.dcn.clk.bw_dppclk_khz = context->bw_ctx.bw.dcn.clk.dppclk_khz;
   2852 	context->bw_ctx.bw.dcn.clk.bw_dispclk_khz = context->bw_ctx.bw.dcn.clk.dispclk_khz;
   2853 	context->bw_ctx.bw.dcn.clk.max_supported_dppclk_khz = context->bw_ctx.dml.soc.clock_limits[vlevel].dppclk_mhz * 1000;
   2854 	context->bw_ctx.bw.dcn.clk.max_supported_dispclk_khz = context->bw_ctx.dml.soc.clock_limits[vlevel].dispclk_mhz * 1000;
   2855 
   2856 	for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) {
   2857 		bool cstate_en = context->bw_ctx.dml.vba.PrefetchMode[vlevel][context->bw_ctx.dml.vba.maxMpcComb] != 2;
   2858 
   2859 		if (!context->res_ctx.pipe_ctx[i].stream)
   2860 			continue;
   2861 
   2862 		context->bw_ctx.dml.funcs.rq_dlg_get_dlg_reg(&context->bw_ctx.dml,
   2863 				&context->res_ctx.pipe_ctx[i].dlg_regs,
   2864 				&context->res_ctx.pipe_ctx[i].ttu_regs,
   2865 				pipes,
   2866 				pipe_cnt,
   2867 				pipe_idx,
   2868 				cstate_en,
   2869 				context->bw_ctx.bw.dcn.clk.p_state_change_support,
   2870 				false, false, false);
   2871 
   2872 		context->bw_ctx.dml.funcs.rq_dlg_get_rq_reg(&context->bw_ctx.dml,
   2873 				&context->res_ctx.pipe_ctx[i].rq_regs,
   2874 				pipes[pipe_idx].pipe);
   2875 		pipe_idx++;
   2876 	}
   2877 }
   2878 
   2879 static bool dcn20_validate_bandwidth_internal(struct dc *dc, struct dc_state *context,
   2880 		bool fast_validate)
   2881 {
   2882 	bool out = false;
   2883 
   2884 	BW_VAL_TRACE_SETUP();
   2885 
   2886 	int vlevel = 0;
   2887 	int pipe_split_from[MAX_PIPES];
   2888 	int pipe_cnt = 0;
   2889 	display_e2e_pipe_params_st *pipes = kzalloc(dc->res_pool->pipe_count * sizeof(display_e2e_pipe_params_st), GFP_KERNEL);
   2890 	DC_LOGGER_INIT(dc->ctx->logger);
   2891 
   2892 	BW_VAL_TRACE_COUNT();
   2893 
   2894 	out = dcn20_fast_validate_bw(dc, context, pipes, &pipe_cnt, pipe_split_from, &vlevel);
   2895 
   2896 	if (pipe_cnt == 0)
   2897 		goto validate_out;
   2898 
   2899 	if (!out)
   2900 		goto validate_fail;
   2901 
   2902 	BW_VAL_TRACE_END_VOLTAGE_LEVEL();
   2903 
   2904 	if (fast_validate) {
   2905 		BW_VAL_TRACE_SKIP(fast);
   2906 		goto validate_out;
   2907 	}
   2908 
   2909 	dcn20_calculate_wm(dc, context, pipes, &pipe_cnt, pipe_split_from, vlevel);
   2910 	dcn20_calculate_dlg_params(dc, context, pipes, pipe_cnt, vlevel);
   2911 
   2912 	BW_VAL_TRACE_END_WATERMARKS();
   2913 
   2914 	goto validate_out;
   2915 
   2916 validate_fail:
   2917 	DC_LOG_WARNING("Mode Validation Warning: %s failed validation.\n",
   2918 		dml_get_status_message(context->bw_ctx.dml.vba.ValidationStatus[context->bw_ctx.dml.vba.soc.num_states]));
   2919 
   2920 	BW_VAL_TRACE_SKIP(fail);
   2921 	out = false;
   2922 
   2923 validate_out:
   2924 	kfree(pipes);
   2925 
   2926 	BW_VAL_TRACE_FINISH();
   2927 
   2928 	return out;
   2929 }
   2930 
   2931 
   2932 bool dcn20_validate_bandwidth(struct dc *dc, struct dc_state *context,
   2933 		bool fast_validate)
   2934 {
   2935 	volatile bool voltage_supported = false;
   2936 	bool full_pstate_supported = false;
   2937 	bool dummy_pstate_supported = false;
   2938 	double p_state_latency_us;
   2939 
   2940 	DC_FP_START();
   2941 	p_state_latency_us = context->bw_ctx.dml.soc.dram_clock_change_latency_us;
   2942 	context->bw_ctx.dml.soc.disable_dram_clock_change_vactive_support =
   2943 		dc->debug.disable_dram_clock_change_vactive_support;
   2944 
   2945 	if (fast_validate) {
   2946 		voltage_supported = dcn20_validate_bandwidth_internal(dc, context, true);
   2947 
   2948 		DC_FP_END();
   2949 		return voltage_supported;
   2950 	}
   2951 
   2952 	// Best case, we support full UCLK switch latency
   2953 	voltage_supported = dcn20_validate_bandwidth_internal(dc, context, false);
   2954 	full_pstate_supported = context->bw_ctx.bw.dcn.clk.p_state_change_support;
   2955 
   2956 	if (context->bw_ctx.dml.soc.dummy_pstate_latency_us == 0 ||
   2957 		(voltage_supported && full_pstate_supported)) {
   2958 		context->bw_ctx.bw.dcn.clk.p_state_change_support = full_pstate_supported;
   2959 		goto restore_dml_state;
   2960 	}
   2961 
   2962 	// Fallback: Try to only support G6 temperature read latency
   2963 	context->bw_ctx.dml.soc.dram_clock_change_latency_us = context->bw_ctx.dml.soc.dummy_pstate_latency_us;
   2964 
   2965 	voltage_supported = dcn20_validate_bandwidth_internal(dc, context, false);
   2966 	dummy_pstate_supported = context->bw_ctx.bw.dcn.clk.p_state_change_support;
   2967 
   2968 	if (voltage_supported && dummy_pstate_supported) {
   2969 		context->bw_ctx.bw.dcn.clk.p_state_change_support = false;
   2970 		goto restore_dml_state;
   2971 	}
   2972 
   2973 	// ERROR: fallback is supposed to always work.
   2974 	ASSERT(false);
   2975 
   2976 restore_dml_state:
   2977 	context->bw_ctx.dml.soc.dram_clock_change_latency_us = p_state_latency_us;
   2978 
   2979 	DC_FP_END();
   2980 	return voltage_supported;
   2981 }
   2982 
   2983 struct pipe_ctx *dcn20_acquire_idle_pipe_for_layer(
   2984 		struct dc_state *state,
   2985 		const struct resource_pool *pool,
   2986 		struct dc_stream_state *stream)
   2987 {
   2988 	struct resource_context *res_ctx = &state->res_ctx;
   2989 	struct pipe_ctx *head_pipe = resource_get_head_pipe_for_stream(res_ctx, stream);
   2990 	struct pipe_ctx *idle_pipe = find_idle_secondary_pipe(res_ctx, pool, head_pipe);
   2991 
   2992 	if (!head_pipe)
   2993 		ASSERT(0);
   2994 
   2995 	if (!idle_pipe)
   2996 		return NULL;
   2997 
   2998 	idle_pipe->stream = head_pipe->stream;
   2999 	idle_pipe->stream_res.tg = head_pipe->stream_res.tg;
   3000 	idle_pipe->stream_res.opp = head_pipe->stream_res.opp;
   3001 
   3002 	idle_pipe->plane_res.hubp = pool->hubps[idle_pipe->pipe_idx];
   3003 	idle_pipe->plane_res.ipp = pool->ipps[idle_pipe->pipe_idx];
   3004 	idle_pipe->plane_res.dpp = pool->dpps[idle_pipe->pipe_idx];
   3005 	idle_pipe->plane_res.mpcc_inst = pool->dpps[idle_pipe->pipe_idx]->inst;
   3006 
   3007 	return idle_pipe;
   3008 }
   3009 
   3010 bool dcn20_get_dcc_compression_cap(const struct dc *dc,
   3011 		const struct dc_dcc_surface_param *input,
   3012 		struct dc_surface_dcc_cap *output)
   3013 {
   3014 	return dc->res_pool->hubbub->funcs->get_dcc_compression_cap(
   3015 			dc->res_pool->hubbub,
   3016 			input,
   3017 			output);
   3018 }
   3019 
   3020 static void dcn20_destroy_resource_pool(struct resource_pool **pool)
   3021 {
   3022 	struct dcn20_resource_pool *dcn20_pool = TO_DCN20_RES_POOL(*pool);
   3023 
   3024 	dcn20_resource_destruct(dcn20_pool);
   3025 	kfree(dcn20_pool);
   3026 	*pool = NULL;
   3027 }
   3028 
   3029 
   3030 static struct dc_cap_funcs cap_funcs = {
   3031 	.get_dcc_compression_cap = dcn20_get_dcc_compression_cap
   3032 };
   3033 
   3034 
   3035 enum dc_status dcn20_get_default_swizzle_mode(struct dc_plane_state *plane_state)
   3036 {
   3037 	enum dc_status result = DC_OK;
   3038 
   3039 	enum surface_pixel_format surf_pix_format = plane_state->format;
   3040 	unsigned int bpp = resource_pixel_format_to_bpp(surf_pix_format);
   3041 
   3042 	enum swizzle_mode_values swizzle = DC_SW_LINEAR;
   3043 
   3044 	if (bpp == 64)
   3045 		swizzle = DC_SW_64KB_D;
   3046 	else
   3047 		swizzle = DC_SW_64KB_S;
   3048 
   3049 	plane_state->tiling_info.gfx9.swizzle = swizzle;
   3050 	return result;
   3051 }
   3052 
   3053 static struct resource_funcs dcn20_res_pool_funcs = {
   3054 	.destroy = dcn20_destroy_resource_pool,
   3055 	.link_enc_create = dcn20_link_encoder_create,
   3056 	.validate_bandwidth = dcn20_validate_bandwidth,
   3057 	.acquire_idle_pipe_for_layer = dcn20_acquire_idle_pipe_for_layer,
   3058 	.add_stream_to_ctx = dcn20_add_stream_to_ctx,
   3059 	.remove_stream_from_ctx = dcn20_remove_stream_from_ctx,
   3060 	.populate_dml_writeback_from_context = dcn20_populate_dml_writeback_from_context,
   3061 	.get_default_swizzle_mode = dcn20_get_default_swizzle_mode,
   3062 	.set_mcif_arb_params = dcn20_set_mcif_arb_params,
   3063 	.populate_dml_pipes = dcn20_populate_dml_pipes_from_context,
   3064 	.find_first_free_match_stream_enc_for_link = dcn10_find_first_free_match_stream_enc_for_link
   3065 };
   3066 
   3067 bool dcn20_dwbc_create(struct dc_context *ctx, struct resource_pool *pool)
   3068 {
   3069 	int i;
   3070 	uint32_t pipe_count = pool->res_cap->num_dwb;
   3071 
   3072 	for (i = 0; i < pipe_count; i++) {
   3073 		struct dcn20_dwbc *dwbc20 = kzalloc(sizeof(struct dcn20_dwbc),
   3074 						    GFP_KERNEL);
   3075 
   3076 		if (!dwbc20) {
   3077 			dm_error("DC: failed to create dwbc20!\n");
   3078 			return false;
   3079 		}
   3080 		dcn20_dwbc_construct(dwbc20, ctx,
   3081 				&dwbc20_regs[i],
   3082 				&dwbc20_shift,
   3083 				&dwbc20_mask,
   3084 				i);
   3085 		pool->dwbc[i] = &dwbc20->base;
   3086 	}
   3087 	return true;
   3088 }
   3089 
   3090 bool dcn20_mmhubbub_create(struct dc_context *ctx, struct resource_pool *pool)
   3091 {
   3092 	int i;
   3093 	uint32_t pipe_count = pool->res_cap->num_dwb;
   3094 
   3095 	ASSERT(pipe_count > 0);
   3096 
   3097 	for (i = 0; i < pipe_count; i++) {
   3098 		struct dcn20_mmhubbub *mcif_wb20 = kzalloc(sizeof(struct dcn20_mmhubbub),
   3099 						    GFP_KERNEL);
   3100 
   3101 		if (!mcif_wb20) {
   3102 			dm_error("DC: failed to create mcif_wb20!\n");
   3103 			return false;
   3104 		}
   3105 
   3106 		dcn20_mmhubbub_construct(mcif_wb20, ctx,
   3107 				&mcif_wb20_regs[i],
   3108 				&mcif_wb20_shift,
   3109 				&mcif_wb20_mask,
   3110 				i);
   3111 
   3112 		pool->mcif_wb[i] = &mcif_wb20->base;
   3113 	}
   3114 	return true;
   3115 }
   3116 
   3117 static struct pp_smu_funcs *dcn20_pp_smu_create(struct dc_context *ctx)
   3118 {
   3119 	struct pp_smu_funcs *pp_smu = kzalloc(sizeof(*pp_smu), GFP_KERNEL);
   3120 
   3121 	if (!pp_smu)
   3122 		return pp_smu;
   3123 
   3124 	dm_pp_get_funcs(ctx, pp_smu);
   3125 
   3126 	if (pp_smu->ctx.ver != PP_SMU_VER_NV)
   3127 		pp_smu = memset(pp_smu, 0, sizeof(struct pp_smu_funcs));
   3128 
   3129 	return pp_smu;
   3130 }
   3131 
   3132 static void dcn20_pp_smu_destroy(struct pp_smu_funcs **pp_smu)
   3133 {
   3134 	if (pp_smu && *pp_smu) {
   3135 		kfree(*pp_smu);
   3136 		*pp_smu = NULL;
   3137 	}
   3138 }
   3139 
   3140 void dcn20_cap_soc_clocks(
   3141 		struct _vcs_dpi_soc_bounding_box_st *bb,
   3142 		struct pp_smu_nv_clock_table max_clocks)
   3143 {
   3144 	int i;
   3145 
   3146 	// First pass - cap all clocks higher than the reported max
   3147 	for (i = 0; i < bb->num_states; i++) {
   3148 		if ((bb->clock_limits[i].dcfclk_mhz > (max_clocks.dcfClockInKhz / 1000))
   3149 				&& max_clocks.dcfClockInKhz != 0)
   3150 			bb->clock_limits[i].dcfclk_mhz = (max_clocks.dcfClockInKhz / 1000);
   3151 
   3152 		if ((bb->clock_limits[i].dram_speed_mts > (max_clocks.uClockInKhz / 1000) * 16)
   3153 						&& max_clocks.uClockInKhz != 0)
   3154 			bb->clock_limits[i].dram_speed_mts = (max_clocks.uClockInKhz / 1000) * 16;
   3155 
   3156 		if ((bb->clock_limits[i].fabricclk_mhz > (max_clocks.fabricClockInKhz / 1000))
   3157 						&& max_clocks.fabricClockInKhz != 0)
   3158 			bb->clock_limits[i].fabricclk_mhz = (max_clocks.fabricClockInKhz / 1000);
   3159 
   3160 		if ((bb->clock_limits[i].dispclk_mhz > (max_clocks.displayClockInKhz / 1000))
   3161 						&& max_clocks.displayClockInKhz != 0)
   3162 			bb->clock_limits[i].dispclk_mhz = (max_clocks.displayClockInKhz / 1000);
   3163 
   3164 		if ((bb->clock_limits[i].dppclk_mhz > (max_clocks.dppClockInKhz / 1000))
   3165 						&& max_clocks.dppClockInKhz != 0)
   3166 			bb->clock_limits[i].dppclk_mhz = (max_clocks.dppClockInKhz / 1000);
   3167 
   3168 		if ((bb->clock_limits[i].phyclk_mhz > (max_clocks.phyClockInKhz / 1000))
   3169 						&& max_clocks.phyClockInKhz != 0)
   3170 			bb->clock_limits[i].phyclk_mhz = (max_clocks.phyClockInKhz / 1000);
   3171 
   3172 		if ((bb->clock_limits[i].socclk_mhz > (max_clocks.socClockInKhz / 1000))
   3173 						&& max_clocks.socClockInKhz != 0)
   3174 			bb->clock_limits[i].socclk_mhz = (max_clocks.socClockInKhz / 1000);
   3175 
   3176 		if ((bb->clock_limits[i].dscclk_mhz > (max_clocks.dscClockInKhz / 1000))
   3177 						&& max_clocks.dscClockInKhz != 0)
   3178 			bb->clock_limits[i].dscclk_mhz = (max_clocks.dscClockInKhz / 1000);
   3179 	}
   3180 
   3181 	// Second pass - remove all duplicate clock states
   3182 	for (i = bb->num_states - 1; i > 1; i--) {
   3183 		bool duplicate = true;
   3184 
   3185 		if (bb->clock_limits[i-1].dcfclk_mhz != bb->clock_limits[i].dcfclk_mhz)
   3186 			duplicate = false;
   3187 		if (bb->clock_limits[i-1].dispclk_mhz != bb->clock_limits[i].dispclk_mhz)
   3188 			duplicate = false;
   3189 		if (bb->clock_limits[i-1].dppclk_mhz != bb->clock_limits[i].dppclk_mhz)
   3190 			duplicate = false;
   3191 		if (bb->clock_limits[i-1].dram_speed_mts != bb->clock_limits[i].dram_speed_mts)
   3192 			duplicate = false;
   3193 		if (bb->clock_limits[i-1].dscclk_mhz != bb->clock_limits[i].dscclk_mhz)
   3194 			duplicate = false;
   3195 		if (bb->clock_limits[i-1].fabricclk_mhz != bb->clock_limits[i].fabricclk_mhz)
   3196 			duplicate = false;
   3197 		if (bb->clock_limits[i-1].phyclk_mhz != bb->clock_limits[i].phyclk_mhz)
   3198 			duplicate = false;
   3199 		if (bb->clock_limits[i-1].socclk_mhz != bb->clock_limits[i].socclk_mhz)
   3200 			duplicate = false;
   3201 
   3202 		if (duplicate)
   3203 			bb->num_states--;
   3204 	}
   3205 }
   3206 
   3207 void dcn20_update_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_st *bb,
   3208 		struct pp_smu_nv_clock_table *max_clocks, unsigned int *uclk_states, unsigned int num_states)
   3209 {
   3210 	struct _vcs_dpi_voltage_scaling_st calculated_states[MAX_CLOCK_LIMIT_STATES];
   3211 	int i;
   3212 	int num_calculated_states = 0;
   3213 	int min_dcfclk = 0;
   3214 
   3215 	if (num_states == 0)
   3216 		return;
   3217 
   3218 	memset(calculated_states, 0, sizeof(calculated_states));
   3219 
   3220 	if (dc->bb_overrides.min_dcfclk_mhz > 0)
   3221 		min_dcfclk = dc->bb_overrides.min_dcfclk_mhz;
   3222 	else {
   3223 		if (ASICREV_IS_NAVI12_P(dc->ctx->asic_id.hw_internal_rev))
   3224 			min_dcfclk = 310;
   3225 		else
   3226 			// Accounting for SOC/DCF relationship, we can go as high as
   3227 			// 506Mhz in Vmin.
   3228 			min_dcfclk = 506;
   3229 	}
   3230 
   3231 	for (i = 0; i < num_states; i++) {
   3232 		int min_fclk_required_by_uclk;
   3233 		calculated_states[i].state = i;
   3234 		calculated_states[i].dram_speed_mts = uclk_states[i] * 16 / 1000;
   3235 
   3236 		// FCLK:UCLK ratio is 1.08
   3237 		min_fclk_required_by_uclk = mul_u64_u32_shr(BIT_ULL(32) * 1080 / 1000000, uclk_states[i], 32);
   3238 
   3239 		calculated_states[i].fabricclk_mhz = (min_fclk_required_by_uclk < min_dcfclk) ?
   3240 				min_dcfclk : min_fclk_required_by_uclk;
   3241 
   3242 		calculated_states[i].socclk_mhz = (calculated_states[i].fabricclk_mhz > max_clocks->socClockInKhz / 1000) ?
   3243 				max_clocks->socClockInKhz / 1000 : calculated_states[i].fabricclk_mhz;
   3244 
   3245 		calculated_states[i].dcfclk_mhz = (calculated_states[i].fabricclk_mhz > max_clocks->dcfClockInKhz / 1000) ?
   3246 				max_clocks->dcfClockInKhz / 1000 : calculated_states[i].fabricclk_mhz;
   3247 
   3248 		calculated_states[i].dispclk_mhz = max_clocks->displayClockInKhz / 1000;
   3249 		calculated_states[i].dppclk_mhz = max_clocks->displayClockInKhz / 1000;
   3250 		calculated_states[i].dscclk_mhz = max_clocks->displayClockInKhz / (1000 * 3);
   3251 
   3252 		calculated_states[i].phyclk_mhz = max_clocks->phyClockInKhz / 1000;
   3253 
   3254 		num_calculated_states++;
   3255 	}
   3256 
   3257 	calculated_states[num_calculated_states - 1].socclk_mhz = max_clocks->socClockInKhz / 1000;
   3258 	calculated_states[num_calculated_states - 1].fabricclk_mhz = max_clocks->socClockInKhz / 1000;
   3259 	calculated_states[num_calculated_states - 1].dcfclk_mhz = max_clocks->dcfClockInKhz / 1000;
   3260 
   3261 	memcpy(bb->clock_limits, calculated_states, sizeof(bb->clock_limits));
   3262 	bb->num_states = num_calculated_states;
   3263 
   3264 	// Duplicate the last state, DML always an extra state identical to max state to work
   3265 	memcpy(&bb->clock_limits[num_calculated_states], &bb->clock_limits[num_calculated_states - 1], sizeof(struct _vcs_dpi_voltage_scaling_st));
   3266 	bb->clock_limits[num_calculated_states].state = bb->num_states;
   3267 }
   3268 
   3269 void dcn20_patch_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_st *bb)
   3270 {
   3271 	if ((int)(bb->sr_exit_time_us * 1000) != dc->bb_overrides.sr_exit_time_ns
   3272 			&& dc->bb_overrides.sr_exit_time_ns) {
   3273 		bb->sr_exit_time_us = dc->bb_overrides.sr_exit_time_ns / 1000.0;
   3274 	}
   3275 
   3276 	if ((int)(bb->sr_enter_plus_exit_time_us * 1000)
   3277 				!= dc->bb_overrides.sr_enter_plus_exit_time_ns
   3278 			&& dc->bb_overrides.sr_enter_plus_exit_time_ns) {
   3279 		bb->sr_enter_plus_exit_time_us =
   3280 				dc->bb_overrides.sr_enter_plus_exit_time_ns / 1000.0;
   3281 	}
   3282 
   3283 	if ((int)(bb->urgent_latency_us * 1000) != dc->bb_overrides.urgent_latency_ns
   3284 			&& dc->bb_overrides.urgent_latency_ns) {
   3285 		bb->urgent_latency_us = dc->bb_overrides.urgent_latency_ns / 1000.0;
   3286 	}
   3287 
   3288 	if ((int)(bb->dram_clock_change_latency_us * 1000)
   3289 				!= dc->bb_overrides.dram_clock_change_latency_ns
   3290 			&& dc->bb_overrides.dram_clock_change_latency_ns) {
   3291 		bb->dram_clock_change_latency_us =
   3292 				dc->bb_overrides.dram_clock_change_latency_ns / 1000.0;
   3293 	}
   3294 }
   3295 
   3296 static struct _vcs_dpi_soc_bounding_box_st *get_asic_rev_soc_bb(
   3297 	uint32_t hw_internal_rev)
   3298 {
   3299 	if (ASICREV_IS_NAVI12_P(hw_internal_rev))
   3300 		return &dcn2_0_nv12_soc;
   3301 
   3302 	return &dcn2_0_soc;
   3303 }
   3304 
   3305 static struct _vcs_dpi_ip_params_st *get_asic_rev_ip_params(
   3306 	uint32_t hw_internal_rev)
   3307 {
   3308 	/* NV14 */
   3309 	if (ASICREV_IS_NAVI14_M(hw_internal_rev))
   3310 		return &dcn2_0_nv14_ip;
   3311 
   3312 	/* NV12 and NV10 */
   3313 	return &dcn2_0_ip;
   3314 }
   3315 
   3316 static enum dml_project get_dml_project_version(uint32_t hw_internal_rev)
   3317 {
   3318 	return DML_PROJECT_NAVI10v2;
   3319 }
   3320 
   3321 #define fixed16_to_double(x) (((double) x) / ((double) (1 << 16)))
   3322 #define fixed16_to_double_to_cpu(x) fixed16_to_double(le32_to_cpu(x))
   3323 
   3324 static bool init_soc_bounding_box(struct dc *dc,
   3325 				  struct dcn20_resource_pool *pool)
   3326 {
   3327 	const struct gpu_info_soc_bounding_box_v1_0 *bb = dc->soc_bounding_box;
   3328 	struct _vcs_dpi_soc_bounding_box_st *loaded_bb =
   3329 			get_asic_rev_soc_bb(dc->ctx->asic_id.hw_internal_rev);
   3330 	struct _vcs_dpi_ip_params_st *loaded_ip =
   3331 			get_asic_rev_ip_params(dc->ctx->asic_id.hw_internal_rev);
   3332 
   3333 	DC_LOGGER_INIT(dc->ctx->logger);
   3334 
   3335 	/* TODO: upstream NV12 bounding box when its launched */
   3336 	if (!bb && ASICREV_IS_NAVI12_P(dc->ctx->asic_id.hw_internal_rev)) {
   3337 		DC_LOG_ERROR("%s: not valid soc bounding box/n", __func__);
   3338 		return false;
   3339 	}
   3340 
   3341 	if (bb && ASICREV_IS_NAVI12_P(dc->ctx->asic_id.hw_internal_rev)) {
   3342 		int i;
   3343 
   3344 		dcn2_0_nv12_soc.sr_exit_time_us =
   3345 				fixed16_to_double_to_cpu(bb->sr_exit_time_us);
   3346 		dcn2_0_nv12_soc.sr_enter_plus_exit_time_us =
   3347 				fixed16_to_double_to_cpu(bb->sr_enter_plus_exit_time_us);
   3348 		dcn2_0_nv12_soc.urgent_latency_us =
   3349 				fixed16_to_double_to_cpu(bb->urgent_latency_us);
   3350 		dcn2_0_nv12_soc.urgent_latency_pixel_data_only_us =
   3351 				fixed16_to_double_to_cpu(bb->urgent_latency_pixel_data_only_us);
   3352 		dcn2_0_nv12_soc.urgent_latency_pixel_mixed_with_vm_data_us =
   3353 				fixed16_to_double_to_cpu(bb->urgent_latency_pixel_mixed_with_vm_data_us);
   3354 		dcn2_0_nv12_soc.urgent_latency_vm_data_only_us =
   3355 				fixed16_to_double_to_cpu(bb->urgent_latency_vm_data_only_us);
   3356 		dcn2_0_nv12_soc.urgent_out_of_order_return_per_channel_pixel_only_bytes =
   3357 				le32_to_cpu(bb->urgent_out_of_order_return_per_channel_pixel_only_bytes);
   3358 		dcn2_0_nv12_soc.urgent_out_of_order_return_per_channel_pixel_and_vm_bytes =
   3359 				le32_to_cpu(bb->urgent_out_of_order_return_per_channel_pixel_and_vm_bytes);
   3360 		dcn2_0_nv12_soc.urgent_out_of_order_return_per_channel_vm_only_bytes =
   3361 				le32_to_cpu(bb->urgent_out_of_order_return_per_channel_vm_only_bytes);
   3362 		dcn2_0_nv12_soc.pct_ideal_dram_sdp_bw_after_urgent_pixel_only =
   3363 				fixed16_to_double_to_cpu(bb->pct_ideal_dram_sdp_bw_after_urgent_pixel_only);
   3364 		dcn2_0_nv12_soc.pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm =
   3365 				fixed16_to_double_to_cpu(bb->pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm);
   3366 		dcn2_0_nv12_soc.pct_ideal_dram_sdp_bw_after_urgent_vm_only =
   3367 				fixed16_to_double_to_cpu(bb->pct_ideal_dram_sdp_bw_after_urgent_vm_only);
   3368 		dcn2_0_nv12_soc.max_avg_sdp_bw_use_normal_percent =
   3369 				fixed16_to_double_to_cpu(bb->max_avg_sdp_bw_use_normal_percent);
   3370 		dcn2_0_nv12_soc.max_avg_dram_bw_use_normal_percent =
   3371 				fixed16_to_double_to_cpu(bb->max_avg_dram_bw_use_normal_percent);
   3372 		dcn2_0_nv12_soc.writeback_latency_us =
   3373 				fixed16_to_double_to_cpu(bb->writeback_latency_us);
   3374 		dcn2_0_nv12_soc.ideal_dram_bw_after_urgent_percent =
   3375 				fixed16_to_double_to_cpu(bb->ideal_dram_bw_after_urgent_percent);
   3376 		dcn2_0_nv12_soc.max_request_size_bytes =
   3377 				le32_to_cpu(bb->max_request_size_bytes);
   3378 		dcn2_0_nv12_soc.dram_channel_width_bytes =
   3379 				le32_to_cpu(bb->dram_channel_width_bytes);
   3380 		dcn2_0_nv12_soc.fabric_datapath_to_dcn_data_return_bytes =
   3381 				le32_to_cpu(bb->fabric_datapath_to_dcn_data_return_bytes);
   3382 		dcn2_0_nv12_soc.dcn_downspread_percent =
   3383 				fixed16_to_double_to_cpu(bb->dcn_downspread_percent);
   3384 		dcn2_0_nv12_soc.downspread_percent =
   3385 				fixed16_to_double_to_cpu(bb->downspread_percent);
   3386 		dcn2_0_nv12_soc.dram_page_open_time_ns =
   3387 				fixed16_to_double_to_cpu(bb->dram_page_open_time_ns);
   3388 		dcn2_0_nv12_soc.dram_rw_turnaround_time_ns =
   3389 				fixed16_to_double_to_cpu(bb->dram_rw_turnaround_time_ns);
   3390 		dcn2_0_nv12_soc.dram_return_buffer_per_channel_bytes =
   3391 				le32_to_cpu(bb->dram_return_buffer_per_channel_bytes);
   3392 		dcn2_0_nv12_soc.round_trip_ping_latency_dcfclk_cycles =
   3393 				le32_to_cpu(bb->round_trip_ping_latency_dcfclk_cycles);
   3394 		dcn2_0_nv12_soc.urgent_out_of_order_return_per_channel_bytes =
   3395 				le32_to_cpu(bb->urgent_out_of_order_return_per_channel_bytes);
   3396 		dcn2_0_nv12_soc.channel_interleave_bytes =
   3397 				le32_to_cpu(bb->channel_interleave_bytes);
   3398 		dcn2_0_nv12_soc.num_banks =
   3399 				le32_to_cpu(bb->num_banks);
   3400 		dcn2_0_nv12_soc.num_chans =
   3401 				le32_to_cpu(bb->num_chans);
   3402 		dcn2_0_nv12_soc.vmm_page_size_bytes =
   3403 				le32_to_cpu(bb->vmm_page_size_bytes);
   3404 		dcn2_0_nv12_soc.dram_clock_change_latency_us =
   3405 				fixed16_to_double_to_cpu(bb->dram_clock_change_latency_us);
   3406 		// HACK!! Lower uclock latency switch time so we don't switch
   3407 		dcn2_0_nv12_soc.dram_clock_change_latency_us = 10;
   3408 		dcn2_0_nv12_soc.writeback_dram_clock_change_latency_us =
   3409 				fixed16_to_double_to_cpu(bb->writeback_dram_clock_change_latency_us);
   3410 		dcn2_0_nv12_soc.return_bus_width_bytes =
   3411 				le32_to_cpu(bb->return_bus_width_bytes);
   3412 		dcn2_0_nv12_soc.dispclk_dppclk_vco_speed_mhz =
   3413 				le32_to_cpu(bb->dispclk_dppclk_vco_speed_mhz);
   3414 		dcn2_0_nv12_soc.xfc_bus_transport_time_us =
   3415 				le32_to_cpu(bb->xfc_bus_transport_time_us);
   3416 		dcn2_0_nv12_soc.xfc_xbuf_latency_tolerance_us =
   3417 				le32_to_cpu(bb->xfc_xbuf_latency_tolerance_us);
   3418 		dcn2_0_nv12_soc.use_urgent_burst_bw =
   3419 				le32_to_cpu(bb->use_urgent_burst_bw);
   3420 		dcn2_0_nv12_soc.num_states =
   3421 				le32_to_cpu(bb->num_states);
   3422 
   3423 		for (i = 0; i < dcn2_0_nv12_soc.num_states; i++) {
   3424 			dcn2_0_nv12_soc.clock_limits[i].state =
   3425 					le32_to_cpu(bb->clock_limits[i].state);
   3426 			dcn2_0_nv12_soc.clock_limits[i].dcfclk_mhz =
   3427 					fixed16_to_double_to_cpu(bb->clock_limits[i].dcfclk_mhz);
   3428 			dcn2_0_nv12_soc.clock_limits[i].fabricclk_mhz =
   3429 					fixed16_to_double_to_cpu(bb->clock_limits[i].fabricclk_mhz);
   3430 			dcn2_0_nv12_soc.clock_limits[i].dispclk_mhz =
   3431 					fixed16_to_double_to_cpu(bb->clock_limits[i].dispclk_mhz);
   3432 			dcn2_0_nv12_soc.clock_limits[i].dppclk_mhz =
   3433 					fixed16_to_double_to_cpu(bb->clock_limits[i].dppclk_mhz);
   3434 			dcn2_0_nv12_soc.clock_limits[i].phyclk_mhz =
   3435 					fixed16_to_double_to_cpu(bb->clock_limits[i].phyclk_mhz);
   3436 			dcn2_0_nv12_soc.clock_limits[i].socclk_mhz =
   3437 					fixed16_to_double_to_cpu(bb->clock_limits[i].socclk_mhz);
   3438 			dcn2_0_nv12_soc.clock_limits[i].dscclk_mhz =
   3439 					fixed16_to_double_to_cpu(bb->clock_limits[i].dscclk_mhz);
   3440 			dcn2_0_nv12_soc.clock_limits[i].dram_speed_mts =
   3441 					fixed16_to_double_to_cpu(bb->clock_limits[i].dram_speed_mts);
   3442 		}
   3443 	}
   3444 
   3445 	if (pool->base.pp_smu) {
   3446 		struct pp_smu_nv_clock_table max_clocks = {0};
   3447 		unsigned int uclk_states[8] = {0};
   3448 		unsigned int num_states = 0;
   3449 		enum pp_smu_status status;
   3450 		bool clock_limits_available = false;
   3451 		bool uclk_states_available = false;
   3452 
   3453 		if (pool->base.pp_smu->nv_funcs.get_uclk_dpm_states) {
   3454 			status = (pool->base.pp_smu->nv_funcs.get_uclk_dpm_states)
   3455 				(&pool->base.pp_smu->nv_funcs.pp_smu, uclk_states, &num_states);
   3456 
   3457 			uclk_states_available = (status == PP_SMU_RESULT_OK);
   3458 		}
   3459 
   3460 		if (pool->base.pp_smu->nv_funcs.get_maximum_sustainable_clocks) {
   3461 			status = (*pool->base.pp_smu->nv_funcs.get_maximum_sustainable_clocks)
   3462 					(&pool->base.pp_smu->nv_funcs.pp_smu, &max_clocks);
   3463 			/* SMU cannot set DCF clock to anything equal to or higher than SOC clock
   3464 			 */
   3465 			if (max_clocks.dcfClockInKhz >= max_clocks.socClockInKhz)
   3466 				max_clocks.dcfClockInKhz = max_clocks.socClockInKhz - 1000;
   3467 			clock_limits_available = (status == PP_SMU_RESULT_OK);
   3468 		}
   3469 
   3470 		if (clock_limits_available && uclk_states_available && num_states)
   3471 			dcn20_update_bounding_box(dc, loaded_bb, &max_clocks, uclk_states, num_states);
   3472 		else if (clock_limits_available)
   3473 			dcn20_cap_soc_clocks(loaded_bb, max_clocks);
   3474 	}
   3475 
   3476 	loaded_ip->max_num_otg = pool->base.res_cap->num_timing_generator;
   3477 	loaded_ip->max_num_dpp = pool->base.pipe_count;
   3478 	dcn20_patch_bounding_box(dc, loaded_bb);
   3479 
   3480 	return true;
   3481 }
   3482 
   3483 static bool dcn20_resource_construct(
   3484 	uint8_t num_virtual_links,
   3485 	struct dc *dc,
   3486 	struct dcn20_resource_pool *pool)
   3487 {
   3488 	int i;
   3489 	struct dc_context *ctx = dc->ctx;
   3490 	struct irq_service_init_data init_data;
   3491 	struct ddc_service_init_data ddc_init_data;
   3492 	struct _vcs_dpi_soc_bounding_box_st *loaded_bb =
   3493 			get_asic_rev_soc_bb(ctx->asic_id.hw_internal_rev);
   3494 	struct _vcs_dpi_ip_params_st *loaded_ip =
   3495 			get_asic_rev_ip_params(ctx->asic_id.hw_internal_rev);
   3496 	enum dml_project dml_project_version =
   3497 			get_dml_project_version(ctx->asic_id.hw_internal_rev);
   3498 
   3499 	DC_FP_START();
   3500 
   3501 	ctx->dc_bios->regs = &bios_regs;
   3502 	pool->base.funcs = &dcn20_res_pool_funcs;
   3503 
   3504 	if (ASICREV_IS_NAVI14_M(ctx->asic_id.hw_internal_rev)) {
   3505 		pool->base.res_cap = &res_cap_nv14;
   3506 		pool->base.pipe_count = 5;
   3507 		pool->base.mpcc_count = 5;
   3508 	} else {
   3509 		pool->base.res_cap = &res_cap_nv10;
   3510 		pool->base.pipe_count = 6;
   3511 		pool->base.mpcc_count = 6;
   3512 	}
   3513 	/*************************************************
   3514 	 *  Resource + asic cap harcoding                *
   3515 	 *************************************************/
   3516 	pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE;
   3517 
   3518 	dc->caps.max_downscale_ratio = 200;
   3519 	dc->caps.i2c_speed_in_khz = 100;
   3520 	dc->caps.max_cursor_size = 256;
   3521 	dc->caps.dmdata_alloc_size = 2048;
   3522 
   3523 	dc->caps.max_slave_planes = 1;
   3524 	dc->caps.post_blend_color_processing = true;
   3525 	dc->caps.force_dp_tps4_for_cp2520 = true;
   3526 	dc->caps.hw_3d_lut = true;
   3527 	dc->caps.extended_aux_timeout_support = true;
   3528 
   3529 	if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV) {
   3530 		dc->debug = debug_defaults_drv;
   3531 	} else if (dc->ctx->dce_environment == DCE_ENV_FPGA_MAXIMUS) {
   3532 		pool->base.pipe_count = 4;
   3533 		pool->base.mpcc_count = pool->base.pipe_count;
   3534 		dc->debug = debug_defaults_diags;
   3535 	} else {
   3536 		dc->debug = debug_defaults_diags;
   3537 	}
   3538 	//dcn2.0x
   3539 	dc->work_arounds.dedcn20_305_wa = true;
   3540 
   3541 	// Init the vm_helper
   3542 	if (dc->vm_helper)
   3543 		vm_helper_init(dc->vm_helper, 16);
   3544 
   3545 	/*************************************************
   3546 	 *  Create resources                             *
   3547 	 *************************************************/
   3548 
   3549 	pool->base.clock_sources[DCN20_CLK_SRC_PLL0] =
   3550 			dcn20_clock_source_create(ctx, ctx->dc_bios,
   3551 				CLOCK_SOURCE_COMBO_PHY_PLL0,
   3552 				&clk_src_regs[0], false);
   3553 	pool->base.clock_sources[DCN20_CLK_SRC_PLL1] =
   3554 			dcn20_clock_source_create(ctx, ctx->dc_bios,
   3555 				CLOCK_SOURCE_COMBO_PHY_PLL1,
   3556 				&clk_src_regs[1], false);
   3557 	pool->base.clock_sources[DCN20_CLK_SRC_PLL2] =
   3558 			dcn20_clock_source_create(ctx, ctx->dc_bios,
   3559 				CLOCK_SOURCE_COMBO_PHY_PLL2,
   3560 				&clk_src_regs[2], false);
   3561 	pool->base.clock_sources[DCN20_CLK_SRC_PLL3] =
   3562 			dcn20_clock_source_create(ctx, ctx->dc_bios,
   3563 				CLOCK_SOURCE_COMBO_PHY_PLL3,
   3564 				&clk_src_regs[3], false);
   3565 	pool->base.clock_sources[DCN20_CLK_SRC_PLL4] =
   3566 			dcn20_clock_source_create(ctx, ctx->dc_bios,
   3567 				CLOCK_SOURCE_COMBO_PHY_PLL4,
   3568 				&clk_src_regs[4], false);
   3569 	pool->base.clock_sources[DCN20_CLK_SRC_PLL5] =
   3570 			dcn20_clock_source_create(ctx, ctx->dc_bios,
   3571 				CLOCK_SOURCE_COMBO_PHY_PLL5,
   3572 				&clk_src_regs[5], false);
   3573 	pool->base.clk_src_count = DCN20_CLK_SRC_TOTAL;
   3574 	/* todo: not reuse phy_pll registers */
   3575 	pool->base.dp_clock_source =
   3576 			dcn20_clock_source_create(ctx, ctx->dc_bios,
   3577 				CLOCK_SOURCE_ID_DP_DTO,
   3578 				&clk_src_regs[0], true);
   3579 
   3580 	for (i = 0; i < pool->base.clk_src_count; i++) {
   3581 		if (pool->base.clock_sources[i] == NULL) {
   3582 			dm_error("DC: failed to create clock sources!\n");
   3583 			BREAK_TO_DEBUGGER();
   3584 			goto create_fail;
   3585 		}
   3586 	}
   3587 
   3588 	pool->base.dccg = dccg2_create(ctx, &dccg_regs, &dccg_shift, &dccg_mask);
   3589 	if (pool->base.dccg == NULL) {
   3590 		dm_error("DC: failed to create dccg!\n");
   3591 		BREAK_TO_DEBUGGER();
   3592 		goto create_fail;
   3593 	}
   3594 
   3595 	pool->base.dmcu = dcn20_dmcu_create(ctx,
   3596 			&dmcu_regs,
   3597 			&dmcu_shift,
   3598 			&dmcu_mask);
   3599 	if (pool->base.dmcu == NULL) {
   3600 		dm_error("DC: failed to create dmcu!\n");
   3601 		BREAK_TO_DEBUGGER();
   3602 		goto create_fail;
   3603 	}
   3604 
   3605 	pool->base.abm = dce_abm_create(ctx,
   3606 			&abm_regs,
   3607 			&abm_shift,
   3608 			&abm_mask);
   3609 	if (pool->base.abm == NULL) {
   3610 		dm_error("DC: failed to create abm!\n");
   3611 		BREAK_TO_DEBUGGER();
   3612 		goto create_fail;
   3613 	}
   3614 
   3615 	pool->base.pp_smu = dcn20_pp_smu_create(ctx);
   3616 
   3617 
   3618 	if (!init_soc_bounding_box(dc, pool)) {
   3619 		dm_error("DC: failed to initialize soc bounding box!\n");
   3620 		BREAK_TO_DEBUGGER();
   3621 		goto create_fail;
   3622 	}
   3623 
   3624 	dml_init_instance(&dc->dml, loaded_bb, loaded_ip, dml_project_version);
   3625 
   3626 	if (!dc->debug.disable_pplib_wm_range) {
   3627 		struct pp_smu_wm_range_sets ranges = {0};
   3628 		int i = 0;
   3629 
   3630 		ranges.num_reader_wm_sets = 0;
   3631 
   3632 		if (loaded_bb->num_states == 1) {
   3633 			ranges.reader_wm_sets[0].wm_inst = i;
   3634 			ranges.reader_wm_sets[0].min_drain_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MIN;
   3635 			ranges.reader_wm_sets[0].max_drain_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX;
   3636 			ranges.reader_wm_sets[0].min_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MIN;
   3637 			ranges.reader_wm_sets[0].max_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX;
   3638 
   3639 			ranges.num_reader_wm_sets = 1;
   3640 		} else if (loaded_bb->num_states > 1) {
   3641 			for (i = 0; i < 4 && i < loaded_bb->num_states; i++) {
   3642 				ranges.reader_wm_sets[i].wm_inst = i;
   3643 				ranges.reader_wm_sets[i].min_drain_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MIN;
   3644 				ranges.reader_wm_sets[i].max_drain_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX;
   3645 				ranges.reader_wm_sets[i].min_fill_clk_mhz = (i > 0) ? (loaded_bb->clock_limits[i - 1].dram_speed_mts / 16) + 1 : 0;
   3646 				ranges.reader_wm_sets[i].max_fill_clk_mhz = loaded_bb->clock_limits[i].dram_speed_mts / 16;
   3647 
   3648 				ranges.num_reader_wm_sets = i + 1;
   3649 			}
   3650 
   3651 			ranges.reader_wm_sets[0].min_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MIN;
   3652 			ranges.reader_wm_sets[ranges.num_reader_wm_sets - 1].max_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX;
   3653 		}
   3654 
   3655 		ranges.num_writer_wm_sets = 1;
   3656 
   3657 		ranges.writer_wm_sets[0].wm_inst = 0;
   3658 		ranges.writer_wm_sets[0].min_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MIN;
   3659 		ranges.writer_wm_sets[0].max_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX;
   3660 		ranges.writer_wm_sets[0].min_drain_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MIN;
   3661 		ranges.writer_wm_sets[0].max_drain_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX;
   3662 
   3663 		/* Notify PP Lib/SMU which Watermarks to use for which clock ranges */
   3664 		if (pool->base.pp_smu->nv_funcs.set_wm_ranges)
   3665 			pool->base.pp_smu->nv_funcs.set_wm_ranges(&pool->base.pp_smu->nv_funcs.pp_smu, &ranges);
   3666 	}
   3667 
   3668 	init_data.ctx = dc->ctx;
   3669 	pool->base.irqs = dal_irq_service_dcn20_create(&init_data);
   3670 	if (!pool->base.irqs)
   3671 		goto create_fail;
   3672 
   3673 	/* mem input -> ipp -> dpp -> opp -> TG */
   3674 	for (i = 0; i < pool->base.pipe_count; i++) {
   3675 		pool->base.hubps[i] = dcn20_hubp_create(ctx, i);
   3676 		if (pool->base.hubps[i] == NULL) {
   3677 			BREAK_TO_DEBUGGER();
   3678 			dm_error(
   3679 				"DC: failed to create memory input!\n");
   3680 			goto create_fail;
   3681 		}
   3682 
   3683 		pool->base.ipps[i] = dcn20_ipp_create(ctx, i);
   3684 		if (pool->base.ipps[i] == NULL) {
   3685 			BREAK_TO_DEBUGGER();
   3686 			dm_error(
   3687 				"DC: failed to create input pixel processor!\n");
   3688 			goto create_fail;
   3689 		}
   3690 
   3691 		pool->base.dpps[i] = dcn20_dpp_create(ctx, i);
   3692 		if (pool->base.dpps[i] == NULL) {
   3693 			BREAK_TO_DEBUGGER();
   3694 			dm_error(
   3695 				"DC: failed to create dpps!\n");
   3696 			goto create_fail;
   3697 		}
   3698 	}
   3699 	for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
   3700 		pool->base.engines[i] = dcn20_aux_engine_create(ctx, i);
   3701 		if (pool->base.engines[i] == NULL) {
   3702 			BREAK_TO_DEBUGGER();
   3703 			dm_error(
   3704 				"DC:failed to create aux engine!!\n");
   3705 			goto create_fail;
   3706 		}
   3707 		pool->base.hw_i2cs[i] = dcn20_i2c_hw_create(ctx, i);
   3708 		if (pool->base.hw_i2cs[i] == NULL) {
   3709 			BREAK_TO_DEBUGGER();
   3710 			dm_error(
   3711 				"DC:failed to create hw i2c!!\n");
   3712 			goto create_fail;
   3713 		}
   3714 		pool->base.sw_i2cs[i] = NULL;
   3715 	}
   3716 
   3717 	for (i = 0; i < pool->base.res_cap->num_opp; i++) {
   3718 		pool->base.opps[i] = dcn20_opp_create(ctx, i);
   3719 		if (pool->base.opps[i] == NULL) {
   3720 			BREAK_TO_DEBUGGER();
   3721 			dm_error(
   3722 				"DC: failed to create output pixel processor!\n");
   3723 			goto create_fail;
   3724 		}
   3725 	}
   3726 
   3727 	for (i = 0; i < pool->base.res_cap->num_timing_generator; i++) {
   3728 		pool->base.timing_generators[i] = dcn20_timing_generator_create(
   3729 				ctx, i);
   3730 		if (pool->base.timing_generators[i] == NULL) {
   3731 			BREAK_TO_DEBUGGER();
   3732 			dm_error("DC: failed to create tg!\n");
   3733 			goto create_fail;
   3734 		}
   3735 	}
   3736 
   3737 	pool->base.timing_generator_count = i;
   3738 
   3739 	pool->base.mpc = dcn20_mpc_create(ctx);
   3740 	if (pool->base.mpc == NULL) {
   3741 		BREAK_TO_DEBUGGER();
   3742 		dm_error("DC: failed to create mpc!\n");
   3743 		goto create_fail;
   3744 	}
   3745 
   3746 	pool->base.hubbub = dcn20_hubbub_create(ctx);
   3747 	if (pool->base.hubbub == NULL) {
   3748 		BREAK_TO_DEBUGGER();
   3749 		dm_error("DC: failed to create hubbub!\n");
   3750 		goto create_fail;
   3751 	}
   3752 
   3753 	for (i = 0; i < pool->base.res_cap->num_dsc; i++) {
   3754 		pool->base.dscs[i] = dcn20_dsc_create(ctx, i);
   3755 		if (pool->base.dscs[i] == NULL) {
   3756 			BREAK_TO_DEBUGGER();
   3757 			dm_error("DC: failed to create display stream compressor %d!\n", i);
   3758 			goto create_fail;
   3759 		}
   3760 	}
   3761 
   3762 	if (!dcn20_dwbc_create(ctx, &pool->base)) {
   3763 		BREAK_TO_DEBUGGER();
   3764 		dm_error("DC: failed to create dwbc!\n");
   3765 		goto create_fail;
   3766 	}
   3767 	if (!dcn20_mmhubbub_create(ctx, &pool->base)) {
   3768 		BREAK_TO_DEBUGGER();
   3769 		dm_error("DC: failed to create mcif_wb!\n");
   3770 		goto create_fail;
   3771 	}
   3772 
   3773 	if (!resource_construct(num_virtual_links, dc, &pool->base,
   3774 			(!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment) ?
   3775 			&res_create_funcs : &res_create_maximus_funcs)))
   3776 			goto create_fail;
   3777 
   3778 	dcn20_hw_sequencer_construct(dc);
   3779 
   3780 	dc->caps.max_planes =  pool->base.pipe_count;
   3781 
   3782 	for (i = 0; i < dc->caps.max_planes; ++i)
   3783 		dc->caps.planes[i] = plane_cap;
   3784 
   3785 	dc->cap_funcs = cap_funcs;
   3786 
   3787 	if (dc->ctx->dc_bios->fw_info.oem_i2c_present) {
   3788 		ddc_init_data.ctx = dc->ctx;
   3789 		ddc_init_data.link = NULL;
   3790 		ddc_init_data.id.id = dc->ctx->dc_bios->fw_info.oem_i2c_obj_id;
   3791 		ddc_init_data.id.enum_id = 0;
   3792 		ddc_init_data.id.type = OBJECT_TYPE_GENERIC;
   3793 		pool->base.oem_device = dal_ddc_service_create(&ddc_init_data);
   3794 	} else {
   3795 		pool->base.oem_device = NULL;
   3796 	}
   3797 
   3798 	DC_FP_END();
   3799 	return true;
   3800 
   3801 create_fail:
   3802 
   3803 	DC_FP_END();
   3804 	dcn20_resource_destruct(pool);
   3805 
   3806 	return false;
   3807 }
   3808 
   3809 struct resource_pool *dcn20_create_resource_pool(
   3810 		const struct dc_init_data *init_data,
   3811 		struct dc *dc)
   3812 {
   3813 	struct dcn20_resource_pool *pool =
   3814 		kzalloc(sizeof(struct dcn20_resource_pool), GFP_KERNEL);
   3815 
   3816 	if (!pool)
   3817 		return NULL;
   3818 
   3819 	if (dcn20_resource_construct(init_data->num_virtual_links, dc, pool))
   3820 		return &pool->base;
   3821 
   3822 	BREAK_TO_DEBUGGER();
   3823 	kfree(pool);
   3824 	return NULL;
   3825 }
   3826