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