1 // SPDX-License-Identifier: MIT
2 //
3 // Copyright 2026 Advanced Micro Devices, Inc.
4
5 #include "dm_services.h"
6 #include "dc.h"
7
8 #include "dcn32/dcn32_init.h"
9 #include "dcn42/dcn42_init.h"
10
11 #include "resource.h"
12 #include "basics/conversion.h"
13 #include "include/irq_service_interface.h"
14
15 #include "dcn42_resource.h"
16 #include "dcn42_resource_fpu.h"
17 #include "dcn20/dcn20_resource.h"
18 #include "dcn30/dcn30_resource.h"
19 #include "dcn31/dcn31_resource.h"
20 #include "dcn32/dcn32_resource.h"
21 #include "dcn35/dcn35_resource.h"
22 #include "dcn321/dcn321_resource.h"
23 #include "dcn401/dcn401_resource.h"
24
25 #include "dcn10/dcn10_ipp.h"
26 #include "dcn35/dcn35_hubbub.h"
27 #include "dcn42/dcn42_hubbub.h"
28 #include "dcn401/dcn401_mpc.h"
29 #include "dcn42/dcn42_mpc.h"
30 #include "dcn35/dcn35_hubp.h"
31 #include "dcn42/dcn42_hubp.h"
32 #include "irq/dcn42/irq_service_dcn42.h"
33 #include "dcn42/dcn42_dpp.h"
34 #include "dcn401/dcn401_dsc.h"
35 #include "dcn42/dcn42_optc.h"
36 #include "dcn20/dcn20_hwseq.h"
37 #include "dcn30/dcn30_hwseq.h"
38 #include "dce110/dce110_hwseq.h"
39 #include "dcn35/dcn35_opp.h"
40 #include "dcn30/dcn30_vpg.h"
41 #include "dcn31/dcn31_vpg.h"
42 #include "dcn42/dcn42_dio_stream_encoder.h"
43 #include "dcn42/dcn42_pg_cntl.h"
44 #include "dcn401/dcn401_hpo_frl_stream_encoder.h"
45 #include "dcn42/dcn42_hpo_frl_stream_encoder.h"
46 #include "dcn30/dcn30_hpo_frl_link_encoder.h"
47 #include "dcn31/dcn31_hpo_dp_stream_encoder.h"
48 #include "dcn31/dcn31_hpo_dp_link_encoder.h"
49 #include "dcn32/dcn32_hpo_dp_link_encoder.h"
50 #include "dcn42/dcn42_hpo_dp_link_encoder.h"
51 #include "dcn31/dcn31_apg.h"
52 #include "dcn31/dcn31_dio_link_encoder.h"
53 #include "dcn401/dcn401_dio_link_encoder.h"
54 #include "dcn10/dcn10_link_encoder.h"
55 #include "dcn321/dcn321_dio_link_encoder.h"
56 #include "dce/dce_clock_source.h"
57 #include "dce/dce_audio.h"
58 #include "dce/dce_hwseq.h"
59 #include "clk_mgr.h"
60 #include "dio/virtual/virtual_stream_encoder.h"
61 #include "dml/display_mode_vba.h"
62 #include "dcn42/dcn42_dccg.h"
63 #include "dcn10/dcn10_resource.h"
64 #include "link_service.h"
65 #include "dcn31/dcn31_panel_cntl.h"
66
67 #include "dcn30/dcn30_dwb.h"
68 #include "dcn42/dcn42_mmhubbub.h"
69 #include "dcn42/dcn42_dio_link_encoder.h"
70
71 #include "dcn/dcn_4_2_0_offset.h"
72 #include "dcn/dcn_4_2_0_sh_mask.h"
73 #include "dpcs/dpcs_4_0_0_offset.h"
74 #include "dpcs/dpcs_4_0_0_sh_mask.h"
75
76 #include "reg_helper.h"
77 #include "dce/dmub_abm.h"
78 #include "dce/dmub_psr.h"
79 #include "dce/dmub_replay.h"
80 #include "dce/dce_aux.h"
81 #include "dce/dce_i2c.h"
82
83 #include "dml/dcn30/display_mode_vba_30.h"
84 #include "vm_helper.h"
85 #include "dcn20/dcn20_vmid.h"
86
87 #include "dc_state_priv.h"
88 #include "link_enc_cfg.h"
89
90 #include "dml2_0/dml2_wrapper.h"
91
92 #define regBIF_BX0_BIOS_SCRATCH_3 0x003b
93 #define regBIF_BX0_BIOS_SCRATCH_3_BASE_IDX 1
94 #define regBIF_BX0_BIOS_SCRATCH_6 0x003e
95 #define regBIF_BX0_BIOS_SCRATCH_6_BASE_IDX 1
96
97 #define DC_LOGGER_INIT(logger)
98
99 enum dcn401_clk_src_array_id {
100 DCN401_CLK_SRC_PLL0,
101 DCN401_CLK_SRC_PLL1,
102 DCN401_CLK_SRC_PLL2,
103 DCN401_CLK_SRC_PLL3,
104 DCN401_CLK_SRC_PLL4,
105 DCN401_CLK_SRC_TOTAL
106 };
107
108 /* begin
109 * macros to expend register list macro defined in HW object header file
110 */
111
112 /* DCN */
113 #define BASE_INNER(seg) ctx->dcn_reg_offsets[seg]
114
115 #define BASE(seg) BASE_INNER(seg)
116
117 #define SR(reg_name) \
118 REG_STRUCT.reg_name = BASE(reg##reg_name##_BASE_IDX) + \
119 reg##reg_name
120 #define SR_ARR(reg_name, id) \
121 REG_STRUCT[id].reg_name = BASE(reg##reg_name##_BASE_IDX) + \
122 reg##reg_name
123 #define SR_ARR_INIT(reg_name, id, value) \
124 REG_STRUCT[id].reg_name = value
125
126 #define SRI(reg_name, block, id) \
127 REG_STRUCT.reg_name = BASE(reg##block##id##_##reg_name##_BASE_IDX) + \
128 reg##block##id##_##reg_name
129
130 #define SRI_ARR(reg_name, block, id) \
131 REG_STRUCT[id].reg_name = BASE(reg##block##id##_##reg_name##_BASE_IDX) + \
132 reg##block##id##_##reg_name
133
134 /*
135 * Used when a reg_name would otherwise begin with an integer
136 */
137 #define SRI_ARR_US(reg_name, block, id) \
138 REG_STRUCT[id].reg_name = BASE(reg##block##id##reg_name##_BASE_IDX) + \
139 reg##block##id##reg_name
140 #define SR_ARR_I2C(reg_name, id) \
141 REG_STRUCT[id - 1].reg_name = BASE(reg##reg_name##_BASE_IDX) + reg##reg_name
142
143 #define SRI_ARR_I2C(reg_name, block, id) \
144 REG_STRUCT[id - 1].reg_name = BASE(reg##block##id##_##reg_name##_BASE_IDX) + \
145 reg##block##id##_##reg_name
146
147 #define SRI_ARR_DME(reg_name, block, id, offset) \
148 REG_STRUCT[id - offset].reg_name = BASE(reg##block##id##_##reg_name##_BASE_IDX) + \
149 reg##block##id##_##reg_name
150
151 #define SRI_ARR_ALPHABET(reg_name, block, index, id) \
152 REG_STRUCT[index].reg_name = BASE(reg##block##id##_##reg_name##_BASE_IDX) + \
153 reg##block##id##_##reg_name
154
155 #define SRI2(reg_name, block, id) \
156 .reg_name = BASE(reg##reg_name##_BASE_IDX) + \
157 reg##reg_name
158 #define SRI2_ARR(reg_name, block, id) \
159 REG_STRUCT[id].reg_name = BASE(reg##reg_name##_BASE_IDX) + \
160 reg##reg_name
161
162 #define SRIR(var_name, reg_name, block, id) \
163 .var_name = BASE(reg##block##id##_##reg_name##_BASE_IDX) + \
164 reg##block##id##_##reg_name
165
166 #define SRII(reg_name, block, id) \
167 REG_STRUCT.reg_name[id] = BASE(reg##block##id##_##reg_name##_BASE_IDX) + \
168 reg##block##id##_##reg_name
169
170 #define SRII_ARR_2(reg_name, block, id, inst) \
171 REG_STRUCT[inst].reg_name[id] = BASE(reg##block##id##_##reg_name##_BASE_IDX) + \
172 reg##block##id##_##reg_name
173
174 #define SRII_MPC_RMU(reg_name, block, id) \
175 .RMU##_##reg_name[id] = BASE(reg##block##id##_##reg_name##_BASE_IDX) + \
176 reg##block##id##_##reg_name
177
178 #define SRII_DWB(reg_name, temp_name, block, id) \
179 REG_STRUCT.reg_name[id] = \
180 BASE(reg##block##id##_##temp_name##_BASE_IDX) + \
181 reg##block##id##_##temp_name
182
183 #define DCCG_SRII(reg_name, block, id) \
184 REG_STRUCT.block##_##reg_name[id] = \
185 BASE(reg##block##id##_##reg_name##_BASE_IDX) + \
186 reg##block##id##_##reg_name
187
188 #define SF_DWB2(reg_name, block, id, field_name, post_fix) \
189 .field_name = reg_name##__##field_name##post_fix
190
191 #define VUPDATE_SRII(reg_name, block, id) \
192 REG_STRUCT.reg_name[id] = BASE(reg##reg_name##_##block##id##_BASE_IDX) + \
193 reg##reg_name##_##block##id
194
195 /* NBIO */
196 #define NBIO_BASE_INNER(seg) ctx->nbio_reg_offsets[seg]
197
198 #define NBIO_BASE(seg) \
199 NBIO_BASE_INNER(seg)
200
201 #define NBIO_SR(reg_name) \
202 REG_STRUCT.reg_name = NBIO_BASE(regBIF_BX0_##reg_name##_BASE_IDX) + \
203 regBIF_BX0_##reg_name
204 #define NBIO_SR_ARR(reg_name, id) \
205 REG_STRUCT[id].reg_name = NBIO_BASE(regBIF_BX0_##reg_name##_BASE_IDX) + \
206 regBIF_BX0_##reg_name
207
208 #define CTX ctx
209 #define REG(reg_name) \
210 (ctx->dcn_reg_offsets[reg##reg_name##_BASE_IDX] + reg##reg_name)
211
212 static struct bios_registers bios_regs;
213
214 #define bios_regs_init() \
215 NBIO_SR(BIOS_SCRATCH_3), \
216 NBIO_SR(BIOS_SCRATCH_6)
217
218 #define clk_src_regs_init(index, pllid) \
219 CS_COMMON_REG_LIST_DCN42_RI(index, pllid)
220
221 static struct dce110_clk_src_regs clk_src_regs[5];
222
223 static const struct dce110_clk_src_shift cs_shift = {
224 CS_COMMON_MASK_SH_LIST_DCN4_0_1(__SHIFT)
225 };
226 static const struct dce110_clk_src_mask cs_mask = {
227 CS_COMMON_MASK_SH_LIST_DCN4_0_1(_MASK)
228 };
229 #define abm_regs_init(id) \
230 ABM_DCN42_REG_LIST_RI(id)
231
232 static struct dce_abm_registers abm_regs[4];
233
234 static const struct dce_abm_shift abm_shift = {
235 ABM_MASK_SH_LIST_DCN42(__SHIFT)};
236
237 static const struct dce_abm_mask abm_mask = {
238 ABM_MASK_SH_LIST_DCN42(_MASK)};
239
240 #define audio_regs_init(id) \
241 AUD_COMMON_REG_LIST_RI(id)
242
243 static struct dce_audio_registers audio_regs[5];
244
245 static const struct dce_audio_shift audio_shift = {
246 DCN42_AUD_COMMON_MASK_SH_LIST(__SHIFT)
247 };
248
249 static const struct dce_audio_mask audio_mask = {
250 DCN42_AUD_COMMON_MASK_SH_LIST(_MASK)
251 };
252
253 #define vpg_regs_init(id) \
254 VPG_DCN401_REG_LIST_RI(id)
255
256 static struct dcn31_vpg_registers vpg_regs[10];
257
258 static const struct dcn31_vpg_shift vpg_shift = {
259 DCN31_VPG_MASK_SH_LIST(__SHIFT)};
260
261 static const struct dcn31_vpg_mask vpg_mask = {
262 DCN31_VPG_MASK_SH_LIST(_MASK)};
263
264 #define apg_regs_init(id) \
265 APG_DCN31_REG_LIST_RI(id)
266
267 static struct dcn31_apg_registers apg_regs[10];
268
269 static const struct dcn31_apg_shift apg_shift = {
270 DCN31_APG_MASK_SH_LIST(__SHIFT)};
271
272 static const struct dcn31_apg_mask apg_mask = {
273 DCN31_APG_MASK_SH_LIST(_MASK)};
274
275 #define stream_enc_regs_init(id) \
276 SE_DCN42_REG_LIST_RI(id)
277
278 static struct dcn10_stream_enc_registers stream_enc_regs[5];
279
280 static const struct dcn10_stream_encoder_shift se_shift = {
281 SE_COMMON_MASK_SH_LIST_DCN42(__SHIFT)};
282
283 static const struct dcn10_stream_encoder_mask se_mask = {
284 SE_COMMON_MASK_SH_LIST_DCN42(_MASK)};
285
286 #define aux_regs_init(id) \
287 DCN2_AUX_REG_LIST_RI(id)
288
289 static struct dcn10_link_enc_aux_registers link_enc_aux_regs[5];
290
291 #define hpd_regs_init(id) \
292 HPD_REG_LIST_RI(id)
293
294 static struct dcn10_link_enc_hpd_registers link_enc_hpd_regs[5];
295
296 #define link_regs_init(id, phyid) \
297 LE_DCN401_REG_LIST_RI(id)
298
299 static struct dcn10_link_enc_registers link_enc_regs[5];
300
301 static const struct dcn10_link_enc_shift le_shift = {
302 LINK_ENCODER_MASK_SH_LIST_DCN42(__SHIFT)};
303
304 static const struct dcn10_link_enc_mask le_mask = {
305 LINK_ENCODER_MASK_SH_LIST_DCN42(_MASK)};
306
307 #define hpo_frl_stream_encoder_reg_list(id) \
308 DCN42_HPO_FRL_STREAM_ENC_REG_LIST_RI(id)
309
310 #define hpo_frl_stream_encoder_dme_reg_list(id) \
311 DCN3_0_HPO_STREAM_ENC_DME_REG_LIST_RI(id, 6)
312
313 static struct dcn30_hpo_frl_stream_enc_registers hpo_frl_stream_enc_regs[2];
314
315 static const struct dcn401_hpo_frl_stream_encoder_shift hpo_se_shift = {
316 DCN401_HPO_STREAM_ENC_MASK_SH_LIST(__SHIFT),
317 DCN42_HDMI_STREAM_ENC_MASK_SH_LIST(__SHIFT)
318 };
319 static const struct dcn401_hpo_frl_stream_encoder_mask hpo_se_mask = {
320 DCN401_HPO_STREAM_ENC_MASK_SH_LIST(_MASK),
321 DCN42_HDMI_STREAM_ENC_MASK_SH_LIST(_MASK)
322 };
323
324 #define hpo_frl_link_encoder_reg_list(id) \
325 DCN3_0_HPO_FRL_LINK_ENC_REG_LIST_RI(id)
326
327 static struct dcn30_hpo_frl_link_encoder_registers hpo_frl_link_enc_regs[1];
328
329 static const struct dcn30_hpo_frl_link_encoder_shift hpo_le_shift = {
330 DCN3_0_HPO_FRL_LINK_ENC_MASK_SH_LIST(__SHIFT)};
331
332 static const struct dcn30_hpo_frl_link_encoder_mask hpo_le_mask = {
333 DCN3_0_HPO_FRL_LINK_ENC_MASK_SH_LIST(_MASK)};
334
335 #define hpo_dp_stream_encoder_reg_init(id) \
336 DCN42_HPO_DP_STREAM_ENC_REG_LIST_RI(id)
337
338 static struct dcn31_hpo_dp_stream_encoder_registers hpo_dp_stream_enc_regs[4];
339
340 static const struct dcn31_hpo_dp_stream_encoder_shift hpo_dp_se_shift = {
341 DCN4_2_HPO_DP_STREAM_ENC_MASK_SH_LIST(__SHIFT)};
342
343 static const struct dcn31_hpo_dp_stream_encoder_mask hpo_dp_se_mask = {
344 DCN4_2_HPO_DP_STREAM_ENC_MASK_SH_LIST(_MASK)};
345
346 #define hpo_dp_link_encoder_reg_init(id) \
347 DCN42_HPO_DP_LINK_ENC_REG_LIST_RI(id)
348
349 static struct dcn31_hpo_dp_link_encoder_registers hpo_dp_link_enc_regs[4];
350
351 static const struct dcn31_hpo_dp_link_encoder_shift hpo_dp_le_shift = {
352 DCN3_2_HPO_DP_LINK_ENC_MASK_SH_LIST(__SHIFT)};
353
354 static const struct dcn31_hpo_dp_link_encoder_mask hpo_dp_le_mask = {
355 DCN3_2_HPO_DP_LINK_ENC_MASK_SH_LIST(_MASK)};
356
357 #define dpp_regs_init(id) \
358 DPP_REG_LIST_DCN42_COMMON_RI(id)
359
360 static struct dcn42_dpp_registers dpp_regs[4];
361
362 static const struct dcn42_dpp_shift tf_shift = {
363 DPP_REG_LIST_SH_MASK_DCN42_COMMON(__SHIFT)};
364
365 static const struct dcn42_dpp_mask tf_mask = {
366 DPP_REG_LIST_SH_MASK_DCN42_COMMON(_MASK)};
367
368 #define opp_regs_init(id) \
369 OPP_REG_LIST_DCN401_RI(id)
370
371 static struct dcn20_opp_registers opp_regs[4];
372
373 static const struct dcn20_opp_shift opp_shift = {
374 OPP_MASK_SH_LIST_DCN20(__SHIFT)};
375
376 static const struct dcn20_opp_mask opp_mask = {
377 OPP_MASK_SH_LIST_DCN20(_MASK)};
378
379 #define aux_engine_regs_init(id) \
380 AUX_COMMON_REG_LIST0_RI(id), SR_ARR_INIT(AUXN_IMPCAL, id, 0), \
381 SR_ARR_INIT(AUXP_IMPCAL, id, 0), \
382 SR_ARR_INIT(AUX_RESET_MASK, id, DP_AUX0_AUX_CONTROL__AUX_RESET_MASK), \
383 SR_ARR_INIT(AUX_RESET_MASK, id, DP_AUX0_AUX_CONTROL__AUX_RESET_MASK)
384
385 static struct dce110_aux_registers aux_engine_regs[5];
386
387 static const struct dce110_aux_registers_shift aux_shift = {
388 DCN_AUX_MASK_SH_LIST(__SHIFT)};
389
390 static const struct dce110_aux_registers_mask aux_mask = {
391 DCN_AUX_MASK_SH_LIST(_MASK)};
392
393 #define dwbc_regs_dcn401_init(id) \
394 DWBC_COMMON_REG_LIST_DCN30_RI(id)
395
396 static struct dcn30_dwbc_registers dwbc401_regs[1];
397
398 static const struct dcn30_dwbc_shift dwbc401_shift = {
399 DWBC_COMMON_MASK_SH_LIST_DCN30(__SHIFT)};
400
401 static const struct dcn30_dwbc_mask dwbc401_mask = {
402 DWBC_COMMON_MASK_SH_LIST_DCN30(_MASK)};
403
404 #define mcif_wb_regs_dcn401_init(id) \
405 MCIF_WB_COMMON_REG_LIST_DCN4_01_RI(id)
406
407 static struct dcn35_mmhubbub_registers mcif_wb401_regs[1];
408
409 static const struct dcn401_mmhubbub_shift mcif_wb401_shift = {
410 MCIF_WB_COMMON_MASK_SH_LIST_DCN4_01(__SHIFT)
411 };
412
413 static const struct dcn401_mmhubbub_mask mcif_wb401_mask = {
414 MCIF_WB_COMMON_MASK_SH_LIST_DCN4_01(_MASK)
415 };
416
417 #define dsc_regs_init(id) \
418 DSC_REG_LIST_DCN401_RI(id)
419
420 static struct dcn401_dsc_registers dsc_regs[4];
421
422 static const struct dcn401_dsc_shift dsc_shift = {
423 DSC_REG_LIST_SH_MASK_DCN401(__SHIFT)};
424
425 static const struct dcn401_dsc_mask dsc_mask = {
426 DSC_REG_LIST_SH_MASK_DCN401(_MASK)};
427
428 static struct dcn42_mpc_registers mpc_regs;
429
430 #define dcn_mpc_regs_init() \
431 MPC_REG_LIST_DCN42(0), \
432 MPC_REG_LIST_DCN42(1), \
433 MPC_REG_LIST_DCN42(2), \
434 MPC_REG_LIST_DCN42(3), \
435 MPC_OUT_MUX_REG_LIST_DCN3_0_RI(0), \
436 MPC_OUT_MUX_REG_LIST_DCN3_0_RI(1), \
437 MPC_OUT_MUX_REG_LIST_DCN3_0_RI(2), \
438 MPC_OUT_MUX_REG_LIST_DCN3_0_RI(3), \
439 MPC_DWB_MUX_REG_LIST_DCN3_0_RI(0), \
440 MPC_RMCM_REG_LIST_DCN42(0), \
441 MPC_RMCM_REG_LIST_DCN42(1)
442
443 static const struct dcn42_mpc_shift mpc_shift = {
444 MPC_COMMON_MASK_SH_LIST_DCN42(__SHIFT)};
445
446 static const struct dcn42_mpc_mask mpc_mask = {
447 MPC_COMMON_MASK_SH_LIST_DCN42(_MASK)};
448
449 #define optc_regs_init(id) \
450 OPTC_COMMON_REG_LIST_DCN42_RI(id)
451
452 static struct dcn_optc_registers optc_regs[4];
453
454 static const struct dcn_optc_shift optc_shift = {
455 OPTC_COMMON_MASK_SH_LIST_DCN42(__SHIFT)};
456
457 static const struct dcn_optc_mask optc_mask = {
458 OPTC_COMMON_MASK_SH_LIST_DCN42(_MASK)};
459
460 #define hubp_regs_init(id) \
461 HUBP_REG_LIST_DCN42_RI(id)
462
463 static struct dcn_hubp2_registers hubp_regs[4];
464
465 static const struct dcn_hubp2_shift hubp_shift = {
466 HUBP_MASK_SH_LIST_DCN42(__SHIFT)};
467
468 static const struct dcn_hubp2_mask hubp_mask = {
469 HUBP_MASK_SH_LIST_DCN42(_MASK)};
470
471 static struct dcn_hubbub_registers hubbub_reg;
472
473 #define hubbub_reg_init() \
474 HUBBUB_REG_LIST_DCN42(0)
475
476 static const struct dcn_hubbub_shift hubbub_shift = {
477 HUBBUB_MASK_SH_LIST_DCN4_2(__SHIFT)};
478
479 static const struct dcn_hubbub_mask hubbub_mask = {
480 HUBBUB_MASK_SH_LIST_DCN4_2(_MASK)};
481
482 static struct dccg_registers dccg_regs;
483
484 #define dccg_regs_init() \
485 DCCG_REG_LIST_DCN42_RI()
486
487 static const struct dccg_shift dccg_shift = {
488 DCCG_MASK_SH_LIST_DCN42(__SHIFT)};
489
490 static const struct dccg_mask dccg_mask = {
491 DCCG_MASK_SH_LIST_DCN42(_MASK)};
492
493 static struct pg_cntl_registers pg_cntl_regs;
494
495 #define pg_cntl_dcn42_regs_init() \
496 PG_CNTL_REG_LIST_DCN42()
497
498 static const struct pg_cntl_shift pg_cntl_shift = {
499 PG_CNTL_MASK_SH_LIST_DCN42(__SHIFT)
500 };
501
502 static const struct pg_cntl_mask pg_cntl_mask = {
503 PG_CNTL_MASK_SH_LIST_DCN42(_MASK)
504 };
505 #define SRII2(reg_name_pre, reg_name_post, id) \
506 .reg_name_pre##_##reg_name_post[id] = \
507 BASE(reg##reg_name_pre##id##_##reg_name_post##_BASE_IDX) + \
508 reg##reg_name_pre##id##_##reg_name_post
509
510 #define HWSEQ_DCN42_REG_LIST() \
511 SR(DCHUBBUB_GLOBAL_TIMER_CNTL), \
512 SR(DIO_MEM_PWR_CTRL), \
513 SR(ODM_MEM_PWR_CTRL3), \
514 SR(MMHUBBUB_MEM_PWR_CNTL), \
515 SR(DCCG_GATE_DISABLE_CNTL), \
516 SR(DCCG_GATE_DISABLE_CNTL2), \
517 SR(DCFCLK_CNTL), \
518 SR(DC_MEM_GLOBAL_PWR_REQ_CNTL), \
519 SRII(PIXEL_RATE_CNTL, OTG, 0), \
520 SRII(PIXEL_RATE_CNTL, OTG, 1), \
521 SRII(PIXEL_RATE_CNTL, OTG, 2), \
522 SRII(PIXEL_RATE_CNTL, OTG, 3),\
523 SRII(PHYPLL_PIXEL_RATE_CNTL, OTG, 0), \
524 SRII(PHYPLL_PIXEL_RATE_CNTL, OTG, 1), \
525 SRII(PHYPLL_PIXEL_RATE_CNTL, OTG, 2), \
526 SRII(PHYPLL_PIXEL_RATE_CNTL, OTG, 3),\
527 SR(MICROSECOND_TIME_BASE_DIV), \
528 SR(MILLISECOND_TIME_BASE_DIV), \
529 SR(DISPCLK_FREQ_CHANGE_CNTL), \
530 SR(RBBMIF_TIMEOUT_DIS), \
531 SR(RBBMIF_TIMEOUT_DIS_2), \
532 SR(DCHUBBUB_CRC_CTRL), \
533 SR(DPP_TOP0_DPP_CRC_CTRL), \
534 SR(DPP_TOP0_DPP_CRC_VAL_R), \
535 SR(DPP_TOP0_DPP_CRC_VAL_G), \
536 SR(DPP_TOP0_DPP_CRC_VAL_B), \
537 SR(MPC_CRC_CTRL), \
538 SR(MPC_CRC_RESULT_R), \
539 SR(MPC_CRC_RESULT_G), \
540 SR(MPC_CRC_RESULT_B), \
541 SR(MPC_CRC_RESULT_A), \
542 SR(DOMAIN0_PG_CONFIG), \
543 SR(DOMAIN1_PG_CONFIG), \
544 SR(DOMAIN2_PG_CONFIG), \
545 SR(DOMAIN3_PG_CONFIG), \
546 SR(DOMAIN16_PG_CONFIG), \
547 SR(DOMAIN17_PG_CONFIG), \
548 SR(DOMAIN18_PG_CONFIG), \
549 SR(DOMAIN19_PG_CONFIG), \
550 SR(DOMAIN22_PG_CONFIG), \
551 SR(DOMAIN23_PG_CONFIG), \
552 SR(DOMAIN24_PG_CONFIG), \
553 SR(DOMAIN25_PG_CONFIG), \
554 SR(DOMAIN26_PG_CONFIG), \
555 SR(DOMAIN0_PG_STATUS), \
556 SR(DOMAIN1_PG_STATUS), \
557 SR(DOMAIN2_PG_STATUS), \
558 SR(DOMAIN3_PG_STATUS), \
559 SR(DOMAIN16_PG_STATUS), \
560 SR(DOMAIN17_PG_STATUS), \
561 SR(DOMAIN18_PG_STATUS), \
562 SR(DOMAIN19_PG_STATUS), \
563 SR(DOMAIN22_PG_STATUS), \
564 SR(DOMAIN23_PG_STATUS), \
565 SR(DOMAIN24_PG_STATUS), \
566 SR(DOMAIN25_PG_STATUS), \
567 SR(DOMAIN26_PG_STATUS), \
568 SR(DC_IP_REQUEST_CNTL), \
569 SR(AZALIA_AUDIO_DTO), \
570 SR(HPO_TOP_HW_CONTROL), \
571 SR(AZALIA_CONTROLLER_CLOCK_GATING)
572
573 static struct dce_hwseq_registers hwseq_reg;
574
575 #define hwseq_reg_init() \
576 HWSEQ_DCN42_REG_LIST()
577
578 #define HWSEQ_DCN42_MASK_SH_LIST(mask_sh) \
579 HWSEQ_DCN_MASK_SH_LIST(mask_sh), \
580 HWS_SF(, DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, mask_sh), \
581 HWS_SF(, DCHUBBUB_ARB_HOSTVM_CNTL, DISABLE_HOSTVM_FORCE_ALLOW_PSTATE, mask_sh), \
582 HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \
583 HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \
584 HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \
585 HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \
586 HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \
587 HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \
588 HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \
589 HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \
590 HWS_SF(, DOMAIN16_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \
591 HWS_SF(, DOMAIN16_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \
592 HWS_SF(, DOMAIN17_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \
593 HWS_SF(, DOMAIN17_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \
594 HWS_SF(, DOMAIN18_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \
595 HWS_SF(, DOMAIN18_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \
596 HWS_SF(, DOMAIN19_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \
597 HWS_SF(, DOMAIN19_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \
598 HWS_SF(, DOMAIN22_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \
599 HWS_SF(, DOMAIN22_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \
600 HWS_SF(, DOMAIN23_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \
601 HWS_SF(, DOMAIN23_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \
602 HWS_SF(, DOMAIN24_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \
603 HWS_SF(, DOMAIN24_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \
604 HWS_SF(, DOMAIN25_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \
605 HWS_SF(, DOMAIN25_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \
606 HWS_SF(, DOMAIN26_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \
607 HWS_SF(, DOMAIN26_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \
608 HWS_SF(, DOMAIN0_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \
609 HWS_SF(, DOMAIN1_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \
610 HWS_SF(, DOMAIN2_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \
611 HWS_SF(, DOMAIN3_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \
612 HWS_SF(, DOMAIN16_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \
613 HWS_SF(, DOMAIN17_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \
614 HWS_SF(, DOMAIN18_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \
615 HWS_SF(, DOMAIN19_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \
616 HWS_SF(, DOMAIN22_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \
617 HWS_SF(, DOMAIN23_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \
618 HWS_SF(, DOMAIN24_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \
619 HWS_SF(, DOMAIN25_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \
620 HWS_SF(, DOMAIN26_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \
621 HWS_SF(, DC_IP_REQUEST_CNTL, IP_REQUEST_EN, mask_sh), \
622 HWS_SF(, AZALIA_AUDIO_DTO, AZALIA_AUDIO_DTO_MODULE, mask_sh), \
623 HWS_SF(, HPO_TOP_CLOCK_CONTROL, HPO_HDMISTREAMCLK_G_GATE_DIS, mask_sh), \
624 HWS_SF(, HPO_TOP_HW_CONTROL, HPO_IO_EN, mask_sh), \
625 HWS_SF(, ODM_MEM_PWR_CTRL3, ODM_MEM_UNASSIGNED_PWR_MODE, mask_sh), \
626 HWS_SF(, ODM_MEM_PWR_CTRL3, ODM_MEM_VBLANK_PWR_MODE, mask_sh), \
627 HWS_SF(, DIO_MEM_PWR_CTRL, I2C_LIGHT_SLEEP_FORCE, mask_sh), \
628 HWS_SF(, DMU_CLK_CNTL, DISPCLK_R_DMU_GATE_DIS, mask_sh),\
629 HWS_SF(, DMU_CLK_CNTL, DISPCLK_G_RBBMIF_GATE_DIS, mask_sh),\
630 HWS_SF(, DMU_CLK_CNTL, RBBMIF_FGCG_REP_DIS, mask_sh),\
631 HWS_SF(, DMU_CLK_CNTL, DPREFCLK_ALLOW_DS_CLKSTOP, mask_sh),\
632 HWS_SF(, DMU_CLK_CNTL, DISPCLK_ALLOW_DS_CLKSTOP, mask_sh),\
633 HWS_SF(, DMU_CLK_CNTL, DPPCLK_ALLOW_DS_CLKSTOP, mask_sh),\
634 HWS_SF(, DMU_CLK_CNTL, DTBCLK_ALLOW_DS_CLKSTOP, mask_sh),\
635 HWS_SF(, DMU_CLK_CNTL, DCFCLK_ALLOW_DS_CLKSTOP, mask_sh),\
636 HWS_SF(, DMU_CLK_CNTL, DPIACLK_ALLOW_DS_CLKSTOP, mask_sh),\
637 HWS_SF(, DMU_CLK_CNTL, LONO_FGCG_REP_DIS, mask_sh),\
638 HWS_SF(, DMU_CLK_CNTL, LONO_DISPCLK_GATE_DISABLE, mask_sh),\
639 HWS_SF(, DMU_CLK_CNTL, LONO_SOCCLK_GATE_DISABLE, mask_sh),\
640 HWS_SF(, DMU_CLK_CNTL, LONO_DMCUBCLK_GATE_DISABLE, mask_sh),\
641 HWS_SF(, DCCG_GATE_DISABLE_CNTL2, SYMCLKA_FE_GATE_DISABLE, mask_sh), \
642 HWS_SF(, DCCG_GATE_DISABLE_CNTL2, SYMCLKB_FE_GATE_DISABLE, mask_sh), \
643 HWS_SF(, DCCG_GATE_DISABLE_CNTL2, SYMCLKC_FE_GATE_DISABLE, mask_sh), \
644 HWS_SF(, DCCG_GATE_DISABLE_CNTL2, SYMCLKD_FE_GATE_DISABLE, mask_sh), \
645 HWS_SF(, DCCG_GATE_DISABLE_CNTL2, SYMCLKE_FE_GATE_DISABLE, mask_sh), \
646 HWS_SF(, DCCG_GATE_DISABLE_CNTL2, HDMICHARCLK0_GATE_DISABLE, mask_sh), \
647 HWS_SF(, DCCG_GATE_DISABLE_CNTL2, SYMCLKA_GATE_DISABLE, mask_sh), \
648 HWS_SF(, DCCG_GATE_DISABLE_CNTL2, SYMCLKB_GATE_DISABLE, mask_sh), \
649 HWS_SF(, DCCG_GATE_DISABLE_CNTL2, SYMCLKC_GATE_DISABLE, mask_sh), \
650 HWS_SF(, DCCG_GATE_DISABLE_CNTL2, SYMCLKD_GATE_DISABLE, mask_sh), \
651 HWS_SF(, DCCG_GATE_DISABLE_CNTL2, SYMCLKE_GATE_DISABLE, mask_sh), \
652 HWS_SF(, DCCG_GATE_DISABLE_CNTL2, PHYASYMCLK_ROOT_GATE_DISABLE, mask_sh), \
653 HWS_SF(, DCCG_GATE_DISABLE_CNTL2, PHYBSYMCLK_ROOT_GATE_DISABLE, mask_sh), \
654 HWS_SF(, DCCG_GATE_DISABLE_CNTL2, PHYCSYMCLK_ROOT_GATE_DISABLE, mask_sh), \
655 HWS_SF(, DCCG_GATE_DISABLE_CNTL2, PHYDSYMCLK_ROOT_GATE_DISABLE, mask_sh), \
656 HWS_SF(, DCCG_GATE_DISABLE_CNTL2, PHYESYMCLK_ROOT_GATE_DISABLE, mask_sh),\
657 HWS_SF(, DCCG_GATE_DISABLE_CNTL5, DTBCLK_P0_GATE_DISABLE, mask_sh),\
658 HWS_SF(, DCCG_GATE_DISABLE_CNTL5, DTBCLK_P1_GATE_DISABLE, mask_sh),\
659 HWS_SF(, DCCG_GATE_DISABLE_CNTL5, DTBCLK_P2_GATE_DISABLE, mask_sh),\
660 HWS_SF(, DCCG_GATE_DISABLE_CNTL5, DTBCLK_P3_GATE_DISABLE, mask_sh),\
661 HWS_SF(, DCCG_GATE_DISABLE_CNTL5, DPSTREAMCLK0_GATE_DISABLE, mask_sh),\
662 HWS_SF(, DCCG_GATE_DISABLE_CNTL5, DPSTREAMCLK1_GATE_DISABLE, mask_sh),\
663 HWS_SF(, DCCG_GATE_DISABLE_CNTL5, DPSTREAMCLK2_GATE_DISABLE, mask_sh),\
664 HWS_SF(, DCCG_GATE_DISABLE_CNTL5, DPSTREAMCLK3_GATE_DISABLE, mask_sh),\
665 HWS_SF(, DCCG_GATE_DISABLE_CNTL4, DPIASYMCLK0_GATE_DISABLE, mask_sh),\
666 HWS_SF(, DCCG_GATE_DISABLE_CNTL4, DPIASYMCLK1_GATE_DISABLE, mask_sh),\
667 HWS_SF(, DCCG_GATE_DISABLE_CNTL4, DPIASYMCLK2_GATE_DISABLE, mask_sh),\
668 HWS_SF(, DCCG_GATE_DISABLE_CNTL4, DPIASYMCLK3_GATE_DISABLE, mask_sh),\
669 HWS_SF(, DCCG_GATE_DISABLE_CNTL4, DPIASYMCLK4_GATE_DISABLE, mask_sh),\
670 HWS_SF(, DCCG_GATE_DISABLE_CNTL4, DPIASYMCLK5_GATE_DISABLE, mask_sh)
671
672 static const struct dce_hwseq_shift hwseq_shift = {
673 HWSEQ_DCN42_MASK_SH_LIST(__SHIFT)};
674
675 static const struct dce_hwseq_mask hwseq_mask = {
676 HWSEQ_DCN42_MASK_SH_LIST(_MASK)};
677
678 #define vmid_regs_init(id) \
679 DCN20_VMID_REG_LIST_RI(id)
680
681 static struct dcn_vmid_registers vmid_regs[16];
682
683 static const struct dcn20_vmid_shift vmid_shifts = {
684 DCN20_VMID_MASK_SH_LIST(__SHIFT)};
685
686 static const struct dcn20_vmid_mask vmid_masks = {
687 DCN20_VMID_MASK_SH_LIST(_MASK)};
688
689 static const struct resource_caps res_cap_dcn42 = {
690 .num_timing_generator = 4,
691 .num_opp = 4,
692 .num_dpp = 4,
693 .num_video_plane = 4,
694 .num_audio = 5,
695 .num_stream_encoder = 5,
696 .num_dig_link_enc = 5,
697 .num_usb4_dpia = 6,
698 .num_hpo_frl = 1,
699 .num_hpo_dp_stream_encoder = 4,
700 .num_hpo_dp_link_encoder = 4,
701 .num_pll = 5,
702 .num_dwb = 1,
703 .num_ddc = 5,
704 .num_vmid = 16,
705 .num_mpc_3dlut = 2,
706 .num_dsc = 4,
707 .num_rmcm = 2,
708 };
709
710 static const struct dc_plane_cap plane_cap = {
711 .type = DC_PLANE_TYPE_DCN_UNIVERSAL,
712 .per_pixel_alpha = true,
713
714 .pixel_format_support = {
715 .argb8888 = true,
716 .nv12 = true,
717 .fp16 = true,
718 .p010 = true,
719 .ayuv = false,
720 },
721
722 .max_upscale_factor = {.argb8888 = 16000, .nv12 = 16000, .fp16 = 16000},
723
724 // 6:1 downscaling ratio: 1000/6 = 166.666
725 .max_downscale_factor = {.argb8888 = 167, .nv12 = 167, .fp16 = 167},
726
727 .min_width = 64,
728 .min_height = 64};
729
730 static const struct dc_debug_options debug_defaults_drv = {
731 .limit_ffe = 3,
732 .disable_dmcu = true,
733 .force_abm_enable = false,
734 .clock_trace = true,
735 .disable_pplib_clock_request = false,
736 .ignore_pg = false,
737 .disable_dpp_power_gate = false,
738 .disable_hubp_power_gate = false,
739 .disable_optc_power_gate = true,
740 .disable_dsc_power_gate = false,
741 .disable_dio_power_gate = true,
742 .disable_hpo_power_gate = true,
743 .pipe_split_policy = MPC_SPLIT_AVOID,
744 .force_single_disp_pipe_split = false,
745 .disable_dcc = DCC_ENABLE,
746 .vsr_support = true,
747 .performance_trace = false,
748 .max_downscale_src_width = 4096, /*up to 4K for APU*/
749 .disable_pplib_wm_range = false,
750 .scl_reset_length10 = true,
751 .sanity_checks = false,
752 .underflow_assert_delay_us = 0xFFFFFFFF,
753 .dwb_fi_phase = -1, // -1 = disable,
754 .dmub_command_table = true,
755 .pstate_enabled = true,
756 .enable_mem_low_power = {
757 .bits = {
758 .vga = false,
759 .i2c = true,
760 .dscl = true,
761 .cm = true,
762 .mpc = true,
763 .optc = true,
764 .vpg = true,
765 }},
766 .root_clock_optimization = {
767 .bits = {
768 .dpp = true,
769 .dsc = true,/*dscclk and dsc pg*/
770 .hdmistream = true,
771 .hdmichar = true,
772 .dpstream = true,
773 .symclk32_se = true,
774 .symclk32_le = true,
775 .symclk_fe = true,
776 .physymclk = false,
777 .dpiasymclk = true,
778 }
779 },
780 .seamless_boot_odm_combine = DML_FAIL_SOURCE_PIXEL_FORMAT,
781 .enable_z9_disable_interface = true, /* Allow support for the PMFW interface for disable Z9*/
782 .minimum_z8_residency_time = 1, /* Always allow when other conditions are met */
783 .support_eDP1_5 = true,
784 .use_max_lb = true,
785 .force_disable_subvp = false,
786 .exit_idle_opt_for_cursor_updates = true,
787 .using_dml2 = true,
788 .using_dml21 = true,
789 .enable_single_display_2to1_odm_policy = true,
790
791 // must match enable_single_display_2to1_odm_policy to support dynamic ODM transitions
792 .enable_double_buffered_dsc_pg_support = true,
793 .enable_dp_dig_pixel_rate_div_policy = 1,
794 .allow_sw_cursor_fallback = false,
795 .psp_disabled_wa = true,
796 .alloc_extra_way_for_cursor = true,
797 .min_prefetch_in_strobe_ns = 60000, // 60us
798 .disable_unbounded_requesting = false,
799 .dcc_meta_propagation_delay_us = 10,
800 .disable_timeout = true,
801 .min_disp_clk_khz = 50000,
802 .static_screen_wait_frames = 2,
803 .disable_z10 = false,
804 .disable_stutter_for_wm_program = true,
805 .min_deep_sleep_dcfclk_khz = 8000,
806 .replay_skip_crtc_disabled = true,
807 .psr_skip_crtc_disable = true,
808 .force_odm2to1_for_edp_pixclk_mhz = 0, // disable the policy for now
809 .iommu_mismatch_temp_wka = 0x7,
810 };
811
812 static const struct dc_check_config config_defaults = {
813 .enable_legacy_fast_update = false,
814 };
815
dcn42_aux_engine_create(struct dc_context * ctx,uint32_t inst)816 static struct dce_aux *dcn42_aux_engine_create(
817 struct dc_context *ctx,
818 uint32_t inst)
819 {
820 struct aux_engine_dce110 *aux_engine =
821 kzalloc_obj(struct aux_engine_dce110);
822
823 if (!aux_engine)
824 return NULL;
825
826 #undef REG_STRUCT
827 #define REG_STRUCT aux_engine_regs
828 aux_engine_regs_init(0),
829 aux_engine_regs_init(1),
830 aux_engine_regs_init(2),
831 aux_engine_regs_init(3),
832 aux_engine_regs_init(4);
833
834 dce110_aux_engine_construct(aux_engine, ctx, inst,
835 SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD,
836 &aux_engine_regs[inst],
837 &aux_mask,
838 &aux_shift,
839 ctx->dc->caps.extended_aux_timeout_support);
840
841 return &aux_engine->base;
842 }
843
844 #define i2c_inst_regs_init(id) \
845 I2C_HW_ENGINE_COMMON_REG_LIST_DCN30_RI(id)
846
847 static struct dce_i2c_registers i2c_hw_regs[5];
848
849 static const struct dce_i2c_shift i2c_shifts = {
850 I2C_COMMON_MASK_SH_LIST_DCN35(__SHIFT)
851 };
852 static const struct dce_i2c_mask i2c_masks = {
853 I2C_COMMON_MASK_SH_LIST_DCN35(_MASK)
854 };
855
856 /* ========================================================== */
857
858 /*
859 * DPIA index | Preferred Encoder | Host Router
860 * 0 | C | 0
861 * 1 | First Available | 0
862 * 2 | D | 1
863 * 3 | First Available | 1
864 * 4 | E | 2
865 * 5 | First Available | 2
866 */
867 /* ========================================================== */
868 static const enum engine_id dpia_to_preferred_enc_id_table[] = {
869 ENGINE_ID_DIGC,
870 ENGINE_ID_DIGC,
871 ENGINE_ID_DIGD,
872 ENGINE_ID_DIGD,
873 ENGINE_ID_DIGE,
874 ENGINE_ID_DIGE
875 };
876
dcn42_get_preferred_eng_id_dpia(unsigned int dpia_index)877 static enum engine_id dcn42_get_preferred_eng_id_dpia(unsigned int dpia_index)
878 {
879 return dpia_to_preferred_enc_id_table[dpia_index];
880 }
881
dcn42_i2c_hw_create(struct dc_context * ctx,uint32_t inst)882 static struct dce_i2c_hw *dcn42_i2c_hw_create(
883 struct dc_context *ctx,
884 uint32_t inst)
885 {
886 struct dce_i2c_hw *dce_i2c_hw =
887 kzalloc_obj(struct dce_i2c_hw);
888
889 if (!dce_i2c_hw)
890 return NULL;
891
892 #undef REG_STRUCT
893 #define REG_STRUCT i2c_hw_regs
894 i2c_inst_regs_init(1),
895 i2c_inst_regs_init(2),
896 i2c_inst_regs_init(3),
897 i2c_inst_regs_init(4),
898 i2c_inst_regs_init(5);
899 dcn2_i2c_hw_construct(dce_i2c_hw, ctx, inst,
900 &i2c_hw_regs[inst], &i2c_shifts, &i2c_masks);
901
902 return dce_i2c_hw;
903 }
904
dcn42_clock_source_create(struct dc_context * ctx,struct dc_bios * bios,enum clock_source_id id,const struct dce110_clk_src_regs * regs,bool dp_clk_src)905 static struct clock_source *dcn42_clock_source_create(
906 struct dc_context *ctx,
907 struct dc_bios *bios,
908 enum clock_source_id id,
909 const struct dce110_clk_src_regs *regs,
910 bool dp_clk_src)
911 {
912 struct dce110_clk_src *clk_src =
913 kzalloc_obj(struct dce110_clk_src);
914
915 if (!clk_src)
916 return NULL;
917
918 if (dcn401_clk_src_construct(clk_src, ctx, bios, id, regs, &cs_shift, &cs_mask)) {
919 clk_src->base.dp_clk_src = dp_clk_src;
920 return &clk_src->base;
921 }
922
923 kfree(clk_src);
924 BREAK_TO_DEBUGGER();
925 return NULL;
926 }
927
dcn42_hubbub_create(struct dc_context * ctx)928 static struct hubbub *dcn42_hubbub_create(struct dc_context *ctx)
929 {
930 int i;
931
932 struct dcn20_hubbub *hubbub3 = kzalloc_obj(struct dcn20_hubbub);
933
934 if (!hubbub3)
935 return NULL;
936
937 #undef REG_STRUCT
938 #define REG_STRUCT hubbub_reg
939 hubbub_reg_init();
940
941 #undef REG_STRUCT
942 #define REG_STRUCT vmid_regs
943 vmid_regs_init(0),
944 vmid_regs_init(1),
945 vmid_regs_init(2),
946 vmid_regs_init(3),
947 vmid_regs_init(4),
948 vmid_regs_init(5),
949 vmid_regs_init(6),
950 vmid_regs_init(7),
951 vmid_regs_init(8),
952 vmid_regs_init(9),
953 vmid_regs_init(10),
954 vmid_regs_init(11),
955 vmid_regs_init(12),
956 vmid_regs_init(13),
957 vmid_regs_init(14),
958 vmid_regs_init(15);
959
960 hubbub42_construct(hubbub3, ctx,
961 &hubbub_reg,
962 &hubbub_shift,
963 &hubbub_mask,
964 DCN42_DEFAULT_DET_SIZE,
965 8,
966 DCN42_CRB_SIZE_KB);
967 for (i = 0; i < res_cap_dcn42.num_vmid; i++) {
968 struct dcn20_vmid *vmid = &hubbub3->vmid[i];
969
970 vmid->ctx = ctx;
971
972 vmid->regs = &vmid_regs[i];
973 vmid->shifts = &vmid_shifts;
974 vmid->masks = &vmid_masks;
975 }
976
977 return &hubbub3->base;
978 }
979
dcn42_hubp_create(struct dc_context * ctx,uint32_t inst)980 static struct hubp *dcn42_hubp_create(
981 struct dc_context *ctx,
982 uint32_t inst)
983 {
984 struct dcn20_hubp *hubp2 =
985 kzalloc_obj(struct dcn20_hubp);
986
987 if (!hubp2)
988 return NULL;
989
990 #undef REG_STRUCT
991 #define REG_STRUCT hubp_regs
992 hubp_regs_init(0),
993 hubp_regs_init(1),
994 hubp_regs_init(2),
995 hubp_regs_init(3);
996
997 if (hubp42_construct(hubp2, ctx, inst,
998 &hubp_regs[inst], &hubp_shift, &hubp_mask))
999 return &hubp2->base;
1000
1001 BREAK_TO_DEBUGGER();
1002 kfree(hubp2);
1003 return NULL;
1004 }
1005 static const struct dc_panel_config dcn42_panel_config_defaults = {
1006 .psr = {
1007 .disable_psr = false,
1008 .disallow_psrsu = false,
1009 .disallow_replay = false,
1010 },
1011 .ilr = {
1012 .optimize_edp_link_rate = true,
1013 },
1014 };
1015
dcn42_dpp_destroy(struct dpp ** dpp)1016 static void dcn42_dpp_destroy(struct dpp **dpp)
1017 {
1018 kfree(TO_DCN42_DPP(*dpp));
1019 *dpp = NULL;
1020 }
1021
dcn42_dpp_create(struct dc_context * ctx,uint32_t inst)1022 static struct dpp *dcn42_dpp_create(
1023 struct dc_context *ctx,
1024 uint32_t inst)
1025 {
1026 struct dcn42_dpp *dpp42 =
1027 kzalloc_obj(struct dcn42_dpp);
1028
1029 if (!dpp42)
1030 return NULL;
1031
1032 #undef REG_STRUCT
1033 #define REG_STRUCT dpp_regs
1034 dpp_regs_init(0),
1035 dpp_regs_init(1),
1036 dpp_regs_init(2),
1037 dpp_regs_init(3);
1038
1039 if (dpp42_construct(dpp42, ctx, inst,
1040 &dpp_regs[inst], &tf_shift, &tf_mask))
1041 return &dpp42->base;
1042
1043 BREAK_TO_DEBUGGER();
1044 kfree(dpp42);
1045 return NULL;
1046 }
1047
dcn42_mpc_create(struct dc_context * ctx,int num_mpcc,int num_rmu)1048 static struct mpc *dcn42_mpc_create(
1049 struct dc_context *ctx,
1050 int num_mpcc,
1051 int num_rmu)
1052 {
1053 struct dcn42_mpc *mpc401 = kzalloc_obj(struct dcn42_mpc);
1054
1055 if (!mpc401)
1056 return NULL;
1057
1058 #undef REG_STRUCT
1059 #define REG_STRUCT mpc_regs
1060 dcn_mpc_regs_init();
1061
1062 dcn42_mpc_construct(mpc401, ctx,
1063 &mpc_regs,
1064 &mpc_shift,
1065 &mpc_mask,
1066 num_mpcc,
1067 num_rmu);
1068
1069 return &mpc401->base;
1070 }
1071
dcn42_opp_create(struct dc_context * ctx,uint32_t inst)1072 static struct output_pixel_processor *dcn42_opp_create(
1073 struct dc_context *ctx, uint32_t inst)
1074 {
1075 struct dcn20_opp *opp4 =
1076 kzalloc_obj(struct dcn20_opp);
1077
1078 if (!opp4) {
1079 BREAK_TO_DEBUGGER();
1080 return NULL;
1081 }
1082
1083 #undef REG_STRUCT
1084 #define REG_STRUCT opp_regs
1085 opp_regs_init(0),
1086 opp_regs_init(1),
1087 opp_regs_init(2),
1088 opp_regs_init(3);
1089 dcn20_opp_construct(opp4, ctx, inst,
1090 &opp_regs[inst], &opp_shift, &opp_mask);
1091 return &opp4->base;
1092 }
1093
dcn42_timing_generator_create(struct dc_context * ctx,uint32_t instance)1094 static struct timing_generator *dcn42_timing_generator_create(
1095 struct dc_context *ctx,
1096 uint32_t instance)
1097 {
1098 struct optc *tgn10 =
1099 kzalloc_obj(struct optc);
1100
1101 if (!tgn10)
1102 return NULL;
1103 #undef REG_STRUCT
1104 #define REG_STRUCT optc_regs
1105 optc_regs_init(0),
1106 optc_regs_init(1),
1107 optc_regs_init(2),
1108 optc_regs_init(3);
1109 tgn10->base.inst = instance;
1110 tgn10->base.ctx = ctx;
1111
1112 tgn10->tg_regs = &optc_regs[instance];
1113 tgn10->tg_shift = &optc_shift;
1114 tgn10->tg_mask = &optc_mask;
1115
1116 dcn42_timing_generator_init(tgn10);
1117
1118 return &tgn10->base;
1119 }
1120
1121 static const struct encoder_feature_support link_enc_feature = {
1122 .max_hdmi_deep_color = COLOR_DEPTH_121212,
1123 .max_hdmi_pixel_clock = 600000,
1124 .hdmi_ycbcr420_supported = true,
1125 .dp_ycbcr420_supported = true,
1126 .fec_supported = true,
1127 .flags.bits.IS_HBR2_CAPABLE = true,
1128 .flags.bits.IS_HBR3_CAPABLE = true,
1129 .flags.bits.IS_TPS3_CAPABLE = true,
1130 .flags.bits.IS_TPS4_CAPABLE = true};
1131
dcn42_link_encoder_create(struct dc_context * ctx,const struct encoder_init_data * enc_init_data)1132 static struct link_encoder *dcn42_link_encoder_create(
1133 struct dc_context *ctx,
1134 const struct encoder_init_data *enc_init_data)
1135 {
1136 struct dcn20_link_encoder *enc20 =
1137 kzalloc_obj(struct dcn20_link_encoder);
1138
1139 if (!enc20 || enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs))
1140 return NULL;
1141
1142 #undef REG_STRUCT
1143 #define REG_STRUCT link_enc_aux_regs
1144 aux_regs_init(0),
1145 aux_regs_init(1),
1146 aux_regs_init(2),
1147 aux_regs_init(3),
1148 aux_regs_init(4);
1149 #undef REG_STRUCT
1150 #define REG_STRUCT link_enc_hpd_regs
1151 hpd_regs_init(0),
1152 hpd_regs_init(1),
1153 hpd_regs_init(2),
1154 hpd_regs_init(3),
1155 hpd_regs_init(4);
1156 #undef REG_STRUCT
1157 #define REG_STRUCT link_enc_regs
1158 link_regs_init(0, A),
1159 link_regs_init(1, B),
1160 link_regs_init(2, C),
1161 link_regs_init(3, D),
1162 link_regs_init(4, E);
1163
1164 dcn42_link_encoder_construct(enc20,
1165 enc_init_data,
1166 &link_enc_feature,
1167 &link_enc_regs[enc_init_data->transmitter],
1168 &link_enc_aux_regs[enc_init_data->channel - 1],
1169 &link_enc_hpd_regs[enc_init_data->hpd_source],
1170 &le_shift,
1171 &le_mask);
1172 return &enc20->enc10.base;
1173 }
1174
read_dce_straps(struct dc_context * ctx,struct resource_straps * straps)1175 static void read_dce_straps(
1176 struct dc_context *ctx,
1177 struct resource_straps *straps)
1178 {
1179 generic_reg_get(ctx, regDC_PINSTRAPS + BASE(regDC_PINSTRAPS_BASE_IDX),
1180 FN(DC_PINSTRAPS, DC_PINSTRAPS_AUDIO), &straps->dc_pinstraps_audio);
1181 }
1182
dcn42_create_audio(struct dc_context * ctx,unsigned int inst)1183 static struct audio *dcn42_create_audio(
1184 struct dc_context *ctx, unsigned int inst)
1185 {
1186
1187 #undef REG_STRUCT
1188 #define REG_STRUCT audio_regs
1189 audio_regs_init(0),
1190 audio_regs_init(1),
1191 audio_regs_init(2),
1192 audio_regs_init(3),
1193 audio_regs_init(4);
1194
1195 return dce_audio_create(ctx, inst,
1196 &audio_regs[inst], &audio_shift, &audio_mask);
1197 }
1198
dcn42_vpg_create(struct dc_context * ctx,uint32_t inst)1199 static struct vpg *dcn42_vpg_create(
1200 struct dc_context *ctx,
1201 uint32_t inst)
1202 {
1203 struct dcn31_vpg *vpg4 = kzalloc_obj(struct dcn31_vpg);
1204
1205 if (!vpg4)
1206 return NULL;
1207
1208 #undef REG_STRUCT
1209 #define REG_STRUCT vpg_regs
1210 vpg_regs_init(0),
1211 vpg_regs_init(1),
1212 vpg_regs_init(2),
1213 vpg_regs_init(3),
1214 vpg_regs_init(4),
1215 vpg_regs_init(5),
1216 vpg_regs_init(6),
1217 vpg_regs_init(7),
1218 vpg_regs_init(8),
1219 vpg_regs_init(9);
1220 vpg31_construct(vpg4, ctx, inst,
1221 &vpg_regs[inst],
1222 &vpg_shift,
1223 &vpg_mask);
1224
1225 return &vpg4->base;
1226 }
1227
dcn42_apg_create(struct dc_context * ctx,uint32_t inst)1228 static struct apg *dcn42_apg_create(
1229 struct dc_context *ctx,
1230 uint32_t inst)
1231 {
1232 struct dcn31_apg *apg31 = kzalloc_obj(struct dcn31_apg);
1233
1234 if (!apg31)
1235 return NULL;
1236
1237 #undef REG_STRUCT
1238 #define REG_STRUCT apg_regs
1239 apg_regs_init(0),
1240 apg_regs_init(1),
1241 apg_regs_init(2),
1242 apg_regs_init(3),
1243 apg_regs_init(4),
1244 apg_regs_init(5),
1245 apg_regs_init(6),
1246 apg_regs_init(7),
1247 apg_regs_init(8),
1248 apg_regs_init(9);
1249
1250 apg31_construct(apg31, ctx, inst,
1251 &apg_regs[inst],
1252 &apg_shift,
1253 &apg_mask);
1254
1255 return &apg31->base;
1256 }
1257
dcn42_stream_encoder_create(enum engine_id eng_id,struct dc_context * ctx)1258 static struct stream_encoder *dcn42_stream_encoder_create(
1259 enum engine_id eng_id,
1260 struct dc_context *ctx)
1261 {
1262 struct dcn10_stream_encoder *enc1;
1263 struct vpg *vpg;
1264 struct apg *apg;
1265
1266 uint32_t vpg_inst;
1267 uint32_t apg_inst;
1268
1269 /* Mapping of VPG, DME register blocks to DIO block instance */
1270 if (eng_id <= ENGINE_ID_DIGE) {
1271 vpg_inst = eng_id;
1272 apg_inst = eng_id;
1273 } else
1274 return NULL;
1275
1276 enc1 = kzalloc_obj(struct dcn10_stream_encoder);
1277 vpg = dcn42_vpg_create(ctx, vpg_inst);
1278 apg = dcn42_apg_create(ctx, apg_inst);
1279
1280 if (!enc1 || !vpg || !apg) {
1281 kfree(enc1);
1282 kfree(vpg);
1283 kfree(apg);
1284 return NULL;
1285 }
1286 #undef REG_STRUCT
1287 #define REG_STRUCT stream_enc_regs
1288 stream_enc_regs_init(0),
1289 stream_enc_regs_init(1),
1290 stream_enc_regs_init(2),
1291 stream_enc_regs_init(3),
1292 stream_enc_regs_init(4);
1293
1294 dcn42_dio_stream_encoder_construct(enc1, ctx, ctx->dc_bios,
1295 eng_id, vpg, apg,
1296 &stream_enc_regs[eng_id],
1297 &se_shift, &se_mask);
1298 return &enc1->base;
1299 }
1300
dcn42_hpo_frl_stream_encoder_create(enum engine_id eng_id,struct dc_context * ctx)1301 static struct hpo_frl_stream_encoder *dcn42_hpo_frl_stream_encoder_create(
1302 enum engine_id eng_id,
1303 struct dc_context *ctx)
1304 {
1305 struct dcn42_hpo_frl_stream_encoder *hpo_enc42;
1306 struct vpg *vpg;
1307 struct apg *apg;
1308
1309 uint32_t vpg_inst;
1310 uint32_t apg_inst;
1311
1312
1313 #undef REG_STRUCT
1314 #define REG_STRUCT hpo_frl_stream_enc_regs
1315 hpo_frl_stream_encoder_reg_list(0),
1316 hpo_frl_stream_encoder_dme_reg_list(6);
1317
1318 /* Mapping of VPG, DME register blocks to HPO block instance */
1319 if (eng_id == ENGINE_ID_HPO_0) {
1320 vpg_inst = 9; /*hw hard wired to inst 9, ref to dcn header file*/
1321 apg_inst = 9;
1322 } else
1323 return NULL;
1324
1325 /* allocate HPO stream encoder and create VPG sub-block */
1326 hpo_enc42 = kzalloc_obj(struct dcn42_hpo_frl_stream_encoder);
1327 vpg = dcn42_vpg_create(ctx, vpg_inst);
1328 apg = dcn42_apg_create(ctx, apg_inst);
1329
1330 if (!hpo_enc42 || !vpg || !apg) {
1331 kfree(hpo_enc42);
1332 kfree(vpg);
1333 kfree(apg);
1334 return NULL;
1335 }
1336
1337 dcn42_hpo_frl_stream_encoder_construct(hpo_enc42, ctx, ctx->dc_bios,
1338 eng_id, vpg, apg,
1339 &hpo_frl_stream_enc_regs[eng_id - ENGINE_ID_HPO_0],
1340 &hpo_se_shift, &hpo_se_mask);
1341
1342 return &hpo_enc42->base;
1343 }
1344
dcn42_hpo_frl_link_encoder_create(enum engine_id eng_id,struct dc_context * ctx)1345 static struct hpo_frl_link_encoder *dcn42_hpo_frl_link_encoder_create(
1346 enum engine_id eng_id,
1347 struct dc_context *ctx)
1348 {
1349 struct dcn30_hpo_frl_link_encoder *hpo_link_enc;
1350
1351 ASSERT((eng_id == ENGINE_ID_HPO_0) || (eng_id == ENGINE_ID_HPO_1));
1352
1353 #undef REG_STRUCT
1354 #define REG_STRUCT hpo_frl_link_enc_regs
1355 hpo_frl_link_encoder_reg_list(0);
1356
1357 /* allocate HPO link encoder */
1358 hpo_link_enc = kzalloc_obj(struct dcn30_hpo_frl_link_encoder);
1359 if (!hpo_link_enc)
1360 return NULL; /* out of memory */
1361
1362 hpo_frl_link_encoder3_construct(hpo_link_enc, ctx, eng_id - ENGINE_ID_HPO_0,
1363 &hpo_frl_link_enc_regs[eng_id - ENGINE_ID_HPO_0],
1364 &hpo_le_shift, &hpo_le_mask);
1365
1366 return &hpo_link_enc->base;
1367 }
1368
dcn42_hpo_dp_stream_encoder_create(enum engine_id eng_id,struct dc_context * ctx)1369 static struct hpo_dp_stream_encoder *dcn42_hpo_dp_stream_encoder_create(
1370 enum engine_id eng_id,
1371 struct dc_context *ctx)
1372 {
1373 struct dcn31_hpo_dp_stream_encoder *hpo_dp_enc31;
1374 struct vpg *vpg;
1375 struct apg *apg;
1376 uint32_t hpo_dp_inst;
1377 uint32_t vpg_inst;
1378 uint32_t apg_inst;
1379
1380 ASSERT((eng_id >= ENGINE_ID_HPO_DP_0) && (eng_id <= ENGINE_ID_HPO_DP_3));
1381 hpo_dp_inst = eng_id - ENGINE_ID_HPO_DP_0;
1382
1383 /* Mapping of VPG register blocks to HPO DP block instance:
1384 * VPG[5] -> HPO_DP[0]
1385 * VPG[6] -> HPO_DP[1]
1386 * VPG[7] -> HPO_DP[2]
1387 * VPG[8] -> HPO_DP[3]
1388 */
1389 vpg_inst = hpo_dp_inst + 5;
1390
1391 /* Mapping of APG register blocks to HPO DP block instance:
1392 * APG[6] -> HPO_DP[0]
1393 * APG[7] -> HPO_DP[1]
1394 * APG[8] -> HPO_DP[2]
1395 * APG[9] -> HPO_DP[3]
1396 */
1397 apg_inst = hpo_dp_inst + 5;
1398
1399 /* allocate HPO stream encoder and create VPG sub-block */
1400 hpo_dp_enc31 = kzalloc_obj(struct dcn31_hpo_dp_stream_encoder);
1401 vpg = dcn42_vpg_create(ctx, vpg_inst);
1402 apg = dcn42_apg_create(ctx, apg_inst);
1403
1404 if (!hpo_dp_enc31 || !vpg || !apg) {
1405 kfree(hpo_dp_enc31);
1406 kfree(vpg);
1407 kfree(apg);
1408 return NULL;
1409 }
1410
1411 #undef REG_STRUCT
1412 #define REG_STRUCT hpo_dp_stream_enc_regs
1413 hpo_dp_stream_encoder_reg_init(0),
1414 hpo_dp_stream_encoder_reg_init(1),
1415 hpo_dp_stream_encoder_reg_init(2),
1416 hpo_dp_stream_encoder_reg_init(3);
1417
1418 dcn31_hpo_dp_stream_encoder_construct(hpo_dp_enc31, ctx, ctx->dc_bios,
1419 hpo_dp_inst, eng_id, vpg, apg,
1420 &hpo_dp_stream_enc_regs[hpo_dp_inst],
1421 &hpo_dp_se_shift, &hpo_dp_se_mask);
1422
1423 return &hpo_dp_enc31->base;
1424 }
1425
dcn42_hpo_dp_link_encoder_create(uint8_t inst,struct dc_context * ctx)1426 static struct hpo_dp_link_encoder *dcn42_hpo_dp_link_encoder_create(
1427 uint8_t inst,
1428 struct dc_context *ctx)
1429 {
1430 struct dcn31_hpo_dp_link_encoder *hpo_dp_enc31;
1431
1432 /* allocate HPO link encoder */
1433 hpo_dp_enc31 = kzalloc_obj(struct dcn31_hpo_dp_link_encoder);
1434 if (!hpo_dp_enc31)
1435 return NULL; /* out of memory */
1436
1437 #undef REG_STRUCT
1438 #define REG_STRUCT hpo_dp_link_enc_regs
1439 hpo_dp_link_encoder_reg_init(0),
1440 hpo_dp_link_encoder_reg_init(1),
1441 hpo_dp_link_encoder_reg_init(2),
1442 hpo_dp_link_encoder_reg_init(3);
1443
1444 hpo_dp_link_encoder42_construct(hpo_dp_enc31, ctx, inst,
1445 &hpo_dp_link_enc_regs[inst],
1446 &hpo_dp_le_shift, &hpo_dp_le_mask);
1447
1448 return &hpo_dp_enc31->base;
1449 }
1450
dcn42_hwseq_create(struct dc_context * ctx)1451 static struct dce_hwseq *dcn42_hwseq_create(
1452 struct dc_context *ctx)
1453 {
1454 struct dce_hwseq *hws = kzalloc_obj(struct dce_hwseq);
1455
1456 #undef REG_STRUCT
1457 #define REG_STRUCT hwseq_reg
1458 hwseq_reg_init();
1459
1460 if (hws) {
1461 hws->ctx = ctx;
1462 hws->regs = &hwseq_reg;
1463 hws->shifts = &hwseq_shift;
1464 hws->masks = &hwseq_mask;
1465 }
1466
1467 return hws;
1468 }
1469
1470 static const struct resource_create_funcs res_create_funcs = {
1471 .read_dce_straps = read_dce_straps,
1472 .create_audio = dcn42_create_audio,
1473 .create_stream_encoder = dcn42_stream_encoder_create,
1474 .create_hpo_frl_stream_encoder = dcn42_hpo_frl_stream_encoder_create,
1475 .create_hpo_dp_stream_encoder = dcn42_hpo_dp_stream_encoder_create,
1476 .create_hpo_dp_link_encoder = dcn42_hpo_dp_link_encoder_create,
1477 .create_hwseq = dcn42_hwseq_create,
1478 };
1479
dcn42_dsc_destroy(struct display_stream_compressor ** dsc)1480 static void dcn42_dsc_destroy(struct display_stream_compressor **dsc)
1481 {
1482 kfree(container_of(*dsc, struct dcn401_dsc, base));
1483 *dsc = NULL;
1484 }
1485
dcn42_resource_destruct(struct dcn42_resource_pool * pool)1486 static void dcn42_resource_destruct(struct dcn42_resource_pool *pool)
1487 {
1488 unsigned int i;
1489
1490 for (i = 0; i < pool->base.stream_enc_count; i++) {
1491 if (pool->base.stream_enc[i] != NULL) {
1492 if (pool->base.stream_enc[i]->vpg != NULL) {
1493 kfree(DCN31_VPG_FROM_VPG(pool->base.stream_enc[i]->vpg));
1494 pool->base.stream_enc[i]->vpg = NULL;
1495 }
1496 if (pool->base.stream_enc[i]->apg != NULL) {
1497 kfree(DCN31_APG_FROM_APG(pool->base.stream_enc[i]->apg));
1498 pool->base.stream_enc[i]->apg = NULL;
1499 }
1500 kfree(DCN10STRENC_FROM_STRENC(pool->base.stream_enc[i]));
1501 pool->base.stream_enc[i] = NULL;
1502 }
1503 }
1504
1505 for (i = 0; i < pool->base.hpo_frl_stream_enc_count; i++) {
1506 if (pool->base.hpo_frl_stream_enc[i] != NULL) {
1507 if (pool->base.hpo_frl_stream_enc[i]->vpg != NULL) {
1508 kfree(DCN31_VPG_FROM_VPG(pool->base.hpo_frl_stream_enc[i]->vpg));
1509 pool->base.hpo_frl_stream_enc[i]->vpg = NULL;
1510 }
1511 if (pool->base.hpo_frl_stream_enc[i]->apg != NULL) {
1512 kfree(DCN31_APG_FROM_APG(pool->base.hpo_frl_stream_enc[i]->apg));
1513 pool->base.hpo_frl_stream_enc[i]->apg = NULL;
1514 }
1515 kfree(DCN401_HPO_FRL_STRENC_FROM_HPO_FRL_STRENC(pool->base.hpo_frl_stream_enc[i]));
1516 pool->base.hpo_frl_stream_enc[i] = NULL;
1517 }
1518 }
1519
1520 for (i = 0; i < pool->base.hpo_dp_stream_enc_count; i++) {
1521 if (pool->base.hpo_dp_stream_enc[i] != NULL) {
1522 if (pool->base.hpo_dp_stream_enc[i]->vpg != NULL) {
1523 kfree(DCN31_VPG_FROM_VPG(pool->base.hpo_dp_stream_enc[i]->vpg));
1524 pool->base.hpo_dp_stream_enc[i]->vpg = NULL;
1525 }
1526 if (pool->base.hpo_dp_stream_enc[i]->apg != NULL) {
1527 kfree(DCN31_APG_FROM_APG(pool->base.hpo_dp_stream_enc[i]->apg));
1528 pool->base.hpo_dp_stream_enc[i]->apg = NULL;
1529 }
1530 kfree(DCN3_1_HPO_DP_STREAM_ENC_FROM_HPO_STREAM_ENC(pool->base.hpo_dp_stream_enc[i]));
1531 pool->base.hpo_dp_stream_enc[i] = NULL;
1532 }
1533 }
1534
1535 for (i = 0; i < pool->base.hpo_dp_link_enc_count; i++) {
1536 if (pool->base.hpo_dp_link_enc[i] != NULL) {
1537 kfree(DCN3_1_HPO_DP_LINK_ENC_FROM_HPO_LINK_ENC(pool->base.hpo_dp_link_enc[i]));
1538 pool->base.hpo_dp_link_enc[i] = NULL;
1539 }
1540 }
1541
1542 for (i = 0; i < (unsigned int)pool->base.res_cap->num_dsc; i++) {
1543 if (pool->base.dscs[i] != NULL)
1544 dcn42_dsc_destroy(&pool->base.dscs[i]);
1545 }
1546
1547 if (pool->base.mpc != NULL) {
1548 kfree(TO_DCN20_MPC(pool->base.mpc));
1549 pool->base.mpc = NULL;
1550 }
1551 if (pool->base.hubbub != NULL) {
1552 kfree(TO_DCN20_HUBBUB(pool->base.hubbub));
1553 pool->base.hubbub = NULL;
1554 }
1555 for (i = 0; i < pool->base.pipe_count; i++) {
1556 if (pool->base.dpps[i] != NULL)
1557 dcn42_dpp_destroy(&pool->base.dpps[i]);
1558
1559 if (pool->base.ipps[i] != NULL)
1560 pool->base.ipps[i]->funcs->ipp_destroy(&pool->base.ipps[i]);
1561
1562 if (pool->base.hubps[i] != NULL) {
1563 kfree(TO_DCN20_HUBP(pool->base.hubps[i]));
1564 pool->base.hubps[i] = NULL;
1565 }
1566
1567 if (pool->base.irqs != NULL)
1568 dal_irq_service_destroy(&pool->base.irqs);
1569 }
1570
1571 for (i = 0; i < (unsigned int)pool->base.res_cap->num_ddc; i++) {
1572 if (pool->base.engines[i] != NULL)
1573 dce110_engine_destroy(&pool->base.engines[i]);
1574 if (pool->base.hw_i2cs[i] != NULL) {
1575 kfree(pool->base.hw_i2cs[i]);
1576 pool->base.hw_i2cs[i] = NULL;
1577 }
1578 if (pool->base.sw_i2cs[i] != NULL) {
1579 kfree(pool->base.sw_i2cs[i]);
1580 pool->base.sw_i2cs[i] = NULL;
1581 }
1582 }
1583
1584 for (i = 0; i < (unsigned int)pool->base.res_cap->num_opp; i++) {
1585 if (pool->base.opps[i] != NULL)
1586 pool->base.opps[i]->funcs->opp_destroy(&pool->base.opps[i]);
1587 }
1588
1589 for (i = 0; i < (unsigned int)pool->base.res_cap->num_timing_generator; i++) {
1590 if (pool->base.timing_generators[i] != NULL) {
1591 kfree(DCN10TG_FROM_TG(pool->base.timing_generators[i]));
1592 pool->base.timing_generators[i] = NULL;
1593 }
1594 }
1595
1596 for (i = 0; i < (unsigned int)pool->base.res_cap->num_dwb; i++) {
1597 if (pool->base.dwbc[i] != NULL) {
1598 kfree(TO_DCN30_DWBC(pool->base.dwbc[i]));
1599 pool->base.dwbc[i] = NULL;
1600 }
1601 if (pool->base.mcif_wb[i] != NULL) {
1602 kfree(TO_DCN30_MMHUBBUB(pool->base.mcif_wb[i]));
1603 pool->base.mcif_wb[i] = NULL;
1604 }
1605 }
1606
1607 for (i = 0; i < pool->base.audio_count; i++) {
1608 if (pool->base.audios[i])
1609 dce_aud_destroy(&pool->base.audios[i]);
1610 }
1611
1612 for (i = 0; i < pool->base.clk_src_count; i++) {
1613 if (pool->base.clock_sources[i] != NULL) {
1614 dcn20_clock_source_destroy(&pool->base.clock_sources[i]);
1615 pool->base.clock_sources[i] = NULL;
1616 }
1617 }
1618
1619 for (i = 0; i < (unsigned int)pool->base.res_cap->num_mpc_3dlut; i++) {
1620 if (pool->base.mpc_lut[i] != NULL) {
1621 dc_3dlut_func_release(pool->base.mpc_lut[i]);
1622 pool->base.mpc_lut[i] = NULL;
1623 }
1624 if (pool->base.mpc_shaper[i] != NULL) {
1625 dc_transfer_func_release(pool->base.mpc_shaper[i]);
1626 pool->base.mpc_shaper[i] = NULL;
1627 }
1628 }
1629
1630 if (pool->base.dp_clock_source != NULL) {
1631 dcn20_clock_source_destroy(&pool->base.dp_clock_source);
1632 pool->base.dp_clock_source = NULL;
1633 }
1634
1635 for (i = 0; i < (unsigned int)pool->base.res_cap->num_timing_generator; i++) {
1636 if (pool->base.multiple_abms[i] != NULL)
1637 dce_abm_destroy(&pool->base.multiple_abms[i]);
1638 }
1639
1640 if (pool->base.psr != NULL)
1641 dmub_psr_destroy(&pool->base.psr);
1642
1643 if (pool->base.pg_cntl != NULL)
1644 dcn_pg_cntl_destroy(&pool->base.pg_cntl);
1645
1646 if (pool->base.replay != NULL)
1647 dmub_replay_destroy(&pool->base.replay);
1648
1649 if (pool->base.dccg != NULL)
1650 dcn_dccg_destroy(&pool->base.dccg);
1651
1652 if (pool->base.oem_device != NULL) {
1653 struct dc *dc = pool->base.oem_device->ctx->dc;
1654
1655 dc->link_srv->destroy_ddc_service(&pool->base.oem_device);
1656 }
1657 }
1658
dcn42_build_pipe_pix_clk_params(struct pipe_ctx * pipe_ctx)1659 static void dcn42_build_pipe_pix_clk_params(struct pipe_ctx *pipe_ctx)
1660 {
1661 const struct dc_stream_state *stream = pipe_ctx->stream;
1662 struct dc_link *link = stream->link;
1663 struct link_encoder *link_enc = pipe_ctx->link_res.dio_link_enc;
1664 struct pixel_clk_params *pixel_clk_params = &pipe_ctx->stream_res.pix_clk_params;
1665
1666 pixel_clk_params->requested_pix_clk_100hz = stream->timing.pix_clk_100hz;
1667
1668 if (pipe_ctx->dsc_padding_params.dsc_hactive_padding != 0)
1669 pixel_clk_params->requested_pix_clk_100hz = pipe_ctx->dsc_padding_params.dsc_pix_clk_100hz;
1670
1671 if (!pipe_ctx->stream->ctx->dc->config.unify_link_enc_assignment)
1672 link_enc = link_enc_cfg_get_link_enc(link);
1673 if (link_enc)
1674 pixel_clk_params->encoder_object_id = link_enc->id;
1675
1676 pixel_clk_params->signal_type = pipe_ctx->stream->signal;
1677 pixel_clk_params->controller_id = pipe_ctx->stream_res.tg->inst + 1;
1678 /* TODO: un-hardcode*/
1679
1680 /* TODO - DP2.0 HW: calculate requested_sym_clk for UHBR rates */
1681
1682 pixel_clk_params->requested_sym_clk = LINK_RATE_LOW *
1683 LINK_RATE_REF_FREQ_IN_KHZ;
1684 pixel_clk_params->flags.ENABLE_SS = 0;
1685 pixel_clk_params->color_depth =
1686 stream->timing.display_color_depth;
1687 pixel_clk_params->flags.DISPLAY_BLANKED = 1;
1688 pixel_clk_params->pixel_encoding = stream->timing.pixel_encoding;
1689
1690 if (stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR422)
1691 pixel_clk_params->color_depth = COLOR_DEPTH_888;
1692
1693 if (stream->timing.timing_3d_format == TIMING_3D_FORMAT_HW_FRAME_PACKING)
1694 pixel_clk_params->requested_pix_clk_100hz *= 2;
1695 if (dc_is_tmds_signal(stream->signal) &&
1696 stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR420)
1697 pixel_clk_params->requested_pix_clk_100hz /= 2;
1698
1699 pipe_ctx->clock_source->funcs->get_pix_clk_dividers(
1700 pipe_ctx->clock_source,
1701 &pipe_ctx->stream_res.pix_clk_params,
1702 &pipe_ctx->pll_settings);
1703
1704 pixel_clk_params->dio_se_pix_per_cycle = 1;
1705 if (dc_is_tmds_signal(stream->signal) &&
1706 stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR420) {
1707 pixel_clk_params->dio_se_pix_per_cycle = 2;
1708 } else if (dc_is_dp_signal(stream->signal)) {
1709 /* round up to nearest power of 2, or max at 8 pixels per cycle */
1710 if (pixel_clk_params->requested_pix_clk_100hz > (uint32_t)(4 * stream->ctx->dc->clk_mgr->dprefclk_khz * 10)) {
1711 pixel_clk_params->dio_se_pix_per_cycle = 8;
1712 } else if (pixel_clk_params->requested_pix_clk_100hz > (uint32_t)(2 * stream->ctx->dc->clk_mgr->dprefclk_khz * 10)) {
1713 pixel_clk_params->dio_se_pix_per_cycle = 4;
1714 } else if (pixel_clk_params->requested_pix_clk_100hz > (uint32_t)(stream->ctx->dc->clk_mgr->dprefclk_khz * 10)) {
1715 pixel_clk_params->dio_se_pix_per_cycle = 2;
1716 } else {
1717 pixel_clk_params->dio_se_pix_per_cycle = 1;
1718 }
1719 }
1720 }
1721
dcn42_dwbc_create(struct dc_context * ctx,struct resource_pool * pool)1722 static bool dcn42_dwbc_create(struct dc_context *ctx, struct resource_pool *pool)
1723 {
1724 unsigned int i;
1725 uint32_t dwb_count = pool->res_cap->num_dwb;
1726
1727 for (i = 0; i < dwb_count; i++) {
1728 struct dcn30_dwbc *dwbc42 = kzalloc_obj(struct dcn30_dwbc);
1729
1730 if (!dwbc42) {
1731 dm_error("DC: failed to create dwbc42!\n");
1732 return false;
1733 }
1734
1735 #undef REG_STRUCT
1736 #define REG_STRUCT dwbc401_regs
1737 dwbc_regs_dcn401_init(0);
1738
1739 dcn30_dwbc_construct(dwbc42, ctx,
1740 &dwbc401_regs[i],
1741 &dwbc401_shift,
1742 &dwbc401_mask,
1743 i);
1744
1745 pool->dwbc[i] = &dwbc42->base;
1746 }
1747 return true;
1748 }
1749
dcn42_mmhubbub_init(struct dcn30_mmhubbub * mcif_wb30,struct dc_context * ctx)1750 static void dcn42_mmhubbub_init(struct dcn30_mmhubbub *mcif_wb30,
1751 struct dc_context *ctx)
1752 {
1753 dcn42_mmhubbub_set_fgcg(
1754 mcif_wb30,
1755 ctx->dc->debug.enable_fine_grain_clock_gating.bits.mmhubbub);
1756 }
1757
dcn42_mmhubbub_create(struct dc_context * ctx,struct resource_pool * pool)1758 static bool dcn42_mmhubbub_create(struct dc_context *ctx, struct resource_pool *pool)
1759 {
1760 unsigned int i;
1761 uint32_t pipe_count = pool->res_cap->num_dwb;
1762
1763 for (i = 0; i < pipe_count; i++) {
1764 struct dcn30_mmhubbub *mcif_wb30 = kzalloc_obj(struct dcn30_mmhubbub);
1765
1766 if (!mcif_wb30) {
1767 dm_error("DC: failed to create mcif_wb30!\n");
1768 return false;
1769 }
1770
1771 #undef REG_STRUCT
1772 #define REG_STRUCT mcif_wb401_regs
1773 mcif_wb_regs_dcn401_init(0);
1774
1775 dcn401_mmhubbub_construct(mcif_wb30, ctx,
1776 &mcif_wb401_regs[i],
1777 &mcif_wb401_shift,
1778 &mcif_wb401_mask,
1779 i);
1780
1781 dcn42_mmhubbub_init(mcif_wb30, ctx);
1782
1783 pool->mcif_wb[i] = &mcif_wb30->base;
1784 }
1785 return true;
1786 }
1787
dcn42_dsc_create(struct dc_context * ctx,uint32_t inst)1788 static struct display_stream_compressor *dcn42_dsc_create(
1789 struct dc_context *ctx, uint32_t inst)
1790 {
1791 struct dcn401_dsc *dsc =
1792 kzalloc_obj(struct dcn401_dsc);
1793
1794 if (!dsc) {
1795 BREAK_TO_DEBUGGER();
1796 return NULL;
1797 }
1798
1799 #undef REG_STRUCT
1800 #define REG_STRUCT dsc_regs
1801 dsc_regs_init(0),
1802 dsc_regs_init(1),
1803 dsc_regs_init(2),
1804 dsc_regs_init(3);
1805
1806 dsc401_construct(dsc, ctx, inst, &dsc_regs[inst], &dsc_shift, &dsc_mask);
1807 dsc401_set_fgcg(dsc, ctx->dc->debug.enable_fine_grain_clock_gating.bits.dsc);
1808
1809 dsc->max_image_width = 5760;
1810
1811 return &dsc->base;
1812 }
1813
dcn42_destroy_resource_pool(struct resource_pool ** pool)1814 static void dcn42_destroy_resource_pool(struct resource_pool **pool)
1815 {
1816 struct dcn42_resource_pool *dcn42_pool = TO_DCN42_RES_POOL(*pool);
1817
1818 dcn42_resource_destruct(dcn42_pool);
1819 kfree(dcn42_pool);
1820 *pool = NULL;
1821 }
1822
1823 static struct dc_cap_funcs cap_funcs = {
1824 .get_dcc_compression_cap = dcn20_get_dcc_compression_cap};
1825
dcn42_update_bw_bounding_box_fpu(struct dc * dc,struct clk_bw_params * bw_params)1826 static void dcn42_update_bw_bounding_box_fpu(struct dc *dc, struct clk_bw_params *bw_params)
1827 {
1828 (void)bw_params;
1829 dc_assert_fp_enabled();
1830
1831 if (dc->current_state && dc->current_state->bw_ctx.dml2)
1832 dml2_reinit(dc, &dc->dml2_options, &dc->current_state->bw_ctx.dml2);
1833 }
1834
dcn42_update_bw_bounding_box(struct dc * dc,struct clk_bw_params * bw_params)1835 static void dcn42_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params)
1836 {
1837 DC_FP_START();
1838 dcn42_update_bw_bounding_box_fpu(dc, bw_params);
1839 DC_FP_END();
1840 }
dcn42_validate_bandwidth(struct dc * dc,struct dc_state * context,enum dc_validate_mode validate_mode)1841 enum dc_status dcn42_validate_bandwidth(struct dc *dc,
1842 struct dc_state *context,
1843 enum dc_validate_mode validate_mode)
1844 {
1845 bool out = false;
1846
1847 DC_FP_START();
1848 if (validate_mode == DC_VALIDATE_MODE_AND_PROGRAMMING) {
1849 /*only do this when programing HW*/
1850 dcn42_decide_odm_override(dc, context);
1851 }
1852
1853 out = dml2_validate(dc, context, context->bw_ctx.dml2,
1854 validate_mode);
1855
1856
1857 if (validate_mode == DC_VALIDATE_MODE_AND_PROGRAMMING) {
1858 /*not required for mode enumeration*/
1859 dcn42_decide_zstate_support(dc, context);
1860 }
1861
1862 DC_FP_END();
1863
1864 return out ? DC_OK : DC_FAIL_BANDWIDTH_VALIDATE;
1865 }
dcn42_prepare_mcache_programming(struct dc * dc,struct dc_state * context)1866 void dcn42_prepare_mcache_programming(struct dc *dc,
1867 struct dc_state *context)
1868 {
1869 if (dc->debug.using_dml21) {
1870 DC_FP_START();
1871 dml2_prepare_mcache_programming(dc, context,
1872 context->power_source == DC_POWER_SOURCE_DC ?
1873 context->bw_ctx.dml2_dc_power_source : context->bw_ctx.dml2);
1874 DC_FP_END();
1875 }
1876 }
1877 /* Create a minimal link encoder object not associated with a particular
1878 * physical connector.
1879 * resource_funcs.link_enc_create_minimal
1880 */
dcn42_link_enc_create_minimal(struct dc_context * ctx,enum engine_id eng_id)1881 static struct link_encoder *dcn42_link_enc_create_minimal(
1882 struct dc_context *ctx, enum engine_id eng_id)
1883 {
1884 struct dcn20_link_encoder *enc20;
1885
1886 if ((unsigned int)(eng_id - ENGINE_ID_DIGA) >= ctx->dc->res_pool->res_cap->num_dig_link_enc)
1887 return NULL;
1888
1889 enc20 = kzalloc_obj(struct dcn20_link_encoder);
1890 if (!enc20)
1891 return NULL;
1892
1893 dcn31_link_encoder_construct_minimal(
1894 enc20,
1895 ctx,
1896 &link_enc_feature,
1897 &link_enc_regs[eng_id - ENGINE_ID_DIGA],
1898 &le_shift,
1899 &le_mask,
1900 eng_id);
1901
1902 return &enc20->enc10.base;
1903 }
dcn42_get_panel_config_defaults(struct dc_panel_config * panel_config)1904 static void dcn42_get_panel_config_defaults(struct dc_panel_config *panel_config)
1905 {
1906 *panel_config = dcn42_panel_config_defaults;
1907 }
dcn42_get_max_hw_cursor_size(const struct dc * dc,struct dc_state * state,const struct dc_stream_state * stream)1908 static unsigned int dcn42_get_max_hw_cursor_size(const struct dc *dc,
1909 struct dc_state *state,
1910 const struct dc_stream_state *stream)
1911 {
1912 (void)state;
1913 (void)stream;
1914 return dc->caps.max_cursor_size;
1915 }
1916 static struct resource_funcs dcn42_res_pool_funcs = {
1917 .destroy = dcn42_destroy_resource_pool,
1918 .link_enc_create = dcn42_link_encoder_create,
1919 .link_enc_create_minimal = dcn42_link_enc_create_minimal,
1920 .link_encs_assign = link_enc_cfg_link_encs_assign,
1921 .link_enc_unassign = link_enc_cfg_link_enc_unassign,
1922 .hpo_frl_link_enc_create = dcn42_hpo_frl_link_encoder_create,
1923 .panel_cntl_create = dcn32_panel_cntl_create,
1924 .validate_bandwidth = dcn42_validate_bandwidth,
1925 .calculate_wm_and_dlg = NULL,
1926 .populate_dml_pipes = NULL,
1927 .acquire_free_pipe_as_secondary_dpp_pipe = dcn32_acquire_free_pipe_as_secondary_dpp_pipe,
1928 .acquire_free_pipe_as_secondary_opp_head = dcn32_acquire_free_pipe_as_secondary_opp_head,
1929 .release_pipe = dcn20_release_pipe,
1930 .add_stream_to_ctx = dcn30_add_stream_to_ctx,
1931 .add_dsc_to_stream_resource = dcn20_add_dsc_to_stream_resource,
1932 .remove_stream_from_ctx = dcn20_remove_stream_from_ctx,
1933 .populate_dml_writeback_from_context = dcn30_populate_dml_writeback_from_context,
1934 .set_mcif_arb_params = dcn30_set_mcif_arb_params,
1935 .find_first_free_match_stream_enc_for_link = dcn10_find_first_free_match_stream_enc_for_link,
1936 .acquire_post_bldn_3dlut = dcn32_acquire_post_bldn_3dlut,
1937 .release_post_bldn_3dlut = dcn32_release_post_bldn_3dlut,
1938 .update_bw_bounding_box = dcn42_update_bw_bounding_box,
1939 .patch_unknown_plane_state = dcn35_patch_unknown_plane_state,
1940 .get_panel_config_defaults = dcn42_get_panel_config_defaults,
1941 .get_preferred_eng_id_dpia = dcn42_get_preferred_eng_id_dpia,
1942 .update_soc_for_wm_a = dcn30_update_soc_for_wm_a,
1943 .prepare_mcache_programming = dcn42_prepare_mcache_programming,
1944 .build_pipe_pix_clk_params = dcn42_build_pipe_pix_clk_params,
1945 .get_power_profile = dcn401_get_power_profile,
1946 .get_vstartup_for_pipe = dcn401_get_vstartup_for_pipe,
1947 .get_max_hw_cursor_size = dcn42_get_max_hw_cursor_size,
1948 .get_default_tiling_info = dcn10_get_default_tiling_info
1949 };
1950
read_pipe_fuses(struct dc_context * ctx)1951 static uint32_t read_pipe_fuses(struct dc_context *ctx)
1952 {
1953 uint32_t value = REG_READ(CC_DC_PIPE_DIS);
1954
1955 if (value == 0 && ctx->dce_environment == DCE_ENV_DIAG)
1956 value = 0xF;
1957 /* DCN401 support max 4 pipes */
1958 value = value & 0xf;
1959 return value;
1960 }
1961
dcn42_resource_construct(uint8_t num_virtual_links,struct dc * dc,struct dcn42_resource_pool * pool)1962 static bool dcn42_resource_construct(
1963 uint8_t num_virtual_links,
1964 struct dc *dc,
1965 struct dcn42_resource_pool *pool)
1966 {
1967 unsigned int i, j;
1968 struct dc_context *ctx = dc->ctx;
1969 struct irq_service_init_data init_data;
1970 uint32_t pipe_fuses;
1971 uint32_t num_pipes;
1972
1973 #undef REG_STRUCT
1974 #define REG_STRUCT bios_regs
1975 bios_regs_init();
1976
1977 #undef REG_STRUCT
1978 #define REG_STRUCT clk_src_regs
1979 clk_src_regs_init(0, A),
1980 clk_src_regs_init(1, B),
1981 clk_src_regs_init(2, C),
1982 clk_src_regs_init(3, D),
1983 clk_src_regs_init(4, E);
1984
1985 #undef REG_STRUCT
1986 #define REG_STRUCT abm_regs
1987 abm_regs_init(0),
1988 abm_regs_init(1),
1989 abm_regs_init(2),
1990 abm_regs_init(3);
1991 #undef REG_STRUCT
1992 #define REG_STRUCT dccg_regs
1993 dccg_regs_init();
1994
1995 ctx->dc_bios->regs = &bios_regs;
1996
1997 pool->base.res_cap = &res_cap_dcn42;
1998
1999 /* max number of pipes for ASIC before checking for pipe fuses */
2000 num_pipes = pool->base.res_cap->num_dpp;
2001 pipe_fuses = read_pipe_fuses(ctx);
2002
2003 for (i = 0; i < (unsigned int)pool->base.res_cap->num_dpp; i++)
2004 if (pipe_fuses & 1 << i)
2005 num_pipes--;
2006
2007 if (pipe_fuses & 1)
2008 ASSERT(0); // Unexpected - Pipe 0 should always be fully functional!
2009
2010 if (pipe_fuses & CC_DC_PIPE_DIS__DC_FULL_DIS_MASK)
2011 ASSERT(0); // Entire DCN is harvested!
2012
2013 pool->base.funcs = &dcn42_res_pool_funcs;
2014
2015 /*************************************************
2016 * Resource + asic cap harcoding *
2017 *************************************************/
2018 pool->base.underlay_pipe_index = (unsigned int)NO_UNDERLAY_PIPE;
2019 pool->base.timing_generator_count = pool->base.res_cap->num_timing_generator;
2020 pool->base.pipe_count = num_pipes;
2021 pool->base.mpcc_count = num_pipes;
2022 dc->caps.ips_v2_support = true;
2023 dc->caps.max_downscale_ratio = 600;
2024 dc->caps.i2c_speed_in_khz = 100;
2025 dc->caps.i2c_speed_in_khz_hdcp = 100; /*1.4 w/a applied by default*/
2026 /* TODO: Bring max cursor size back to 256 after subvp cursor corruption is fixed*/
2027 dc->caps.max_cursor_size = 64;
2028 dc->caps.max_buffered_cursor_size = 64;
2029 dc->caps.cursor_not_scaled = true;
2030 dc->caps.min_horizontal_blanking_period = 80;
2031 dc->caps.dmdata_alloc_size = 2048;
2032 dc->caps.cursor_cache_size = dc->caps.max_cursor_size * dc->caps.max_cursor_size * 8;
2033
2034 dc->caps.max_slave_planes = 2;
2035 dc->caps.max_slave_yuv_planes = 2;
2036 dc->caps.max_slave_rgb_planes = 2;
2037 dc->caps.post_blend_color_processing = true;
2038 dc->caps.force_dp_tps4_for_cp2520 = true;
2039 if (dc->config.forceHBR2CP2520)
2040 dc->caps.force_dp_tps4_for_cp2520 = false;
2041 dc->caps.hdmi_hpo = true;
2042 dc->caps.dp_hdmi21_pcon_support = true;
2043 dc->caps.dp_hpo = true;
2044 dc->caps.edp_dsc_support = true;
2045 dc->caps.extended_aux_timeout_support = true;
2046 dc->caps.dmcub_support = true;
2047 dc->caps.is_apu = true;
2048 dc->caps.seamless_odm = true;
2049 dc->caps.zstate_support = true;
2050 dc->caps.ips_support = true;
2051 dc->caps.max_v_total = (1 << 15) - 1;
2052 dc->caps.vtotal_limited_by_fp2 = true;
2053
2054 /* Color pipeline capabilities */
2055 dc->caps.color.dpp.dcn_arch = 1;
2056 dc->caps.color.dpp.input_lut_shared = 0;
2057 dc->caps.color.dpp.icsc = 1;
2058 dc->caps.color.dpp.dgam_ram = 0; // must use gamma_corr
2059 dc->caps.color.dpp.dgam_rom_caps.srgb = 1;
2060 dc->caps.color.dpp.dgam_rom_caps.bt2020 = 1;
2061 dc->caps.color.dpp.dgam_rom_caps.gamma2_2 = 1;
2062 dc->caps.color.dpp.dgam_rom_caps.pq = 1;
2063 dc->caps.color.dpp.dgam_rom_caps.hlg = 1;
2064 dc->caps.color.dpp.post_csc = 1;
2065 dc->caps.color.dpp.gamma_corr = 1;
2066 dc->caps.color.dpp.dgam_rom_for_yuv = 0;
2067 dc->caps.color.dpp.upsp_pre_scaler = 0;
2068
2069 dc->caps.color.dpp.hw_3d_lut = 0;
2070 dc->caps.color.dpp.ogam_ram = 0;
2071 // no OGAM ROM on DCN2 and later ASICs
2072 dc->caps.color.dpp.ogam_rom_caps.srgb = 0;
2073 dc->caps.color.dpp.ogam_rom_caps.bt2020 = 0;
2074 dc->caps.color.dpp.ogam_rom_caps.gamma2_2 = 0;
2075 dc->caps.color.dpp.ogam_rom_caps.pq = 0;
2076 dc->caps.color.dpp.ogam_rom_caps.hlg = 0;
2077 dc->caps.color.dpp.ocsc = 0;
2078
2079 dc->caps.color.mpc.gamut_remap = 1;
2080 //configurable to be before or after BLND in MPCC
2081 dc->caps.color.mpc.num_3dluts = (uint16_t)pool->base.res_cap->num_mpc_3dlut;
2082 dc->caps.color.mpc.num_rmcm_3dluts = 2;
2083 dc->caps.color.mpc.ogam_ram = 1;
2084 dc->caps.color.mpc.ogam_rom_caps.srgb = 0;
2085 dc->caps.color.mpc.ogam_rom_caps.bt2020 = 0;
2086 dc->caps.color.mpc.ogam_rom_caps.gamma2_2 = 0;
2087 dc->caps.color.mpc.ogam_rom_caps.pq = 0;
2088 dc->caps.color.mpc.ogam_rom_caps.hlg = 0;
2089 dc->caps.color.mpc.ocsc = 1;
2090 dc->caps.color.mpc.preblend = true;
2091 dc->caps.color.mpc.mcm_3d_lut_caps.dma_3d_lut = 1;
2092 dc->caps.color.mpc.mcm_3d_lut_caps.lut_dim_caps.dim_9 = 1;
2093 dc->caps.color.mpc.mcm_3d_lut_caps.lut_dim_caps.dim_17 = 1;
2094 dc->caps.color.mpc.mcm_3d_lut_caps.mem_layout_support.linear_1d = 1;
2095 dc->caps.color.mpc.mcm_3d_lut_caps.mem_layout_support.swizzle_3d_bgr = 1;
2096 dc->caps.color.mpc.mcm_3d_lut_caps.mem_layout_support.swizzle_3d_rgb = 1;
2097 dc->caps.color.mpc.mcm_3d_lut_caps.mem_format_support.unorm_12msb = 1;
2098 dc->caps.color.mpc.mcm_3d_lut_caps.mem_format_support.unorm_12lsb = 1;
2099 dc->caps.color.mpc.mcm_3d_lut_caps.mem_format_support.float_fp1_5_10 = 1;
2100 dc->caps.color.mpc.mcm_3d_lut_caps.mem_pixel_order_support.order_rgba = 1;
2101 dc->caps.color.mpc.mcm_3d_lut_caps.mem_pixel_order_support.order_bgra = 1;
2102 dc->caps.color.mpc.rmcm_3d_lut_caps.dma_3d_lut = 1;
2103 dc->caps.color.mpc.rmcm_3d_lut_caps.lut_dim_caps.dim_17 = 1;
2104 dc->caps.color.mpc.rmcm_3d_lut_caps.lut_dim_caps.dim_33 = 1;
2105 dc->caps.color.mpc.rmcm_3d_lut_caps.mem_layout_support.linear_1d = 1;
2106 dc->caps.color.mpc.rmcm_3d_lut_caps.mem_layout_support.swizzle_3d_bgr = 1;
2107 dc->caps.color.mpc.rmcm_3d_lut_caps.mem_layout_support.swizzle_3d_rgb = 1;
2108 dc->caps.color.mpc.rmcm_3d_lut_caps.mem_format_support.unorm_12msb = 1;
2109 dc->caps.color.mpc.rmcm_3d_lut_caps.mem_format_support.unorm_12lsb = 1;
2110 dc->caps.color.mpc.rmcm_3d_lut_caps.mem_format_support.float_fp1_5_10 = 1;
2111 dc->caps.color.mpc.rmcm_3d_lut_caps.mem_pixel_order_support.order_rgba = 1;
2112 dc->caps.color.mpc.rmcm_3d_lut_caps.mem_pixel_order_support.order_bgra = 1;
2113 dc->caps.color.mpc.max_gamut_remap_coeff = dc_fixpt_from_fraction(S3D12_MAX, DIVIDER);
2114
2115 dc->caps.num_of_host_routers = 3;
2116 dc->caps.num_of_dpias_per_host_router = 2;
2117
2118 /* max_disp_clock_khz_at_vmin is slightly lower than the STA value in order
2119 * to provide some margin.
2120 * It's expected for furture ASIC to have equal or higher value, in order to
2121 * have determinstic power improvement from generate to genration.
2122 * (i.e., we should not expect new ASIC generation with lower vmin rate)
2123 */
2124 dc->caps.max_disp_clock_khz_at_vmin = 650000;
2125 dc->config.use_spl = true;
2126 dc->config.prefer_easf = true;
2127
2128 dc->config.dcn_sharpness_range.sdr_rgb_min = 0;
2129 dc->config.dcn_sharpness_range.sdr_rgb_max = 1750;
2130 dc->config.dcn_sharpness_range.sdr_rgb_mid = 750;
2131 dc->config.dcn_sharpness_range.sdr_yuv_min = 0;
2132 dc->config.dcn_sharpness_range.sdr_yuv_max = 3500;
2133 dc->config.dcn_sharpness_range.sdr_yuv_mid = 1500;
2134 dc->config.dcn_sharpness_range.hdr_rgb_min = 0;
2135 dc->config.dcn_sharpness_range.hdr_rgb_max = 2750;
2136 dc->config.dcn_sharpness_range.hdr_rgb_mid = 1500;
2137
2138 dc->config.dcn_override_sharpness_range.sdr_rgb_min = 0;
2139 dc->config.dcn_override_sharpness_range.sdr_rgb_max = 3250;
2140 dc->config.dcn_override_sharpness_range.sdr_rgb_mid = 1250;
2141 dc->config.dcn_override_sharpness_range.sdr_yuv_min = 0;
2142 dc->config.dcn_override_sharpness_range.sdr_yuv_max = 3500;
2143 dc->config.dcn_override_sharpness_range.sdr_yuv_mid = 1500;
2144 dc->config.dcn_override_sharpness_range.hdr_rgb_min = 0;
2145 dc->config.dcn_override_sharpness_range.hdr_rgb_max = 2750;
2146 dc->config.dcn_override_sharpness_range.hdr_rgb_mid = 1500;
2147
2148 dc->config.use_pipe_ctx_sync_logic = true;
2149 dc->config.dc_mode_clk_limit_support = false;
2150 dc->config.enable_windowed_mpo_odm = true;
2151 dc->config.set_pipe_unlock_order = true; /* Need to ensure DET gets freed before allocating */
2152 /* Use psp mailbox to enable assr */
2153 dc->config.use_assr_psp_message = true;
2154 /* dcn42 and afterward always support external panel replay */
2155 dc->config.frame_update_cmd_version2 = true;
2156
2157 /* read VBIOS LTTPR caps */
2158 {
2159 if (ctx->dc_bios->funcs->get_lttpr_caps) {
2160 enum bp_result bp_query_result;
2161 uint8_t is_vbios_lttpr_enable = 0;
2162
2163 bp_query_result = ctx->dc_bios->funcs->get_lttpr_caps(ctx->dc_bios, &is_vbios_lttpr_enable);
2164 dc->caps.vbios_lttpr_enable = (bp_query_result == BP_RESULT_OK) && !!is_vbios_lttpr_enable;
2165 }
2166
2167 dc->caps.vbios_lttpr_aware = true;
2168 }
2169 dc->check_config = config_defaults;
2170
2171 if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV)
2172 dc->debug = debug_defaults_drv;
2173
2174 /*HW default is to have all the FGCG enabled, SW no need to program them*/
2175 dc->debug.enable_fine_grain_clock_gating.u32All = 0xFFFF;
2176 // Init the vm_helper
2177 if (dc->vm_helper)
2178 vm_helper_init(dc->vm_helper, 16);
2179
2180 /*************************************************
2181 * Create resources *
2182 *************************************************/
2183
2184 /* Clock Sources for Pixel Clock*/
2185 pool->base.clock_sources[DCN401_CLK_SRC_PLL0] =
2186 dcn42_clock_source_create(ctx, ctx->dc_bios,
2187 CLOCK_SOURCE_COMBO_PHY_PLL0,
2188 &clk_src_regs[0], false);
2189 pool->base.clock_sources[DCN401_CLK_SRC_PLL1] =
2190 dcn42_clock_source_create(ctx, ctx->dc_bios,
2191 CLOCK_SOURCE_COMBO_PHY_PLL1,
2192 &clk_src_regs[1], false);
2193 pool->base.clock_sources[DCN401_CLK_SRC_PLL2] =
2194 dcn42_clock_source_create(ctx, ctx->dc_bios,
2195 CLOCK_SOURCE_COMBO_PHY_PLL2,
2196 &clk_src_regs[2], false);
2197 pool->base.clock_sources[DCN401_CLK_SRC_PLL3] =
2198 dcn42_clock_source_create(ctx, ctx->dc_bios,
2199 CLOCK_SOURCE_COMBO_PHY_PLL3,
2200 &clk_src_regs[3], false);
2201 pool->base.clock_sources[DCN401_CLK_SRC_PLL4] =
2202 dcn42_clock_source_create(ctx, ctx->dc_bios,
2203 CLOCK_SOURCE_COMBO_PHY_PLL4,
2204 &clk_src_regs[4], false);
2205
2206 pool->base.clk_src_count = DCN401_CLK_SRC_TOTAL;
2207
2208 /* todo: not reuse phy_pll registers */
2209 pool->base.dp_clock_source =
2210 dcn42_clock_source_create(ctx, ctx->dc_bios,
2211 CLOCK_SOURCE_ID_DP_DTO,
2212 &clk_src_regs[0], true);
2213
2214 for (i = 0; i < pool->base.clk_src_count; i++) {
2215 if (pool->base.clock_sources[i] == NULL) {
2216 dm_error("DC: failed to create clock sources!\n");
2217 BREAK_TO_DEBUGGER();
2218 goto create_fail;
2219 }
2220 }
2221
2222 /* DCCG */
2223 pool->base.dccg = dccg42_create(ctx, &dccg_regs, &dccg_shift, &dccg_mask);
2224 if (pool->base.dccg == NULL) {
2225 dm_error("DC: failed to create dccg!\n");
2226 BREAK_TO_DEBUGGER();
2227 goto create_fail;
2228 }
2229
2230 #undef REG_STRUCT
2231 #define REG_STRUCT pg_cntl_regs
2232 pg_cntl_dcn42_regs_init();
2233
2234 pool->base.pg_cntl = pg_cntl42_create(ctx, &pg_cntl_regs, &pg_cntl_shift, &pg_cntl_mask);
2235 if (pool->base.pg_cntl == NULL) {
2236 dm_error("DC: failed to create power gate control!\n");
2237 BREAK_TO_DEBUGGER();
2238 goto create_fail;
2239 }
2240 /* IRQ Service */
2241 init_data.ctx = dc->ctx;
2242 pool->base.irqs = dal_irq_service_dcn42_create(&init_data);
2243 if (!pool->base.irqs)
2244 goto create_fail;
2245
2246 /* HUBBUB */
2247 pool->base.hubbub = dcn42_hubbub_create(ctx);
2248 if (pool->base.hubbub == NULL) {
2249 BREAK_TO_DEBUGGER();
2250 dm_error("DC: failed to create hubbub!\n");
2251 goto create_fail;
2252 }
2253
2254 /* HUBPs, DPPs, OPPs, TGs, ABMs */
2255 for (i = 0, j = 0; i < (unsigned int)pool->base.res_cap->num_timing_generator; i++) {
2256 /* if pipe is disabled, skip instance of HW pipe,
2257 * i.e, skip ASIC register instance
2258 */
2259 if (pipe_fuses & 1 << i)
2260 continue;
2261
2262 pool->base.hubps[j] = dcn42_hubp_create(ctx, i);
2263 if (pool->base.hubps[j] == NULL) {
2264 BREAK_TO_DEBUGGER();
2265 dm_error(
2266 "DC: failed to create hubps!\n");
2267 goto create_fail;
2268 }
2269
2270 pool->base.dpps[j] = dcn42_dpp_create(ctx, i);
2271 if (pool->base.dpps[j] == NULL) {
2272 BREAK_TO_DEBUGGER();
2273 dm_error(
2274 "DC: failed to create dpps!\n");
2275 goto create_fail;
2276 }
2277
2278 pool->base.opps[j] = dcn42_opp_create(ctx, i);
2279 if (pool->base.opps[j] == NULL) {
2280 BREAK_TO_DEBUGGER();
2281 dm_error(
2282 "DC: failed to create output pixel processor!\n");
2283 goto create_fail;
2284 }
2285
2286 pool->base.timing_generators[j] = dcn42_timing_generator_create(
2287 ctx, i);
2288 if (pool->base.timing_generators[j] == NULL) {
2289 BREAK_TO_DEBUGGER();
2290 dm_error("DC: failed to create tg!\n");
2291 goto create_fail;
2292 }
2293
2294 pool->base.multiple_abms[j] = dmub_abm_create(ctx,
2295 &abm_regs[i],
2296 &abm_shift,
2297 &abm_mask);
2298 if (pool->base.multiple_abms[j] == NULL) {
2299 dm_error("DC: failed to create abm for pipe %u!\n", i);
2300 BREAK_TO_DEBUGGER();
2301 goto create_fail;
2302 }
2303
2304 /* index for resource pool arrays for next valid pipe */
2305 j++;
2306 }
2307
2308 /* PSR */
2309 pool->base.psr = dmub_psr_create(ctx);
2310 if (pool->base.psr == NULL) {
2311 dm_error("DC: failed to create psr obj!\n");
2312 BREAK_TO_DEBUGGER();
2313 goto create_fail;
2314 }
2315
2316 /* Replay */
2317 pool->base.replay = dmub_replay_create(ctx);
2318 if (pool->base.replay == NULL) {
2319 dm_error("DC: failed to create replay obj!\n");
2320 BREAK_TO_DEBUGGER();
2321 goto create_fail;
2322 }
2323
2324 /* MPCCs */
2325 pool->base.mpc = dcn42_mpc_create(ctx, pool->base.res_cap->num_timing_generator,
2326 pool->base.res_cap->num_mpc_3dlut);
2327 if (pool->base.mpc == NULL) {
2328 BREAK_TO_DEBUGGER();
2329 dm_error("DC: failed to create mpc!\n");
2330 goto create_fail;
2331 }
2332
2333 /* DSCs */
2334 for (i = 0; i < (unsigned int)pool->base.res_cap->num_dsc; i++) {
2335 pool->base.dscs[i] = dcn42_dsc_create(ctx, i);
2336 if (pool->base.dscs[i] == NULL) {
2337 BREAK_TO_DEBUGGER();
2338 dm_error("DC: failed to create display stream compressor %u!\n", i);
2339 goto create_fail;
2340 }
2341 }
2342
2343 /* DWB */
2344 if (!dcn42_dwbc_create(ctx, &pool->base)) {
2345 BREAK_TO_DEBUGGER();
2346 dm_error("DC: failed to create dwbc!\n");
2347 goto create_fail;
2348 }
2349
2350 /* MMHUBBUB */
2351 if (!dcn42_mmhubbub_create(ctx, &pool->base)) {
2352 BREAK_TO_DEBUGGER();
2353 dm_error("DC: failed to create mcif_wb!\n");
2354 goto create_fail;
2355 }
2356
2357 /* AUX and I2C */
2358 for (i = 0; i < (unsigned int)pool->base.res_cap->num_ddc; i++) {
2359 pool->base.engines[i] = dcn42_aux_engine_create(ctx, i);
2360
2361 if (pool->base.engines[i] == NULL) {
2362 BREAK_TO_DEBUGGER();
2363 dm_error(
2364 "DC:failed to create aux engine!!\n");
2365 goto create_fail;
2366 }
2367 pool->base.hw_i2cs[i] = dcn42_i2c_hw_create(ctx, i);
2368 if (pool->base.hw_i2cs[i] == NULL) {
2369 BREAK_TO_DEBUGGER();
2370 dm_error(
2371 "DC:failed to create hw i2c!!\n");
2372 goto create_fail;
2373 }
2374 pool->base.sw_i2cs[i] = NULL;
2375 }
2376 /* DCN4.2 has 6 DPIA */
2377 pool->base.usb4_dpia_count = dc->caps.num_of_host_routers * dc->caps.num_of_dpias_per_host_router;
2378 if (dc->debug.dpia_debug.bits.disable_dpia)
2379 pool->base.usb4_dpia_count = 0;
2380
2381 /* Audio, HWSeq, Stream Encoders including HPO and virtual, MPC 3D LUTs */
2382 if (!resource_construct(num_virtual_links, dc, &pool->base,
2383 &res_create_funcs))
2384 goto create_fail;
2385
2386 /* HW Sequencer init functions and Plane caps */
2387 dcn42_hw_sequencer_init_functions(dc);
2388
2389 dc->caps.max_planes = pool->base.pipe_count;
2390
2391 for (i = 0; i < dc->caps.max_planes; ++i)
2392 dc->caps.planes[i] = plane_cap;
2393
2394 dc->caps.max_odm_combine_factor = 4;
2395
2396 dc->cap_funcs = cap_funcs;
2397 dc->dcn_ip->max_num_dpp = pool->base.pipe_count;
2398
2399 // For now enable SDPIF_REQUEST_RATE_LIMIT on DCN4_01 when vram_info.num_chans provided
2400 if (dc->config.sdpif_request_limit_words_per_umc == 0)
2401 dc->config.sdpif_request_limit_words_per_umc = 16;
2402
2403 dc->dml2_options.dcn_pipe_count = pool->base.pipe_count;
2404 /*this will use real soc clock table*/
2405 dc->dml2_options.use_native_soc_bb_construction = true;
2406 dc->dml2_options.minimize_dispclk_using_odm = false;
2407 if (dc->config.EnableMinDispClkODM)
2408 dc->dml2_options.minimize_dispclk_using_odm = true;
2409 dc->dml2_options.enable_windowed_mpo_odm = dc->config.enable_windowed_mpo_odm;
2410 dc->dml2_options.map_dc_pipes_with_callbacks = true;
2411 dc->dml2_options.force_tdlut_enable = true;
2412
2413 resource_init_common_dml2_callbacks(dc, &dc->dml2_options);
2414 dc->dml2_options.callbacks.can_support_mclk_switch_using_fw_based_vblank_stretch =
2415 &dcn30_can_support_mclk_switch_using_fw_based_vblank_stretch;
2416
2417 dc->dml2_options.max_segments_per_hubp = 24;
2418 dc->dml2_options.det_segment_size = DCN42_CRB_SEGMENT_SIZE_KB;
2419 dc->dml2_options.gpuvm_enable = true;
2420 dc->dml2_options.hostvm_enable = true;
2421
2422 dc->dml2_options.pmo.force_mandatory_uclk_pstate_support = true;
2423
2424 /* SPL */
2425 dc->caps.scl_caps.sharpener_support = true;
2426
2427 return true;
2428
2429 create_fail:
2430
2431 dcn42_resource_destruct(pool);
2432
2433 return false;
2434 }
dcn42_create_resource_pool(const struct dc_init_data * init_data,struct dc * dc)2435 struct resource_pool *dcn42_create_resource_pool(
2436 const struct dc_init_data *init_data,
2437 struct dc *dc)
2438 {
2439 struct dcn42_resource_pool *pool =
2440 kzalloc_obj(struct dcn42_resource_pool);
2441
2442 if (!pool)
2443 return NULL;
2444
2445 if (dcn42_resource_construct((uint8_t)init_data->num_virtual_links, dc, pool))
2446 return &pool->base;
2447
2448 BREAK_TO_DEBUGGER();
2449 kfree(pool);
2450 return NULL;
2451 }
2452