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