Line data Source code
1 : /*
2 : * Copyright 2019 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 :
27 : #include "dm_services.h"
28 : #include "dc.h"
29 :
30 : #include "dcn31/dcn31_init.h"
31 :
32 : #include "resource.h"
33 : #include "include/irq_service_interface.h"
34 : #include "dcn31_resource.h"
35 :
36 : #include "dcn20/dcn20_resource.h"
37 : #include "dcn30/dcn30_resource.h"
38 :
39 : #include "dml/dcn30/dcn30_fpu.h"
40 :
41 : #include "dcn10/dcn10_ipp.h"
42 : #include "dcn30/dcn30_hubbub.h"
43 : #include "dcn31/dcn31_hubbub.h"
44 : #include "dcn30/dcn30_mpc.h"
45 : #include "dcn31/dcn31_hubp.h"
46 : #include "irq/dcn31/irq_service_dcn31.h"
47 : #include "dcn30/dcn30_dpp.h"
48 : #include "dcn31/dcn31_optc.h"
49 : #include "dcn20/dcn20_hwseq.h"
50 : #include "dcn30/dcn30_hwseq.h"
51 : #include "dce110/dce110_hw_sequencer.h"
52 : #include "dcn30/dcn30_opp.h"
53 : #include "dcn20/dcn20_dsc.h"
54 : #include "dcn30/dcn30_vpg.h"
55 : #include "dcn30/dcn30_afmt.h"
56 : #include "dcn30/dcn30_dio_stream_encoder.h"
57 : #include "dcn31/dcn31_hpo_dp_stream_encoder.h"
58 : #include "dcn31/dcn31_hpo_dp_link_encoder.h"
59 : #include "dcn31/dcn31_apg.h"
60 : #include "dcn31/dcn31_dio_link_encoder.h"
61 : #include "dcn31/dcn31_vpg.h"
62 : #include "dcn31/dcn31_afmt.h"
63 : #include "dce/dce_clock_source.h"
64 : #include "dce/dce_audio.h"
65 : #include "dce/dce_hwseq.h"
66 : #include "clk_mgr.h"
67 : #include "virtual/virtual_stream_encoder.h"
68 : #include "dce110/dce110_resource.h"
69 : #include "dml/display_mode_vba.h"
70 : #include "dml/dcn31/dcn31_fpu.h"
71 : #include "dcn31/dcn31_dccg.h"
72 : #include "dcn10/dcn10_resource.h"
73 : #include "dcn31_panel_cntl.h"
74 :
75 : #include "dcn30/dcn30_dwb.h"
76 : #include "dcn30/dcn30_mmhubbub.h"
77 :
78 : // TODO: change include headers /amd/include/asic_reg after upstream
79 : #include "yellow_carp_offset.h"
80 : #include "dcn/dcn_3_1_2_offset.h"
81 : #include "dcn/dcn_3_1_2_sh_mask.h"
82 : #include "nbio/nbio_7_2_0_offset.h"
83 : #include "dpcs/dpcs_4_2_0_offset.h"
84 : #include "dpcs/dpcs_4_2_0_sh_mask.h"
85 : #include "mmhub/mmhub_2_3_0_offset.h"
86 : #include "mmhub/mmhub_2_3_0_sh_mask.h"
87 :
88 :
89 : #define regDCHUBBUB_DEBUG_CTRL_0 0x04d6
90 : #define regDCHUBBUB_DEBUG_CTRL_0_BASE_IDX 2
91 : #define DCHUBBUB_DEBUG_CTRL_0__DET_DEPTH__SHIFT 0x10
92 : #define DCHUBBUB_DEBUG_CTRL_0__DET_DEPTH_MASK 0x01FF0000L
93 :
94 : #include "reg_helper.h"
95 : #include "dce/dmub_abm.h"
96 : #include "dce/dmub_psr.h"
97 : #include "dce/dce_aux.h"
98 : #include "dce/dce_i2c.h"
99 :
100 : #include "dml/dcn30/display_mode_vba_30.h"
101 : #include "vm_helper.h"
102 : #include "dcn20/dcn20_vmid.h"
103 :
104 : #include "link_enc_cfg.h"
105 :
106 : #define DC_LOGGER_INIT(logger)
107 :
108 : enum dcn31_clk_src_array_id {
109 : DCN31_CLK_SRC_PLL0,
110 : DCN31_CLK_SRC_PLL1,
111 : DCN31_CLK_SRC_PLL2,
112 : DCN31_CLK_SRC_PLL3,
113 : DCN31_CLK_SRC_PLL4,
114 : DCN30_CLK_SRC_TOTAL
115 : };
116 :
117 : /* begin *********************
118 : * macros to expend register list macro defined in HW object header file
119 : */
120 :
121 : /* DCN */
122 : /* TODO awful hack. fixup dcn20_dwb.h */
123 : #undef BASE_INNER
124 : #define BASE_INNER(seg) DCN_BASE__INST0_SEG ## seg
125 :
126 : #define BASE(seg) BASE_INNER(seg)
127 :
128 : #define SR(reg_name)\
129 : .reg_name = BASE(reg ## reg_name ## _BASE_IDX) + \
130 : reg ## reg_name
131 :
132 : #define SRI(reg_name, block, id)\
133 : .reg_name = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
134 : reg ## block ## id ## _ ## reg_name
135 :
136 : #define SRI2(reg_name, block, id)\
137 : .reg_name = BASE(reg ## reg_name ## _BASE_IDX) + \
138 : reg ## reg_name
139 :
140 : #define SRIR(var_name, reg_name, block, id)\
141 : .var_name = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
142 : reg ## block ## id ## _ ## reg_name
143 :
144 : #define SRII(reg_name, block, id)\
145 : .reg_name[id] = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
146 : reg ## block ## id ## _ ## reg_name
147 :
148 : #define SRII_MPC_RMU(reg_name, block, id)\
149 : .RMU##_##reg_name[id] = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
150 : reg ## block ## id ## _ ## reg_name
151 :
152 : #define SRII_DWB(reg_name, temp_name, block, id)\
153 : .reg_name[id] = BASE(reg ## block ## id ## _ ## temp_name ## _BASE_IDX) + \
154 : reg ## block ## id ## _ ## temp_name
155 :
156 : #define DCCG_SRII(reg_name, block, id)\
157 : .block ## _ ## reg_name[id] = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
158 : reg ## block ## id ## _ ## reg_name
159 :
160 : #define VUPDATE_SRII(reg_name, block, id)\
161 : .reg_name[id] = BASE(reg ## reg_name ## _ ## block ## id ## _BASE_IDX) + \
162 : reg ## reg_name ## _ ## block ## id
163 :
164 : /* NBIO */
165 : #define NBIO_BASE_INNER(seg) \
166 : NBIO_BASE__INST0_SEG ## seg
167 :
168 : #define NBIO_BASE(seg) \
169 : NBIO_BASE_INNER(seg)
170 :
171 : #define NBIO_SR(reg_name)\
172 : .reg_name = NBIO_BASE(regBIF_BX1_ ## reg_name ## _BASE_IDX) + \
173 : regBIF_BX1_ ## reg_name
174 :
175 : /* MMHUB */
176 : #define MMHUB_BASE_INNER(seg) \
177 : MMHUB_BASE__INST0_SEG ## seg
178 :
179 : #define MMHUB_BASE(seg) \
180 : MMHUB_BASE_INNER(seg)
181 :
182 : #define MMHUB_SR(reg_name)\
183 : .reg_name = MMHUB_BASE(mm ## reg_name ## _BASE_IDX) + \
184 : mm ## reg_name
185 :
186 : /* CLOCK */
187 : #define CLK_BASE_INNER(seg) \
188 : CLK_BASE__INST0_SEG ## seg
189 :
190 : #define CLK_BASE(seg) \
191 : CLK_BASE_INNER(seg)
192 :
193 : #define CLK_SRI(reg_name, block, inst)\
194 : .reg_name = CLK_BASE(reg ## block ## _ ## inst ## _ ## reg_name ## _BASE_IDX) + \
195 : reg ## block ## _ ## inst ## _ ## reg_name
196 :
197 :
198 : static const struct bios_registers bios_regs = {
199 : NBIO_SR(BIOS_SCRATCH_3),
200 : NBIO_SR(BIOS_SCRATCH_6)
201 : };
202 :
203 : #define clk_src_regs(index, pllid)\
204 : [index] = {\
205 : CS_COMMON_REG_LIST_DCN3_0(index, pllid),\
206 : }
207 :
208 : static const struct dce110_clk_src_regs clk_src_regs[] = {
209 : clk_src_regs(0, A),
210 : clk_src_regs(1, B),
211 : clk_src_regs(2, C),
212 : clk_src_regs(3, D),
213 : clk_src_regs(4, E)
214 : };
215 : /*pll_id being rempped in dmub, in driver it is logical instance*/
216 : static const struct dce110_clk_src_regs clk_src_regs_b0[] = {
217 : clk_src_regs(0, A),
218 : clk_src_regs(1, B),
219 : clk_src_regs(2, F),
220 : clk_src_regs(3, G),
221 : clk_src_regs(4, E)
222 : };
223 :
224 : static const struct dce110_clk_src_shift cs_shift = {
225 : CS_COMMON_MASK_SH_LIST_DCN2_0(__SHIFT)
226 : };
227 :
228 : static const struct dce110_clk_src_mask cs_mask = {
229 : CS_COMMON_MASK_SH_LIST_DCN2_0(_MASK)
230 : };
231 :
232 : #define abm_regs(id)\
233 : [id] = {\
234 : ABM_DCN302_REG_LIST(id)\
235 : }
236 :
237 : static const struct dce_abm_registers abm_regs[] = {
238 : abm_regs(0),
239 : abm_regs(1),
240 : abm_regs(2),
241 : abm_regs(3),
242 : };
243 :
244 : static const struct dce_abm_shift abm_shift = {
245 : ABM_MASK_SH_LIST_DCN30(__SHIFT)
246 : };
247 :
248 : static const struct dce_abm_mask abm_mask = {
249 : ABM_MASK_SH_LIST_DCN30(_MASK)
250 : };
251 :
252 : #define audio_regs(id)\
253 : [id] = {\
254 : AUD_COMMON_REG_LIST(id)\
255 : }
256 :
257 : static const struct dce_audio_registers audio_regs[] = {
258 : audio_regs(0),
259 : audio_regs(1),
260 : audio_regs(2),
261 : audio_regs(3),
262 : audio_regs(4),
263 : audio_regs(5),
264 : audio_regs(6)
265 : };
266 :
267 : #define DCE120_AUD_COMMON_MASK_SH_LIST(mask_sh)\
268 : SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_INDEX, AZALIA_ENDPOINT_REG_INDEX, mask_sh),\
269 : SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_DATA, AZALIA_ENDPOINT_REG_DATA, mask_sh),\
270 : AUD_COMMON_MASK_SH_LIST_BASE(mask_sh)
271 :
272 : static const struct dce_audio_shift audio_shift = {
273 : DCE120_AUD_COMMON_MASK_SH_LIST(__SHIFT)
274 : };
275 :
276 : static const struct dce_audio_mask audio_mask = {
277 : DCE120_AUD_COMMON_MASK_SH_LIST(_MASK)
278 : };
279 :
280 : #define vpg_regs(id)\
281 : [id] = {\
282 : VPG_DCN31_REG_LIST(id)\
283 : }
284 :
285 : static const struct dcn31_vpg_registers vpg_regs[] = {
286 : vpg_regs(0),
287 : vpg_regs(1),
288 : vpg_regs(2),
289 : vpg_regs(3),
290 : vpg_regs(4),
291 : vpg_regs(5),
292 : vpg_regs(6),
293 : vpg_regs(7),
294 : vpg_regs(8),
295 : vpg_regs(9),
296 : };
297 :
298 : static const struct dcn31_vpg_shift vpg_shift = {
299 : DCN31_VPG_MASK_SH_LIST(__SHIFT)
300 : };
301 :
302 : static const struct dcn31_vpg_mask vpg_mask = {
303 : DCN31_VPG_MASK_SH_LIST(_MASK)
304 : };
305 :
306 : #define afmt_regs(id)\
307 : [id] = {\
308 : AFMT_DCN31_REG_LIST(id)\
309 : }
310 :
311 : static const struct dcn31_afmt_registers afmt_regs[] = {
312 : afmt_regs(0),
313 : afmt_regs(1),
314 : afmt_regs(2),
315 : afmt_regs(3),
316 : afmt_regs(4),
317 : afmt_regs(5)
318 : };
319 :
320 : static const struct dcn31_afmt_shift afmt_shift = {
321 : DCN31_AFMT_MASK_SH_LIST(__SHIFT)
322 : };
323 :
324 : static const struct dcn31_afmt_mask afmt_mask = {
325 : DCN31_AFMT_MASK_SH_LIST(_MASK)
326 : };
327 :
328 : #define apg_regs(id)\
329 : [id] = {\
330 : APG_DCN31_REG_LIST(id)\
331 : }
332 :
333 : static const struct dcn31_apg_registers apg_regs[] = {
334 : apg_regs(0),
335 : apg_regs(1),
336 : apg_regs(2),
337 : apg_regs(3)
338 : };
339 :
340 : static const struct dcn31_apg_shift apg_shift = {
341 : DCN31_APG_MASK_SH_LIST(__SHIFT)
342 : };
343 :
344 : static const struct dcn31_apg_mask apg_mask = {
345 : DCN31_APG_MASK_SH_LIST(_MASK)
346 : };
347 :
348 : #define stream_enc_regs(id)\
349 : [id] = {\
350 : SE_DCN3_REG_LIST(id)\
351 : }
352 :
353 : /* Some encoders won't be initialized here - but they're logical, not physical. */
354 : static const struct dcn10_stream_enc_registers stream_enc_regs[ENGINE_ID_COUNT] = {
355 : stream_enc_regs(0),
356 : stream_enc_regs(1),
357 : stream_enc_regs(2),
358 : stream_enc_regs(3),
359 : stream_enc_regs(4)
360 : };
361 :
362 : static const struct dcn10_stream_encoder_shift se_shift = {
363 : SE_COMMON_MASK_SH_LIST_DCN30(__SHIFT)
364 : };
365 :
366 : static const struct dcn10_stream_encoder_mask se_mask = {
367 : SE_COMMON_MASK_SH_LIST_DCN30(_MASK)
368 : };
369 :
370 :
371 : #define aux_regs(id)\
372 : [id] = {\
373 : DCN2_AUX_REG_LIST(id)\
374 : }
375 :
376 : static const struct dcn10_link_enc_aux_registers link_enc_aux_regs[] = {
377 : aux_regs(0),
378 : aux_regs(1),
379 : aux_regs(2),
380 : aux_regs(3),
381 : aux_regs(4)
382 : };
383 :
384 : #define hpd_regs(id)\
385 : [id] = {\
386 : HPD_REG_LIST(id)\
387 : }
388 :
389 : static const struct dcn10_link_enc_hpd_registers link_enc_hpd_regs[] = {
390 : hpd_regs(0),
391 : hpd_regs(1),
392 : hpd_regs(2),
393 : hpd_regs(3),
394 : hpd_regs(4)
395 : };
396 :
397 : #define link_regs(id, phyid)\
398 : [id] = {\
399 : LE_DCN31_REG_LIST(id), \
400 : UNIPHY_DCN2_REG_LIST(phyid), \
401 : DPCS_DCN31_REG_LIST(id), \
402 : }
403 :
404 : static const struct dce110_aux_registers_shift aux_shift = {
405 : DCN_AUX_MASK_SH_LIST(__SHIFT)
406 : };
407 :
408 : static const struct dce110_aux_registers_mask aux_mask = {
409 : DCN_AUX_MASK_SH_LIST(_MASK)
410 : };
411 :
412 : static const struct dcn10_link_enc_registers link_enc_regs[] = {
413 : link_regs(0, A),
414 : link_regs(1, B),
415 : link_regs(2, C),
416 : link_regs(3, D),
417 : link_regs(4, E)
418 : };
419 :
420 : static const struct dcn10_link_enc_shift le_shift = {
421 : LINK_ENCODER_MASK_SH_LIST_DCN31(__SHIFT), \
422 : DPCS_DCN31_MASK_SH_LIST(__SHIFT)
423 : };
424 :
425 : static const struct dcn10_link_enc_mask le_mask = {
426 : LINK_ENCODER_MASK_SH_LIST_DCN31(_MASK), \
427 : DPCS_DCN31_MASK_SH_LIST(_MASK)
428 : };
429 :
430 : #define hpo_dp_stream_encoder_reg_list(id)\
431 : [id] = {\
432 : DCN3_1_HPO_DP_STREAM_ENC_REG_LIST(id)\
433 : }
434 :
435 : static const struct dcn31_hpo_dp_stream_encoder_registers hpo_dp_stream_enc_regs[] = {
436 : hpo_dp_stream_encoder_reg_list(0),
437 : hpo_dp_stream_encoder_reg_list(1),
438 : hpo_dp_stream_encoder_reg_list(2),
439 : hpo_dp_stream_encoder_reg_list(3),
440 : };
441 :
442 : static const struct dcn31_hpo_dp_stream_encoder_shift hpo_dp_se_shift = {
443 : DCN3_1_HPO_DP_STREAM_ENC_MASK_SH_LIST(__SHIFT)
444 : };
445 :
446 : static const struct dcn31_hpo_dp_stream_encoder_mask hpo_dp_se_mask = {
447 : DCN3_1_HPO_DP_STREAM_ENC_MASK_SH_LIST(_MASK)
448 : };
449 :
450 : #define hpo_dp_link_encoder_reg_list(id)\
451 : [id] = {\
452 : DCN3_1_HPO_DP_LINK_ENC_REG_LIST(id),\
453 : DCN3_1_RDPCSTX_REG_LIST(0),\
454 : DCN3_1_RDPCSTX_REG_LIST(1),\
455 : DCN3_1_RDPCSTX_REG_LIST(2),\
456 : DCN3_1_RDPCSTX_REG_LIST(3),\
457 : DCN3_1_RDPCSTX_REG_LIST(4)\
458 : }
459 :
460 : static const struct dcn31_hpo_dp_link_encoder_registers hpo_dp_link_enc_regs[] = {
461 : hpo_dp_link_encoder_reg_list(0),
462 : hpo_dp_link_encoder_reg_list(1),
463 : };
464 :
465 : static const struct dcn31_hpo_dp_link_encoder_shift hpo_dp_le_shift = {
466 : DCN3_1_HPO_DP_LINK_ENC_MASK_SH_LIST(__SHIFT)
467 : };
468 :
469 : static const struct dcn31_hpo_dp_link_encoder_mask hpo_dp_le_mask = {
470 : DCN3_1_HPO_DP_LINK_ENC_MASK_SH_LIST(_MASK)
471 : };
472 :
473 : #define dpp_regs(id)\
474 : [id] = {\
475 : DPP_REG_LIST_DCN30(id),\
476 : }
477 :
478 : static const struct dcn3_dpp_registers dpp_regs[] = {
479 : dpp_regs(0),
480 : dpp_regs(1),
481 : dpp_regs(2),
482 : dpp_regs(3)
483 : };
484 :
485 : static const struct dcn3_dpp_shift tf_shift = {
486 : DPP_REG_LIST_SH_MASK_DCN30(__SHIFT)
487 : };
488 :
489 : static const struct dcn3_dpp_mask tf_mask = {
490 : DPP_REG_LIST_SH_MASK_DCN30(_MASK)
491 : };
492 :
493 : #define opp_regs(id)\
494 : [id] = {\
495 : OPP_REG_LIST_DCN30(id),\
496 : }
497 :
498 : static const struct dcn20_opp_registers opp_regs[] = {
499 : opp_regs(0),
500 : opp_regs(1),
501 : opp_regs(2),
502 : opp_regs(3)
503 : };
504 :
505 : static const struct dcn20_opp_shift opp_shift = {
506 : OPP_MASK_SH_LIST_DCN20(__SHIFT)
507 : };
508 :
509 : static const struct dcn20_opp_mask opp_mask = {
510 : OPP_MASK_SH_LIST_DCN20(_MASK)
511 : };
512 :
513 : #define aux_engine_regs(id)\
514 : [id] = {\
515 : AUX_COMMON_REG_LIST0(id), \
516 : .AUXN_IMPCAL = 0, \
517 : .AUXP_IMPCAL = 0, \
518 : .AUX_RESET_MASK = DP_AUX0_AUX_CONTROL__AUX_RESET_MASK, \
519 : }
520 :
521 : static const struct dce110_aux_registers aux_engine_regs[] = {
522 : aux_engine_regs(0),
523 : aux_engine_regs(1),
524 : aux_engine_regs(2),
525 : aux_engine_regs(3),
526 : aux_engine_regs(4)
527 : };
528 :
529 : #define dwbc_regs_dcn3(id)\
530 : [id] = {\
531 : DWBC_COMMON_REG_LIST_DCN30(id),\
532 : }
533 :
534 : static const struct dcn30_dwbc_registers dwbc30_regs[] = {
535 : dwbc_regs_dcn3(0),
536 : };
537 :
538 : static const struct dcn30_dwbc_shift dwbc30_shift = {
539 : DWBC_COMMON_MASK_SH_LIST_DCN30(__SHIFT)
540 : };
541 :
542 : static const struct dcn30_dwbc_mask dwbc30_mask = {
543 : DWBC_COMMON_MASK_SH_LIST_DCN30(_MASK)
544 : };
545 :
546 : #define mcif_wb_regs_dcn3(id)\
547 : [id] = {\
548 : MCIF_WB_COMMON_REG_LIST_DCN30(id),\
549 : }
550 :
551 : static const struct dcn30_mmhubbub_registers mcif_wb30_regs[] = {
552 : mcif_wb_regs_dcn3(0)
553 : };
554 :
555 : static const struct dcn30_mmhubbub_shift mcif_wb30_shift = {
556 : MCIF_WB_COMMON_MASK_SH_LIST_DCN30(__SHIFT)
557 : };
558 :
559 : static const struct dcn30_mmhubbub_mask mcif_wb30_mask = {
560 : MCIF_WB_COMMON_MASK_SH_LIST_DCN30(_MASK)
561 : };
562 :
563 : #define dsc_regsDCN20(id)\
564 : [id] = {\
565 : DSC_REG_LIST_DCN20(id)\
566 : }
567 :
568 : static const struct dcn20_dsc_registers dsc_regs[] = {
569 : dsc_regsDCN20(0),
570 : dsc_regsDCN20(1),
571 : dsc_regsDCN20(2)
572 : };
573 :
574 : static const struct dcn20_dsc_shift dsc_shift = {
575 : DSC_REG_LIST_SH_MASK_DCN20(__SHIFT)
576 : };
577 :
578 : static const struct dcn20_dsc_mask dsc_mask = {
579 : DSC_REG_LIST_SH_MASK_DCN20(_MASK)
580 : };
581 :
582 : static const struct dcn30_mpc_registers mpc_regs = {
583 : MPC_REG_LIST_DCN3_0(0),
584 : MPC_REG_LIST_DCN3_0(1),
585 : MPC_REG_LIST_DCN3_0(2),
586 : MPC_REG_LIST_DCN3_0(3),
587 : MPC_OUT_MUX_REG_LIST_DCN3_0(0),
588 : MPC_OUT_MUX_REG_LIST_DCN3_0(1),
589 : MPC_OUT_MUX_REG_LIST_DCN3_0(2),
590 : MPC_OUT_MUX_REG_LIST_DCN3_0(3),
591 : MPC_RMU_GLOBAL_REG_LIST_DCN3AG,
592 : MPC_RMU_REG_LIST_DCN3AG(0),
593 : MPC_RMU_REG_LIST_DCN3AG(1),
594 : //MPC_RMU_REG_LIST_DCN3AG(2),
595 : MPC_DWB_MUX_REG_LIST_DCN3_0(0),
596 : };
597 :
598 : static const struct dcn30_mpc_shift mpc_shift = {
599 : MPC_COMMON_MASK_SH_LIST_DCN30(__SHIFT)
600 : };
601 :
602 : static const struct dcn30_mpc_mask mpc_mask = {
603 : MPC_COMMON_MASK_SH_LIST_DCN30(_MASK)
604 : };
605 :
606 : #define optc_regs(id)\
607 : [id] = {OPTC_COMMON_REG_LIST_DCN3_1(id)}
608 :
609 : static const struct dcn_optc_registers optc_regs[] = {
610 : optc_regs(0),
611 : optc_regs(1),
612 : optc_regs(2),
613 : optc_regs(3)
614 : };
615 :
616 : static const struct dcn_optc_shift optc_shift = {
617 : OPTC_COMMON_MASK_SH_LIST_DCN3_1(__SHIFT)
618 : };
619 :
620 : static const struct dcn_optc_mask optc_mask = {
621 : OPTC_COMMON_MASK_SH_LIST_DCN3_1(_MASK)
622 : };
623 :
624 : #define hubp_regs(id)\
625 : [id] = {\
626 : HUBP_REG_LIST_DCN30(id)\
627 : }
628 :
629 : static const struct dcn_hubp2_registers hubp_regs[] = {
630 : hubp_regs(0),
631 : hubp_regs(1),
632 : hubp_regs(2),
633 : hubp_regs(3)
634 : };
635 :
636 :
637 : static const struct dcn_hubp2_shift hubp_shift = {
638 : HUBP_MASK_SH_LIST_DCN31(__SHIFT)
639 : };
640 :
641 : static const struct dcn_hubp2_mask hubp_mask = {
642 : HUBP_MASK_SH_LIST_DCN31(_MASK)
643 : };
644 : static const struct dcn_hubbub_registers hubbub_reg = {
645 : HUBBUB_REG_LIST_DCN31(0)
646 : };
647 :
648 : static const struct dcn_hubbub_shift hubbub_shift = {
649 : HUBBUB_MASK_SH_LIST_DCN31(__SHIFT)
650 : };
651 :
652 : static const struct dcn_hubbub_mask hubbub_mask = {
653 : HUBBUB_MASK_SH_LIST_DCN31(_MASK)
654 : };
655 :
656 : static const struct dccg_registers dccg_regs = {
657 : DCCG_REG_LIST_DCN31()
658 : };
659 :
660 : static const struct dccg_shift dccg_shift = {
661 : DCCG_MASK_SH_LIST_DCN31(__SHIFT)
662 : };
663 :
664 : static const struct dccg_mask dccg_mask = {
665 : DCCG_MASK_SH_LIST_DCN31(_MASK)
666 : };
667 :
668 :
669 : #define SRII2(reg_name_pre, reg_name_post, id)\
670 : .reg_name_pre ## _ ## reg_name_post[id] = BASE(reg ## reg_name_pre \
671 : ## id ## _ ## reg_name_post ## _BASE_IDX) + \
672 : reg ## reg_name_pre ## id ## _ ## reg_name_post
673 :
674 :
675 : #define HWSEQ_DCN31_REG_LIST()\
676 : SR(DCHUBBUB_GLOBAL_TIMER_CNTL), \
677 : SR(DCHUBBUB_ARB_HOSTVM_CNTL), \
678 : SR(DIO_MEM_PWR_CTRL), \
679 : SR(ODM_MEM_PWR_CTRL3), \
680 : SR(DMU_MEM_PWR_CNTL), \
681 : SR(MMHUBBUB_MEM_PWR_CNTL), \
682 : SR(DCCG_GATE_DISABLE_CNTL), \
683 : SR(DCCG_GATE_DISABLE_CNTL2), \
684 : SR(DCFCLK_CNTL),\
685 : SR(DC_MEM_GLOBAL_PWR_REQ_CNTL), \
686 : SRII(PIXEL_RATE_CNTL, OTG, 0), \
687 : SRII(PIXEL_RATE_CNTL, OTG, 1),\
688 : SRII(PIXEL_RATE_CNTL, OTG, 2),\
689 : SRII(PIXEL_RATE_CNTL, OTG, 3),\
690 : SRII(PHYPLL_PIXEL_RATE_CNTL, OTG, 0),\
691 : SRII(PHYPLL_PIXEL_RATE_CNTL, OTG, 1),\
692 : SRII(PHYPLL_PIXEL_RATE_CNTL, OTG, 2),\
693 : SRII(PHYPLL_PIXEL_RATE_CNTL, OTG, 3),\
694 : SR(MICROSECOND_TIME_BASE_DIV), \
695 : SR(MILLISECOND_TIME_BASE_DIV), \
696 : SR(DISPCLK_FREQ_CHANGE_CNTL), \
697 : SR(RBBMIF_TIMEOUT_DIS), \
698 : SR(RBBMIF_TIMEOUT_DIS_2), \
699 : SR(DCHUBBUB_CRC_CTRL), \
700 : SR(DPP_TOP0_DPP_CRC_CTRL), \
701 : SR(DPP_TOP0_DPP_CRC_VAL_B_A), \
702 : SR(DPP_TOP0_DPP_CRC_VAL_R_G), \
703 : SR(MPC_CRC_CTRL), \
704 : SR(MPC_CRC_RESULT_GB), \
705 : SR(MPC_CRC_RESULT_C), \
706 : SR(MPC_CRC_RESULT_AR), \
707 : SR(DOMAIN0_PG_CONFIG), \
708 : SR(DOMAIN1_PG_CONFIG), \
709 : SR(DOMAIN2_PG_CONFIG), \
710 : SR(DOMAIN3_PG_CONFIG), \
711 : SR(DOMAIN16_PG_CONFIG), \
712 : SR(DOMAIN17_PG_CONFIG), \
713 : SR(DOMAIN18_PG_CONFIG), \
714 : SR(DOMAIN0_PG_STATUS), \
715 : SR(DOMAIN1_PG_STATUS), \
716 : SR(DOMAIN2_PG_STATUS), \
717 : SR(DOMAIN3_PG_STATUS), \
718 : SR(DOMAIN16_PG_STATUS), \
719 : SR(DOMAIN17_PG_STATUS), \
720 : SR(DOMAIN18_PG_STATUS), \
721 : SR(D1VGA_CONTROL), \
722 : SR(D2VGA_CONTROL), \
723 : SR(D3VGA_CONTROL), \
724 : SR(D4VGA_CONTROL), \
725 : SR(D5VGA_CONTROL), \
726 : SR(D6VGA_CONTROL), \
727 : SR(DC_IP_REQUEST_CNTL), \
728 : SR(AZALIA_AUDIO_DTO), \
729 : SR(AZALIA_CONTROLLER_CLOCK_GATING), \
730 : SR(HPO_TOP_HW_CONTROL)
731 :
732 : static const struct dce_hwseq_registers hwseq_reg = {
733 : HWSEQ_DCN31_REG_LIST()
734 : };
735 :
736 : #define HWSEQ_DCN31_MASK_SH_LIST(mask_sh)\
737 : HWSEQ_DCN_MASK_SH_LIST(mask_sh), \
738 : HWS_SF(, DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, mask_sh), \
739 : HWS_SF(, DCHUBBUB_ARB_HOSTVM_CNTL, DISABLE_HOSTVM_FORCE_ALLOW_PSTATE, mask_sh), \
740 : HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \
741 : HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \
742 : HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \
743 : HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \
744 : HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \
745 : HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \
746 : HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \
747 : HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \
748 : HWS_SF(, DOMAIN16_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \
749 : HWS_SF(, DOMAIN16_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \
750 : HWS_SF(, DOMAIN17_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \
751 : HWS_SF(, DOMAIN17_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \
752 : HWS_SF(, DOMAIN18_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \
753 : HWS_SF(, DOMAIN18_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \
754 : HWS_SF(, DOMAIN0_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \
755 : HWS_SF(, DOMAIN1_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \
756 : HWS_SF(, DOMAIN2_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \
757 : HWS_SF(, DOMAIN3_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \
758 : HWS_SF(, DOMAIN16_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \
759 : HWS_SF(, DOMAIN17_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \
760 : HWS_SF(, DOMAIN18_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \
761 : HWS_SF(, DC_IP_REQUEST_CNTL, IP_REQUEST_EN, mask_sh), \
762 : HWS_SF(, AZALIA_AUDIO_DTO, AZALIA_AUDIO_DTO_MODULE, mask_sh), \
763 : HWS_SF(, HPO_TOP_CLOCK_CONTROL, HPO_HDMISTREAMCLK_G_GATE_DIS, mask_sh), \
764 : HWS_SF(, DMU_MEM_PWR_CNTL, DMCU_ERAM_MEM_PWR_FORCE, mask_sh), \
765 : HWS_SF(, ODM_MEM_PWR_CTRL3, ODM_MEM_UNASSIGNED_PWR_MODE, mask_sh), \
766 : HWS_SF(, ODM_MEM_PWR_CTRL3, ODM_MEM_VBLANK_PWR_MODE, mask_sh), \
767 : HWS_SF(, MMHUBBUB_MEM_PWR_CNTL, VGA_MEM_PWR_FORCE, mask_sh), \
768 : HWS_SF(, DIO_MEM_PWR_CTRL, I2C_LIGHT_SLEEP_FORCE, mask_sh), \
769 : HWS_SF(, HPO_TOP_HW_CONTROL, HPO_IO_EN, mask_sh)
770 :
771 : static const struct dce_hwseq_shift hwseq_shift = {
772 : HWSEQ_DCN31_MASK_SH_LIST(__SHIFT)
773 : };
774 :
775 : static const struct dce_hwseq_mask hwseq_mask = {
776 : HWSEQ_DCN31_MASK_SH_LIST(_MASK)
777 : };
778 : #define vmid_regs(id)\
779 : [id] = {\
780 : DCN20_VMID_REG_LIST(id)\
781 : }
782 :
783 : static const struct dcn_vmid_registers vmid_regs[] = {
784 : vmid_regs(0),
785 : vmid_regs(1),
786 : vmid_regs(2),
787 : vmid_regs(3),
788 : vmid_regs(4),
789 : vmid_regs(5),
790 : vmid_regs(6),
791 : vmid_regs(7),
792 : vmid_regs(8),
793 : vmid_regs(9),
794 : vmid_regs(10),
795 : vmid_regs(11),
796 : vmid_regs(12),
797 : vmid_regs(13),
798 : vmid_regs(14),
799 : vmid_regs(15)
800 : };
801 :
802 : static const struct dcn20_vmid_shift vmid_shifts = {
803 : DCN20_VMID_MASK_SH_LIST(__SHIFT)
804 : };
805 :
806 : static const struct dcn20_vmid_mask vmid_masks = {
807 : DCN20_VMID_MASK_SH_LIST(_MASK)
808 : };
809 :
810 : static const struct resource_caps res_cap_dcn31 = {
811 : .num_timing_generator = 4,
812 : .num_opp = 4,
813 : .num_video_plane = 4,
814 : .num_audio = 5,
815 : .num_stream_encoder = 5,
816 : .num_dig_link_enc = 5,
817 : .num_hpo_dp_stream_encoder = 4,
818 : .num_hpo_dp_link_encoder = 2,
819 : .num_pll = 5,
820 : .num_dwb = 1,
821 : .num_ddc = 5,
822 : .num_vmid = 16,
823 : .num_mpc_3dlut = 2,
824 : .num_dsc = 3,
825 : };
826 :
827 : static const struct dc_plane_cap plane_cap = {
828 : .type = DC_PLANE_TYPE_DCN_UNIVERSAL,
829 : .blends_with_above = true,
830 : .blends_with_below = true,
831 : .per_pixel_alpha = true,
832 :
833 : .pixel_format_support = {
834 : .argb8888 = true,
835 : .nv12 = true,
836 : .fp16 = true,
837 : .p010 = true,
838 : .ayuv = false,
839 : },
840 :
841 : .max_upscale_factor = {
842 : .argb8888 = 16000,
843 : .nv12 = 16000,
844 : .fp16 = 16000
845 : },
846 :
847 : // 6:1 downscaling ratio: 1000/6 = 166.666
848 : .max_downscale_factor = {
849 : .argb8888 = 167,
850 : .nv12 = 167,
851 : .fp16 = 167
852 : },
853 : 64,
854 : 64
855 : };
856 :
857 : static const struct dc_debug_options debug_defaults_drv = {
858 : .disable_dmcu = true,
859 : .force_abm_enable = false,
860 : .timing_trace = false,
861 : .clock_trace = true,
862 : .disable_pplib_clock_request = false,
863 : .pipe_split_policy = MPC_SPLIT_DYNAMIC,
864 : .force_single_disp_pipe_split = false,
865 : .disable_dcc = DCC_ENABLE,
866 : .vsr_support = true,
867 : .performance_trace = false,
868 : .max_downscale_src_width = 4096,/*upto true 4K*/
869 : .disable_pplib_wm_range = false,
870 : .scl_reset_length10 = true,
871 : .sanity_checks = true,
872 : .underflow_assert_delay_us = 0xFFFFFFFF,
873 : .dwb_fi_phase = -1, // -1 = disable,
874 : .dmub_command_table = true,
875 : .pstate_enabled = true,
876 : .use_max_lb = true,
877 : .enable_mem_low_power = {
878 : .bits = {
879 : .vga = true,
880 : .i2c = true,
881 : .dmcu = false, // This is previously known to cause hang on S3 cycles if enabled
882 : .dscl = true,
883 : .cm = true,
884 : .mpc = true,
885 : .optc = true,
886 : .vpg = true,
887 : .afmt = true,
888 : }
889 : },
890 : .disable_z10 = true,
891 : .optimize_edp_link_rate = true,
892 : .enable_z9_disable_interface = true, /* Allow support for the PMFW interface for disable Z9*/
893 : .dml_hostvm_override = DML_HOSTVM_OVERRIDE_FALSE,
894 : };
895 :
896 : static const struct dc_debug_options debug_defaults_diags = {
897 : .disable_dmcu = true,
898 : .force_abm_enable = false,
899 : .timing_trace = true,
900 : .clock_trace = true,
901 : .disable_dpp_power_gate = true,
902 : .disable_hubp_power_gate = true,
903 : .disable_clock_gate = true,
904 : .disable_pplib_clock_request = true,
905 : .disable_pplib_wm_range = true,
906 : .disable_stutter = false,
907 : .scl_reset_length10 = true,
908 : .dwb_fi_phase = -1, // -1 = disable
909 : .dmub_command_table = true,
910 : .enable_tri_buf = true,
911 : .use_max_lb = true
912 : };
913 :
914 : static void dcn31_dpp_destroy(struct dpp **dpp)
915 : {
916 0 : kfree(TO_DCN20_DPP(*dpp));
917 0 : *dpp = NULL;
918 : }
919 :
920 0 : static struct dpp *dcn31_dpp_create(
921 : struct dc_context *ctx,
922 : uint32_t inst)
923 : {
924 0 : struct dcn3_dpp *dpp =
925 : kzalloc(sizeof(struct dcn3_dpp), GFP_KERNEL);
926 :
927 0 : if (!dpp)
928 : return NULL;
929 :
930 0 : if (dpp3_construct(dpp, ctx, inst,
931 : &dpp_regs[inst], &tf_shift, &tf_mask))
932 0 : return &dpp->base;
933 :
934 0 : BREAK_TO_DEBUGGER();
935 0 : kfree(dpp);
936 0 : return NULL;
937 : }
938 :
939 0 : static struct output_pixel_processor *dcn31_opp_create(
940 : struct dc_context *ctx, uint32_t inst)
941 : {
942 0 : struct dcn20_opp *opp =
943 : kzalloc(sizeof(struct dcn20_opp), GFP_KERNEL);
944 :
945 0 : if (!opp) {
946 0 : BREAK_TO_DEBUGGER();
947 0 : return NULL;
948 : }
949 :
950 0 : dcn20_opp_construct(opp, ctx, inst,
951 : &opp_regs[inst], &opp_shift, &opp_mask);
952 0 : return &opp->base;
953 : }
954 :
955 0 : static struct dce_aux *dcn31_aux_engine_create(
956 : struct dc_context *ctx,
957 : uint32_t inst)
958 : {
959 0 : struct aux_engine_dce110 *aux_engine =
960 : kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL);
961 :
962 0 : if (!aux_engine)
963 : return NULL;
964 :
965 0 : dce110_aux_engine_construct(aux_engine, ctx, inst,
966 : SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD,
967 : &aux_engine_regs[inst],
968 : &aux_mask,
969 : &aux_shift,
970 0 : ctx->dc->caps.extended_aux_timeout_support);
971 :
972 0 : return &aux_engine->base;
973 : }
974 : #define i2c_inst_regs(id) { I2C_HW_ENGINE_COMMON_REG_LIST_DCN30(id) }
975 :
976 : static const struct dce_i2c_registers i2c_hw_regs[] = {
977 : i2c_inst_regs(1),
978 : i2c_inst_regs(2),
979 : i2c_inst_regs(3),
980 : i2c_inst_regs(4),
981 : i2c_inst_regs(5),
982 : };
983 :
984 : static const struct dce_i2c_shift i2c_shifts = {
985 : I2C_COMMON_MASK_SH_LIST_DCN30(__SHIFT)
986 : };
987 :
988 : static const struct dce_i2c_mask i2c_masks = {
989 : I2C_COMMON_MASK_SH_LIST_DCN30(_MASK)
990 : };
991 :
992 0 : static struct dce_i2c_hw *dcn31_i2c_hw_create(
993 : struct dc_context *ctx,
994 : uint32_t inst)
995 : {
996 0 : struct dce_i2c_hw *dce_i2c_hw =
997 : kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL);
998 :
999 0 : if (!dce_i2c_hw)
1000 : return NULL;
1001 :
1002 0 : dcn2_i2c_hw_construct(dce_i2c_hw, ctx, inst,
1003 : &i2c_hw_regs[inst], &i2c_shifts, &i2c_masks);
1004 :
1005 0 : return dce_i2c_hw;
1006 : }
1007 0 : static struct mpc *dcn31_mpc_create(
1008 : struct dc_context *ctx,
1009 : int num_mpcc,
1010 : int num_rmu)
1011 : {
1012 0 : struct dcn30_mpc *mpc30 = kzalloc(sizeof(struct dcn30_mpc),
1013 : GFP_KERNEL);
1014 :
1015 0 : if (!mpc30)
1016 : return NULL;
1017 :
1018 0 : dcn30_mpc_construct(mpc30, ctx,
1019 : &mpc_regs,
1020 : &mpc_shift,
1021 : &mpc_mask,
1022 : num_mpcc,
1023 : num_rmu);
1024 :
1025 0 : return &mpc30->base;
1026 : }
1027 :
1028 0 : static struct hubbub *dcn31_hubbub_create(struct dc_context *ctx)
1029 : {
1030 : int i;
1031 :
1032 0 : struct dcn20_hubbub *hubbub3 = kzalloc(sizeof(struct dcn20_hubbub),
1033 : GFP_KERNEL);
1034 :
1035 0 : if (!hubbub3)
1036 : return NULL;
1037 :
1038 0 : hubbub31_construct(hubbub3, ctx,
1039 : &hubbub_reg,
1040 : &hubbub_shift,
1041 : &hubbub_mask,
1042 0 : dcn3_1_ip.det_buffer_size_kbytes,
1043 0 : dcn3_1_ip.pixel_chunk_size_kbytes,
1044 0 : dcn3_1_ip.config_return_buffer_size_in_kbytes);
1045 :
1046 :
1047 0 : for (i = 0; i < res_cap_dcn31.num_vmid; i++) {
1048 0 : struct dcn20_vmid *vmid = &hubbub3->vmid[i];
1049 :
1050 0 : vmid->ctx = ctx;
1051 :
1052 0 : vmid->regs = &vmid_regs[i];
1053 0 : vmid->shifts = &vmid_shifts;
1054 0 : vmid->masks = &vmid_masks;
1055 : }
1056 :
1057 0 : return &hubbub3->base;
1058 : }
1059 :
1060 0 : static struct timing_generator *dcn31_timing_generator_create(
1061 : struct dc_context *ctx,
1062 : uint32_t instance)
1063 : {
1064 0 : struct optc *tgn10 =
1065 : kzalloc(sizeof(struct optc), GFP_KERNEL);
1066 :
1067 0 : if (!tgn10)
1068 : return NULL;
1069 :
1070 0 : tgn10->base.inst = instance;
1071 0 : tgn10->base.ctx = ctx;
1072 :
1073 0 : tgn10->tg_regs = &optc_regs[instance];
1074 0 : tgn10->tg_shift = &optc_shift;
1075 0 : tgn10->tg_mask = &optc_mask;
1076 :
1077 0 : dcn31_timing_generator_init(tgn10);
1078 :
1079 0 : return &tgn10->base;
1080 : }
1081 :
1082 : static const struct encoder_feature_support link_enc_feature = {
1083 : .max_hdmi_deep_color = COLOR_DEPTH_121212,
1084 : .max_hdmi_pixel_clock = 600000,
1085 : .hdmi_ycbcr420_supported = true,
1086 : .dp_ycbcr420_supported = true,
1087 : .fec_supported = true,
1088 : .flags.bits.IS_HBR2_CAPABLE = true,
1089 : .flags.bits.IS_HBR3_CAPABLE = true,
1090 : .flags.bits.IS_TPS3_CAPABLE = true,
1091 : .flags.bits.IS_TPS4_CAPABLE = true
1092 : };
1093 :
1094 0 : static struct link_encoder *dcn31_link_encoder_create(
1095 : struct dc_context *ctx,
1096 : const struct encoder_init_data *enc_init_data)
1097 : {
1098 0 : struct dcn20_link_encoder *enc20 =
1099 : kzalloc(sizeof(struct dcn20_link_encoder), GFP_KERNEL);
1100 :
1101 0 : if (!enc20)
1102 : return NULL;
1103 :
1104 0 : dcn31_link_encoder_construct(enc20,
1105 : enc_init_data,
1106 : &link_enc_feature,
1107 0 : &link_enc_regs[enc_init_data->transmitter],
1108 0 : &link_enc_aux_regs[enc_init_data->channel - 1],
1109 0 : &link_enc_hpd_regs[enc_init_data->hpd_source],
1110 : &le_shift,
1111 : &le_mask);
1112 :
1113 0 : return &enc20->enc10.base;
1114 : }
1115 :
1116 : /* Create a minimal link encoder object not associated with a particular
1117 : * physical connector.
1118 : * resource_funcs.link_enc_create_minimal
1119 : */
1120 0 : static struct link_encoder *dcn31_link_enc_create_minimal(
1121 : struct dc_context *ctx, enum engine_id eng_id)
1122 : {
1123 : struct dcn20_link_encoder *enc20;
1124 :
1125 0 : if ((eng_id - ENGINE_ID_DIGA) > ctx->dc->res_pool->res_cap->num_dig_link_enc)
1126 : return NULL;
1127 :
1128 0 : enc20 = kzalloc(sizeof(struct dcn20_link_encoder), GFP_KERNEL);
1129 0 : if (!enc20)
1130 : return NULL;
1131 :
1132 0 : dcn31_link_encoder_construct_minimal(
1133 : enc20,
1134 : ctx,
1135 : &link_enc_feature,
1136 : &link_enc_regs[eng_id - ENGINE_ID_DIGA],
1137 : eng_id);
1138 :
1139 0 : return &enc20->enc10.base;
1140 : }
1141 :
1142 0 : static struct panel_cntl *dcn31_panel_cntl_create(const struct panel_cntl_init_data *init_data)
1143 : {
1144 0 : struct dcn31_panel_cntl *panel_cntl =
1145 : kzalloc(sizeof(struct dcn31_panel_cntl), GFP_KERNEL);
1146 :
1147 0 : if (!panel_cntl)
1148 : return NULL;
1149 :
1150 0 : dcn31_panel_cntl_construct(panel_cntl, init_data);
1151 :
1152 0 : return &panel_cntl->base;
1153 : }
1154 :
1155 0 : static void read_dce_straps(
1156 : struct dc_context *ctx,
1157 : struct resource_straps *straps)
1158 : {
1159 0 : generic_reg_get(ctx, regDC_PINSTRAPS + BASE(regDC_PINSTRAPS_BASE_IDX),
1160 : FN(DC_PINSTRAPS, DC_PINSTRAPS_AUDIO), &straps->dc_pinstraps_audio);
1161 :
1162 0 : }
1163 :
1164 0 : static struct audio *dcn31_create_audio(
1165 : struct dc_context *ctx, unsigned int inst)
1166 : {
1167 0 : return dce_audio_create(ctx, inst,
1168 : &audio_regs[inst], &audio_shift, &audio_mask);
1169 : }
1170 :
1171 0 : static struct vpg *dcn31_vpg_create(
1172 : struct dc_context *ctx,
1173 : uint32_t inst)
1174 : {
1175 0 : struct dcn31_vpg *vpg31 = kzalloc(sizeof(struct dcn31_vpg), GFP_KERNEL);
1176 :
1177 0 : if (!vpg31)
1178 : return NULL;
1179 :
1180 0 : vpg31_construct(vpg31, ctx, inst,
1181 : &vpg_regs[inst],
1182 : &vpg_shift,
1183 : &vpg_mask);
1184 :
1185 0 : return &vpg31->base;
1186 : }
1187 :
1188 0 : static struct afmt *dcn31_afmt_create(
1189 : struct dc_context *ctx,
1190 : uint32_t inst)
1191 : {
1192 0 : struct dcn31_afmt *afmt31 = kzalloc(sizeof(struct dcn31_afmt), GFP_KERNEL);
1193 :
1194 0 : if (!afmt31)
1195 : return NULL;
1196 :
1197 0 : afmt31_construct(afmt31, ctx, inst,
1198 : &afmt_regs[inst],
1199 : &afmt_shift,
1200 : &afmt_mask);
1201 :
1202 : // Light sleep by default, no need to power down here
1203 :
1204 0 : return &afmt31->base;
1205 : }
1206 :
1207 0 : static struct apg *dcn31_apg_create(
1208 : struct dc_context *ctx,
1209 : uint32_t inst)
1210 : {
1211 0 : struct dcn31_apg *apg31 = kzalloc(sizeof(struct dcn31_apg), GFP_KERNEL);
1212 :
1213 0 : if (!apg31)
1214 : return NULL;
1215 :
1216 0 : apg31_construct(apg31, ctx, inst,
1217 : &apg_regs[inst],
1218 : &apg_shift,
1219 : &apg_mask);
1220 :
1221 0 : return &apg31->base;
1222 : }
1223 :
1224 0 : static struct stream_encoder *dcn31_stream_encoder_create(
1225 : enum engine_id eng_id,
1226 : struct dc_context *ctx)
1227 : {
1228 : struct dcn10_stream_encoder *enc1;
1229 : struct vpg *vpg;
1230 : struct afmt *afmt;
1231 : int vpg_inst;
1232 : int afmt_inst;
1233 :
1234 : /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */
1235 0 : if (eng_id <= ENGINE_ID_DIGF) {
1236 0 : vpg_inst = eng_id;
1237 0 : afmt_inst = eng_id;
1238 : } else
1239 : return NULL;
1240 :
1241 0 : enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL);
1242 0 : vpg = dcn31_vpg_create(ctx, vpg_inst);
1243 0 : afmt = dcn31_afmt_create(ctx, afmt_inst);
1244 :
1245 0 : if (!enc1 || !vpg || !afmt) {
1246 0 : kfree(enc1);
1247 0 : kfree(vpg);
1248 0 : kfree(afmt);
1249 0 : return NULL;
1250 : }
1251 :
1252 0 : dcn30_dio_stream_encoder_construct(enc1, ctx, ctx->dc_bios,
1253 : eng_id, vpg, afmt,
1254 : &stream_enc_regs[eng_id],
1255 : &se_shift, &se_mask);
1256 :
1257 0 : return &enc1->base;
1258 : }
1259 :
1260 0 : static struct hpo_dp_stream_encoder *dcn31_hpo_dp_stream_encoder_create(
1261 : enum engine_id eng_id,
1262 : struct dc_context *ctx)
1263 : {
1264 : struct dcn31_hpo_dp_stream_encoder *hpo_dp_enc31;
1265 : struct vpg *vpg;
1266 : struct apg *apg;
1267 : uint32_t hpo_dp_inst;
1268 : uint32_t vpg_inst;
1269 : uint32_t apg_inst;
1270 :
1271 0 : ASSERT((eng_id >= ENGINE_ID_HPO_DP_0) && (eng_id <= ENGINE_ID_HPO_DP_3));
1272 0 : hpo_dp_inst = eng_id - ENGINE_ID_HPO_DP_0;
1273 :
1274 : /* Mapping of VPG register blocks to HPO DP block instance:
1275 : * VPG[6] -> HPO_DP[0]
1276 : * VPG[7] -> HPO_DP[1]
1277 : * VPG[8] -> HPO_DP[2]
1278 : * VPG[9] -> HPO_DP[3]
1279 : */
1280 0 : vpg_inst = hpo_dp_inst + 6;
1281 :
1282 : /* Mapping of APG register blocks to HPO DP block instance:
1283 : * APG[0] -> HPO_DP[0]
1284 : * APG[1] -> HPO_DP[1]
1285 : * APG[2] -> HPO_DP[2]
1286 : * APG[3] -> HPO_DP[3]
1287 : */
1288 0 : apg_inst = hpo_dp_inst;
1289 :
1290 : /* allocate HPO stream encoder and create VPG sub-block */
1291 0 : hpo_dp_enc31 = kzalloc(sizeof(struct dcn31_hpo_dp_stream_encoder), GFP_KERNEL);
1292 0 : vpg = dcn31_vpg_create(ctx, vpg_inst);
1293 0 : apg = dcn31_apg_create(ctx, apg_inst);
1294 :
1295 0 : if (!hpo_dp_enc31 || !vpg || !apg) {
1296 0 : kfree(hpo_dp_enc31);
1297 0 : kfree(vpg);
1298 0 : kfree(apg);
1299 0 : return NULL;
1300 : }
1301 :
1302 0 : dcn31_hpo_dp_stream_encoder_construct(hpo_dp_enc31, ctx, ctx->dc_bios,
1303 : hpo_dp_inst, eng_id, vpg, apg,
1304 : &hpo_dp_stream_enc_regs[hpo_dp_inst],
1305 : &hpo_dp_se_shift, &hpo_dp_se_mask);
1306 :
1307 0 : return &hpo_dp_enc31->base;
1308 : }
1309 :
1310 0 : static struct hpo_dp_link_encoder *dcn31_hpo_dp_link_encoder_create(
1311 : uint8_t inst,
1312 : struct dc_context *ctx)
1313 : {
1314 : struct dcn31_hpo_dp_link_encoder *hpo_dp_enc31;
1315 :
1316 : /* allocate HPO link encoder */
1317 0 : hpo_dp_enc31 = kzalloc(sizeof(struct dcn31_hpo_dp_link_encoder), GFP_KERNEL);
1318 :
1319 0 : hpo_dp_link_encoder31_construct(hpo_dp_enc31, ctx, inst,
1320 0 : &hpo_dp_link_enc_regs[inst],
1321 : &hpo_dp_le_shift, &hpo_dp_le_mask);
1322 :
1323 0 : return &hpo_dp_enc31->base;
1324 : }
1325 :
1326 0 : static struct dce_hwseq *dcn31_hwseq_create(
1327 : struct dc_context *ctx)
1328 : {
1329 0 : struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL);
1330 :
1331 0 : if (hws) {
1332 0 : hws->ctx = ctx;
1333 0 : hws->regs = &hwseq_reg;
1334 0 : hws->shifts = &hwseq_shift;
1335 0 : hws->masks = &hwseq_mask;
1336 : /* DCN3.1 FPGA Workaround
1337 : * Need to enable HPO DP Stream Encoder before setting OTG master enable.
1338 : * To do so, move calling function enable_stream_timing to only be done AFTER calling
1339 : * function core_link_enable_stream
1340 : */
1341 0 : if (IS_FPGA_MAXIMUS_DC(ctx->dce_environment))
1342 0 : hws->wa.dp_hpo_and_otg_sequence = true;
1343 : }
1344 0 : return hws;
1345 : }
1346 : static const struct resource_create_funcs res_create_funcs = {
1347 : .read_dce_straps = read_dce_straps,
1348 : .create_audio = dcn31_create_audio,
1349 : .create_stream_encoder = dcn31_stream_encoder_create,
1350 : .create_hpo_dp_stream_encoder = dcn31_hpo_dp_stream_encoder_create,
1351 : .create_hpo_dp_link_encoder = dcn31_hpo_dp_link_encoder_create,
1352 : .create_hwseq = dcn31_hwseq_create,
1353 : };
1354 :
1355 : static const struct resource_create_funcs res_create_maximus_funcs = {
1356 : .read_dce_straps = NULL,
1357 : .create_audio = NULL,
1358 : .create_stream_encoder = NULL,
1359 : .create_hpo_dp_stream_encoder = dcn31_hpo_dp_stream_encoder_create,
1360 : .create_hpo_dp_link_encoder = dcn31_hpo_dp_link_encoder_create,
1361 : .create_hwseq = dcn31_hwseq_create,
1362 : };
1363 :
1364 0 : static void dcn31_resource_destruct(struct dcn31_resource_pool *pool)
1365 : {
1366 : unsigned int i;
1367 :
1368 0 : for (i = 0; i < pool->base.stream_enc_count; i++) {
1369 0 : if (pool->base.stream_enc[i] != NULL) {
1370 0 : if (pool->base.stream_enc[i]->vpg != NULL) {
1371 0 : kfree(DCN30_VPG_FROM_VPG(pool->base.stream_enc[i]->vpg));
1372 0 : pool->base.stream_enc[i]->vpg = NULL;
1373 : }
1374 0 : if (pool->base.stream_enc[i]->afmt != NULL) {
1375 0 : kfree(DCN30_AFMT_FROM_AFMT(pool->base.stream_enc[i]->afmt));
1376 0 : pool->base.stream_enc[i]->afmt = NULL;
1377 : }
1378 0 : kfree(DCN10STRENC_FROM_STRENC(pool->base.stream_enc[i]));
1379 0 : pool->base.stream_enc[i] = NULL;
1380 : }
1381 : }
1382 :
1383 0 : for (i = 0; i < pool->base.hpo_dp_stream_enc_count; i++) {
1384 0 : if (pool->base.hpo_dp_stream_enc[i] != NULL) {
1385 0 : if (pool->base.hpo_dp_stream_enc[i]->vpg != NULL) {
1386 0 : kfree(DCN30_VPG_FROM_VPG(pool->base.hpo_dp_stream_enc[i]->vpg));
1387 0 : pool->base.hpo_dp_stream_enc[i]->vpg = NULL;
1388 : }
1389 0 : if (pool->base.hpo_dp_stream_enc[i]->apg != NULL) {
1390 0 : kfree(DCN31_APG_FROM_APG(pool->base.hpo_dp_stream_enc[i]->apg));
1391 0 : pool->base.hpo_dp_stream_enc[i]->apg = NULL;
1392 : }
1393 0 : kfree(DCN3_1_HPO_DP_STREAM_ENC_FROM_HPO_STREAM_ENC(pool->base.hpo_dp_stream_enc[i]));
1394 0 : pool->base.hpo_dp_stream_enc[i] = NULL;
1395 : }
1396 : }
1397 :
1398 0 : for (i = 0; i < pool->base.hpo_dp_link_enc_count; i++) {
1399 0 : if (pool->base.hpo_dp_link_enc[i] != NULL) {
1400 0 : kfree(DCN3_1_HPO_DP_LINK_ENC_FROM_HPO_LINK_ENC(pool->base.hpo_dp_link_enc[i]));
1401 0 : pool->base.hpo_dp_link_enc[i] = NULL;
1402 : }
1403 : }
1404 :
1405 0 : for (i = 0; i < pool->base.res_cap->num_dsc; i++) {
1406 0 : if (pool->base.dscs[i] != NULL)
1407 0 : dcn20_dsc_destroy(&pool->base.dscs[i]);
1408 : }
1409 :
1410 0 : if (pool->base.mpc != NULL) {
1411 0 : kfree(TO_DCN20_MPC(pool->base.mpc));
1412 0 : pool->base.mpc = NULL;
1413 : }
1414 0 : if (pool->base.hubbub != NULL) {
1415 0 : kfree(pool->base.hubbub);
1416 0 : pool->base.hubbub = NULL;
1417 : }
1418 0 : for (i = 0; i < pool->base.pipe_count; i++) {
1419 0 : if (pool->base.dpps[i] != NULL)
1420 0 : dcn31_dpp_destroy(&pool->base.dpps[i]);
1421 :
1422 0 : if (pool->base.ipps[i] != NULL)
1423 0 : pool->base.ipps[i]->funcs->ipp_destroy(&pool->base.ipps[i]);
1424 :
1425 0 : if (pool->base.hubps[i] != NULL) {
1426 0 : kfree(TO_DCN20_HUBP(pool->base.hubps[i]));
1427 0 : pool->base.hubps[i] = NULL;
1428 : }
1429 :
1430 0 : if (pool->base.irqs != NULL) {
1431 0 : dal_irq_service_destroy(&pool->base.irqs);
1432 : }
1433 : }
1434 :
1435 0 : for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
1436 0 : if (pool->base.engines[i] != NULL)
1437 0 : dce110_engine_destroy(&pool->base.engines[i]);
1438 0 : if (pool->base.hw_i2cs[i] != NULL) {
1439 0 : kfree(pool->base.hw_i2cs[i]);
1440 0 : pool->base.hw_i2cs[i] = NULL;
1441 : }
1442 0 : if (pool->base.sw_i2cs[i] != NULL) {
1443 0 : kfree(pool->base.sw_i2cs[i]);
1444 0 : pool->base.sw_i2cs[i] = NULL;
1445 : }
1446 : }
1447 :
1448 0 : for (i = 0; i < pool->base.res_cap->num_opp; i++) {
1449 0 : if (pool->base.opps[i] != NULL)
1450 0 : pool->base.opps[i]->funcs->opp_destroy(&pool->base.opps[i]);
1451 : }
1452 :
1453 0 : for (i = 0; i < pool->base.res_cap->num_timing_generator; i++) {
1454 0 : if (pool->base.timing_generators[i] != NULL) {
1455 0 : kfree(DCN10TG_FROM_TG(pool->base.timing_generators[i]));
1456 0 : pool->base.timing_generators[i] = NULL;
1457 : }
1458 : }
1459 :
1460 0 : for (i = 0; i < pool->base.res_cap->num_dwb; i++) {
1461 0 : if (pool->base.dwbc[i] != NULL) {
1462 0 : kfree(TO_DCN30_DWBC(pool->base.dwbc[i]));
1463 0 : pool->base.dwbc[i] = NULL;
1464 : }
1465 0 : if (pool->base.mcif_wb[i] != NULL) {
1466 0 : kfree(TO_DCN30_MMHUBBUB(pool->base.mcif_wb[i]));
1467 0 : pool->base.mcif_wb[i] = NULL;
1468 : }
1469 : }
1470 :
1471 0 : for (i = 0; i < pool->base.audio_count; i++) {
1472 0 : if (pool->base.audios[i])
1473 0 : dce_aud_destroy(&pool->base.audios[i]);
1474 : }
1475 :
1476 0 : for (i = 0; i < pool->base.clk_src_count; i++) {
1477 0 : if (pool->base.clock_sources[i] != NULL) {
1478 0 : dcn20_clock_source_destroy(&pool->base.clock_sources[i]);
1479 0 : pool->base.clock_sources[i] = NULL;
1480 : }
1481 : }
1482 :
1483 0 : for (i = 0; i < pool->base.res_cap->num_mpc_3dlut; i++) {
1484 0 : if (pool->base.mpc_lut[i] != NULL) {
1485 0 : dc_3dlut_func_release(pool->base.mpc_lut[i]);
1486 0 : pool->base.mpc_lut[i] = NULL;
1487 : }
1488 0 : if (pool->base.mpc_shaper[i] != NULL) {
1489 0 : dc_transfer_func_release(pool->base.mpc_shaper[i]);
1490 0 : pool->base.mpc_shaper[i] = NULL;
1491 : }
1492 : }
1493 :
1494 0 : if (pool->base.dp_clock_source != NULL) {
1495 0 : dcn20_clock_source_destroy(&pool->base.dp_clock_source);
1496 0 : pool->base.dp_clock_source = NULL;
1497 : }
1498 :
1499 0 : for (i = 0; i < pool->base.res_cap->num_timing_generator; i++) {
1500 0 : if (pool->base.multiple_abms[i] != NULL)
1501 0 : dce_abm_destroy(&pool->base.multiple_abms[i]);
1502 : }
1503 :
1504 0 : if (pool->base.psr != NULL)
1505 0 : dmub_psr_destroy(&pool->base.psr);
1506 :
1507 0 : if (pool->base.dccg != NULL)
1508 0 : dcn_dccg_destroy(&pool->base.dccg);
1509 0 : }
1510 :
1511 0 : static struct hubp *dcn31_hubp_create(
1512 : struct dc_context *ctx,
1513 : uint32_t inst)
1514 : {
1515 0 : struct dcn20_hubp *hubp2 =
1516 : kzalloc(sizeof(struct dcn20_hubp), GFP_KERNEL);
1517 :
1518 0 : if (!hubp2)
1519 : return NULL;
1520 :
1521 0 : if (hubp31_construct(hubp2, ctx, inst,
1522 : &hubp_regs[inst], &hubp_shift, &hubp_mask))
1523 0 : return &hubp2->base;
1524 :
1525 0 : BREAK_TO_DEBUGGER();
1526 0 : kfree(hubp2);
1527 0 : return NULL;
1528 : }
1529 :
1530 0 : static bool dcn31_dwbc_create(struct dc_context *ctx, struct resource_pool *pool)
1531 : {
1532 : int i;
1533 0 : uint32_t pipe_count = pool->res_cap->num_dwb;
1534 :
1535 0 : for (i = 0; i < pipe_count; i++) {
1536 0 : struct dcn30_dwbc *dwbc30 = kzalloc(sizeof(struct dcn30_dwbc),
1537 : GFP_KERNEL);
1538 :
1539 0 : if (!dwbc30) {
1540 0 : dm_error("DC: failed to create dwbc30!\n");
1541 : return false;
1542 : }
1543 :
1544 0 : dcn30_dwbc_construct(dwbc30, ctx,
1545 : &dwbc30_regs[i],
1546 : &dwbc30_shift,
1547 : &dwbc30_mask,
1548 : i);
1549 :
1550 0 : pool->dwbc[i] = &dwbc30->base;
1551 : }
1552 : return true;
1553 : }
1554 :
1555 0 : static bool dcn31_mmhubbub_create(struct dc_context *ctx, struct resource_pool *pool)
1556 : {
1557 : int i;
1558 0 : uint32_t pipe_count = pool->res_cap->num_dwb;
1559 :
1560 0 : for (i = 0; i < pipe_count; i++) {
1561 0 : struct dcn30_mmhubbub *mcif_wb30 = kzalloc(sizeof(struct dcn30_mmhubbub),
1562 : GFP_KERNEL);
1563 :
1564 0 : if (!mcif_wb30) {
1565 0 : dm_error("DC: failed to create mcif_wb30!\n");
1566 : return false;
1567 : }
1568 :
1569 0 : dcn30_mmhubbub_construct(mcif_wb30, ctx,
1570 : &mcif_wb30_regs[i],
1571 : &mcif_wb30_shift,
1572 : &mcif_wb30_mask,
1573 : i);
1574 :
1575 0 : pool->mcif_wb[i] = &mcif_wb30->base;
1576 : }
1577 : return true;
1578 : }
1579 :
1580 0 : static struct display_stream_compressor *dcn31_dsc_create(
1581 : struct dc_context *ctx, uint32_t inst)
1582 : {
1583 0 : struct dcn20_dsc *dsc =
1584 : kzalloc(sizeof(struct dcn20_dsc), GFP_KERNEL);
1585 :
1586 0 : if (!dsc) {
1587 0 : BREAK_TO_DEBUGGER();
1588 0 : return NULL;
1589 : }
1590 :
1591 0 : dsc2_construct(dsc, ctx, inst, &dsc_regs[inst], &dsc_shift, &dsc_mask);
1592 0 : return &dsc->base;
1593 : }
1594 :
1595 0 : static void dcn31_destroy_resource_pool(struct resource_pool **pool)
1596 : {
1597 0 : struct dcn31_resource_pool *dcn31_pool = TO_DCN31_RES_POOL(*pool);
1598 :
1599 0 : dcn31_resource_destruct(dcn31_pool);
1600 0 : kfree(dcn31_pool);
1601 0 : *pool = NULL;
1602 0 : }
1603 :
1604 0 : static struct clock_source *dcn31_clock_source_create(
1605 : struct dc_context *ctx,
1606 : struct dc_bios *bios,
1607 : enum clock_source_id id,
1608 : const struct dce110_clk_src_regs *regs,
1609 : bool dp_clk_src)
1610 : {
1611 0 : struct dce110_clk_src *clk_src =
1612 : kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL);
1613 :
1614 0 : if (!clk_src)
1615 : return NULL;
1616 :
1617 0 : if (dcn3_clk_src_construct(clk_src, ctx, bios, id,
1618 : regs, &cs_shift, &cs_mask)) {
1619 0 : clk_src->base.dp_clk_src = dp_clk_src;
1620 0 : return &clk_src->base;
1621 : }
1622 :
1623 0 : BREAK_TO_DEBUGGER();
1624 0 : return NULL;
1625 : }
1626 :
1627 : static bool is_dual_plane(enum surface_pixel_format format)
1628 : {
1629 : return format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN || format == SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA;
1630 : }
1631 :
1632 0 : int dcn31_populate_dml_pipes_from_context(
1633 : struct dc *dc, struct dc_state *context,
1634 : display_e2e_pipe_params_st *pipes,
1635 : bool fast_validate)
1636 : {
1637 : int i, pipe_cnt;
1638 0 : struct resource_context *res_ctx = &context->res_ctx;
1639 : struct pipe_ctx *pipe;
1640 0 : bool upscaled = false;
1641 :
1642 0 : DC_FP_START();
1643 0 : dcn20_populate_dml_pipes_from_context(dc, context, pipes, fast_validate);
1644 0 : DC_FP_END();
1645 :
1646 0 : for (i = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {
1647 : struct dc_crtc_timing *timing;
1648 :
1649 0 : if (!res_ctx->pipe_ctx[i].stream)
1650 0 : continue;
1651 0 : pipe = &res_ctx->pipe_ctx[i];
1652 0 : timing = &pipe->stream->timing;
1653 0 : if (pipe->plane_state &&
1654 0 : (pipe->plane_state->src_rect.height < pipe->plane_state->dst_rect.height ||
1655 0 : pipe->plane_state->src_rect.width < pipe->plane_state->dst_rect.width))
1656 0 : upscaled = true;
1657 :
1658 : /*
1659 : * Immediate flip can be set dynamically after enabling the plane.
1660 : * We need to require support for immediate flip or underflow can be
1661 : * intermittently experienced depending on peak b/w requirements.
1662 : */
1663 0 : pipes[pipe_cnt].pipe.src.immediate_flip = true;
1664 0 : pipes[pipe_cnt].pipe.src.unbounded_req_mode = false;
1665 0 : pipes[pipe_cnt].pipe.src.gpuvm = true;
1666 0 : pipes[pipe_cnt].pipe.dest.vfront_porch = timing->v_front_porch;
1667 0 : pipes[pipe_cnt].pipe.src.dcc_rate = 3;
1668 0 : pipes[pipe_cnt].dout.dsc_input_bpc = 0;
1669 0 : DC_FP_START();
1670 0 : dcn31_zero_pipe_dcc_fraction(pipes, pipe_cnt);
1671 0 : DC_FP_END();
1672 :
1673 0 : if (dc->debug.dml_hostvm_override == DML_HOSTVM_NO_OVERRIDE)
1674 0 : pipes[pipe_cnt].pipe.src.hostvm = dc->res_pool->hubbub->riommu_active;
1675 0 : else if (dc->debug.dml_hostvm_override == DML_HOSTVM_OVERRIDE_FALSE)
1676 0 : pipes[pipe_cnt].pipe.src.hostvm = false;
1677 0 : else if (dc->debug.dml_hostvm_override == DML_HOSTVM_OVERRIDE_TRUE)
1678 0 : pipes[pipe_cnt].pipe.src.hostvm = true;
1679 :
1680 0 : if (pipes[pipe_cnt].dout.dsc_enable) {
1681 0 : switch (timing->display_color_depth) {
1682 : case COLOR_DEPTH_888:
1683 0 : pipes[pipe_cnt].dout.dsc_input_bpc = 8;
1684 0 : break;
1685 : case COLOR_DEPTH_101010:
1686 0 : pipes[pipe_cnt].dout.dsc_input_bpc = 10;
1687 0 : break;
1688 : case COLOR_DEPTH_121212:
1689 0 : pipes[pipe_cnt].dout.dsc_input_bpc = 12;
1690 0 : break;
1691 : default:
1692 0 : ASSERT(0);
1693 : break;
1694 : }
1695 : }
1696 :
1697 0 : pipe_cnt++;
1698 : }
1699 0 : context->bw_ctx.dml.ip.det_buffer_size_kbytes = DCN3_1_DEFAULT_DET_SIZE;
1700 0 : dc->config.enable_4to1MPC = false;
1701 0 : if (pipe_cnt == 1 && pipe->plane_state && !dc->debug.disable_z9_mpc) {
1702 0 : if (is_dual_plane(pipe->plane_state->format)
1703 0 : && pipe->plane_state->src_rect.width <= 1920 && pipe->plane_state->src_rect.height <= 1080) {
1704 0 : dc->config.enable_4to1MPC = true;
1705 0 : } else if (!is_dual_plane(pipe->plane_state->format) && pipe->plane_state->src_rect.width <= 5120) {
1706 : /* Limit to 5k max to avoid forced pipe split when there is not enough detile for swath */
1707 0 : context->bw_ctx.dml.ip.det_buffer_size_kbytes = 192;
1708 0 : pipes[0].pipe.src.unbounded_req_mode = true;
1709 : }
1710 0 : } else if (context->stream_count >= dc->debug.crb_alloc_policy_min_disp_count
1711 0 : && dc->debug.crb_alloc_policy > DET_SIZE_DEFAULT) {
1712 0 : context->bw_ctx.dml.ip.det_buffer_size_kbytes = dc->debug.crb_alloc_policy * 64;
1713 0 : } else if (context->stream_count >= 3 && upscaled) {
1714 0 : context->bw_ctx.dml.ip.det_buffer_size_kbytes = 192;
1715 : }
1716 :
1717 0 : return pipe_cnt;
1718 : }
1719 :
1720 0 : void dcn31_calculate_wm_and_dlg(
1721 : struct dc *dc, struct dc_state *context,
1722 : display_e2e_pipe_params_st *pipes,
1723 : int pipe_cnt,
1724 : int vlevel)
1725 : {
1726 0 : DC_FP_START();
1727 0 : dcn31_calculate_wm_and_dlg_fp(dc, context, pipes, pipe_cnt, vlevel);
1728 0 : DC_FP_END();
1729 0 : }
1730 :
1731 : void
1732 0 : dcn31_populate_dml_writeback_from_context(struct dc *dc,
1733 : struct resource_context *res_ctx,
1734 : display_e2e_pipe_params_st *pipes)
1735 : {
1736 0 : DC_FP_START();
1737 0 : dcn30_populate_dml_writeback_from_context(dc, res_ctx, pipes);
1738 0 : DC_FP_END();
1739 0 : }
1740 :
1741 : void
1742 0 : dcn31_set_mcif_arb_params(struct dc *dc,
1743 : struct dc_state *context,
1744 : display_e2e_pipe_params_st *pipes,
1745 : int pipe_cnt)
1746 : {
1747 0 : DC_FP_START();
1748 0 : dcn30_set_mcif_arb_params(dc, context, pipes, pipe_cnt);
1749 0 : DC_FP_END();
1750 0 : }
1751 :
1752 0 : bool dcn31_validate_bandwidth(struct dc *dc,
1753 : struct dc_state *context,
1754 : bool fast_validate)
1755 : {
1756 0 : bool out = false;
1757 :
1758 0 : BW_VAL_TRACE_SETUP();
1759 :
1760 0 : int vlevel = 0;
1761 0 : int pipe_cnt = 0;
1762 0 : display_e2e_pipe_params_st *pipes = kzalloc(dc->res_pool->pipe_count * sizeof(display_e2e_pipe_params_st), GFP_KERNEL);
1763 : DC_LOGGER_INIT(dc->ctx->logger);
1764 :
1765 0 : BW_VAL_TRACE_COUNT();
1766 :
1767 0 : DC_FP_START();
1768 0 : out = dcn30_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel, fast_validate);
1769 0 : DC_FP_END();
1770 :
1771 : // Disable fast_validate to set min dcfclk in alculate_wm_and_dlg
1772 0 : if (pipe_cnt == 0)
1773 0 : fast_validate = false;
1774 :
1775 0 : if (!out)
1776 : goto validate_fail;
1777 :
1778 0 : BW_VAL_TRACE_END_VOLTAGE_LEVEL();
1779 :
1780 0 : if (fast_validate) {
1781 0 : BW_VAL_TRACE_SKIP(fast);
1782 : goto validate_out;
1783 : }
1784 :
1785 0 : dc->res_pool->funcs->calculate_wm_and_dlg(dc, context, pipes, pipe_cnt, vlevel);
1786 :
1787 0 : BW_VAL_TRACE_END_WATERMARKS();
1788 :
1789 : goto validate_out;
1790 :
1791 : validate_fail:
1792 0 : DC_LOG_WARNING("Mode Validation Warning: %s failed validation.\n",
1793 : dml_get_status_message(context->bw_ctx.dml.vba.ValidationStatus[context->bw_ctx.dml.vba.soc.num_states]));
1794 :
1795 0 : BW_VAL_TRACE_SKIP(fail);
1796 : out = false;
1797 :
1798 : validate_out:
1799 0 : kfree(pipes);
1800 :
1801 0 : BW_VAL_TRACE_FINISH();
1802 :
1803 0 : return out;
1804 : }
1805 :
1806 : static struct dc_cap_funcs cap_funcs = {
1807 : .get_dcc_compression_cap = dcn20_get_dcc_compression_cap
1808 : };
1809 :
1810 : static struct resource_funcs dcn31_res_pool_funcs = {
1811 : .destroy = dcn31_destroy_resource_pool,
1812 : .link_enc_create = dcn31_link_encoder_create,
1813 : .link_enc_create_minimal = dcn31_link_enc_create_minimal,
1814 : .link_encs_assign = link_enc_cfg_link_encs_assign,
1815 : .link_enc_unassign = link_enc_cfg_link_enc_unassign,
1816 : .panel_cntl_create = dcn31_panel_cntl_create,
1817 : .validate_bandwidth = dcn31_validate_bandwidth,
1818 : .calculate_wm_and_dlg = dcn31_calculate_wm_and_dlg,
1819 : .update_soc_for_wm_a = dcn31_update_soc_for_wm_a,
1820 : .populate_dml_pipes = dcn31_populate_dml_pipes_from_context,
1821 : .acquire_idle_pipe_for_layer = dcn20_acquire_idle_pipe_for_layer,
1822 : .add_stream_to_ctx = dcn30_add_stream_to_ctx,
1823 : .add_dsc_to_stream_resource = dcn20_add_dsc_to_stream_resource,
1824 : .remove_stream_from_ctx = dcn20_remove_stream_from_ctx,
1825 : .populate_dml_writeback_from_context = dcn31_populate_dml_writeback_from_context,
1826 : .set_mcif_arb_params = dcn31_set_mcif_arb_params,
1827 : .find_first_free_match_stream_enc_for_link = dcn10_find_first_free_match_stream_enc_for_link,
1828 : .acquire_post_bldn_3dlut = dcn30_acquire_post_bldn_3dlut,
1829 : .release_post_bldn_3dlut = dcn30_release_post_bldn_3dlut,
1830 : .update_bw_bounding_box = dcn31_update_bw_bounding_box,
1831 : .patch_unknown_plane_state = dcn20_patch_unknown_plane_state,
1832 : };
1833 :
1834 0 : static struct clock_source *dcn30_clock_source_create(
1835 : struct dc_context *ctx,
1836 : struct dc_bios *bios,
1837 : enum clock_source_id id,
1838 : const struct dce110_clk_src_regs *regs,
1839 : bool dp_clk_src)
1840 : {
1841 0 : struct dce110_clk_src *clk_src =
1842 : kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL);
1843 :
1844 0 : if (!clk_src)
1845 : return NULL;
1846 :
1847 0 : if (dcn31_clk_src_construct(clk_src, ctx, bios, id,
1848 : regs, &cs_shift, &cs_mask)) {
1849 0 : clk_src->base.dp_clk_src = dp_clk_src;
1850 0 : return &clk_src->base;
1851 : }
1852 :
1853 0 : BREAK_TO_DEBUGGER();
1854 0 : return NULL;
1855 : }
1856 :
1857 0 : static bool dcn31_resource_construct(
1858 : uint8_t num_virtual_links,
1859 : struct dc *dc,
1860 : struct dcn31_resource_pool *pool)
1861 : {
1862 : int i;
1863 0 : struct dc_context *ctx = dc->ctx;
1864 : struct irq_service_init_data init_data;
1865 :
1866 0 : ctx->dc_bios->regs = &bios_regs;
1867 :
1868 0 : pool->base.res_cap = &res_cap_dcn31;
1869 :
1870 0 : pool->base.funcs = &dcn31_res_pool_funcs;
1871 :
1872 : /*************************************************
1873 : * Resource + asic cap harcoding *
1874 : *************************************************/
1875 0 : pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE;
1876 0 : pool->base.pipe_count = pool->base.res_cap->num_timing_generator;
1877 0 : pool->base.mpcc_count = pool->base.res_cap->num_timing_generator;
1878 0 : dc->caps.max_downscale_ratio = 600;
1879 0 : dc->caps.i2c_speed_in_khz = 100;
1880 0 : dc->caps.i2c_speed_in_khz_hdcp = 5; /*1.4 w/a applied by default*/
1881 0 : dc->caps.max_cursor_size = 256;
1882 0 : dc->caps.min_horizontal_blanking_period = 80;
1883 0 : dc->caps.dmdata_alloc_size = 2048;
1884 :
1885 0 : dc->caps.max_slave_planes = 2;
1886 0 : dc->caps.max_slave_yuv_planes = 2;
1887 0 : dc->caps.max_slave_rgb_planes = 2;
1888 0 : dc->caps.post_blend_color_processing = true;
1889 0 : dc->caps.force_dp_tps4_for_cp2520 = true;
1890 0 : dc->caps.dp_hpo = true;
1891 0 : dc->caps.dp_hdmi21_pcon_support = true;
1892 0 : dc->caps.edp_dsc_support = true;
1893 0 : dc->caps.extended_aux_timeout_support = true;
1894 0 : dc->caps.dmcub_support = true;
1895 0 : dc->caps.is_apu = true;
1896 0 : dc->caps.zstate_support = true;
1897 :
1898 : /* Color pipeline capabilities */
1899 0 : dc->caps.color.dpp.dcn_arch = 1;
1900 0 : dc->caps.color.dpp.input_lut_shared = 0;
1901 0 : dc->caps.color.dpp.icsc = 1;
1902 0 : dc->caps.color.dpp.dgam_ram = 0; // must use gamma_corr
1903 0 : dc->caps.color.dpp.dgam_rom_caps.srgb = 1;
1904 0 : dc->caps.color.dpp.dgam_rom_caps.bt2020 = 1;
1905 0 : dc->caps.color.dpp.dgam_rom_caps.gamma2_2 = 1;
1906 0 : dc->caps.color.dpp.dgam_rom_caps.pq = 1;
1907 0 : dc->caps.color.dpp.dgam_rom_caps.hlg = 1;
1908 0 : dc->caps.color.dpp.post_csc = 1;
1909 0 : dc->caps.color.dpp.gamma_corr = 1;
1910 0 : dc->caps.color.dpp.dgam_rom_for_yuv = 0;
1911 :
1912 0 : dc->caps.color.dpp.hw_3d_lut = 1;
1913 0 : dc->caps.color.dpp.ogam_ram = 1;
1914 : // no OGAM ROM on DCN301
1915 0 : dc->caps.color.dpp.ogam_rom_caps.srgb = 0;
1916 0 : dc->caps.color.dpp.ogam_rom_caps.bt2020 = 0;
1917 0 : dc->caps.color.dpp.ogam_rom_caps.gamma2_2 = 0;
1918 0 : dc->caps.color.dpp.ogam_rom_caps.pq = 0;
1919 0 : dc->caps.color.dpp.ogam_rom_caps.hlg = 0;
1920 0 : dc->caps.color.dpp.ocsc = 0;
1921 :
1922 0 : dc->caps.color.mpc.gamut_remap = 1;
1923 0 : dc->caps.color.mpc.num_3dluts = pool->base.res_cap->num_mpc_3dlut; //2
1924 0 : dc->caps.color.mpc.ogam_ram = 1;
1925 0 : dc->caps.color.mpc.ogam_rom_caps.srgb = 0;
1926 0 : dc->caps.color.mpc.ogam_rom_caps.bt2020 = 0;
1927 0 : dc->caps.color.mpc.ogam_rom_caps.gamma2_2 = 0;
1928 0 : dc->caps.color.mpc.ogam_rom_caps.pq = 0;
1929 0 : dc->caps.color.mpc.ogam_rom_caps.hlg = 0;
1930 0 : dc->caps.color.mpc.ocsc = 1;
1931 :
1932 : /* Use pipe context based otg sync logic */
1933 0 : dc->config.use_pipe_ctx_sync_logic = true;
1934 :
1935 : /* read VBIOS LTTPR caps */
1936 : {
1937 0 : if (ctx->dc_bios->funcs->get_lttpr_caps) {
1938 : enum bp_result bp_query_result;
1939 0 : uint8_t is_vbios_lttpr_enable = 0;
1940 :
1941 0 : bp_query_result = ctx->dc_bios->funcs->get_lttpr_caps(ctx->dc_bios, &is_vbios_lttpr_enable);
1942 0 : dc->caps.vbios_lttpr_enable = (bp_query_result == BP_RESULT_OK) && !!is_vbios_lttpr_enable;
1943 : }
1944 :
1945 : /* interop bit is implicit */
1946 : {
1947 0 : dc->caps.vbios_lttpr_aware = true;
1948 : }
1949 : }
1950 :
1951 0 : if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV)
1952 0 : dc->debug = debug_defaults_drv;
1953 0 : else if (dc->ctx->dce_environment == DCE_ENV_FPGA_MAXIMUS) {
1954 0 : dc->debug = debug_defaults_diags;
1955 : } else
1956 0 : dc->debug = debug_defaults_diags;
1957 : // Init the vm_helper
1958 0 : if (dc->vm_helper)
1959 0 : vm_helper_init(dc->vm_helper, 16);
1960 :
1961 : /*************************************************
1962 : * Create resources *
1963 : *************************************************/
1964 :
1965 : /* Clock Sources for Pixel Clock*/
1966 0 : pool->base.clock_sources[DCN31_CLK_SRC_PLL0] =
1967 0 : dcn30_clock_source_create(ctx, ctx->dc_bios,
1968 : CLOCK_SOURCE_COMBO_PHY_PLL0,
1969 : &clk_src_regs[0], false);
1970 0 : pool->base.clock_sources[DCN31_CLK_SRC_PLL1] =
1971 0 : dcn30_clock_source_create(ctx, ctx->dc_bios,
1972 : CLOCK_SOURCE_COMBO_PHY_PLL1,
1973 : &clk_src_regs[1], false);
1974 : /*move phypllx_pixclk_resync to dmub next*/
1975 0 : if (dc->ctx->asic_id.hw_internal_rev == YELLOW_CARP_B0) {
1976 0 : pool->base.clock_sources[DCN31_CLK_SRC_PLL2] =
1977 0 : dcn30_clock_source_create(ctx, ctx->dc_bios,
1978 : CLOCK_SOURCE_COMBO_PHY_PLL2,
1979 : &clk_src_regs_b0[2], false);
1980 0 : pool->base.clock_sources[DCN31_CLK_SRC_PLL3] =
1981 0 : dcn30_clock_source_create(ctx, ctx->dc_bios,
1982 : CLOCK_SOURCE_COMBO_PHY_PLL3,
1983 : &clk_src_regs_b0[3], false);
1984 : } else {
1985 0 : pool->base.clock_sources[DCN31_CLK_SRC_PLL2] =
1986 0 : dcn30_clock_source_create(ctx, ctx->dc_bios,
1987 : CLOCK_SOURCE_COMBO_PHY_PLL2,
1988 : &clk_src_regs[2], false);
1989 0 : pool->base.clock_sources[DCN31_CLK_SRC_PLL3] =
1990 0 : dcn30_clock_source_create(ctx, ctx->dc_bios,
1991 : CLOCK_SOURCE_COMBO_PHY_PLL3,
1992 : &clk_src_regs[3], false);
1993 : }
1994 :
1995 0 : pool->base.clock_sources[DCN31_CLK_SRC_PLL4] =
1996 0 : dcn30_clock_source_create(ctx, ctx->dc_bios,
1997 : CLOCK_SOURCE_COMBO_PHY_PLL4,
1998 : &clk_src_regs[4], false);
1999 :
2000 0 : pool->base.clk_src_count = DCN30_CLK_SRC_TOTAL;
2001 :
2002 : /* todo: not reuse phy_pll registers */
2003 0 : pool->base.dp_clock_source =
2004 0 : dcn31_clock_source_create(ctx, ctx->dc_bios,
2005 : CLOCK_SOURCE_ID_DP_DTO,
2006 : &clk_src_regs[0], true);
2007 :
2008 0 : for (i = 0; i < pool->base.clk_src_count; i++) {
2009 0 : if (pool->base.clock_sources[i] == NULL) {
2010 0 : dm_error("DC: failed to create clock sources!\n");
2011 0 : BREAK_TO_DEBUGGER();
2012 0 : goto create_fail;
2013 : }
2014 : }
2015 :
2016 : /* TODO: DCCG */
2017 0 : pool->base.dccg = dccg31_create(ctx, &dccg_regs, &dccg_shift, &dccg_mask);
2018 0 : if (pool->base.dccg == NULL) {
2019 0 : dm_error("DC: failed to create dccg!\n");
2020 0 : BREAK_TO_DEBUGGER();
2021 0 : goto create_fail;
2022 : }
2023 :
2024 : /* TODO: IRQ */
2025 0 : init_data.ctx = dc->ctx;
2026 0 : pool->base.irqs = dal_irq_service_dcn31_create(&init_data);
2027 0 : if (!pool->base.irqs)
2028 : goto create_fail;
2029 :
2030 : /* HUBBUB */
2031 0 : pool->base.hubbub = dcn31_hubbub_create(ctx);
2032 0 : if (pool->base.hubbub == NULL) {
2033 0 : BREAK_TO_DEBUGGER();
2034 0 : dm_error("DC: failed to create hubbub!\n");
2035 0 : goto create_fail;
2036 : }
2037 :
2038 : /* HUBPs, DPPs, OPPs and TGs */
2039 0 : for (i = 0; i < pool->base.pipe_count; i++) {
2040 0 : pool->base.hubps[i] = dcn31_hubp_create(ctx, i);
2041 0 : if (pool->base.hubps[i] == NULL) {
2042 0 : BREAK_TO_DEBUGGER();
2043 0 : dm_error(
2044 : "DC: failed to create hubps!\n");
2045 0 : goto create_fail;
2046 : }
2047 :
2048 0 : pool->base.dpps[i] = dcn31_dpp_create(ctx, i);
2049 0 : if (pool->base.dpps[i] == NULL) {
2050 0 : BREAK_TO_DEBUGGER();
2051 0 : dm_error(
2052 : "DC: failed to create dpps!\n");
2053 0 : goto create_fail;
2054 : }
2055 : }
2056 :
2057 0 : for (i = 0; i < pool->base.res_cap->num_opp; i++) {
2058 0 : pool->base.opps[i] = dcn31_opp_create(ctx, i);
2059 0 : if (pool->base.opps[i] == NULL) {
2060 0 : BREAK_TO_DEBUGGER();
2061 0 : dm_error(
2062 : "DC: failed to create output pixel processor!\n");
2063 0 : goto create_fail;
2064 : }
2065 : }
2066 :
2067 0 : for (i = 0; i < pool->base.res_cap->num_timing_generator; i++) {
2068 0 : pool->base.timing_generators[i] = dcn31_timing_generator_create(
2069 : ctx, i);
2070 0 : if (pool->base.timing_generators[i] == NULL) {
2071 0 : BREAK_TO_DEBUGGER();
2072 0 : dm_error("DC: failed to create tg!\n");
2073 0 : goto create_fail;
2074 : }
2075 : }
2076 0 : pool->base.timing_generator_count = i;
2077 :
2078 : /* PSR */
2079 0 : pool->base.psr = dmub_psr_create(ctx);
2080 0 : if (pool->base.psr == NULL) {
2081 0 : dm_error("DC: failed to create psr obj!\n");
2082 0 : BREAK_TO_DEBUGGER();
2083 0 : goto create_fail;
2084 : }
2085 :
2086 : /* ABM */
2087 0 : for (i = 0; i < pool->base.res_cap->num_timing_generator; i++) {
2088 0 : pool->base.multiple_abms[i] = dmub_abm_create(ctx,
2089 : &abm_regs[i],
2090 : &abm_shift,
2091 : &abm_mask);
2092 0 : if (pool->base.multiple_abms[i] == NULL) {
2093 0 : dm_error("DC: failed to create abm for pipe %d!\n", i);
2094 0 : BREAK_TO_DEBUGGER();
2095 0 : goto create_fail;
2096 : }
2097 : }
2098 :
2099 : /* MPC and DSC */
2100 0 : pool->base.mpc = dcn31_mpc_create(ctx, pool->base.mpcc_count, pool->base.res_cap->num_mpc_3dlut);
2101 0 : if (pool->base.mpc == NULL) {
2102 0 : BREAK_TO_DEBUGGER();
2103 0 : dm_error("DC: failed to create mpc!\n");
2104 0 : goto create_fail;
2105 : }
2106 :
2107 0 : for (i = 0; i < pool->base.res_cap->num_dsc; i++) {
2108 0 : pool->base.dscs[i] = dcn31_dsc_create(ctx, i);
2109 0 : if (pool->base.dscs[i] == NULL) {
2110 0 : BREAK_TO_DEBUGGER();
2111 0 : dm_error("DC: failed to create display stream compressor %d!\n", i);
2112 0 : goto create_fail;
2113 : }
2114 : }
2115 :
2116 : /* DWB and MMHUBBUB */
2117 0 : if (!dcn31_dwbc_create(ctx, &pool->base)) {
2118 0 : BREAK_TO_DEBUGGER();
2119 0 : dm_error("DC: failed to create dwbc!\n");
2120 0 : goto create_fail;
2121 : }
2122 :
2123 0 : if (!dcn31_mmhubbub_create(ctx, &pool->base)) {
2124 0 : BREAK_TO_DEBUGGER();
2125 0 : dm_error("DC: failed to create mcif_wb!\n");
2126 0 : goto create_fail;
2127 : }
2128 :
2129 : /* AUX and I2C */
2130 0 : for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
2131 0 : pool->base.engines[i] = dcn31_aux_engine_create(ctx, i);
2132 0 : if (pool->base.engines[i] == NULL) {
2133 0 : BREAK_TO_DEBUGGER();
2134 0 : dm_error(
2135 : "DC:failed to create aux engine!!\n");
2136 0 : goto create_fail;
2137 : }
2138 0 : pool->base.hw_i2cs[i] = dcn31_i2c_hw_create(ctx, i);
2139 0 : if (pool->base.hw_i2cs[i] == NULL) {
2140 0 : BREAK_TO_DEBUGGER();
2141 0 : dm_error(
2142 : "DC:failed to create hw i2c!!\n");
2143 0 : goto create_fail;
2144 : }
2145 0 : pool->base.sw_i2cs[i] = NULL;
2146 : }
2147 :
2148 0 : if (dc->ctx->asic_id.chip_family == FAMILY_YELLOW_CARP &&
2149 0 : dc->ctx->asic_id.hw_internal_rev == YELLOW_CARP_B0 &&
2150 0 : !dc->debug.dpia_debug.bits.disable_dpia) {
2151 : /* YELLOW CARP B0 has 4 DPIA's */
2152 0 : pool->base.usb4_dpia_count = 4;
2153 : }
2154 :
2155 0 : if (dc->ctx->asic_id.chip_family == AMDGPU_FAMILY_GC_11_0_1)
2156 0 : pool->base.usb4_dpia_count = 4;
2157 :
2158 : /* Audio, Stream Encoders including HPO and virtual, MPC 3D LUTs */
2159 0 : if (!resource_construct(num_virtual_links, dc, &pool->base,
2160 0 : (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment) ?
2161 : &res_create_funcs : &res_create_maximus_funcs)))
2162 : goto create_fail;
2163 :
2164 : /* HW Sequencer and Plane caps */
2165 0 : dcn31_hw_sequencer_construct(dc);
2166 :
2167 0 : dc->caps.max_planes = pool->base.pipe_count;
2168 :
2169 0 : for (i = 0; i < dc->caps.max_planes; ++i)
2170 0 : dc->caps.planes[i] = plane_cap;
2171 :
2172 0 : dc->cap_funcs = cap_funcs;
2173 :
2174 0 : dc->dcn_ip->max_num_dpp = dcn3_1_ip.max_num_dpp;
2175 :
2176 0 : return true;
2177 :
2178 : create_fail:
2179 0 : dcn31_resource_destruct(pool);
2180 :
2181 0 : return false;
2182 : }
2183 :
2184 0 : struct resource_pool *dcn31_create_resource_pool(
2185 : const struct dc_init_data *init_data,
2186 : struct dc *dc)
2187 : {
2188 0 : struct dcn31_resource_pool *pool =
2189 : kzalloc(sizeof(struct dcn31_resource_pool), GFP_KERNEL);
2190 :
2191 0 : if (!pool)
2192 : return NULL;
2193 :
2194 0 : if (dcn31_resource_construct(init_data->num_virtual_links, dc, pool))
2195 0 : return &pool->base;
2196 :
2197 0 : BREAK_TO_DEBUGGER();
2198 0 : kfree(pool);
2199 0 : return NULL;
2200 : }
|