xref: /openbmc/linux/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c (revision d9a07577b8a3131c90c187fb2b89662bee535cfd)
1 /*
2 * Copyright 2018 Advanced Micro Devices, Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20  * OTHER DEALINGS IN THE SOFTWARE.
21  *
22  * Authors: AMD
23  *
24  */
25 
26 #include "dm_services.h"
27 #include "dc.h"
28 
29 #include "resource.h"
30 #include "include/irq_service_interface.h"
31 #include "dcn20/dcn20_resource.h"
32 
33 #include "clk_mgr.h"
34 #include "dcn10/dcn10_hubp.h"
35 #include "dcn10/dcn10_ipp.h"
36 #include "dcn20/dcn20_hubbub.h"
37 #include "dcn20/dcn20_mpc.h"
38 #include "dcn20/dcn20_hubp.h"
39 #include "dcn21_hubp.h"
40 #include "irq/dcn21/irq_service_dcn21.h"
41 #include "dcn20/dcn20_dpp.h"
42 #include "dcn20/dcn20_optc.h"
43 #include "dcn21/dcn21_hwseq.h"
44 #include "dce110/dce110_hw_sequencer.h"
45 #include "dcn20/dcn20_opp.h"
46 #include "dcn20/dcn20_dsc.h"
47 #include "dcn21/dcn21_link_encoder.h"
48 #include "dcn20/dcn20_stream_encoder.h"
49 #include "dce/dce_clock_source.h"
50 #include "dce/dce_audio.h"
51 #include "dce/dce_hwseq.h"
52 #include "virtual/virtual_stream_encoder.h"
53 #include "dce110/dce110_resource.h"
54 #include "dml/display_mode_vba.h"
55 #include "dcn20/dcn20_dccg.h"
56 #include "dcn21_hubbub.h"
57 #include "dcn10/dcn10_resource.h"
58 
59 #include "dcn20/dcn20_dwb.h"
60 #include "dcn20/dcn20_mmhubbub.h"
61 
62 #include "renoir_ip_offset.h"
63 #include "dcn/dcn_2_1_0_offset.h"
64 #include "dcn/dcn_2_1_0_sh_mask.h"
65 
66 #include "nbio/nbio_7_0_offset.h"
67 
68 #include "mmhub/mmhub_2_0_0_offset.h"
69 #include "mmhub/mmhub_2_0_0_sh_mask.h"
70 
71 #include "reg_helper.h"
72 #include "dce/dce_abm.h"
73 #include "dce/dce_dmcu.h"
74 #include "dce/dce_aux.h"
75 #include "dce/dce_i2c.h"
76 #include "dcn21_resource.h"
77 #include "vm_helper.h"
78 #include "dcn20/dcn20_vmid.h"
79 
80 #define SOC_BOUNDING_BOX_VALID false
81 #define DC_LOGGER_INIT(logger)
82 
83 
84 struct _vcs_dpi_ip_params_st dcn2_1_ip = {
85 	.odm_capable = 1,
86 	.gpuvm_enable = 1,
87 	.hostvm_enable = 1,
88 	.gpuvm_max_page_table_levels = 1,
89 	.hostvm_max_page_table_levels = 4,
90 	.hostvm_cached_page_table_levels = 2,
91 #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
92 	.num_dsc = 3,
93 #else
94 	.num_dsc = 0,
95 #endif
96 	.rob_buffer_size_kbytes = 168,
97 	.det_buffer_size_kbytes = 164,
98 	.dpte_buffer_size_in_pte_reqs_luma = 44,
99 	.dpte_buffer_size_in_pte_reqs_chroma = 42,//todo
100 	.dpp_output_buffer_pixels = 2560,
101 	.opp_output_buffer_lines = 1,
102 	.pixel_chunk_size_kbytes = 8,
103 	.pte_enable = 1,
104 	.max_page_table_levels = 4,
105 	.pte_chunk_size_kbytes = 2,
106 	.meta_chunk_size_kbytes = 2,
107 	.writeback_chunk_size_kbytes = 2,
108 	.line_buffer_size_bits = 789504,
109 	.is_line_buffer_bpp_fixed = 0,
110 	.line_buffer_fixed_bpp = 0,
111 	.dcc_supported = true,
112 	.max_line_buffer_lines = 12,
113 	.writeback_luma_buffer_size_kbytes = 12,
114 	.writeback_chroma_buffer_size_kbytes = 8,
115 	.writeback_chroma_line_buffer_width_pixels = 4,
116 	.writeback_max_hscl_ratio = 1,
117 	.writeback_max_vscl_ratio = 1,
118 	.writeback_min_hscl_ratio = 1,
119 	.writeback_min_vscl_ratio = 1,
120 	.writeback_max_hscl_taps = 12,
121 	.writeback_max_vscl_taps = 12,
122 	.writeback_line_buffer_luma_buffer_size = 0,
123 	.writeback_line_buffer_chroma_buffer_size = 14643,
124 	.cursor_buffer_size = 8,
125 	.cursor_chunk_size = 2,
126 	.max_num_otg = 4,
127 	.max_num_dpp = 4,
128 	.max_num_wb = 1,
129 	.max_dchub_pscl_bw_pix_per_clk = 4,
130 	.max_pscl_lb_bw_pix_per_clk = 2,
131 	.max_lb_vscl_bw_pix_per_clk = 4,
132 	.max_vscl_hscl_bw_pix_per_clk = 4,
133 	.max_hscl_ratio = 4,
134 	.max_vscl_ratio = 4,
135 	.hscl_mults = 4,
136 	.vscl_mults = 4,
137 	.max_hscl_taps = 8,
138 	.max_vscl_taps = 8,
139 	.dispclk_ramp_margin_percent = 1,
140 	.underscan_factor = 1.10,
141 	.min_vblank_lines = 32, //
142 	.dppclk_delay_subtotal = 77, //
143 	.dppclk_delay_scl_lb_only = 16,
144 	.dppclk_delay_scl = 50,
145 	.dppclk_delay_cnvc_formatter = 8,
146 	.dppclk_delay_cnvc_cursor = 6,
147 	.dispclk_delay_subtotal = 87, //
148 	.dcfclk_cstate_latency = 10, // SRExitTime
149 	.max_inter_dcn_tile_repeaters = 8,
150 
151 	.xfc_supported = false,
152 	.xfc_fill_bw_overhead_percent = 10.0,
153 	.xfc_fill_constant_bytes = 0,
154 	.ptoi_supported = 0
155 };
156 
157 struct _vcs_dpi_soc_bounding_box_st dcn2_1_soc = {
158 	.clock_limits = {
159 			{
160 				.state = 0,
161 				.dcfclk_mhz = 304.0,
162 				.fabricclk_mhz = 600.0,
163 				.dispclk_mhz = 618.0,
164 				.dppclk_mhz = 440.0,
165 				.phyclk_mhz = 600.0,
166 				.socclk_mhz = 278.0,
167 				.dscclk_mhz = 205.67,
168 				.dram_speed_mts = 1600.0,
169 			},
170 			{
171 				.state = 1,
172 				.dcfclk_mhz = 304.0,
173 				.fabricclk_mhz = 600.0,
174 				.dispclk_mhz = 618.0,
175 				.dppclk_mhz = 618.0,
176 				.phyclk_mhz = 600.0,
177 				.socclk_mhz = 278.0,
178 				.dscclk_mhz = 205.67,
179 				.dram_speed_mts = 1600.0,
180 			},
181 			{
182 				.state = 2,
183 				.dcfclk_mhz = 608.0,
184 				.fabricclk_mhz = 1066.0,
185 				.dispclk_mhz = 888.0,
186 				.dppclk_mhz = 888.0,
187 				.phyclk_mhz = 810.0,
188 				.socclk_mhz = 278.0,
189 				.dscclk_mhz = 287.67,
190 				.dram_speed_mts = 2133.0,
191 			},
192 			{
193 				.state = 3,
194 				.dcfclk_mhz = 676.0,
195 				.fabricclk_mhz = 1600.0,
196 				.dispclk_mhz = 1015.0,
197 				.dppclk_mhz = 1015.0,
198 				.phyclk_mhz = 810.0,
199 				.socclk_mhz = 715.0,
200 				.dscclk_mhz = 318.334,
201 				.dram_speed_mts = 4266.0,
202 			},
203 			{
204 				.state = 4,
205 				.dcfclk_mhz = 810.0,
206 				.fabricclk_mhz = 1600.0,
207 				.dispclk_mhz = 1395.0,
208 				.dppclk_mhz = 1285.0,
209 				.phyclk_mhz = 1325.0,
210 				.socclk_mhz = 953.0,
211 				.dscclk_mhz = 489.0,
212 				.dram_speed_mts = 4266.0,
213 			},
214 			/*Extra state, no dispclk ramping*/
215 			{
216 				.state = 5,
217 				.dcfclk_mhz = 810.0,
218 				.fabricclk_mhz = 1600.0,
219 				.dispclk_mhz = 1395.0,
220 				.dppclk_mhz = 1285.0,
221 				.phyclk_mhz = 1325.0,
222 				.socclk_mhz = 953.0,
223 				.dscclk_mhz = 489.0,
224 				.dram_speed_mts = 4266.0,
225 			},
226 
227 		},
228 
229 	.sr_exit_time_us = 12.5,
230 	.sr_enter_plus_exit_time_us = 17.0,
231 	.urgent_latency_us = 4.0,
232 	.urgent_latency_pixel_data_only_us = 4.0,
233 	.urgent_latency_pixel_mixed_with_vm_data_us = 4.0,
234 	.urgent_latency_vm_data_only_us = 4.0,
235 	.urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096,
236 	.urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096,
237 	.urgent_out_of_order_return_per_channel_vm_only_bytes = 4096,
238 	.pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 80.0,
239 	.pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 75.0,
240 	.pct_ideal_dram_sdp_bw_after_urgent_vm_only = 40.0,
241 	.max_avg_sdp_bw_use_normal_percent = 60.0,
242 	.max_avg_dram_bw_use_normal_percent = 100.0,
243 	.writeback_latency_us = 12.0,
244 	.max_request_size_bytes = 256,
245 	.dram_channel_width_bytes = 4,
246 	.fabric_datapath_to_dcn_data_return_bytes = 32,
247 	.dcn_downspread_percent = 0.5,
248 	.downspread_percent = 0.5,
249 	.dram_page_open_time_ns = 50.0,
250 	.dram_rw_turnaround_time_ns = 17.5,
251 	.dram_return_buffer_per_channel_bytes = 8192,
252 	.round_trip_ping_latency_dcfclk_cycles = 128,
253 	.urgent_out_of_order_return_per_channel_bytes = 4096,
254 	.channel_interleave_bytes = 256,
255 	.num_banks = 8,
256 	.num_chans = 4,
257 	.vmm_page_size_bytes = 4096,
258 	.dram_clock_change_latency_us = 23.84,
259 	.return_bus_width_bytes = 64,
260 	.dispclk_dppclk_vco_speed_mhz = 3550,
261 	.xfc_bus_transport_time_us = 4,
262 	.xfc_xbuf_latency_tolerance_us = 4,
263 	.use_urgent_burst_bw = 1,
264 	.num_states = 5
265 };
266 
267 #ifndef MAX
268 #define MAX(X, Y) ((X) > (Y) ? (X) : (Y))
269 #endif
270 #ifndef MIN
271 #define MIN(X, Y) ((X) < (Y) ? (X) : (Y))
272 #endif
273 
274 /* begin *********************
275  * macros to expend register list macro defined in HW object header file */
276 
277 /* DCN */
278 /* TODO awful hack. fixup dcn20_dwb.h */
279 #undef BASE_INNER
280 #define BASE_INNER(seg) DMU_BASE__INST0_SEG ## seg
281 
282 #define BASE(seg) BASE_INNER(seg)
283 
284 #define SR(reg_name)\
285 		.reg_name = BASE(mm ## reg_name ## _BASE_IDX) +  \
286 					mm ## reg_name
287 
288 #define SRI(reg_name, block, id)\
289 	.reg_name = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
290 					mm ## block ## id ## _ ## reg_name
291 
292 #define SRIR(var_name, reg_name, block, id)\
293 	.var_name = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
294 					mm ## block ## id ## _ ## reg_name
295 
296 #define SRII(reg_name, block, id)\
297 	.reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
298 					mm ## block ## id ## _ ## reg_name
299 
300 #define DCCG_SRII(reg_name, block, id)\
301 	.block ## _ ## reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
302 					mm ## block ## id ## _ ## reg_name
303 
304 /* NBIO */
305 #define NBIO_BASE_INNER(seg) \
306 	NBIF0_BASE__INST0_SEG ## seg
307 
308 #define NBIO_BASE(seg) \
309 	NBIO_BASE_INNER(seg)
310 
311 #define NBIO_SR(reg_name)\
312 		.reg_name = NBIO_BASE(mm ## reg_name ## _BASE_IDX) + \
313 					mm ## reg_name
314 
315 /* MMHUB */
316 #define MMHUB_BASE_INNER(seg) \
317 	MMHUB_BASE__INST0_SEG ## seg
318 
319 #define MMHUB_BASE(seg) \
320 	MMHUB_BASE_INNER(seg)
321 
322 #define MMHUB_SR(reg_name)\
323 		.reg_name = MMHUB_BASE(mmMM ## reg_name ## _BASE_IDX) + \
324 					mmMM ## reg_name
325 
326 #define clk_src_regs(index, pllid)\
327 [index] = {\
328 	CS_COMMON_REG_LIST_DCN2_1(index, pllid),\
329 }
330 
331 static const struct dce110_clk_src_regs clk_src_regs[] = {
332 	clk_src_regs(0, A),
333 	clk_src_regs(1, B),
334 	clk_src_regs(2, C),
335 	clk_src_regs(3, D),
336 	clk_src_regs(4, E),
337 };
338 
339 static const struct dce110_clk_src_shift cs_shift = {
340 		CS_COMMON_MASK_SH_LIST_DCN2_0(__SHIFT)
341 };
342 
343 static const struct dce110_clk_src_mask cs_mask = {
344 		CS_COMMON_MASK_SH_LIST_DCN2_0(_MASK)
345 };
346 
347 static const struct bios_registers bios_regs = {
348 		NBIO_SR(BIOS_SCRATCH_3),
349 		NBIO_SR(BIOS_SCRATCH_6)
350 };
351 
352 static const struct dce_dmcu_registers dmcu_regs = {
353 		DMCU_DCN20_REG_LIST()
354 };
355 
356 static const struct dce_dmcu_shift dmcu_shift = {
357 		DMCU_MASK_SH_LIST_DCN10(__SHIFT)
358 };
359 
360 static const struct dce_dmcu_mask dmcu_mask = {
361 		DMCU_MASK_SH_LIST_DCN10(_MASK)
362 };
363 
364 static const struct dce_abm_registers abm_regs = {
365 		ABM_DCN20_REG_LIST()
366 };
367 
368 static const struct dce_abm_shift abm_shift = {
369 		ABM_MASK_SH_LIST_DCN20(__SHIFT)
370 };
371 
372 static const struct dce_abm_mask abm_mask = {
373 		ABM_MASK_SH_LIST_DCN20(_MASK)
374 };
375 
376 #define audio_regs(id)\
377 [id] = {\
378 		AUD_COMMON_REG_LIST(id)\
379 }
380 
381 static const struct dce_audio_registers audio_regs[] = {
382 	audio_regs(0),
383 	audio_regs(1),
384 	audio_regs(2),
385 	audio_regs(3),
386 	audio_regs(4),
387 	audio_regs(5),
388 };
389 
390 #define DCE120_AUD_COMMON_MASK_SH_LIST(mask_sh)\
391 		SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_INDEX, AZALIA_ENDPOINT_REG_INDEX, mask_sh),\
392 		SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_DATA, AZALIA_ENDPOINT_REG_DATA, mask_sh),\
393 		AUD_COMMON_MASK_SH_LIST_BASE(mask_sh)
394 
395 static const struct dce_audio_shift audio_shift = {
396 		DCE120_AUD_COMMON_MASK_SH_LIST(__SHIFT)
397 };
398 
399 static const struct dce_audio_mask audio_mask = {
400 		DCE120_AUD_COMMON_MASK_SH_LIST(_MASK)
401 };
402 
403 static const struct dccg_registers dccg_regs = {
404 		DCCG_COMMON_REG_LIST_DCN_BASE()
405 };
406 
407 static const struct dccg_shift dccg_shift = {
408 		DCCG_MASK_SH_LIST_DCN2(__SHIFT)
409 };
410 
411 static const struct dccg_mask dccg_mask = {
412 		DCCG_MASK_SH_LIST_DCN2(_MASK)
413 };
414 
415 #define opp_regs(id)\
416 [id] = {\
417 	OPP_REG_LIST_DCN20(id),\
418 }
419 
420 static const struct dcn20_opp_registers opp_regs[] = {
421 	opp_regs(0),
422 	opp_regs(1),
423 	opp_regs(2),
424 	opp_regs(3),
425 	opp_regs(4),
426 	opp_regs(5),
427 };
428 
429 static const struct dcn20_opp_shift opp_shift = {
430 		OPP_MASK_SH_LIST_DCN20(__SHIFT)
431 };
432 
433 static const struct dcn20_opp_mask opp_mask = {
434 		OPP_MASK_SH_LIST_DCN20(_MASK)
435 };
436 
437 #define tg_regs(id)\
438 [id] = {TG_COMMON_REG_LIST_DCN2_0(id)}
439 
440 static const struct dcn_optc_registers tg_regs[] = {
441 	tg_regs(0),
442 	tg_regs(1),
443 	tg_regs(2),
444 	tg_regs(3)
445 };
446 
447 static const struct dcn_optc_shift tg_shift = {
448 	TG_COMMON_MASK_SH_LIST_DCN2_0(__SHIFT)
449 };
450 
451 static const struct dcn_optc_mask tg_mask = {
452 	TG_COMMON_MASK_SH_LIST_DCN2_0(_MASK)
453 };
454 
455 static const struct dcn20_mpc_registers mpc_regs = {
456 		MPC_REG_LIST_DCN2_0(0),
457 		MPC_REG_LIST_DCN2_0(1),
458 		MPC_REG_LIST_DCN2_0(2),
459 		MPC_REG_LIST_DCN2_0(3),
460 		MPC_REG_LIST_DCN2_0(4),
461 		MPC_REG_LIST_DCN2_0(5),
462 		MPC_OUT_MUX_REG_LIST_DCN2_0(0),
463 		MPC_OUT_MUX_REG_LIST_DCN2_0(1),
464 		MPC_OUT_MUX_REG_LIST_DCN2_0(2),
465 		MPC_OUT_MUX_REG_LIST_DCN2_0(3)
466 };
467 
468 static const struct dcn20_mpc_shift mpc_shift = {
469 	MPC_COMMON_MASK_SH_LIST_DCN2_0(__SHIFT)
470 };
471 
472 static const struct dcn20_mpc_mask mpc_mask = {
473 	MPC_COMMON_MASK_SH_LIST_DCN2_0(_MASK)
474 };
475 
476 #define hubp_regs(id)\
477 [id] = {\
478 	HUBP_REG_LIST_DCN21(id)\
479 }
480 
481 static const struct dcn_hubp2_registers hubp_regs[] = {
482 		hubp_regs(0),
483 		hubp_regs(1),
484 		hubp_regs(2),
485 		hubp_regs(3)
486 };
487 
488 static const struct dcn_hubp2_shift hubp_shift = {
489 		HUBP_MASK_SH_LIST_DCN21(__SHIFT)
490 };
491 
492 static const struct dcn_hubp2_mask hubp_mask = {
493 		HUBP_MASK_SH_LIST_DCN21(_MASK)
494 };
495 
496 static const struct dcn_hubbub_registers hubbub_reg = {
497 		HUBBUB_REG_LIST_DCN21()
498 };
499 
500 static const struct dcn_hubbub_shift hubbub_shift = {
501 		HUBBUB_MASK_SH_LIST_DCN21(__SHIFT)
502 };
503 
504 static const struct dcn_hubbub_mask hubbub_mask = {
505 		HUBBUB_MASK_SH_LIST_DCN21(_MASK)
506 };
507 
508 
509 #define vmid_regs(id)\
510 [id] = {\
511 		DCN20_VMID_REG_LIST(id)\
512 }
513 
514 static const struct dcn_vmid_registers vmid_regs[] = {
515 	vmid_regs(0),
516 	vmid_regs(1),
517 	vmid_regs(2),
518 	vmid_regs(3),
519 	vmid_regs(4),
520 	vmid_regs(5),
521 	vmid_regs(6),
522 	vmid_regs(7),
523 	vmid_regs(8),
524 	vmid_regs(9),
525 	vmid_regs(10),
526 	vmid_regs(11),
527 	vmid_regs(12),
528 	vmid_regs(13),
529 	vmid_regs(14),
530 	vmid_regs(15)
531 };
532 
533 static const struct dcn20_vmid_shift vmid_shifts = {
534 		DCN20_VMID_MASK_SH_LIST(__SHIFT)
535 };
536 
537 static const struct dcn20_vmid_mask vmid_masks = {
538 		DCN20_VMID_MASK_SH_LIST(_MASK)
539 };
540 
541 #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
542 #define dsc_regsDCN20(id)\
543 [id] = {\
544 	DSC_REG_LIST_DCN20(id)\
545 }
546 
547 static const struct dcn20_dsc_registers dsc_regs[] = {
548 	dsc_regsDCN20(0),
549 	dsc_regsDCN20(1),
550 	dsc_regsDCN20(2),
551 	dsc_regsDCN20(3),
552 	dsc_regsDCN20(4),
553 	dsc_regsDCN20(5)
554 };
555 
556 static const struct dcn20_dsc_shift dsc_shift = {
557 	DSC_REG_LIST_SH_MASK_DCN20(__SHIFT)
558 };
559 
560 static const struct dcn20_dsc_mask dsc_mask = {
561 	DSC_REG_LIST_SH_MASK_DCN20(_MASK)
562 };
563 #endif
564 
565 #define ipp_regs(id)\
566 [id] = {\
567 	IPP_REG_LIST_DCN20(id),\
568 }
569 
570 static const struct dcn10_ipp_registers ipp_regs[] = {
571 	ipp_regs(0),
572 	ipp_regs(1),
573 	ipp_regs(2),
574 	ipp_regs(3),
575 };
576 
577 static const struct dcn10_ipp_shift ipp_shift = {
578 		IPP_MASK_SH_LIST_DCN20(__SHIFT)
579 };
580 
581 static const struct dcn10_ipp_mask ipp_mask = {
582 		IPP_MASK_SH_LIST_DCN20(_MASK),
583 };
584 
585 #define opp_regs(id)\
586 [id] = {\
587 	OPP_REG_LIST_DCN20(id),\
588 }
589 
590 
591 #define aux_engine_regs(id)\
592 [id] = {\
593 	AUX_COMMON_REG_LIST0(id), \
594 	.AUXN_IMPCAL = 0, \
595 	.AUXP_IMPCAL = 0, \
596 	.AUX_RESET_MASK = DP_AUX0_AUX_CONTROL__AUX_RESET_MASK, \
597 }
598 
599 static const struct dce110_aux_registers aux_engine_regs[] = {
600 		aux_engine_regs(0),
601 		aux_engine_regs(1),
602 		aux_engine_regs(2),
603 		aux_engine_regs(3),
604 		aux_engine_regs(4),
605 };
606 
607 #define tf_regs(id)\
608 [id] = {\
609 	TF_REG_LIST_DCN20(id),\
610 }
611 
612 static const struct dcn2_dpp_registers tf_regs[] = {
613 	tf_regs(0),
614 	tf_regs(1),
615 	tf_regs(2),
616 	tf_regs(3),
617 };
618 
619 static const struct dcn2_dpp_shift tf_shift = {
620 		TF_REG_LIST_SH_MASK_DCN20(__SHIFT)
621 };
622 
623 static const struct dcn2_dpp_mask tf_mask = {
624 		TF_REG_LIST_SH_MASK_DCN20(_MASK)
625 };
626 
627 #define stream_enc_regs(id)\
628 [id] = {\
629 	SE_DCN2_REG_LIST(id)\
630 }
631 
632 static const struct dcn10_stream_enc_registers stream_enc_regs[] = {
633 	stream_enc_regs(0),
634 	stream_enc_regs(1),
635 	stream_enc_regs(2),
636 	stream_enc_regs(3),
637 	stream_enc_regs(4),
638 };
639 
640 static const struct dce110_aux_registers_shift aux_shift = {
641 	DCN_AUX_MASK_SH_LIST(__SHIFT)
642 };
643 
644 static const struct dce110_aux_registers_mask aux_mask = {
645 	DCN_AUX_MASK_SH_LIST(_MASK)
646 };
647 
648 static const struct dcn10_stream_encoder_shift se_shift = {
649 		SE_COMMON_MASK_SH_LIST_DCN20(__SHIFT)
650 };
651 
652 static const struct dcn10_stream_encoder_mask se_mask = {
653 		SE_COMMON_MASK_SH_LIST_DCN20(_MASK)
654 };
655 
656 static void dcn21_pp_smu_destroy(struct pp_smu_funcs **pp_smu);
657 
658 static int dcn21_populate_dml_pipes_from_context(
659 		struct dc *dc, struct resource_context *res_ctx, display_e2e_pipe_params_st *pipes);
660 
661 static struct input_pixel_processor *dcn21_ipp_create(
662 	struct dc_context *ctx, uint32_t inst)
663 {
664 	struct dcn10_ipp *ipp =
665 		kzalloc(sizeof(struct dcn10_ipp), GFP_KERNEL);
666 
667 	if (!ipp) {
668 		BREAK_TO_DEBUGGER();
669 		return NULL;
670 	}
671 
672 	dcn20_ipp_construct(ipp, ctx, inst,
673 			&ipp_regs[inst], &ipp_shift, &ipp_mask);
674 	return &ipp->base;
675 }
676 
677 static struct dpp *dcn21_dpp_create(
678 	struct dc_context *ctx,
679 	uint32_t inst)
680 {
681 	struct dcn20_dpp *dpp =
682 		kzalloc(sizeof(struct dcn20_dpp), GFP_KERNEL);
683 
684 	if (!dpp)
685 		return NULL;
686 
687 	if (dpp2_construct(dpp, ctx, inst,
688 			&tf_regs[inst], &tf_shift, &tf_mask))
689 		return &dpp->base;
690 
691 	BREAK_TO_DEBUGGER();
692 	kfree(dpp);
693 	return NULL;
694 }
695 
696 static struct dce_aux *dcn21_aux_engine_create(
697 	struct dc_context *ctx,
698 	uint32_t inst)
699 {
700 	struct aux_engine_dce110 *aux_engine =
701 		kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL);
702 
703 	if (!aux_engine)
704 		return NULL;
705 
706 	dce110_aux_engine_construct(aux_engine, ctx, inst,
707 				    SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD,
708 				    &aux_engine_regs[inst],
709 					&aux_mask,
710 					&aux_shift,
711 					ctx->dc->caps.extended_aux_timeout_support);
712 
713 	return &aux_engine->base;
714 }
715 
716 #define i2c_inst_regs(id) { I2C_HW_ENGINE_COMMON_REG_LIST(id) }
717 
718 static const struct dce_i2c_registers i2c_hw_regs[] = {
719 		i2c_inst_regs(1),
720 		i2c_inst_regs(2),
721 		i2c_inst_regs(3),
722 		i2c_inst_regs(4),
723 		i2c_inst_regs(5),
724 };
725 
726 static const struct dce_i2c_shift i2c_shifts = {
727 		I2C_COMMON_MASK_SH_LIST_DCN2(__SHIFT)
728 };
729 
730 static const struct dce_i2c_mask i2c_masks = {
731 		I2C_COMMON_MASK_SH_LIST_DCN2(_MASK)
732 };
733 
734 struct dce_i2c_hw *dcn21_i2c_hw_create(
735 	struct dc_context *ctx,
736 	uint32_t inst)
737 {
738 	struct dce_i2c_hw *dce_i2c_hw =
739 		kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL);
740 
741 	if (!dce_i2c_hw)
742 		return NULL;
743 
744 	dcn2_i2c_hw_construct(dce_i2c_hw, ctx, inst,
745 				    &i2c_hw_regs[inst], &i2c_shifts, &i2c_masks);
746 
747 	return dce_i2c_hw;
748 }
749 
750 static const struct resource_caps res_cap_rn = {
751 		.num_timing_generator = 4,
752 		.num_opp = 4,
753 		.num_video_plane = 4,
754 		.num_audio = 4, // 4 audio endpoints.  4 audio streams
755 		.num_stream_encoder = 5,
756 		.num_pll = 5,  // maybe 3 because the last two used for USB-c
757 		.num_dwb = 1,
758 		.num_ddc = 5,
759 		.num_vmid = 1,
760 #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
761 		.num_dsc = 3,
762 #endif
763 };
764 
765 #ifdef DIAGS_BUILD
766 static const struct resource_caps res_cap_rn_FPGA_4pipe = {
767 		.num_timing_generator = 4,
768 		.num_opp = 4,
769 		.num_video_plane = 4,
770 		.num_audio = 7,
771 		.num_stream_encoder = 4,
772 		.num_pll = 4,
773 		.num_dwb = 1,
774 		.num_ddc = 4,
775 		.num_dsc = 0,
776 };
777 
778 static const struct resource_caps res_cap_rn_FPGA_2pipe_dsc = {
779 		.num_timing_generator = 2,
780 		.num_opp = 2,
781 		.num_video_plane = 2,
782 		.num_audio = 7,
783 		.num_stream_encoder = 2,
784 		.num_pll = 4,
785 		.num_dwb = 1,
786 		.num_ddc = 4,
787 #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
788 		.num_dsc = 2,
789 #endif
790 };
791 #endif
792 
793 static const struct dc_plane_cap plane_cap = {
794 	.type = DC_PLANE_TYPE_DCN_UNIVERSAL,
795 	.blends_with_above = true,
796 	.blends_with_below = true,
797 	.per_pixel_alpha = true,
798 
799 	.pixel_format_support = {
800 			.argb8888 = true,
801 			.nv12 = true,
802 			.fp16 = true
803 	},
804 
805 	.max_upscale_factor = {
806 			.argb8888 = 16000,
807 			.nv12 = 16000,
808 			.fp16 = 16000
809 	},
810 
811 	.max_downscale_factor = {
812 			.argb8888 = 250,
813 			.nv12 = 250,
814 			.fp16 = 250
815 	}
816 };
817 
818 static const struct dc_debug_options debug_defaults_drv = {
819 		.disable_dmcu = true,
820 		.force_abm_enable = false,
821 		.timing_trace = false,
822 		.clock_trace = true,
823 		.disable_pplib_clock_request = true,
824 		.pipe_split_policy = MPC_SPLIT_AVOID_MULT_DISP,
825 		.force_single_disp_pipe_split = false,
826 		.disable_dcc = DCC_ENABLE,
827 		.vsr_support = true,
828 		.performance_trace = false,
829 		.max_downscale_src_width = 3840,
830 		.disable_pplib_wm_range = false,
831 		.scl_reset_length10 = true,
832 		.sanity_checks = true,
833 		.disable_48mhz_pwrdwn = false,
834 		.nv12_iflip_vm_wa = true
835 };
836 
837 static const struct dc_debug_options debug_defaults_diags = {
838 		.disable_dmcu = true,
839 		.force_abm_enable = false,
840 		.timing_trace = true,
841 		.clock_trace = true,
842 		.disable_dpp_power_gate = true,
843 		.disable_hubp_power_gate = true,
844 		.disable_clock_gate = true,
845 		.disable_pplib_clock_request = true,
846 		.disable_pplib_wm_range = true,
847 		.disable_stutter = true,
848 		.disable_48mhz_pwrdwn = true,
849 };
850 
851 enum dcn20_clk_src_array_id {
852 	DCN20_CLK_SRC_PLL0,
853 	DCN20_CLK_SRC_PLL1,
854 	DCN20_CLK_SRC_TOTAL_DCN21
855 };
856 
857 static void destruct(struct dcn21_resource_pool *pool)
858 {
859 	unsigned int i;
860 
861 	for (i = 0; i < pool->base.stream_enc_count; i++) {
862 		if (pool->base.stream_enc[i] != NULL) {
863 			kfree(DCN10STRENC_FROM_STRENC(pool->base.stream_enc[i]));
864 			pool->base.stream_enc[i] = NULL;
865 		}
866 	}
867 
868 #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
869 	for (i = 0; i < pool->base.res_cap->num_dsc; i++) {
870 		if (pool->base.dscs[i] != NULL)
871 			dcn20_dsc_destroy(&pool->base.dscs[i]);
872 	}
873 #endif
874 
875 	if (pool->base.mpc != NULL) {
876 		kfree(TO_DCN20_MPC(pool->base.mpc));
877 		pool->base.mpc = NULL;
878 	}
879 	if (pool->base.hubbub != NULL) {
880 		kfree(pool->base.hubbub);
881 		pool->base.hubbub = NULL;
882 	}
883 	for (i = 0; i < pool->base.pipe_count; i++) {
884 		if (pool->base.dpps[i] != NULL)
885 			dcn20_dpp_destroy(&pool->base.dpps[i]);
886 
887 		if (pool->base.ipps[i] != NULL)
888 			pool->base.ipps[i]->funcs->ipp_destroy(&pool->base.ipps[i]);
889 
890 		if (pool->base.hubps[i] != NULL) {
891 			kfree(TO_DCN20_HUBP(pool->base.hubps[i]));
892 			pool->base.hubps[i] = NULL;
893 		}
894 
895 		if (pool->base.irqs != NULL) {
896 			dal_irq_service_destroy(&pool->base.irqs);
897 		}
898 	}
899 
900 	for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
901 		if (pool->base.engines[i] != NULL)
902 			dce110_engine_destroy(&pool->base.engines[i]);
903 		if (pool->base.hw_i2cs[i] != NULL) {
904 			kfree(pool->base.hw_i2cs[i]);
905 			pool->base.hw_i2cs[i] = NULL;
906 		}
907 		if (pool->base.sw_i2cs[i] != NULL) {
908 			kfree(pool->base.sw_i2cs[i]);
909 			pool->base.sw_i2cs[i] = NULL;
910 		}
911 	}
912 
913 	for (i = 0; i < pool->base.res_cap->num_opp; i++) {
914 		if (pool->base.opps[i] != NULL)
915 			pool->base.opps[i]->funcs->opp_destroy(&pool->base.opps[i]);
916 	}
917 
918 	for (i = 0; i < pool->base.res_cap->num_timing_generator; i++) {
919 		if (pool->base.timing_generators[i] != NULL)	{
920 			kfree(DCN10TG_FROM_TG(pool->base.timing_generators[i]));
921 			pool->base.timing_generators[i] = NULL;
922 		}
923 	}
924 
925 	for (i = 0; i < pool->base.res_cap->num_dwb; i++) {
926 		if (pool->base.dwbc[i] != NULL) {
927 			kfree(TO_DCN20_DWBC(pool->base.dwbc[i]));
928 			pool->base.dwbc[i] = NULL;
929 		}
930 		if (pool->base.mcif_wb[i] != NULL) {
931 			kfree(TO_DCN20_MMHUBBUB(pool->base.mcif_wb[i]));
932 			pool->base.mcif_wb[i] = NULL;
933 		}
934 	}
935 
936 	for (i = 0; i < pool->base.audio_count; i++) {
937 		if (pool->base.audios[i])
938 			dce_aud_destroy(&pool->base.audios[i]);
939 	}
940 
941 	for (i = 0; i < pool->base.clk_src_count; i++) {
942 		if (pool->base.clock_sources[i] != NULL) {
943 			dcn20_clock_source_destroy(&pool->base.clock_sources[i]);
944 			pool->base.clock_sources[i] = NULL;
945 		}
946 	}
947 
948 	if (pool->base.dp_clock_source != NULL) {
949 		dcn20_clock_source_destroy(&pool->base.dp_clock_source);
950 		pool->base.dp_clock_source = NULL;
951 	}
952 
953 
954 	if (pool->base.abm != NULL)
955 		dce_abm_destroy(&pool->base.abm);
956 
957 	if (pool->base.dmcu != NULL)
958 		dce_dmcu_destroy(&pool->base.dmcu);
959 
960 	if (pool->base.dccg != NULL)
961 		dcn_dccg_destroy(&pool->base.dccg);
962 
963 	if (pool->base.pp_smu != NULL)
964 		dcn21_pp_smu_destroy(&pool->base.pp_smu);
965 }
966 
967 
968 static void calculate_wm_set_for_vlevel(
969 		int vlevel,
970 		struct wm_range_table_entry *table_entry,
971 		struct dcn_watermarks *wm_set,
972 		struct display_mode_lib *dml,
973 		display_e2e_pipe_params_st *pipes,
974 		int pipe_cnt)
975 {
976 	double dram_clock_change_latency_cached = dml->soc.dram_clock_change_latency_us;
977 
978 	ASSERT(vlevel < dml->soc.num_states);
979 	/* only pipe 0 is read for voltage and dcf/soc clocks */
980 	pipes[0].clks_cfg.voltage = vlevel;
981 	pipes[0].clks_cfg.dcfclk_mhz = dml->soc.clock_limits[vlevel].dcfclk_mhz;
982 	pipes[0].clks_cfg.socclk_mhz = dml->soc.clock_limits[vlevel].socclk_mhz;
983 
984 	dml->soc.dram_clock_change_latency_us = table_entry->pstate_latency_us;
985 
986 	wm_set->urgent_ns = get_wm_urgent(dml, pipes, pipe_cnt) * 1000;
987 	wm_set->cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(dml, pipes, pipe_cnt) * 1000;
988 	wm_set->cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(dml, pipes, pipe_cnt) * 1000;
989 	wm_set->cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(dml, pipes, pipe_cnt) * 1000;
990 	wm_set->pte_meta_urgent_ns = get_wm_memory_trip(dml, pipes, pipe_cnt) * 1000;
991 #if defined(CONFIG_DRM_AMD_DC_DCN2_1)
992 	wm_set->frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(dml, pipes, pipe_cnt) * 1000;
993 	wm_set->frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(dml, pipes, pipe_cnt) * 1000;
994 	wm_set->urgent_latency_ns = get_urgent_latency(dml, pipes, pipe_cnt) * 1000;
995 #endif
996 	dml->soc.dram_clock_change_latency_us = dram_clock_change_latency_cached;
997 
998 }
999 
1000 static void patch_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_st *bb)
1001 {
1002 	kernel_fpu_begin();
1003 	if (dc->bb_overrides.sr_exit_time_ns) {
1004 		bb->sr_exit_time_us = dc->bb_overrides.sr_exit_time_ns / 1000.0;
1005 	}
1006 
1007 	if (dc->bb_overrides.sr_enter_plus_exit_time_ns) {
1008 		bb->sr_enter_plus_exit_time_us =
1009 				dc->bb_overrides.sr_enter_plus_exit_time_ns / 1000.0;
1010 	}
1011 
1012 	if (dc->bb_overrides.urgent_latency_ns) {
1013 		bb->urgent_latency_us = dc->bb_overrides.urgent_latency_ns / 1000.0;
1014 	}
1015 
1016 	if (dc->bb_overrides.dram_clock_change_latency_ns) {
1017 		bb->dram_clock_change_latency_us =
1018 				dc->bb_overrides.dram_clock_change_latency_ns / 1000.0;
1019 	}
1020 	kernel_fpu_end();
1021 }
1022 
1023 void dcn21_calculate_wm(
1024 		struct dc *dc, struct dc_state *context,
1025 		display_e2e_pipe_params_st *pipes,
1026 		int *out_pipe_cnt,
1027 		int *pipe_split_from,
1028 		int vlevel_req)
1029 {
1030 	int pipe_cnt, i, pipe_idx;
1031 	int vlevel, vlevel_max;
1032 	struct wm_range_table_entry *table_entry;
1033 	struct clk_bw_params *bw_params = dc->clk_mgr->bw_params;
1034 
1035 	ASSERT(bw_params);
1036 
1037 	patch_bounding_box(dc, &context->bw_ctx.dml.soc);
1038 
1039 	for (i = 0, pipe_idx = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {
1040 			if (!context->res_ctx.pipe_ctx[i].stream)
1041 				continue;
1042 
1043 			pipes[pipe_cnt].clks_cfg.refclk_mhz = dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000.0;
1044 			pipes[pipe_cnt].clks_cfg.dispclk_mhz = context->bw_ctx.dml.vba.RequiredDISPCLK[vlevel_req][context->bw_ctx.dml.vba.maxMpcComb];
1045 
1046 			if (pipe_split_from[i] < 0) {
1047 				pipes[pipe_cnt].clks_cfg.dppclk_mhz =
1048 						context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel_req][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx];
1049 				if (context->bw_ctx.dml.vba.BlendingAndTiming[pipe_idx] == pipe_idx)
1050 					pipes[pipe_cnt].pipe.dest.odm_combine =
1051 							context->bw_ctx.dml.vba.ODMCombineEnablePerState[vlevel_req][pipe_idx];
1052 				else
1053 					pipes[pipe_cnt].pipe.dest.odm_combine = 0;
1054 				pipe_idx++;
1055 			} else {
1056 				pipes[pipe_cnt].clks_cfg.dppclk_mhz =
1057 						context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel_req][context->bw_ctx.dml.vba.maxMpcComb][pipe_split_from[i]];
1058 				if (context->bw_ctx.dml.vba.BlendingAndTiming[pipe_split_from[i]] == pipe_split_from[i])
1059 					pipes[pipe_cnt].pipe.dest.odm_combine =
1060 							context->bw_ctx.dml.vba.ODMCombineEnablePerState[vlevel_req][pipe_split_from[i]];
1061 				else
1062 					pipes[pipe_cnt].pipe.dest.odm_combine = 0;
1063 			}
1064 			pipe_cnt++;
1065 	}
1066 
1067 	if (pipe_cnt != pipe_idx) {
1068 		if (dc->res_pool->funcs->populate_dml_pipes)
1069 			pipe_cnt = dc->res_pool->funcs->populate_dml_pipes(dc,
1070 				&context->res_ctx, pipes);
1071 		else
1072 			pipe_cnt = dcn21_populate_dml_pipes_from_context(dc,
1073 				&context->res_ctx, pipes);
1074 	}
1075 
1076 	*out_pipe_cnt = pipe_cnt;
1077 
1078 	vlevel_max = bw_params->clk_table.num_entries - 1;
1079 
1080 
1081 	/* WM Set D */
1082 	table_entry = &bw_params->wm_table.entries[WM_D];
1083 	if (table_entry->wm_type == WM_TYPE_RETRAINING)
1084 		vlevel = 0;
1085 	else
1086 		vlevel = vlevel_max;
1087 	calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.d,
1088 						&context->bw_ctx.dml, pipes, pipe_cnt);
1089 	/* WM Set C */
1090 	table_entry = &bw_params->wm_table.entries[WM_C];
1091 	vlevel = MIN(MAX(vlevel_req, 2), vlevel_max);
1092 	calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.c,
1093 						&context->bw_ctx.dml, pipes, pipe_cnt);
1094 	/* WM Set B */
1095 	table_entry = &bw_params->wm_table.entries[WM_B];
1096 	vlevel = MIN(MAX(vlevel_req, 1), vlevel_max);
1097 	calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.b,
1098 						&context->bw_ctx.dml, pipes, pipe_cnt);
1099 
1100 	/* WM Set A */
1101 	table_entry = &bw_params->wm_table.entries[WM_A];
1102 	vlevel = MIN(vlevel_req, vlevel_max);
1103 	calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.a,
1104 						&context->bw_ctx.dml, pipes, pipe_cnt);
1105 }
1106 
1107 
1108 bool dcn21_validate_bandwidth(struct dc *dc, struct dc_state *context,
1109 		bool fast_validate)
1110 {
1111 	bool out = false;
1112 
1113 	BW_VAL_TRACE_SETUP();
1114 
1115 	int vlevel = 0;
1116 	int pipe_split_from[MAX_PIPES];
1117 	int pipe_cnt = 0;
1118 	display_e2e_pipe_params_st *pipes = kzalloc(dc->res_pool->pipe_count * sizeof(display_e2e_pipe_params_st), GFP_KERNEL);
1119 	DC_LOGGER_INIT(dc->ctx->logger);
1120 
1121 	BW_VAL_TRACE_COUNT();
1122 
1123 	out = dcn20_fast_validate_bw(dc, context, pipes, &pipe_cnt, pipe_split_from, &vlevel);
1124 
1125 	if (pipe_cnt == 0)
1126 		goto validate_out;
1127 
1128 	if (!out)
1129 		goto validate_fail;
1130 
1131 	BW_VAL_TRACE_END_VOLTAGE_LEVEL();
1132 
1133 	if (fast_validate) {
1134 		BW_VAL_TRACE_SKIP(fast);
1135 		goto validate_out;
1136 	}
1137 
1138 	dcn21_calculate_wm(dc, context, pipes, &pipe_cnt, pipe_split_from, vlevel);
1139 	dcn20_calculate_dlg_params(dc, context, pipes, pipe_cnt, vlevel);
1140 
1141 	BW_VAL_TRACE_END_WATERMARKS();
1142 
1143 	goto validate_out;
1144 
1145 validate_fail:
1146 	DC_LOG_WARNING("Mode Validation Warning: %s failed validation.\n",
1147 		dml_get_status_message(context->bw_ctx.dml.vba.ValidationStatus[context->bw_ctx.dml.vba.soc.num_states]));
1148 
1149 	BW_VAL_TRACE_SKIP(fail);
1150 	out = false;
1151 
1152 validate_out:
1153 	kfree(pipes);
1154 
1155 	BW_VAL_TRACE_FINISH();
1156 
1157 	return out;
1158 }
1159 static void dcn21_destroy_resource_pool(struct resource_pool **pool)
1160 {
1161 	struct dcn21_resource_pool *dcn21_pool = TO_DCN21_RES_POOL(*pool);
1162 
1163 	destruct(dcn21_pool);
1164 	kfree(dcn21_pool);
1165 	*pool = NULL;
1166 }
1167 
1168 static struct clock_source *dcn21_clock_source_create(
1169 		struct dc_context *ctx,
1170 		struct dc_bios *bios,
1171 		enum clock_source_id id,
1172 		const struct dce110_clk_src_regs *regs,
1173 		bool dp_clk_src)
1174 {
1175 	struct dce110_clk_src *clk_src =
1176 		kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL);
1177 
1178 	if (!clk_src)
1179 		return NULL;
1180 
1181 	if (dcn20_clk_src_construct(clk_src, ctx, bios, id,
1182 			regs, &cs_shift, &cs_mask)) {
1183 		clk_src->base.dp_clk_src = dp_clk_src;
1184 		return &clk_src->base;
1185 	}
1186 
1187 	BREAK_TO_DEBUGGER();
1188 	return NULL;
1189 }
1190 
1191 static struct hubp *dcn21_hubp_create(
1192 	struct dc_context *ctx,
1193 	uint32_t inst)
1194 {
1195 	struct dcn21_hubp *hubp21 =
1196 		kzalloc(sizeof(struct dcn21_hubp), GFP_KERNEL);
1197 
1198 	if (!hubp21)
1199 		return NULL;
1200 
1201 	if (hubp21_construct(hubp21, ctx, inst,
1202 			&hubp_regs[inst], &hubp_shift, &hubp_mask))
1203 		return &hubp21->base;
1204 
1205 	BREAK_TO_DEBUGGER();
1206 	kfree(hubp21);
1207 	return NULL;
1208 }
1209 
1210 static struct hubbub *dcn21_hubbub_create(struct dc_context *ctx)
1211 {
1212 	int i;
1213 
1214 	struct dcn20_hubbub *hubbub = kzalloc(sizeof(struct dcn20_hubbub),
1215 					  GFP_KERNEL);
1216 
1217 	if (!hubbub)
1218 		return NULL;
1219 
1220 	hubbub21_construct(hubbub, ctx,
1221 			&hubbub_reg,
1222 			&hubbub_shift,
1223 			&hubbub_mask);
1224 
1225 	for (i = 0; i < res_cap_rn.num_vmid; i++) {
1226 		struct dcn20_vmid *vmid = &hubbub->vmid[i];
1227 
1228 		vmid->ctx = ctx;
1229 
1230 		vmid->regs = &vmid_regs[i];
1231 		vmid->shifts = &vmid_shifts;
1232 		vmid->masks = &vmid_masks;
1233 	}
1234 
1235 	return &hubbub->base;
1236 }
1237 
1238 struct output_pixel_processor *dcn21_opp_create(
1239 	struct dc_context *ctx, uint32_t inst)
1240 {
1241 	struct dcn20_opp *opp =
1242 		kzalloc(sizeof(struct dcn20_opp), GFP_KERNEL);
1243 
1244 	if (!opp) {
1245 		BREAK_TO_DEBUGGER();
1246 		return NULL;
1247 	}
1248 
1249 	dcn20_opp_construct(opp, ctx, inst,
1250 			&opp_regs[inst], &opp_shift, &opp_mask);
1251 	return &opp->base;
1252 }
1253 
1254 struct timing_generator *dcn21_timing_generator_create(
1255 		struct dc_context *ctx,
1256 		uint32_t instance)
1257 {
1258 	struct optc *tgn10 =
1259 		kzalloc(sizeof(struct optc), GFP_KERNEL);
1260 
1261 	if (!tgn10)
1262 		return NULL;
1263 
1264 	tgn10->base.inst = instance;
1265 	tgn10->base.ctx = ctx;
1266 
1267 	tgn10->tg_regs = &tg_regs[instance];
1268 	tgn10->tg_shift = &tg_shift;
1269 	tgn10->tg_mask = &tg_mask;
1270 
1271 	dcn20_timing_generator_init(tgn10);
1272 
1273 	return &tgn10->base;
1274 }
1275 
1276 struct mpc *dcn21_mpc_create(struct dc_context *ctx)
1277 {
1278 	struct dcn20_mpc *mpc20 = kzalloc(sizeof(struct dcn20_mpc),
1279 					  GFP_KERNEL);
1280 
1281 	if (!mpc20)
1282 		return NULL;
1283 
1284 	dcn20_mpc_construct(mpc20, ctx,
1285 			&mpc_regs,
1286 			&mpc_shift,
1287 			&mpc_mask,
1288 			6);
1289 
1290 	return &mpc20->base;
1291 }
1292 
1293 static void read_dce_straps(
1294 	struct dc_context *ctx,
1295 	struct resource_straps *straps)
1296 {
1297 	generic_reg_get(ctx, mmDC_PINSTRAPS + BASE(mmDC_PINSTRAPS_BASE_IDX),
1298 		FN(DC_PINSTRAPS, DC_PINSTRAPS_AUDIO), &straps->dc_pinstraps_audio);
1299 
1300 }
1301 
1302 #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
1303 
1304 struct display_stream_compressor *dcn21_dsc_create(
1305 	struct dc_context *ctx, uint32_t inst)
1306 {
1307 	struct dcn20_dsc *dsc =
1308 		kzalloc(sizeof(struct dcn20_dsc), GFP_KERNEL);
1309 
1310 	if (!dsc) {
1311 		BREAK_TO_DEBUGGER();
1312 		return NULL;
1313 	}
1314 
1315 	dsc2_construct(dsc, ctx, inst, &dsc_regs[inst], &dsc_shift, &dsc_mask);
1316 	return &dsc->base;
1317 }
1318 #endif
1319 
1320 static void update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params)
1321 {
1322 	/*
1323 	TODO: Fix this function to calcualte correct values.
1324 	There are known issues with this function currently
1325 	that will need to be investigated. Use hardcoded known good values for now.
1326 
1327 
1328 	struct dcn21_resource_pool *pool = TO_DCN21_RES_POOL(dc->res_pool);
1329 	struct clk_limit_table *clk_table = &bw_params->clk_table;
1330 	int i;
1331 
1332 	dcn2_1_ip.max_num_otg = pool->base.res_cap->num_timing_generator;
1333 	dcn2_1_ip.max_num_dpp = pool->base.pipe_count;
1334 	dcn2_1_soc.num_chans = bw_params->num_channels;
1335 
1336 	for (i = 0; i < clk_table->num_entries; i++) {
1337 
1338 		dcn2_1_soc.clock_limits[i].state = i;
1339 		dcn2_1_soc.clock_limits[i].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz;
1340 		dcn2_1_soc.clock_limits[i].fabricclk_mhz = clk_table->entries[i].fclk_mhz;
1341 		dcn2_1_soc.clock_limits[i].socclk_mhz = clk_table->entries[i].socclk_mhz;
1342 		dcn2_1_soc.clock_limits[i].dram_speed_mts = clk_table->entries[i].memclk_mhz * 16 / 1000;
1343 	}
1344 	dcn2_1_soc.clock_limits[i] = dcn2_1_soc.clock_limits[i - i];
1345 	dcn2_1_soc.num_states = i;
1346 	*/
1347 }
1348 
1349 /* Temporary Place holder until we can get them from fuse */
1350 static struct dpm_clocks dummy_clocks = {
1351 		.DcfClocks = {
1352 				{.Freq = 400, .Vol = 1},
1353 				{.Freq = 483, .Vol = 1},
1354 				{.Freq = 602, .Vol = 1},
1355 				{.Freq = 738, .Vol = 1} },
1356 		.SocClocks = {
1357 				{.Freq = 300, .Vol = 1},
1358 				{.Freq = 400, .Vol = 1},
1359 				{.Freq = 400, .Vol = 1},
1360 				{.Freq = 400, .Vol = 1} },
1361 		.FClocks = {
1362 				{.Freq = 400, .Vol = 1},
1363 				{.Freq = 800, .Vol = 1},
1364 				{.Freq = 1067, .Vol = 1},
1365 				{.Freq = 1600, .Vol = 1} },
1366 		.MemClocks = {
1367 				{.Freq = 800, .Vol = 1},
1368 				{.Freq = 1600, .Vol = 1},
1369 				{.Freq = 1067, .Vol = 1},
1370 				{.Freq = 1600, .Vol = 1} },
1371 
1372 };
1373 
1374 static enum pp_smu_status dummy_set_wm_ranges(struct pp_smu *pp,
1375 		struct pp_smu_wm_range_sets *ranges)
1376 {
1377 	return PP_SMU_RESULT_OK;
1378 }
1379 
1380 static enum pp_smu_status dummy_get_dpm_clock_table(struct pp_smu *pp,
1381 		struct dpm_clocks *clock_table)
1382 {
1383 	*clock_table = dummy_clocks;
1384 	return PP_SMU_RESULT_OK;
1385 }
1386 
1387 static struct pp_smu_funcs *dcn21_pp_smu_create(struct dc_context *ctx)
1388 {
1389 	struct pp_smu_funcs *pp_smu = kzalloc(sizeof(*pp_smu), GFP_KERNEL);
1390 
1391 	if (!pp_smu)
1392 		return pp_smu;
1393 
1394 	if (IS_FPGA_MAXIMUS_DC(ctx->dce_environment) || IS_DIAG_DC(ctx->dce_environment)) {
1395 		pp_smu->ctx.ver = PP_SMU_VER_RN;
1396 		pp_smu->rn_funcs.get_dpm_clock_table = dummy_get_dpm_clock_table;
1397 		pp_smu->rn_funcs.set_wm_ranges = dummy_set_wm_ranges;
1398 	} else {
1399 
1400 		dm_pp_get_funcs(ctx, pp_smu);
1401 
1402 		if (pp_smu->ctx.ver != PP_SMU_VER_RN)
1403 			pp_smu = memset(pp_smu, 0, sizeof(struct pp_smu_funcs));
1404 	}
1405 
1406 	return pp_smu;
1407 }
1408 
1409 static void dcn21_pp_smu_destroy(struct pp_smu_funcs **pp_smu)
1410 {
1411 	if (pp_smu && *pp_smu) {
1412 		kfree(*pp_smu);
1413 		*pp_smu = NULL;
1414 	}
1415 }
1416 
1417 static struct audio *dcn21_create_audio(
1418 		struct dc_context *ctx, unsigned int inst)
1419 {
1420 	return dce_audio_create(ctx, inst,
1421 			&audio_regs[inst], &audio_shift, &audio_mask);
1422 }
1423 
1424 static struct dc_cap_funcs cap_funcs = {
1425 	.get_dcc_compression_cap = dcn20_get_dcc_compression_cap
1426 };
1427 
1428 struct stream_encoder *dcn21_stream_encoder_create(
1429 	enum engine_id eng_id,
1430 	struct dc_context *ctx)
1431 {
1432 	struct dcn10_stream_encoder *enc1 =
1433 		kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL);
1434 
1435 	if (!enc1)
1436 		return NULL;
1437 
1438 	dcn20_stream_encoder_construct(enc1, ctx, ctx->dc_bios, eng_id,
1439 					&stream_enc_regs[eng_id],
1440 					&se_shift, &se_mask);
1441 
1442 	return &enc1->base;
1443 }
1444 
1445 static const struct dce_hwseq_registers hwseq_reg = {
1446 		HWSEQ_DCN21_REG_LIST()
1447 };
1448 
1449 static const struct dce_hwseq_shift hwseq_shift = {
1450 		HWSEQ_DCN21_MASK_SH_LIST(__SHIFT)
1451 };
1452 
1453 static const struct dce_hwseq_mask hwseq_mask = {
1454 		HWSEQ_DCN21_MASK_SH_LIST(_MASK)
1455 };
1456 
1457 static struct dce_hwseq *dcn21_hwseq_create(
1458 	struct dc_context *ctx)
1459 {
1460 	struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL);
1461 
1462 	if (hws) {
1463 		hws->ctx = ctx;
1464 		hws->regs = &hwseq_reg;
1465 		hws->shifts = &hwseq_shift;
1466 		hws->masks = &hwseq_mask;
1467 		hws->wa.DEGVIDCN21 = true;
1468 	}
1469 	return hws;
1470 }
1471 
1472 static const struct resource_create_funcs res_create_funcs = {
1473 	.read_dce_straps = read_dce_straps,
1474 	.create_audio = dcn21_create_audio,
1475 	.create_stream_encoder = dcn21_stream_encoder_create,
1476 	.create_hwseq = dcn21_hwseq_create,
1477 };
1478 
1479 static const struct resource_create_funcs res_create_maximus_funcs = {
1480 	.read_dce_straps = NULL,
1481 	.create_audio = NULL,
1482 	.create_stream_encoder = NULL,
1483 	.create_hwseq = dcn21_hwseq_create,
1484 };
1485 
1486 static const struct encoder_feature_support link_enc_feature = {
1487 		.max_hdmi_deep_color = COLOR_DEPTH_121212,
1488 		.max_hdmi_pixel_clock = 600000,
1489 		.hdmi_ycbcr420_supported = true,
1490 		.dp_ycbcr420_supported = true,
1491 		.flags.bits.IS_HBR2_CAPABLE = true,
1492 		.flags.bits.IS_HBR3_CAPABLE = true,
1493 		.flags.bits.IS_TPS3_CAPABLE = true,
1494 		.flags.bits.IS_TPS4_CAPABLE = true
1495 };
1496 
1497 
1498 #define link_regs(id, phyid)\
1499 [id] = {\
1500 	LE_DCN10_REG_LIST(id), \
1501 	UNIPHY_DCN2_REG_LIST(phyid), \
1502 	SRI(DP_DPHY_INTERNAL_CTRL, DP, id) \
1503 }
1504 
1505 static const struct dcn10_link_enc_registers link_enc_regs[] = {
1506 	link_regs(0, A),
1507 	link_regs(1, B),
1508 	link_regs(2, C),
1509 	link_regs(3, D),
1510 	link_regs(4, E),
1511 };
1512 
1513 #define aux_regs(id)\
1514 [id] = {\
1515 	DCN2_AUX_REG_LIST(id)\
1516 }
1517 
1518 static const struct dcn10_link_enc_aux_registers link_enc_aux_regs[] = {
1519 		aux_regs(0),
1520 		aux_regs(1),
1521 		aux_regs(2),
1522 		aux_regs(3),
1523 		aux_regs(4)
1524 };
1525 
1526 #define hpd_regs(id)\
1527 [id] = {\
1528 	HPD_REG_LIST(id)\
1529 }
1530 
1531 static const struct dcn10_link_enc_hpd_registers link_enc_hpd_regs[] = {
1532 		hpd_regs(0),
1533 		hpd_regs(1),
1534 		hpd_regs(2),
1535 		hpd_regs(3),
1536 		hpd_regs(4)
1537 };
1538 
1539 static const struct dcn10_link_enc_shift le_shift = {
1540 	LINK_ENCODER_MASK_SH_LIST_DCN20(__SHIFT)
1541 };
1542 
1543 static const struct dcn10_link_enc_mask le_mask = {
1544 	LINK_ENCODER_MASK_SH_LIST_DCN20(_MASK)
1545 };
1546 
1547 static int map_transmitter_id_to_phy_instance(
1548 	enum transmitter transmitter)
1549 {
1550 	switch (transmitter) {
1551 	case TRANSMITTER_UNIPHY_A:
1552 		return 0;
1553 	break;
1554 	case TRANSMITTER_UNIPHY_B:
1555 		return 1;
1556 	break;
1557 	case TRANSMITTER_UNIPHY_C:
1558 		return 2;
1559 	break;
1560 	case TRANSMITTER_UNIPHY_D:
1561 		return 3;
1562 	break;
1563 	case TRANSMITTER_UNIPHY_E:
1564 		return 4;
1565 	break;
1566 	default:
1567 		ASSERT(0);
1568 		return 0;
1569 	}
1570 }
1571 
1572 static struct link_encoder *dcn21_link_encoder_create(
1573 	const struct encoder_init_data *enc_init_data)
1574 {
1575 	struct dcn21_link_encoder *enc21 =
1576 		kzalloc(sizeof(struct dcn21_link_encoder), GFP_KERNEL);
1577 	int link_regs_id;
1578 
1579 	if (!enc21)
1580 		return NULL;
1581 
1582 	link_regs_id =
1583 		map_transmitter_id_to_phy_instance(enc_init_data->transmitter);
1584 
1585 	dcn21_link_encoder_construct(enc21,
1586 				      enc_init_data,
1587 				      &link_enc_feature,
1588 				      &link_enc_regs[link_regs_id],
1589 				      &link_enc_aux_regs[enc_init_data->channel - 1],
1590 				      &link_enc_hpd_regs[enc_init_data->hpd_source],
1591 				      &le_shift,
1592 				      &le_mask);
1593 
1594 	return &enc21->enc10.base;
1595 }
1596 #define CTX ctx
1597 
1598 #define REG(reg_name) \
1599 	(DCN_BASE.instance[0].segment[mm ## reg_name ## _BASE_IDX] + mm ## reg_name)
1600 
1601 static uint32_t read_pipe_fuses(struct dc_context *ctx)
1602 {
1603 	uint32_t value = REG_READ(CC_DC_PIPE_DIS);
1604 	/* RV1 support max 4 pipes */
1605 	value = value & 0xf;
1606 	return value;
1607 }
1608 
1609 static int dcn21_populate_dml_pipes_from_context(
1610 		struct dc *dc, struct resource_context *res_ctx, display_e2e_pipe_params_st *pipes)
1611 {
1612 	uint32_t pipe_cnt = dcn20_populate_dml_pipes_from_context(dc, res_ctx, pipes);
1613 	int i;
1614 
1615 	for (i = 0; i < dc->res_pool->pipe_count; i++) {
1616 
1617 		if (!res_ctx->pipe_ctx[i].stream)
1618 			continue;
1619 
1620 		pipes[i].pipe.src.hostvm = 1;
1621 		pipes[i].pipe.src.gpuvm = 1;
1622 	}
1623 
1624 	return pipe_cnt;
1625 }
1626 
1627 static struct resource_funcs dcn21_res_pool_funcs = {
1628 	.destroy = dcn21_destroy_resource_pool,
1629 	.link_enc_create = dcn21_link_encoder_create,
1630 	.validate_bandwidth = dcn21_validate_bandwidth,
1631 	.populate_dml_pipes = dcn21_populate_dml_pipes_from_context,
1632 	.add_stream_to_ctx = dcn20_add_stream_to_ctx,
1633 	.remove_stream_from_ctx = dcn20_remove_stream_from_ctx,
1634 	.acquire_idle_pipe_for_layer = dcn20_acquire_idle_pipe_for_layer,
1635 	.populate_dml_writeback_from_context = dcn20_populate_dml_writeback_from_context,
1636 	.get_default_swizzle_mode = dcn20_get_default_swizzle_mode,
1637 	.set_mcif_arb_params = dcn20_set_mcif_arb_params,
1638 	.find_first_free_match_stream_enc_for_link = dcn10_find_first_free_match_stream_enc_for_link,
1639 	.update_bw_bounding_box = update_bw_bounding_box
1640 };
1641 
1642 static bool construct(
1643 	uint8_t num_virtual_links,
1644 	struct dc *dc,
1645 	struct dcn21_resource_pool *pool)
1646 {
1647 	int i, j;
1648 	struct dc_context *ctx = dc->ctx;
1649 	struct irq_service_init_data init_data;
1650 	uint32_t pipe_fuses = read_pipe_fuses(ctx);
1651 	uint32_t num_pipes;
1652 
1653 	ctx->dc_bios->regs = &bios_regs;
1654 
1655 	pool->base.res_cap = &res_cap_rn;
1656 #ifdef DIAGS_BUILD
1657 	if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment))
1658 		//pool->base.res_cap = &res_cap_nv10_FPGA_2pipe_dsc;
1659 		pool->base.res_cap = &res_cap_rn_FPGA_4pipe;
1660 #endif
1661 
1662 	pool->base.funcs = &dcn21_res_pool_funcs;
1663 
1664 	/*************************************************
1665 	 *  Resource + asic cap harcoding                *
1666 	 *************************************************/
1667 	pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE;
1668 
1669 	/* max pipe num for ASIC before check pipe fuses */
1670 	pool->base.pipe_count = pool->base.res_cap->num_timing_generator;
1671 
1672 	dc->caps.max_downscale_ratio = 200;
1673 	dc->caps.i2c_speed_in_khz = 100;
1674 	dc->caps.max_cursor_size = 256;
1675 	dc->caps.dmdata_alloc_size = 2048;
1676 	dc->caps.hw_3d_lut = true;
1677 
1678 	dc->caps.max_slave_planes = 1;
1679 	dc->caps.post_blend_color_processing = true;
1680 	dc->caps.force_dp_tps4_for_cp2520 = true;
1681 	dc->caps.extended_aux_timeout_support = true;
1682 	dc->caps.dmcub_support = true;
1683 
1684 	if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV)
1685 		dc->debug = debug_defaults_drv;
1686 	else if (dc->ctx->dce_environment == DCE_ENV_FPGA_MAXIMUS) {
1687 		pool->base.pipe_count = 4;
1688 		dc->debug = debug_defaults_diags;
1689 	} else
1690 		dc->debug = debug_defaults_diags;
1691 
1692 	// Init the vm_helper
1693 	if (dc->vm_helper)
1694 		vm_helper_init(dc->vm_helper, 16);
1695 
1696 	/*************************************************
1697 	 *  Create resources                             *
1698 	 *************************************************/
1699 
1700 	pool->base.clock_sources[DCN20_CLK_SRC_PLL0] =
1701 			dcn21_clock_source_create(ctx, ctx->dc_bios,
1702 				CLOCK_SOURCE_COMBO_PHY_PLL0,
1703 				&clk_src_regs[0], false);
1704 	pool->base.clock_sources[DCN20_CLK_SRC_PLL1] =
1705 			dcn21_clock_source_create(ctx, ctx->dc_bios,
1706 				CLOCK_SOURCE_COMBO_PHY_PLL1,
1707 				&clk_src_regs[1], false);
1708 
1709 	pool->base.clk_src_count = DCN20_CLK_SRC_TOTAL_DCN21;
1710 
1711 	/* todo: not reuse phy_pll registers */
1712 	pool->base.dp_clock_source =
1713 			dcn21_clock_source_create(ctx, ctx->dc_bios,
1714 				CLOCK_SOURCE_ID_DP_DTO,
1715 				&clk_src_regs[0], true);
1716 
1717 	for (i = 0; i < pool->base.clk_src_count; i++) {
1718 		if (pool->base.clock_sources[i] == NULL) {
1719 			dm_error("DC: failed to create clock sources!\n");
1720 			BREAK_TO_DEBUGGER();
1721 			goto create_fail;
1722 		}
1723 	}
1724 
1725 	pool->base.dccg = dccg2_create(ctx, &dccg_regs, &dccg_shift, &dccg_mask);
1726 	if (pool->base.dccg == NULL) {
1727 		dm_error("DC: failed to create dccg!\n");
1728 		BREAK_TO_DEBUGGER();
1729 		goto create_fail;
1730 	}
1731 
1732 	pool->base.dmcu = dcn21_dmcu_create(ctx,
1733 			&dmcu_regs,
1734 			&dmcu_shift,
1735 			&dmcu_mask);
1736 	if (pool->base.dmcu == NULL) {
1737 		dm_error("DC: failed to create dmcu!\n");
1738 		BREAK_TO_DEBUGGER();
1739 		goto create_fail;
1740 	}
1741 
1742 	pool->base.abm = dce_abm_create(ctx,
1743 			&abm_regs,
1744 			&abm_shift,
1745 			&abm_mask);
1746 	if (pool->base.abm == NULL) {
1747 		dm_error("DC: failed to create abm!\n");
1748 		BREAK_TO_DEBUGGER();
1749 		goto create_fail;
1750 	}
1751 
1752 	pool->base.pp_smu = dcn21_pp_smu_create(ctx);
1753 
1754 	num_pipes = dcn2_1_ip.max_num_dpp;
1755 
1756 	for (i = 0; i < dcn2_1_ip.max_num_dpp; i++)
1757 		if (pipe_fuses & 1 << i)
1758 			num_pipes--;
1759 	dcn2_1_ip.max_num_dpp = num_pipes;
1760 	dcn2_1_ip.max_num_otg = num_pipes;
1761 
1762 	dml_init_instance(&dc->dml, &dcn2_1_soc, &dcn2_1_ip, DML_PROJECT_DCN21);
1763 
1764 	init_data.ctx = dc->ctx;
1765 	pool->base.irqs = dal_irq_service_dcn21_create(&init_data);
1766 	if (!pool->base.irqs)
1767 		goto create_fail;
1768 
1769 	j = 0;
1770 	/* mem input -> ipp -> dpp -> opp -> TG */
1771 	for (i = 0; i < pool->base.pipe_count; i++) {
1772 		/* if pipe is disabled, skip instance of HW pipe,
1773 		 * i.e, skip ASIC register instance
1774 		 */
1775 		if ((pipe_fuses & (1 << i)) != 0)
1776 			continue;
1777 
1778 		pool->base.hubps[i] = dcn21_hubp_create(ctx, i);
1779 		if (pool->base.hubps[i] == NULL) {
1780 			BREAK_TO_DEBUGGER();
1781 			dm_error(
1782 				"DC: failed to create memory input!\n");
1783 			goto create_fail;
1784 		}
1785 
1786 		pool->base.ipps[i] = dcn21_ipp_create(ctx, i);
1787 		if (pool->base.ipps[i] == NULL) {
1788 			BREAK_TO_DEBUGGER();
1789 			dm_error(
1790 				"DC: failed to create input pixel processor!\n");
1791 			goto create_fail;
1792 		}
1793 
1794 		pool->base.dpps[i] = dcn21_dpp_create(ctx, i);
1795 		if (pool->base.dpps[i] == NULL) {
1796 			BREAK_TO_DEBUGGER();
1797 			dm_error(
1798 				"DC: failed to create dpps!\n");
1799 			goto create_fail;
1800 		}
1801 
1802 		pool->base.opps[i] = dcn21_opp_create(ctx, i);
1803 		if (pool->base.opps[i] == NULL) {
1804 			BREAK_TO_DEBUGGER();
1805 			dm_error(
1806 				"DC: failed to create output pixel processor!\n");
1807 			goto create_fail;
1808 		}
1809 
1810 		pool->base.timing_generators[i] = dcn21_timing_generator_create(
1811 				ctx, i);
1812 		if (pool->base.timing_generators[i] == NULL) {
1813 			BREAK_TO_DEBUGGER();
1814 			dm_error("DC: failed to create tg!\n");
1815 			goto create_fail;
1816 		}
1817 		j++;
1818 	}
1819 
1820 	for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
1821 		pool->base.engines[i] = dcn21_aux_engine_create(ctx, i);
1822 		if (pool->base.engines[i] == NULL) {
1823 			BREAK_TO_DEBUGGER();
1824 			dm_error(
1825 				"DC:failed to create aux engine!!\n");
1826 			goto create_fail;
1827 		}
1828 		pool->base.hw_i2cs[i] = dcn21_i2c_hw_create(ctx, i);
1829 		if (pool->base.hw_i2cs[i] == NULL) {
1830 			BREAK_TO_DEBUGGER();
1831 			dm_error(
1832 				"DC:failed to create hw i2c!!\n");
1833 			goto create_fail;
1834 		}
1835 		pool->base.sw_i2cs[i] = NULL;
1836 	}
1837 
1838 	pool->base.timing_generator_count = j;
1839 	pool->base.pipe_count = j;
1840 	pool->base.mpcc_count = j;
1841 
1842 	pool->base.mpc = dcn21_mpc_create(ctx);
1843 	if (pool->base.mpc == NULL) {
1844 		BREAK_TO_DEBUGGER();
1845 		dm_error("DC: failed to create mpc!\n");
1846 		goto create_fail;
1847 	}
1848 
1849 	pool->base.hubbub = dcn21_hubbub_create(ctx);
1850 	if (pool->base.hubbub == NULL) {
1851 		BREAK_TO_DEBUGGER();
1852 		dm_error("DC: failed to create hubbub!\n");
1853 		goto create_fail;
1854 	}
1855 
1856 #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
1857 	for (i = 0; i < pool->base.res_cap->num_dsc; i++) {
1858 		pool->base.dscs[i] = dcn21_dsc_create(ctx, i);
1859 		if (pool->base.dscs[i] == NULL) {
1860 			BREAK_TO_DEBUGGER();
1861 			dm_error("DC: failed to create display stream compressor %d!\n", i);
1862 			goto create_fail;
1863 		}
1864 	}
1865 #endif
1866 
1867 	if (!dcn20_dwbc_create(ctx, &pool->base)) {
1868 		BREAK_TO_DEBUGGER();
1869 		dm_error("DC: failed to create dwbc!\n");
1870 		goto create_fail;
1871 	}
1872 	if (!dcn20_mmhubbub_create(ctx, &pool->base)) {
1873 		BREAK_TO_DEBUGGER();
1874 		dm_error("DC: failed to create mcif_wb!\n");
1875 		goto create_fail;
1876 	}
1877 
1878 	if (!resource_construct(num_virtual_links, dc, &pool->base,
1879 			(!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment) ?
1880 			&res_create_funcs : &res_create_maximus_funcs)))
1881 			goto create_fail;
1882 
1883 	dcn21_hw_sequencer_construct(dc);
1884 
1885 	dc->caps.max_planes =  pool->base.pipe_count;
1886 
1887 	for (i = 0; i < dc->caps.max_planes; ++i)
1888 		dc->caps.planes[i] = plane_cap;
1889 
1890 	dc->cap_funcs = cap_funcs;
1891 
1892 	return true;
1893 
1894 create_fail:
1895 
1896 	destruct(pool);
1897 
1898 	return false;
1899 }
1900 
1901 struct resource_pool *dcn21_create_resource_pool(
1902 		const struct dc_init_data *init_data,
1903 		struct dc *dc)
1904 {
1905 	struct dcn21_resource_pool *pool =
1906 		kzalloc(sizeof(struct dcn21_resource_pool), GFP_KERNEL);
1907 
1908 	if (!pool)
1909 		return NULL;
1910 
1911 	if (construct(init_data->num_virtual_links, dc, pool))
1912 		return &pool->base;
1913 
1914 	BREAK_TO_DEBUGGER();
1915 	kfree(pool);
1916 	return NULL;
1917 }
1918