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