Loading...
Note: File does not exist in v6.8.
1// SPDX-License-Identifier: MIT
2/*
3 * Copyright 2019 Advanced Micro Devices, Inc.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21 * OTHER DEALINGS IN THE SOFTWARE.
22 *
23 * Authors: AMD
24 *
25 */
26
27#include "dm_services.h"
28#include "dc.h"
29
30#include "dcn32/dcn32_init.h"
31
32#include "resource.h"
33#include "include/irq_service_interface.h"
34#include "dcn32/dcn32_resource.h"
35#include "dcn321_resource.h"
36
37#include "dcn20/dcn20_resource.h"
38#include "dcn30/dcn30_resource.h"
39
40#include "dml/dcn321/dcn321_fpu.h"
41
42#include "dcn10/dcn10_ipp.h"
43#include "dcn30/dcn30_hubbub.h"
44#include "dcn31/dcn31_hubbub.h"
45#include "dcn32/dcn32_hubbub.h"
46#include "dcn32/dcn32_mpc.h"
47#include "dcn32/dcn32_hubp.h"
48#include "irq/dcn32/irq_service_dcn32.h"
49#include "dcn32/dcn32_dpp.h"
50#include "dcn32/dcn32_optc.h"
51#include "dcn20/dcn20_hwseq.h"
52#include "dcn30/dcn30_hwseq.h"
53#include "dce110/dce110_hw_sequencer.h"
54#include "dcn30/dcn30_opp.h"
55#include "dcn20/dcn20_dsc.h"
56#include "dcn30/dcn30_vpg.h"
57#include "dcn30/dcn30_afmt.h"
58#include "dcn30/dcn30_dio_stream_encoder.h"
59#include "dcn32/dcn32_dio_stream_encoder.h"
60#include "dcn31/dcn31_hpo_dp_stream_encoder.h"
61#include "dcn31/dcn31_hpo_dp_link_encoder.h"
62#include "dcn32/dcn32_hpo_dp_link_encoder.h"
63#include "dc_link_dp.h"
64#include "dcn31/dcn31_apg.h"
65#include "dcn31/dcn31_dio_link_encoder.h"
66#include "dcn32/dcn32_dio_link_encoder.h"
67#include "dcn321_dio_link_encoder.h"
68#include "dce/dce_clock_source.h"
69#include "dce/dce_audio.h"
70#include "dce/dce_hwseq.h"
71#include "clk_mgr.h"
72#include "virtual/virtual_stream_encoder.h"
73#include "dml/display_mode_vba.h"
74#include "dcn32/dcn32_dccg.h"
75#include "dcn10/dcn10_resource.h"
76#include "dc_link_ddc.h"
77#include "dcn31/dcn31_panel_cntl.h"
78
79#include "dcn30/dcn30_dwb.h"
80#include "dcn32/dcn32_mmhubbub.h"
81
82#include "dcn/dcn_3_2_1_offset.h"
83#include "dcn/dcn_3_2_1_sh_mask.h"
84#include "nbio/nbio_4_3_0_offset.h"
85
86#include "reg_helper.h"
87#include "dce/dmub_abm.h"
88#include "dce/dmub_psr.h"
89#include "dce/dce_aux.h"
90#include "dce/dce_i2c.h"
91
92#include "dml/dcn30/display_mode_vba_30.h"
93#include "vm_helper.h"
94#include "dcn20/dcn20_vmid.h"
95
96#define DC_LOGGER_INIT(logger)
97
98enum dcn321_clk_src_array_id {
99 DCN321_CLK_SRC_PLL0,
100 DCN321_CLK_SRC_PLL1,
101 DCN321_CLK_SRC_PLL2,
102 DCN321_CLK_SRC_PLL3,
103 DCN321_CLK_SRC_PLL4,
104 DCN321_CLK_SRC_TOTAL
105};
106
107/* begin *********************
108 * macros to expend register list macro defined in HW object header file
109 */
110
111/* DCN */
112#define BASE_INNER(seg) ctx->dcn_reg_offsets[seg]
113
114#define BASE(seg) BASE_INNER(seg)
115
116#define SR(reg_name)\
117 REG_STRUCT.reg_name = BASE(reg ## reg_name ## _BASE_IDX) + \
118 reg ## reg_name
119#define SR_ARR(reg_name, id)\
120 REG_STRUCT[id].reg_name = BASE(reg ## reg_name ## _BASE_IDX) + \
121 reg ## reg_name
122#define SR_ARR_INIT(reg_name, id, value)\
123 REG_STRUCT[id].reg_name = value
124
125#define SRI(reg_name, block, id)\
126 REG_STRUCT.reg_name = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
127 reg ## block ## id ## _ ## reg_name
128
129#define SRI_ARR(reg_name, block, id)\
130 REG_STRUCT[id].reg_name = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
131 reg ## block ## id ## _ ## reg_name
132
133#define SR_ARR_I2C(reg_name, id) \
134 REG_STRUCT[id-1].reg_name = BASE(reg##reg_name##_BASE_IDX) + reg##reg_name
135
136#define SRI_ARR_I2C(reg_name, block, id)\
137 REG_STRUCT[id-1].reg_name = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
138 reg ## block ## id ## _ ## reg_name
139
140#define SRI_ARR_ALPHABET(reg_name, block, index, id)\
141 REG_STRUCT[index].reg_name = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
142 reg ## block ## id ## _ ## reg_name
143
144#define SRI2(reg_name, block, id)\
145 .reg_name = BASE(reg ## reg_name ## _BASE_IDX) + \
146 reg ## reg_name
147#define SRI2_ARR(reg_name, block, id)\
148 REG_STRUCT[id].reg_name = BASE(reg ## reg_name ## _BASE_IDX) + \
149 reg ## reg_name
150
151#define SRIR(var_name, reg_name, block, id)\
152 .var_name = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
153 reg ## block ## id ## _ ## reg_name
154
155#define SRII(reg_name, block, id)\
156 REG_STRUCT.reg_name[id] = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
157 reg ## block ## id ## _ ## reg_name
158
159#define SRII_ARR_2(reg_name, block, id, inst)\
160 REG_STRUCT[inst].reg_name[id] = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
161 reg ## block ## id ## _ ## reg_name
162
163#define SRII_MPC_RMU(reg_name, block, id)\
164 .RMU##_##reg_name[id] = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
165 reg ## block ## id ## _ ## reg_name
166
167#define SRII_DWB(reg_name, temp_name, block, id)\
168 REG_STRUCT.reg_name[id] = BASE(reg ## block ## id ## _ ## temp_name ## _BASE_IDX) + \
169 reg ## block ## id ## _ ## temp_name
170
171#define DCCG_SRII(reg_name, block, id)\
172 REG_STRUCT.block ## _ ## reg_name[id] = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
173 reg ## block ## id ## _ ## reg_name
174
175#define SF_DWB2(reg_name, block, id, field_name, post_fix) \
176 .field_name = reg_name ## __ ## field_name ## post_fix
177
178#define VUPDATE_SRII(reg_name, block, id)\
179 REG_STRUCT.reg_name[id] = BASE(reg ## reg_name ## _ ## block ## id ## _BASE_IDX) + \
180 reg ## reg_name ## _ ## block ## id
181
182/* NBIO */
183#define NBIO_BASE_INNER(seg) ctx->nbio_reg_offsets[seg]
184
185#define NBIO_BASE(seg) \
186 NBIO_BASE_INNER(seg)
187
188#define NBIO_SR(reg_name)\
189 REG_STRUCT.reg_name = NBIO_BASE(regBIF_BX0_ ## reg_name ## _BASE_IDX) + \
190 regBIF_BX0_ ## reg_name
191#define NBIO_SR_ARR(reg_name, id)\
192 REG_STRUCT[id].reg_name = NBIO_BASE(regBIF_BX0_ ## reg_name ## _BASE_IDX) + \
193 regBIF_BX0_ ## reg_name
194
195#define CTX ctx
196#define REG(reg_name) \
197 (ctx->dcn_reg_offsets[reg ## reg_name ## _BASE_IDX] + reg ## reg_name)
198
199static struct bios_registers bios_regs;
200
201#define bios_regs_init() \
202 ( \
203 NBIO_SR(BIOS_SCRATCH_3),\
204 NBIO_SR(BIOS_SCRATCH_6)\
205 )
206
207#define clk_src_regs_init(index, pllid)\
208 CS_COMMON_REG_LIST_DCN3_0_RI(index, pllid)
209
210static struct dce110_clk_src_regs clk_src_regs[5];
211
212static const struct dce110_clk_src_shift cs_shift = {
213 CS_COMMON_MASK_SH_LIST_DCN3_2(__SHIFT)
214};
215
216static const struct dce110_clk_src_mask cs_mask = {
217 CS_COMMON_MASK_SH_LIST_DCN3_2(_MASK)
218};
219
220#define abm_regs_init(id)\
221 ABM_DCN32_REG_LIST_RI(id)
222
223static struct dce_abm_registers abm_regs[4];
224
225static const struct dce_abm_shift abm_shift = {
226 ABM_MASK_SH_LIST_DCN32(__SHIFT)
227};
228
229static const struct dce_abm_mask abm_mask = {
230 ABM_MASK_SH_LIST_DCN32(_MASK)
231};
232
233#define audio_regs_init(id)\
234 AUD_COMMON_REG_LIST_RI(id)
235
236static struct dce_audio_registers audio_regs[5];
237
238#define DCE120_AUD_COMMON_MASK_SH_LIST(mask_sh)\
239 SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_INDEX, AZALIA_ENDPOINT_REG_INDEX, mask_sh),\
240 SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_DATA, AZALIA_ENDPOINT_REG_DATA, mask_sh),\
241 AUD_COMMON_MASK_SH_LIST_BASE(mask_sh)
242
243static const struct dce_audio_shift audio_shift = {
244 DCE120_AUD_COMMON_MASK_SH_LIST(__SHIFT)
245};
246
247static const struct dce_audio_mask audio_mask = {
248 DCE120_AUD_COMMON_MASK_SH_LIST(_MASK)
249};
250
251#define vpg_regs_init(id)\
252 VPG_DCN3_REG_LIST_RI(id)
253
254static struct dcn30_vpg_registers vpg_regs[10];
255
256static const struct dcn30_vpg_shift vpg_shift = {
257 DCN3_VPG_MASK_SH_LIST(__SHIFT)
258};
259
260static const struct dcn30_vpg_mask vpg_mask = {
261 DCN3_VPG_MASK_SH_LIST(_MASK)
262};
263
264#define afmt_regs_init(id)\
265 AFMT_DCN3_REG_LIST_RI(id)
266
267static struct dcn30_afmt_registers afmt_regs[6];
268
269static const struct dcn30_afmt_shift afmt_shift = {
270 DCN3_AFMT_MASK_SH_LIST(__SHIFT)
271};
272
273static const struct dcn30_afmt_mask afmt_mask = {
274 DCN3_AFMT_MASK_SH_LIST(_MASK)
275};
276
277#define apg_regs_init(id)\
278 APG_DCN31_REG_LIST_RI(id)
279
280static struct dcn31_apg_registers apg_regs[4];
281
282static const struct dcn31_apg_shift apg_shift = {
283 DCN31_APG_MASK_SH_LIST(__SHIFT)
284};
285
286static const struct dcn31_apg_mask apg_mask = {
287 DCN31_APG_MASK_SH_LIST(_MASK)
288};
289
290#define stream_enc_regs_init(id)\
291 SE_DCN32_REG_LIST_RI(id)
292
293static struct dcn10_stream_enc_registers stream_enc_regs[5];
294
295static const struct dcn10_stream_encoder_shift se_shift = {
296 SE_COMMON_MASK_SH_LIST_DCN32(__SHIFT)
297};
298
299static const struct dcn10_stream_encoder_mask se_mask = {
300 SE_COMMON_MASK_SH_LIST_DCN32(_MASK)
301};
302
303
304#define aux_regs_init(id)\
305 DCN2_AUX_REG_LIST_RI(id)
306
307static struct dcn10_link_enc_aux_registers link_enc_aux_regs[5];
308
309#define hpd_regs_init(id)\
310 HPD_REG_LIST_RI(id)
311
312static struct dcn10_link_enc_hpd_registers link_enc_hpd_regs[5];
313
314#define link_regs_init(id, phyid)\
315 ( \
316 LE_DCN31_REG_LIST_RI(id), \
317 UNIPHY_DCN2_REG_LIST_RI(id, phyid)\
318 )
319 /*DPCS_DCN31_REG_LIST(id),*/ \
320
321static struct dcn10_link_enc_registers link_enc_regs[5];
322
323static const struct dcn10_link_enc_shift le_shift = {
324 LINK_ENCODER_MASK_SH_LIST_DCN31(__SHIFT), \
325// DPCS_DCN31_MASK_SH_LIST(__SHIFT)
326};
327
328static const struct dcn10_link_enc_mask le_mask = {
329 LINK_ENCODER_MASK_SH_LIST_DCN31(_MASK), \
330// DPCS_DCN31_MASK_SH_LIST(_MASK)
331};
332
333#define hpo_dp_stream_encoder_reg_init(id)\
334 DCN3_1_HPO_DP_STREAM_ENC_REG_LIST_RI(id)
335
336static struct dcn31_hpo_dp_stream_encoder_registers hpo_dp_stream_enc_regs[4];
337
338static const struct dcn31_hpo_dp_stream_encoder_shift hpo_dp_se_shift = {
339 DCN3_1_HPO_DP_STREAM_ENC_MASK_SH_LIST(__SHIFT)
340};
341
342static const struct dcn31_hpo_dp_stream_encoder_mask hpo_dp_se_mask = {
343 DCN3_1_HPO_DP_STREAM_ENC_MASK_SH_LIST(_MASK)
344};
345
346
347#define hpo_dp_link_encoder_reg_init(id)\
348 DCN3_1_HPO_DP_LINK_ENC_REG_LIST_RI(id)
349 /*DCN3_1_RDPCSTX_REG_LIST(0),*/
350 /*DCN3_1_RDPCSTX_REG_LIST(1),*/
351 /*DCN3_1_RDPCSTX_REG_LIST(2),*/
352 /*DCN3_1_RDPCSTX_REG_LIST(3),*/
353
354static struct dcn31_hpo_dp_link_encoder_registers hpo_dp_link_enc_regs[2];
355
356static const struct dcn31_hpo_dp_link_encoder_shift hpo_dp_le_shift = {
357 DCN3_2_HPO_DP_LINK_ENC_MASK_SH_LIST(__SHIFT)
358};
359
360static const struct dcn31_hpo_dp_link_encoder_mask hpo_dp_le_mask = {
361 DCN3_2_HPO_DP_LINK_ENC_MASK_SH_LIST(_MASK)
362};
363
364#define dpp_regs_init(id)\
365 DPP_REG_LIST_DCN30_COMMON_RI(id)
366
367static struct dcn3_dpp_registers dpp_regs[4];
368
369static const struct dcn3_dpp_shift tf_shift = {
370 DPP_REG_LIST_SH_MASK_DCN30_COMMON(__SHIFT)
371};
372
373static const struct dcn3_dpp_mask tf_mask = {
374 DPP_REG_LIST_SH_MASK_DCN30_COMMON(_MASK)
375};
376
377
378#define opp_regs_init(id)\
379 OPP_REG_LIST_DCN30_RI(id)
380
381static struct dcn20_opp_registers opp_regs[4];
382
383static const struct dcn20_opp_shift opp_shift = {
384 OPP_MASK_SH_LIST_DCN20(__SHIFT)
385};
386
387static const struct dcn20_opp_mask opp_mask = {
388 OPP_MASK_SH_LIST_DCN20(_MASK)
389};
390
391#define aux_engine_regs_init(id) \
392 ( \
393 AUX_COMMON_REG_LIST0_RI(id), SR_ARR_INIT(AUXN_IMPCAL, id, 0), \
394 SR_ARR_INIT(AUXP_IMPCAL, id, 0), \
395 SR_ARR_INIT(AUX_RESET_MASK, id, DP_AUX0_AUX_CONTROL__AUX_RESET_MASK), \
396 SR_ARR_INIT(AUX_RESET_MASK, id, DP_AUX0_AUX_CONTROL__AUX_RESET_MASK)\
397 )
398
399static struct dce110_aux_registers aux_engine_regs[5];
400
401static const struct dce110_aux_registers_shift aux_shift = {
402 DCN_AUX_MASK_SH_LIST(__SHIFT)
403};
404
405static const struct dce110_aux_registers_mask aux_mask = {
406 DCN_AUX_MASK_SH_LIST(_MASK)
407};
408
409#define dwbc_regs_dcn3_init(id)\
410 DWBC_COMMON_REG_LIST_DCN30_RI(id)
411
412static struct dcn30_dwbc_registers dwbc30_regs[1];
413
414static const struct dcn30_dwbc_shift dwbc30_shift = {
415 DWBC_COMMON_MASK_SH_LIST_DCN30(__SHIFT)
416};
417
418static const struct dcn30_dwbc_mask dwbc30_mask = {
419 DWBC_COMMON_MASK_SH_LIST_DCN30(_MASK)
420};
421
422#define mcif_wb_regs_dcn3_init(id)\
423 MCIF_WB_COMMON_REG_LIST_DCN32_RI(id)
424
425static struct dcn30_mmhubbub_registers mcif_wb30_regs[1];
426
427static const struct dcn30_mmhubbub_shift mcif_wb30_shift = {
428 MCIF_WB_COMMON_MASK_SH_LIST_DCN32(__SHIFT)
429};
430
431static const struct dcn30_mmhubbub_mask mcif_wb30_mask = {
432 MCIF_WB_COMMON_MASK_SH_LIST_DCN32(_MASK)
433};
434
435#define dsc_regsDCN20_init(id)\
436 DSC_REG_LIST_DCN20_RI(id)
437
438static struct dcn20_dsc_registers dsc_regs[4];
439
440static const struct dcn20_dsc_shift dsc_shift = {
441 DSC_REG_LIST_SH_MASK_DCN20(__SHIFT)
442};
443
444static const struct dcn20_dsc_mask dsc_mask = {
445 DSC_REG_LIST_SH_MASK_DCN20(_MASK)
446};
447
448static struct dcn30_mpc_registers mpc_regs;
449#define dcn_mpc_regs_init()\
450 MPC_REG_LIST_DCN3_2_RI(0),\
451 MPC_REG_LIST_DCN3_2_RI(1),\
452 MPC_REG_LIST_DCN3_2_RI(2),\
453 MPC_REG_LIST_DCN3_2_RI(3),\
454 MPC_OUT_MUX_REG_LIST_DCN3_0_RI(0),\
455 MPC_OUT_MUX_REG_LIST_DCN3_0_RI(1),\
456 MPC_OUT_MUX_REG_LIST_DCN3_0_RI(2),\
457 MPC_OUT_MUX_REG_LIST_DCN3_0_RI(3),\
458 MPC_DWB_MUX_REG_LIST_DCN3_0_RI(0)
459
460static const struct dcn30_mpc_shift mpc_shift = {
461 MPC_COMMON_MASK_SH_LIST_DCN32(__SHIFT)
462};
463
464static const struct dcn30_mpc_mask mpc_mask = {
465 MPC_COMMON_MASK_SH_LIST_DCN32(_MASK)
466};
467
468#define optc_regs_init(id)\
469 OPTC_COMMON_REG_LIST_DCN3_2_RI(id)
470
471static struct dcn_optc_registers optc_regs[4];
472
473static const struct dcn_optc_shift optc_shift = {
474 OPTC_COMMON_MASK_SH_LIST_DCN3_2(__SHIFT)
475};
476
477static const struct dcn_optc_mask optc_mask = {
478 OPTC_COMMON_MASK_SH_LIST_DCN3_2(_MASK)
479};
480
481#define hubp_regs_init(id) \
482 HUBP_REG_LIST_DCN32_RI(id)
483
484static struct dcn_hubp2_registers hubp_regs[4];
485
486static const struct dcn_hubp2_shift hubp_shift = {
487 HUBP_MASK_SH_LIST_DCN32(__SHIFT)
488};
489
490static const struct dcn_hubp2_mask hubp_mask = {
491 HUBP_MASK_SH_LIST_DCN32(_MASK)
492};
493
494static struct dcn_hubbub_registers hubbub_reg;
495#define hubbub_reg_init()\
496 HUBBUB_REG_LIST_DCN32_RI(0)
497
498static const struct dcn_hubbub_shift hubbub_shift = {
499 HUBBUB_MASK_SH_LIST_DCN32(__SHIFT)
500};
501
502static const struct dcn_hubbub_mask hubbub_mask = {
503 HUBBUB_MASK_SH_LIST_DCN32(_MASK)
504};
505
506static struct dccg_registers dccg_regs;
507
508#define dccg_regs_init()\
509 DCCG_REG_LIST_DCN32_RI()
510
511static const struct dccg_shift dccg_shift = {
512 DCCG_MASK_SH_LIST_DCN32(__SHIFT)
513};
514
515static const struct dccg_mask dccg_mask = {
516 DCCG_MASK_SH_LIST_DCN32(_MASK)
517};
518
519
520#define SRII2(reg_name_pre, reg_name_post, id)\
521 .reg_name_pre ## _ ## reg_name_post[id] = BASE(reg ## reg_name_pre \
522 ## id ## _ ## reg_name_post ## _BASE_IDX) + \
523 reg ## reg_name_pre ## id ## _ ## reg_name_post
524
525
526#define HWSEQ_DCN32_REG_LIST()\
527 SR(DCHUBBUB_GLOBAL_TIMER_CNTL), \
528 SR(DIO_MEM_PWR_CTRL), \
529 SR(ODM_MEM_PWR_CTRL3), \
530 SR(MMHUBBUB_MEM_PWR_CNTL), \
531 SR(DCCG_GATE_DISABLE_CNTL), \
532 SR(DCCG_GATE_DISABLE_CNTL2), \
533 SR(DCFCLK_CNTL),\
534 SR(DC_MEM_GLOBAL_PWR_REQ_CNTL), \
535 SRII(PIXEL_RATE_CNTL, OTG, 0), \
536 SRII(PIXEL_RATE_CNTL, OTG, 1),\
537 SRII(PIXEL_RATE_CNTL, OTG, 2),\
538 SRII(PIXEL_RATE_CNTL, OTG, 3),\
539 SRII(PHYPLL_PIXEL_RATE_CNTL, OTG, 0),\
540 SRII(PHYPLL_PIXEL_RATE_CNTL, OTG, 1),\
541 SRII(PHYPLL_PIXEL_RATE_CNTL, OTG, 2),\
542 SRII(PHYPLL_PIXEL_RATE_CNTL, OTG, 3),\
543 SR(MICROSECOND_TIME_BASE_DIV), \
544 SR(MILLISECOND_TIME_BASE_DIV), \
545 SR(DISPCLK_FREQ_CHANGE_CNTL), \
546 SR(RBBMIF_TIMEOUT_DIS), \
547 SR(RBBMIF_TIMEOUT_DIS_2), \
548 SR(DCHUBBUB_CRC_CTRL), \
549 SR(DPP_TOP0_DPP_CRC_CTRL), \
550 SR(DPP_TOP0_DPP_CRC_VAL_B_A), \
551 SR(DPP_TOP0_DPP_CRC_VAL_R_G), \
552 SR(MPC_CRC_CTRL), \
553 SR(MPC_CRC_RESULT_GB), \
554 SR(MPC_CRC_RESULT_C), \
555 SR(MPC_CRC_RESULT_AR), \
556 SR(DOMAIN0_PG_CONFIG), \
557 SR(DOMAIN1_PG_CONFIG), \
558 SR(DOMAIN2_PG_CONFIG), \
559 SR(DOMAIN3_PG_CONFIG), \
560 SR(DOMAIN16_PG_CONFIG), \
561 SR(DOMAIN17_PG_CONFIG), \
562 SR(DOMAIN18_PG_CONFIG), \
563 SR(DOMAIN19_PG_CONFIG), \
564 SR(DOMAIN0_PG_STATUS), \
565 SR(DOMAIN1_PG_STATUS), \
566 SR(DOMAIN2_PG_STATUS), \
567 SR(DOMAIN3_PG_STATUS), \
568 SR(DOMAIN16_PG_STATUS), \
569 SR(DOMAIN17_PG_STATUS), \
570 SR(DOMAIN18_PG_STATUS), \
571 SR(DOMAIN19_PG_STATUS), \
572 SR(D1VGA_CONTROL), \
573 SR(D2VGA_CONTROL), \
574 SR(D3VGA_CONTROL), \
575 SR(D4VGA_CONTROL), \
576 SR(D5VGA_CONTROL), \
577 SR(D6VGA_CONTROL), \
578 SR(DC_IP_REQUEST_CNTL), \
579 SR(AZALIA_AUDIO_DTO), \
580 SR(AZALIA_CONTROLLER_CLOCK_GATING)
581
582static struct dce_hwseq_registers hwseq_reg;
583
584#define hwseq_reg_init()\
585 HWSEQ_DCN32_REG_LIST()
586
587#define HWSEQ_DCN32_MASK_SH_LIST(mask_sh)\
588 HWSEQ_DCN_MASK_SH_LIST(mask_sh), \
589 HWS_SF(, DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, mask_sh), \
590 HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \
591 HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \
592 HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \
593 HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \
594 HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \
595 HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \
596 HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \
597 HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \
598 HWS_SF(, DOMAIN16_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \
599 HWS_SF(, DOMAIN16_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \
600 HWS_SF(, DOMAIN17_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \
601 HWS_SF(, DOMAIN17_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \
602 HWS_SF(, DOMAIN18_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \
603 HWS_SF(, DOMAIN18_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \
604 HWS_SF(, DOMAIN19_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \
605 HWS_SF(, DOMAIN19_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \
606 HWS_SF(, DOMAIN0_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \
607 HWS_SF(, DOMAIN1_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \
608 HWS_SF(, DOMAIN2_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \
609 HWS_SF(, DOMAIN3_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \
610 HWS_SF(, DOMAIN16_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \
611 HWS_SF(, DOMAIN17_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \
612 HWS_SF(, DOMAIN18_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \
613 HWS_SF(, DOMAIN19_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \
614 HWS_SF(, DC_IP_REQUEST_CNTL, IP_REQUEST_EN, mask_sh), \
615 HWS_SF(, AZALIA_AUDIO_DTO, AZALIA_AUDIO_DTO_MODULE, mask_sh), \
616 HWS_SF(, HPO_TOP_CLOCK_CONTROL, HPO_HDMISTREAMCLK_G_GATE_DIS, mask_sh), \
617 HWS_SF(, ODM_MEM_PWR_CTRL3, ODM_MEM_UNASSIGNED_PWR_MODE, mask_sh), \
618 HWS_SF(, ODM_MEM_PWR_CTRL3, ODM_MEM_VBLANK_PWR_MODE, mask_sh), \
619 HWS_SF(, MMHUBBUB_MEM_PWR_CNTL, VGA_MEM_PWR_FORCE, mask_sh)
620
621static const struct dce_hwseq_shift hwseq_shift = {
622 HWSEQ_DCN32_MASK_SH_LIST(__SHIFT)
623};
624
625static const struct dce_hwseq_mask hwseq_mask = {
626 HWSEQ_DCN32_MASK_SH_LIST(_MASK)
627};
628#define vmid_regs_init(id)\
629 DCN20_VMID_REG_LIST_RI(id)
630
631static struct dcn_vmid_registers vmid_regs[16];
632
633static const struct dcn20_vmid_shift vmid_shifts = {
634 DCN20_VMID_MASK_SH_LIST(__SHIFT)
635};
636
637static const struct dcn20_vmid_mask vmid_masks = {
638 DCN20_VMID_MASK_SH_LIST(_MASK)
639};
640
641static const struct resource_caps res_cap_dcn321 = {
642 .num_timing_generator = 4,
643 .num_opp = 4,
644 .num_video_plane = 4,
645 .num_audio = 5,
646 .num_stream_encoder = 5,
647 .num_hpo_dp_stream_encoder = 4,
648 .num_hpo_dp_link_encoder = 2,
649 .num_pll = 5,
650 .num_dwb = 1,
651 .num_ddc = 5,
652 .num_vmid = 16,
653 .num_mpc_3dlut = 4,
654 .num_dsc = 4,
655};
656
657static const struct dc_plane_cap plane_cap = {
658 .type = DC_PLANE_TYPE_DCN_UNIVERSAL,
659 .blends_with_above = true,
660 .blends_with_below = true,
661 .per_pixel_alpha = true,
662
663 .pixel_format_support = {
664 .argb8888 = true,
665 .nv12 = true,
666 .fp16 = true,
667 .p010 = true,
668 .ayuv = false,
669 },
670
671 .max_upscale_factor = {
672 .argb8888 = 16000,
673 .nv12 = 16000,
674 .fp16 = 16000
675 },
676
677 // 6:1 downscaling ratio: 1000/6 = 166.666
678 .max_downscale_factor = {
679 .argb8888 = 167,
680 .nv12 = 167,
681 .fp16 = 167
682 },
683 64,
684 64
685};
686
687static const struct dc_debug_options debug_defaults_drv = {
688 .disable_dmcu = true,
689 .force_abm_enable = false,
690 .timing_trace = false,
691 .clock_trace = true,
692 .disable_pplib_clock_request = false,
693 .pipe_split_policy = MPC_SPLIT_AVOID,
694 .force_single_disp_pipe_split = false,
695 .disable_dcc = DCC_ENABLE,
696 .vsr_support = true,
697 .performance_trace = false,
698 .max_downscale_src_width = 7680,/*upto 8K*/
699 .disable_pplib_wm_range = false,
700 .scl_reset_length10 = true,
701 .sanity_checks = false,
702 .underflow_assert_delay_us = 0xFFFFFFFF,
703 .dwb_fi_phase = -1, // -1 = disable,
704 .dmub_command_table = true,
705 .enable_mem_low_power = {
706 .bits = {
707 .vga = false,
708 .i2c = false,
709 .dmcu = false, // This is previously known to cause hang on S3 cycles if enabled
710 .dscl = false,
711 .cm = false,
712 .mpc = false,
713 .optc = true,
714 }
715 },
716 .use_max_lb = true,
717 .force_disable_subvp = false,
718 .exit_idle_opt_for_cursor_updates = true,
719 .enable_single_display_2to1_odm_policy = true,
720
721 /*must match enable_single_display_2to1_odm_policy to support dynamic ODM transitions*/
722 .enable_double_buffered_dsc_pg_support = true,
723 .enable_dp_dig_pixel_rate_div_policy = 1,
724 .allow_sw_cursor_fallback = false, // Linux can't do SW cursor "fallback"
725 .alloc_extra_way_for_cursor = true,
726 .min_prefetch_in_strobe_ns = 60000, // 60us
727};
728
729static const struct dc_debug_options debug_defaults_diags = {
730 .disable_dmcu = true,
731 .force_abm_enable = false,
732 .timing_trace = true,
733 .clock_trace = true,
734 .disable_dpp_power_gate = true,
735 .disable_hubp_power_gate = true,
736 .disable_dsc_power_gate = true,
737 .disable_clock_gate = true,
738 .disable_pplib_clock_request = true,
739 .disable_pplib_wm_range = true,
740 .disable_stutter = false,
741 .scl_reset_length10 = true,
742 .dwb_fi_phase = -1, // -1 = disable
743 .dmub_command_table = true,
744 .enable_tri_buf = true,
745 .use_max_lb = true,
746 .force_disable_subvp = true,
747};
748
749
750static struct dce_aux *dcn321_aux_engine_create(
751 struct dc_context *ctx,
752 uint32_t inst)
753{
754 struct aux_engine_dce110 *aux_engine =
755 kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL);
756
757 if (!aux_engine)
758 return NULL;
759
760#undef REG_STRUCT
761#define REG_STRUCT aux_engine_regs
762 aux_engine_regs_init(0),
763 aux_engine_regs_init(1),
764 aux_engine_regs_init(2),
765 aux_engine_regs_init(3),
766 aux_engine_regs_init(4);
767
768 dce110_aux_engine_construct(aux_engine, ctx, inst,
769 SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD,
770 &aux_engine_regs[inst],
771 &aux_mask,
772 &aux_shift,
773 ctx->dc->caps.extended_aux_timeout_support);
774
775 return &aux_engine->base;
776}
777#define i2c_inst_regs_init(id)\
778 I2C_HW_ENGINE_COMMON_REG_LIST_DCN30_RI(id)
779
780static struct dce_i2c_registers i2c_hw_regs[5];
781
782static const struct dce_i2c_shift i2c_shifts = {
783 I2C_COMMON_MASK_SH_LIST_DCN30(__SHIFT)
784};
785
786static const struct dce_i2c_mask i2c_masks = {
787 I2C_COMMON_MASK_SH_LIST_DCN30(_MASK)
788};
789
790static struct dce_i2c_hw *dcn321_i2c_hw_create(
791 struct dc_context *ctx,
792 uint32_t inst)
793{
794 struct dce_i2c_hw *dce_i2c_hw =
795 kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL);
796
797 if (!dce_i2c_hw)
798 return NULL;
799
800#undef REG_STRUCT
801#define REG_STRUCT i2c_hw_regs
802 i2c_inst_regs_init(1),
803 i2c_inst_regs_init(2),
804 i2c_inst_regs_init(3),
805 i2c_inst_regs_init(4),
806 i2c_inst_regs_init(5);
807
808 dcn2_i2c_hw_construct(dce_i2c_hw, ctx, inst,
809 &i2c_hw_regs[inst], &i2c_shifts, &i2c_masks);
810
811 return dce_i2c_hw;
812}
813
814static struct clock_source *dcn321_clock_source_create(
815 struct dc_context *ctx,
816 struct dc_bios *bios,
817 enum clock_source_id id,
818 const struct dce110_clk_src_regs *regs,
819 bool dp_clk_src)
820{
821 struct dce110_clk_src *clk_src =
822 kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL);
823
824 if (!clk_src)
825 return NULL;
826
827 if (dcn31_clk_src_construct(clk_src, ctx, bios, id,
828 regs, &cs_shift, &cs_mask)) {
829 clk_src->base.dp_clk_src = dp_clk_src;
830 return &clk_src->base;
831 }
832
833 kfree(clk_src);
834 BREAK_TO_DEBUGGER();
835 return NULL;
836}
837
838static struct hubbub *dcn321_hubbub_create(struct dc_context *ctx)
839{
840 int i;
841
842 struct dcn20_hubbub *hubbub2 = kzalloc(sizeof(struct dcn20_hubbub),
843 GFP_KERNEL);
844
845 if (!hubbub2)
846 return NULL;
847
848#undef REG_STRUCT
849#define REG_STRUCT hubbub_reg
850 hubbub_reg_init();
851
852#undef REG_STRUCT
853#define REG_STRUCT vmid_regs
854 vmid_regs_init(0),
855 vmid_regs_init(1),
856 vmid_regs_init(2),
857 vmid_regs_init(3),
858 vmid_regs_init(4),
859 vmid_regs_init(5),
860 vmid_regs_init(6),
861 vmid_regs_init(7),
862 vmid_regs_init(8),
863 vmid_regs_init(9),
864 vmid_regs_init(10),
865 vmid_regs_init(11),
866 vmid_regs_init(12),
867 vmid_regs_init(13),
868 vmid_regs_init(14),
869 vmid_regs_init(15);
870
871 hubbub32_construct(hubbub2, ctx,
872 &hubbub_reg,
873 &hubbub_shift,
874 &hubbub_mask,
875 ctx->dc->dml.ip.det_buffer_size_kbytes,
876 ctx->dc->dml.ip.pixel_chunk_size_kbytes,
877 ctx->dc->dml.ip.config_return_buffer_size_in_kbytes);
878
879
880 for (i = 0; i < res_cap_dcn321.num_vmid; i++) {
881 struct dcn20_vmid *vmid = &hubbub2->vmid[i];
882
883 vmid->ctx = ctx;
884
885 vmid->regs = &vmid_regs[i];
886 vmid->shifts = &vmid_shifts;
887 vmid->masks = &vmid_masks;
888 }
889
890 return &hubbub2->base;
891}
892
893static struct hubp *dcn321_hubp_create(
894 struct dc_context *ctx,
895 uint32_t inst)
896{
897 struct dcn20_hubp *hubp2 =
898 kzalloc(sizeof(struct dcn20_hubp), GFP_KERNEL);
899
900 if (!hubp2)
901 return NULL;
902
903#undef REG_STRUCT
904#define REG_STRUCT hubp_regs
905 hubp_regs_init(0),
906 hubp_regs_init(1),
907 hubp_regs_init(2),
908 hubp_regs_init(3);
909
910 if (hubp32_construct(hubp2, ctx, inst,
911 &hubp_regs[inst], &hubp_shift, &hubp_mask))
912 return &hubp2->base;
913
914 BREAK_TO_DEBUGGER();
915 kfree(hubp2);
916 return NULL;
917}
918
919static void dcn321_dpp_destroy(struct dpp **dpp)
920{
921 kfree(TO_DCN30_DPP(*dpp));
922 *dpp = NULL;
923}
924
925static struct dpp *dcn321_dpp_create(
926 struct dc_context *ctx,
927 uint32_t inst)
928{
929 struct dcn3_dpp *dpp3 =
930 kzalloc(sizeof(struct dcn3_dpp), GFP_KERNEL);
931
932 if (!dpp3)
933 return NULL;
934
935#undef REG_STRUCT
936#define REG_STRUCT dpp_regs
937 dpp_regs_init(0),
938 dpp_regs_init(1),
939 dpp_regs_init(2),
940 dpp_regs_init(3);
941
942 if (dpp32_construct(dpp3, ctx, inst,
943 &dpp_regs[inst], &tf_shift, &tf_mask))
944 return &dpp3->base;
945
946 BREAK_TO_DEBUGGER();
947 kfree(dpp3);
948 return NULL;
949}
950
951static struct mpc *dcn321_mpc_create(
952 struct dc_context *ctx,
953 int num_mpcc,
954 int num_rmu)
955{
956 struct dcn30_mpc *mpc30 = kzalloc(sizeof(struct dcn30_mpc),
957 GFP_KERNEL);
958
959 if (!mpc30)
960 return NULL;
961
962#undef REG_STRUCT
963#define REG_STRUCT mpc_regs
964 dcn_mpc_regs_init();
965
966 dcn32_mpc_construct(mpc30, ctx,
967 &mpc_regs,
968 &mpc_shift,
969 &mpc_mask,
970 num_mpcc,
971 num_rmu);
972
973 return &mpc30->base;
974}
975
976static struct output_pixel_processor *dcn321_opp_create(
977 struct dc_context *ctx, uint32_t inst)
978{
979 struct dcn20_opp *opp2 =
980 kzalloc(sizeof(struct dcn20_opp), GFP_KERNEL);
981
982 if (!opp2) {
983 BREAK_TO_DEBUGGER();
984 return NULL;
985 }
986
987#undef REG_STRUCT
988#define REG_STRUCT opp_regs
989 opp_regs_init(0),
990 opp_regs_init(1),
991 opp_regs_init(2),
992 opp_regs_init(3);
993
994 dcn20_opp_construct(opp2, ctx, inst,
995 &opp_regs[inst], &opp_shift, &opp_mask);
996 return &opp2->base;
997}
998
999
1000static struct timing_generator *dcn321_timing_generator_create(
1001 struct dc_context *ctx,
1002 uint32_t instance)
1003{
1004 struct optc *tgn10 =
1005 kzalloc(sizeof(struct optc), GFP_KERNEL);
1006
1007 if (!tgn10)
1008 return NULL;
1009
1010#undef REG_STRUCT
1011#define REG_STRUCT optc_regs
1012 optc_regs_init(0),
1013 optc_regs_init(1),
1014 optc_regs_init(2),
1015 optc_regs_init(3);
1016
1017 tgn10->base.inst = instance;
1018 tgn10->base.ctx = ctx;
1019
1020 tgn10->tg_regs = &optc_regs[instance];
1021 tgn10->tg_shift = &optc_shift;
1022 tgn10->tg_mask = &optc_mask;
1023
1024 dcn32_timing_generator_init(tgn10);
1025
1026 return &tgn10->base;
1027}
1028
1029static const struct encoder_feature_support link_enc_feature = {
1030 .max_hdmi_deep_color = COLOR_DEPTH_121212,
1031 .max_hdmi_pixel_clock = 600000,
1032 .hdmi_ycbcr420_supported = true,
1033 .dp_ycbcr420_supported = true,
1034 .fec_supported = true,
1035 .flags.bits.IS_HBR2_CAPABLE = true,
1036 .flags.bits.IS_HBR3_CAPABLE = true,
1037 .flags.bits.IS_TPS3_CAPABLE = true,
1038 .flags.bits.IS_TPS4_CAPABLE = true
1039};
1040
1041static struct link_encoder *dcn321_link_encoder_create(
1042 struct dc_context *ctx,
1043 const struct encoder_init_data *enc_init_data)
1044{
1045 struct dcn20_link_encoder *enc20 =
1046 kzalloc(sizeof(struct dcn20_link_encoder), GFP_KERNEL);
1047
1048 if (!enc20)
1049 return NULL;
1050
1051#undef REG_STRUCT
1052#define REG_STRUCT link_enc_aux_regs
1053 aux_regs_init(0),
1054 aux_regs_init(1),
1055 aux_regs_init(2),
1056 aux_regs_init(3),
1057 aux_regs_init(4);
1058
1059#undef REG_STRUCT
1060#define REG_STRUCT link_enc_hpd_regs
1061 hpd_regs_init(0),
1062 hpd_regs_init(1),
1063 hpd_regs_init(2),
1064 hpd_regs_init(3),
1065 hpd_regs_init(4);
1066
1067#undef REG_STRUCT
1068#define REG_STRUCT link_enc_regs
1069 link_regs_init(0, A),
1070 link_regs_init(1, B),
1071 link_regs_init(2, C),
1072 link_regs_init(3, D),
1073 link_regs_init(4, E);
1074
1075 dcn321_link_encoder_construct(enc20,
1076 enc_init_data,
1077 &link_enc_feature,
1078 &link_enc_regs[enc_init_data->transmitter],
1079 &link_enc_aux_regs[enc_init_data->channel - 1],
1080 &link_enc_hpd_regs[enc_init_data->hpd_source],
1081 &le_shift,
1082 &le_mask);
1083
1084 return &enc20->enc10.base;
1085}
1086
1087static void read_dce_straps(
1088 struct dc_context *ctx,
1089 struct resource_straps *straps)
1090{
1091 generic_reg_get(ctx, ctx->dcn_reg_offsets[regDC_PINSTRAPS_BASE_IDX] + regDC_PINSTRAPS,
1092 FN(DC_PINSTRAPS, DC_PINSTRAPS_AUDIO), &straps->dc_pinstraps_audio);
1093
1094}
1095
1096static struct audio *dcn321_create_audio(
1097 struct dc_context *ctx, unsigned int inst)
1098{
1099
1100#undef REG_STRUCT
1101#define REG_STRUCT audio_regs
1102 audio_regs_init(0),
1103 audio_regs_init(1),
1104 audio_regs_init(2),
1105 audio_regs_init(3),
1106 audio_regs_init(4);
1107
1108 return dce_audio_create(ctx, inst,
1109 &audio_regs[inst], &audio_shift, &audio_mask);
1110}
1111
1112static struct vpg *dcn321_vpg_create(
1113 struct dc_context *ctx,
1114 uint32_t inst)
1115{
1116 struct dcn30_vpg *vpg3 = kzalloc(sizeof(struct dcn30_vpg), GFP_KERNEL);
1117
1118 if (!vpg3)
1119 return NULL;
1120
1121#undef REG_STRUCT
1122#define REG_STRUCT vpg_regs
1123 vpg_regs_init(0),
1124 vpg_regs_init(1),
1125 vpg_regs_init(2),
1126 vpg_regs_init(3),
1127 vpg_regs_init(4),
1128 vpg_regs_init(5),
1129 vpg_regs_init(6),
1130 vpg_regs_init(7),
1131 vpg_regs_init(8),
1132 vpg_regs_init(9);
1133
1134 vpg3_construct(vpg3, ctx, inst,
1135 &vpg_regs[inst],
1136 &vpg_shift,
1137 &vpg_mask);
1138
1139 return &vpg3->base;
1140}
1141
1142static struct afmt *dcn321_afmt_create(
1143 struct dc_context *ctx,
1144 uint32_t inst)
1145{
1146 struct dcn30_afmt *afmt3 = kzalloc(sizeof(struct dcn30_afmt), GFP_KERNEL);
1147
1148 if (!afmt3)
1149 return NULL;
1150
1151#undef REG_STRUCT
1152#define REG_STRUCT afmt_regs
1153 afmt_regs_init(0),
1154 afmt_regs_init(1),
1155 afmt_regs_init(2),
1156 afmt_regs_init(3),
1157 afmt_regs_init(4),
1158 afmt_regs_init(5);
1159
1160 afmt3_construct(afmt3, ctx, inst,
1161 &afmt_regs[inst],
1162 &afmt_shift,
1163 &afmt_mask);
1164
1165 return &afmt3->base;
1166}
1167
1168static struct apg *dcn321_apg_create(
1169 struct dc_context *ctx,
1170 uint32_t inst)
1171{
1172 struct dcn31_apg *apg31 = kzalloc(sizeof(struct dcn31_apg), GFP_KERNEL);
1173
1174 if (!apg31)
1175 return NULL;
1176
1177#undef REG_STRUCT
1178#define REG_STRUCT apg_regs
1179 apg_regs_init(0),
1180 apg_regs_init(1),
1181 apg_regs_init(2),
1182 apg_regs_init(3);
1183
1184 apg31_construct(apg31, ctx, inst,
1185 &apg_regs[inst],
1186 &apg_shift,
1187 &apg_mask);
1188
1189 return &apg31->base;
1190}
1191
1192static struct stream_encoder *dcn321_stream_encoder_create(
1193 enum engine_id eng_id,
1194 struct dc_context *ctx)
1195{
1196 struct dcn10_stream_encoder *enc1;
1197 struct vpg *vpg;
1198 struct afmt *afmt;
1199 int vpg_inst;
1200 int afmt_inst;
1201
1202 /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */
1203 if (eng_id <= ENGINE_ID_DIGF) {
1204 vpg_inst = eng_id;
1205 afmt_inst = eng_id;
1206 } else
1207 return NULL;
1208
1209 enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL);
1210 vpg = dcn321_vpg_create(ctx, vpg_inst);
1211 afmt = dcn321_afmt_create(ctx, afmt_inst);
1212
1213 if (!enc1 || !vpg || !afmt) {
1214 kfree(enc1);
1215 kfree(vpg);
1216 kfree(afmt);
1217 return NULL;
1218 }
1219
1220#undef REG_STRUCT
1221#define REG_STRUCT stream_enc_regs
1222 stream_enc_regs_init(0),
1223 stream_enc_regs_init(1),
1224 stream_enc_regs_init(2),
1225 stream_enc_regs_init(3),
1226 stream_enc_regs_init(4);
1227
1228 dcn32_dio_stream_encoder_construct(enc1, ctx, ctx->dc_bios,
1229 eng_id, vpg, afmt,
1230 &stream_enc_regs[eng_id],
1231 &se_shift, &se_mask);
1232
1233 return &enc1->base;
1234}
1235
1236static struct hpo_dp_stream_encoder *dcn321_hpo_dp_stream_encoder_create(
1237 enum engine_id eng_id,
1238 struct dc_context *ctx)
1239{
1240 struct dcn31_hpo_dp_stream_encoder *hpo_dp_enc31;
1241 struct vpg *vpg;
1242 struct apg *apg;
1243 uint32_t hpo_dp_inst;
1244 uint32_t vpg_inst;
1245 uint32_t apg_inst;
1246
1247 ASSERT((eng_id >= ENGINE_ID_HPO_DP_0) && (eng_id <= ENGINE_ID_HPO_DP_3));
1248 hpo_dp_inst = eng_id - ENGINE_ID_HPO_DP_0;
1249
1250 /* Mapping of VPG register blocks to HPO DP block instance:
1251 * VPG[6] -> HPO_DP[0]
1252 * VPG[7] -> HPO_DP[1]
1253 * VPG[8] -> HPO_DP[2]
1254 * VPG[9] -> HPO_DP[3]
1255 */
1256 vpg_inst = hpo_dp_inst + 6;
1257
1258 /* Mapping of APG register blocks to HPO DP block instance:
1259 * APG[0] -> HPO_DP[0]
1260 * APG[1] -> HPO_DP[1]
1261 * APG[2] -> HPO_DP[2]
1262 * APG[3] -> HPO_DP[3]
1263 */
1264 apg_inst = hpo_dp_inst;
1265
1266 /* allocate HPO stream encoder and create VPG sub-block */
1267 hpo_dp_enc31 = kzalloc(sizeof(struct dcn31_hpo_dp_stream_encoder), GFP_KERNEL);
1268 vpg = dcn321_vpg_create(ctx, vpg_inst);
1269 apg = dcn321_apg_create(ctx, apg_inst);
1270
1271 if (!hpo_dp_enc31 || !vpg || !apg) {
1272 kfree(hpo_dp_enc31);
1273 kfree(vpg);
1274 kfree(apg);
1275 return NULL;
1276 }
1277
1278#undef REG_STRUCT
1279#define REG_STRUCT hpo_dp_stream_enc_regs
1280 hpo_dp_stream_encoder_reg_init(0),
1281 hpo_dp_stream_encoder_reg_init(1),
1282 hpo_dp_stream_encoder_reg_init(2),
1283 hpo_dp_stream_encoder_reg_init(3);
1284
1285 dcn31_hpo_dp_stream_encoder_construct(hpo_dp_enc31, ctx, ctx->dc_bios,
1286 hpo_dp_inst, eng_id, vpg, apg,
1287 &hpo_dp_stream_enc_regs[hpo_dp_inst],
1288 &hpo_dp_se_shift, &hpo_dp_se_mask);
1289
1290 return &hpo_dp_enc31->base;
1291}
1292
1293static struct hpo_dp_link_encoder *dcn321_hpo_dp_link_encoder_create(
1294 uint8_t inst,
1295 struct dc_context *ctx)
1296{
1297 struct dcn31_hpo_dp_link_encoder *hpo_dp_enc31;
1298
1299 /* allocate HPO link encoder */
1300 hpo_dp_enc31 = kzalloc(sizeof(struct dcn31_hpo_dp_link_encoder), GFP_KERNEL);
1301
1302#undef REG_STRUCT
1303#define REG_STRUCT hpo_dp_link_enc_regs
1304 hpo_dp_link_encoder_reg_init(0),
1305 hpo_dp_link_encoder_reg_init(1);
1306
1307 hpo_dp_link_encoder32_construct(hpo_dp_enc31, ctx, inst,
1308 &hpo_dp_link_enc_regs[inst],
1309 &hpo_dp_le_shift, &hpo_dp_le_mask);
1310
1311 return &hpo_dp_enc31->base;
1312}
1313
1314static struct dce_hwseq *dcn321_hwseq_create(
1315 struct dc_context *ctx)
1316{
1317 struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL);
1318
1319#undef REG_STRUCT
1320#define REG_STRUCT hwseq_reg
1321 hwseq_reg_init();
1322
1323 if (hws) {
1324 hws->ctx = ctx;
1325 hws->regs = &hwseq_reg;
1326 hws->shifts = &hwseq_shift;
1327 hws->masks = &hwseq_mask;
1328 }
1329 return hws;
1330}
1331static const struct resource_create_funcs res_create_funcs = {
1332 .read_dce_straps = read_dce_straps,
1333 .create_audio = dcn321_create_audio,
1334 .create_stream_encoder = dcn321_stream_encoder_create,
1335 .create_hpo_dp_stream_encoder = dcn321_hpo_dp_stream_encoder_create,
1336 .create_hpo_dp_link_encoder = dcn321_hpo_dp_link_encoder_create,
1337 .create_hwseq = dcn321_hwseq_create,
1338};
1339
1340static const struct resource_create_funcs res_create_maximus_funcs = {
1341 .read_dce_straps = NULL,
1342 .create_audio = NULL,
1343 .create_stream_encoder = NULL,
1344 .create_hpo_dp_stream_encoder = dcn321_hpo_dp_stream_encoder_create,
1345 .create_hpo_dp_link_encoder = dcn321_hpo_dp_link_encoder_create,
1346 .create_hwseq = dcn321_hwseq_create,
1347};
1348
1349static void dcn321_resource_destruct(struct dcn321_resource_pool *pool)
1350{
1351 unsigned int i;
1352
1353 for (i = 0; i < pool->base.stream_enc_count; i++) {
1354 if (pool->base.stream_enc[i] != NULL) {
1355 if (pool->base.stream_enc[i]->vpg != NULL) {
1356 kfree(DCN30_VPG_FROM_VPG(pool->base.stream_enc[i]->vpg));
1357 pool->base.stream_enc[i]->vpg = NULL;
1358 }
1359 if (pool->base.stream_enc[i]->afmt != NULL) {
1360 kfree(DCN30_AFMT_FROM_AFMT(pool->base.stream_enc[i]->afmt));
1361 pool->base.stream_enc[i]->afmt = NULL;
1362 }
1363 kfree(DCN10STRENC_FROM_STRENC(pool->base.stream_enc[i]));
1364 pool->base.stream_enc[i] = NULL;
1365 }
1366 }
1367
1368 for (i = 0; i < pool->base.hpo_dp_stream_enc_count; i++) {
1369 if (pool->base.hpo_dp_stream_enc[i] != NULL) {
1370 if (pool->base.hpo_dp_stream_enc[i]->vpg != NULL) {
1371 kfree(DCN30_VPG_FROM_VPG(pool->base.hpo_dp_stream_enc[i]->vpg));
1372 pool->base.hpo_dp_stream_enc[i]->vpg = NULL;
1373 }
1374 if (pool->base.hpo_dp_stream_enc[i]->apg != NULL) {
1375 kfree(DCN31_APG_FROM_APG(pool->base.hpo_dp_stream_enc[i]->apg));
1376 pool->base.hpo_dp_stream_enc[i]->apg = NULL;
1377 }
1378 kfree(DCN3_1_HPO_DP_STREAM_ENC_FROM_HPO_STREAM_ENC(pool->base.hpo_dp_stream_enc[i]));
1379 pool->base.hpo_dp_stream_enc[i] = NULL;
1380 }
1381 }
1382
1383 for (i = 0; i < pool->base.hpo_dp_link_enc_count; i++) {
1384 if (pool->base.hpo_dp_link_enc[i] != NULL) {
1385 kfree(DCN3_1_HPO_DP_LINK_ENC_FROM_HPO_LINK_ENC(pool->base.hpo_dp_link_enc[i]));
1386 pool->base.hpo_dp_link_enc[i] = NULL;
1387 }
1388 }
1389
1390 for (i = 0; i < pool->base.res_cap->num_dsc; i++) {
1391 if (pool->base.dscs[i] != NULL)
1392 dcn20_dsc_destroy(&pool->base.dscs[i]);
1393 }
1394
1395 if (pool->base.mpc != NULL) {
1396 kfree(TO_DCN20_MPC(pool->base.mpc));
1397 pool->base.mpc = NULL;
1398 }
1399 if (pool->base.hubbub != NULL) {
1400 kfree(TO_DCN20_HUBBUB(pool->base.hubbub));
1401 pool->base.hubbub = NULL;
1402 }
1403 for (i = 0; i < pool->base.pipe_count; i++) {
1404 if (pool->base.dpps[i] != NULL)
1405 dcn321_dpp_destroy(&pool->base.dpps[i]);
1406
1407 if (pool->base.ipps[i] != NULL)
1408 pool->base.ipps[i]->funcs->ipp_destroy(&pool->base.ipps[i]);
1409
1410 if (pool->base.hubps[i] != NULL) {
1411 kfree(TO_DCN20_HUBP(pool->base.hubps[i]));
1412 pool->base.hubps[i] = NULL;
1413 }
1414
1415 if (pool->base.irqs != NULL)
1416 dal_irq_service_destroy(&pool->base.irqs);
1417 }
1418
1419 for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
1420 if (pool->base.engines[i] != NULL)
1421 dce110_engine_destroy(&pool->base.engines[i]);
1422 if (pool->base.hw_i2cs[i] != NULL) {
1423 kfree(pool->base.hw_i2cs[i]);
1424 pool->base.hw_i2cs[i] = NULL;
1425 }
1426 if (pool->base.sw_i2cs[i] != NULL) {
1427 kfree(pool->base.sw_i2cs[i]);
1428 pool->base.sw_i2cs[i] = NULL;
1429 }
1430 }
1431
1432 for (i = 0; i < pool->base.res_cap->num_opp; i++) {
1433 if (pool->base.opps[i] != NULL)
1434 pool->base.opps[i]->funcs->opp_destroy(&pool->base.opps[i]);
1435 }
1436
1437 for (i = 0; i < pool->base.res_cap->num_timing_generator; i++) {
1438 if (pool->base.timing_generators[i] != NULL) {
1439 kfree(DCN10TG_FROM_TG(pool->base.timing_generators[i]));
1440 pool->base.timing_generators[i] = NULL;
1441 }
1442 }
1443
1444 for (i = 0; i < pool->base.res_cap->num_dwb; i++) {
1445 if (pool->base.dwbc[i] != NULL) {
1446 kfree(TO_DCN30_DWBC(pool->base.dwbc[i]));
1447 pool->base.dwbc[i] = NULL;
1448 }
1449 if (pool->base.mcif_wb[i] != NULL) {
1450 kfree(TO_DCN30_MMHUBBUB(pool->base.mcif_wb[i]));
1451 pool->base.mcif_wb[i] = NULL;
1452 }
1453 }
1454
1455 for (i = 0; i < pool->base.audio_count; i++) {
1456 if (pool->base.audios[i])
1457 dce_aud_destroy(&pool->base.audios[i]);
1458 }
1459
1460 for (i = 0; i < pool->base.clk_src_count; i++) {
1461 if (pool->base.clock_sources[i] != NULL) {
1462 dcn20_clock_source_destroy(&pool->base.clock_sources[i]);
1463 pool->base.clock_sources[i] = NULL;
1464 }
1465 }
1466
1467 for (i = 0; i < pool->base.res_cap->num_mpc_3dlut; i++) {
1468 if (pool->base.mpc_lut[i] != NULL) {
1469 dc_3dlut_func_release(pool->base.mpc_lut[i]);
1470 pool->base.mpc_lut[i] = NULL;
1471 }
1472 if (pool->base.mpc_shaper[i] != NULL) {
1473 dc_transfer_func_release(pool->base.mpc_shaper[i]);
1474 pool->base.mpc_shaper[i] = NULL;
1475 }
1476 }
1477
1478 if (pool->base.dp_clock_source != NULL) {
1479 dcn20_clock_source_destroy(&pool->base.dp_clock_source);
1480 pool->base.dp_clock_source = NULL;
1481 }
1482
1483 for (i = 0; i < pool->base.res_cap->num_timing_generator; i++) {
1484 if (pool->base.multiple_abms[i] != NULL)
1485 dce_abm_destroy(&pool->base.multiple_abms[i]);
1486 }
1487
1488 if (pool->base.psr != NULL)
1489 dmub_psr_destroy(&pool->base.psr);
1490
1491 if (pool->base.dccg != NULL)
1492 dcn_dccg_destroy(&pool->base.dccg);
1493
1494 if (pool->base.oem_device != NULL)
1495 dal_ddc_service_destroy(&pool->base.oem_device);
1496}
1497
1498
1499static bool dcn321_dwbc_create(struct dc_context *ctx, struct resource_pool *pool)
1500{
1501 int i;
1502 uint32_t dwb_count = pool->res_cap->num_dwb;
1503
1504 for (i = 0; i < dwb_count; i++) {
1505 struct dcn30_dwbc *dwbc30 = kzalloc(sizeof(struct dcn30_dwbc),
1506 GFP_KERNEL);
1507
1508 if (!dwbc30) {
1509 dm_error("DC: failed to create dwbc30!\n");
1510 return false;
1511 }
1512
1513#undef REG_STRUCT
1514#define REG_STRUCT dwbc30_regs
1515 dwbc_regs_dcn3_init(0);
1516
1517 dcn30_dwbc_construct(dwbc30, ctx,
1518 &dwbc30_regs[i],
1519 &dwbc30_shift,
1520 &dwbc30_mask,
1521 i);
1522
1523 pool->dwbc[i] = &dwbc30->base;
1524 }
1525 return true;
1526}
1527
1528static bool dcn321_mmhubbub_create(struct dc_context *ctx, struct resource_pool *pool)
1529{
1530 int i;
1531 uint32_t dwb_count = pool->res_cap->num_dwb;
1532
1533 for (i = 0; i < dwb_count; i++) {
1534 struct dcn30_mmhubbub *mcif_wb30 = kzalloc(sizeof(struct dcn30_mmhubbub),
1535 GFP_KERNEL);
1536
1537 if (!mcif_wb30) {
1538 dm_error("DC: failed to create mcif_wb30!\n");
1539 return false;
1540 }
1541
1542#undef REG_STRUCT
1543#define REG_STRUCT mcif_wb30_regs
1544 mcif_wb_regs_dcn3_init(0);
1545
1546 dcn32_mmhubbub_construct(mcif_wb30, ctx,
1547 &mcif_wb30_regs[i],
1548 &mcif_wb30_shift,
1549 &mcif_wb30_mask,
1550 i);
1551
1552 pool->mcif_wb[i] = &mcif_wb30->base;
1553 }
1554 return true;
1555}
1556
1557static struct display_stream_compressor *dcn321_dsc_create(
1558 struct dc_context *ctx, uint32_t inst)
1559{
1560 struct dcn20_dsc *dsc =
1561 kzalloc(sizeof(struct dcn20_dsc), GFP_KERNEL);
1562
1563 if (!dsc) {
1564 BREAK_TO_DEBUGGER();
1565 return NULL;
1566 }
1567
1568#undef REG_STRUCT
1569#define REG_STRUCT dsc_regs
1570 dsc_regsDCN20_init(0),
1571 dsc_regsDCN20_init(1),
1572 dsc_regsDCN20_init(2),
1573 dsc_regsDCN20_init(3);
1574
1575 dsc2_construct(dsc, ctx, inst, &dsc_regs[inst], &dsc_shift, &dsc_mask);
1576
1577 dsc->max_image_width = 6016;
1578
1579 return &dsc->base;
1580}
1581
1582static void dcn321_destroy_resource_pool(struct resource_pool **pool)
1583{
1584 struct dcn321_resource_pool *dcn321_pool = TO_DCN321_RES_POOL(*pool);
1585
1586 dcn321_resource_destruct(dcn321_pool);
1587 kfree(dcn321_pool);
1588 *pool = NULL;
1589}
1590
1591static struct dc_cap_funcs cap_funcs = {
1592 .get_dcc_compression_cap = dcn20_get_dcc_compression_cap
1593};
1594
1595static void dcn321_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params)
1596{
1597 DC_FP_START();
1598 dcn321_update_bw_bounding_box_fpu(dc, bw_params);
1599 DC_FP_END();
1600}
1601
1602static struct resource_funcs dcn321_res_pool_funcs = {
1603 .destroy = dcn321_destroy_resource_pool,
1604 .link_enc_create = dcn321_link_encoder_create,
1605 .link_enc_create_minimal = NULL,
1606 .panel_cntl_create = dcn32_panel_cntl_create,
1607 .validate_bandwidth = dcn32_validate_bandwidth,
1608 .calculate_wm_and_dlg = dcn32_calculate_wm_and_dlg,
1609 .populate_dml_pipes = dcn32_populate_dml_pipes_from_context,
1610 .acquire_idle_pipe_for_head_pipe_in_layer = dcn32_acquire_idle_pipe_for_head_pipe_in_layer,
1611 .add_stream_to_ctx = dcn30_add_stream_to_ctx,
1612 .add_dsc_to_stream_resource = dcn20_add_dsc_to_stream_resource,
1613 .remove_stream_from_ctx = dcn20_remove_stream_from_ctx,
1614 .populate_dml_writeback_from_context = dcn30_populate_dml_writeback_from_context,
1615 .set_mcif_arb_params = dcn30_set_mcif_arb_params,
1616 .find_first_free_match_stream_enc_for_link = dcn10_find_first_free_match_stream_enc_for_link,
1617 .acquire_post_bldn_3dlut = dcn32_acquire_post_bldn_3dlut,
1618 .release_post_bldn_3dlut = dcn32_release_post_bldn_3dlut,
1619 .update_bw_bounding_box = dcn321_update_bw_bounding_box,
1620 .patch_unknown_plane_state = dcn20_patch_unknown_plane_state,
1621 .update_soc_for_wm_a = dcn30_update_soc_for_wm_a,
1622 .add_phantom_pipes = dcn32_add_phantom_pipes,
1623 .remove_phantom_pipes = dcn32_remove_phantom_pipes,
1624 .retain_phantom_pipes = dcn32_retain_phantom_pipes,
1625 .save_mall_state = dcn32_save_mall_state,
1626 .restore_mall_state = dcn32_restore_mall_state,
1627};
1628
1629
1630static bool dcn321_resource_construct(
1631 uint8_t num_virtual_links,
1632 struct dc *dc,
1633 struct dcn321_resource_pool *pool)
1634{
1635 int i, j;
1636 struct dc_context *ctx = dc->ctx;
1637 struct irq_service_init_data init_data;
1638 struct ddc_service_init_data ddc_init_data = {0};
1639 uint32_t pipe_fuses = 0;
1640 uint32_t num_pipes = 4;
1641
1642#undef REG_STRUCT
1643#define REG_STRUCT bios_regs
1644 bios_regs_init();
1645
1646#undef REG_STRUCT
1647#define REG_STRUCT clk_src_regs
1648 clk_src_regs_init(0, A),
1649 clk_src_regs_init(1, B),
1650 clk_src_regs_init(2, C),
1651 clk_src_regs_init(3, D),
1652 clk_src_regs_init(4, E);
1653
1654#undef REG_STRUCT
1655#define REG_STRUCT abm_regs
1656 abm_regs_init(0),
1657 abm_regs_init(1),
1658 abm_regs_init(2),
1659 abm_regs_init(3);
1660
1661#undef REG_STRUCT
1662#define REG_STRUCT dccg_regs
1663 dccg_regs_init();
1664
1665
1666 ctx->dc_bios->regs = &bios_regs;
1667
1668 pool->base.res_cap = &res_cap_dcn321;
1669 /* max number of pipes for ASIC before checking for pipe fuses */
1670 num_pipes = pool->base.res_cap->num_timing_generator;
1671 pipe_fuses = REG_READ(CC_DC_PIPE_DIS);
1672
1673 for (i = 0; i < pool->base.res_cap->num_timing_generator; i++)
1674 if (pipe_fuses & 1 << i)
1675 num_pipes--;
1676
1677 if (pipe_fuses & 1)
1678 ASSERT(0); //Unexpected - Pipe 0 should always be fully functional!
1679
1680 if (pipe_fuses & CC_DC_PIPE_DIS__DC_FULL_DIS_MASK)
1681 ASSERT(0); //Entire DCN is harvested!
1682
1683 /* within dml lib, initial value is hard coded, if ASIC pipe is fused, the
1684 * value will be changed, update max_num_dpp and max_num_otg for dml.
1685 */
1686 dcn3_21_ip.max_num_dpp = num_pipes;
1687 dcn3_21_ip.max_num_otg = num_pipes;
1688
1689 pool->base.funcs = &dcn321_res_pool_funcs;
1690
1691 /*************************************************
1692 * Resource + asic cap harcoding *
1693 *************************************************/
1694 pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE;
1695 pool->base.timing_generator_count = num_pipes;
1696 pool->base.pipe_count = num_pipes;
1697 pool->base.mpcc_count = num_pipes;
1698 dc->caps.max_downscale_ratio = 600;
1699 dc->caps.i2c_speed_in_khz = 100;
1700 dc->caps.i2c_speed_in_khz_hdcp = 100; /*1.4 w/a applied by default*/
1701 /* TODO: Bring max cursor size back to 256 after subvp cursor corruption is fixed*/
1702 dc->caps.max_cursor_size = 64;
1703 dc->caps.min_horizontal_blanking_period = 80;
1704 dc->caps.dmdata_alloc_size = 2048;
1705 dc->caps.mall_size_per_mem_channel = 0;
1706 dc->caps.mall_size_total = 0;
1707 dc->caps.cursor_cache_size = dc->caps.max_cursor_size * dc->caps.max_cursor_size * 8;
1708 dc->caps.cache_line_size = 64;
1709 dc->caps.cache_num_ways = 16;
1710 dc->caps.max_cab_allocation_bytes = 33554432; // 32MB = 1024 * 1024 * 32
1711 dc->caps.subvp_fw_processing_delay_us = 15;
1712 dc->caps.subvp_drr_max_vblank_margin_us = 40;
1713 dc->caps.subvp_prefetch_end_to_mall_start_us = 15;
1714 dc->caps.subvp_swath_height_margin_lines = 16;
1715 dc->caps.subvp_pstate_allow_width_us = 20;
1716 dc->caps.subvp_vertical_int_margin_us = 30;
1717 dc->caps.subvp_drr_vblank_start_margin_us = 100; // 100us margin
1718 dc->caps.max_slave_planes = 1;
1719 dc->caps.max_slave_yuv_planes = 1;
1720 dc->caps.max_slave_rgb_planes = 1;
1721 dc->caps.post_blend_color_processing = true;
1722 dc->caps.force_dp_tps4_for_cp2520 = true;
1723 dc->caps.dp_hpo = true;
1724 dc->caps.dp_hdmi21_pcon_support = true;
1725 dc->caps.edp_dsc_support = true;
1726 dc->caps.extended_aux_timeout_support = true;
1727 dc->caps.dmcub_support = true;
1728
1729 /* Color pipeline capabilities */
1730 dc->caps.color.dpp.dcn_arch = 1;
1731 dc->caps.color.dpp.input_lut_shared = 0;
1732 dc->caps.color.dpp.icsc = 1;
1733 dc->caps.color.dpp.dgam_ram = 0; // must use gamma_corr
1734 dc->caps.color.dpp.dgam_rom_caps.srgb = 1;
1735 dc->caps.color.dpp.dgam_rom_caps.bt2020 = 1;
1736 dc->caps.color.dpp.dgam_rom_caps.gamma2_2 = 1;
1737 dc->caps.color.dpp.dgam_rom_caps.pq = 1;
1738 dc->caps.color.dpp.dgam_rom_caps.hlg = 1;
1739 dc->caps.color.dpp.post_csc = 1;
1740 dc->caps.color.dpp.gamma_corr = 1;
1741 dc->caps.color.dpp.dgam_rom_for_yuv = 0;
1742
1743 dc->caps.color.dpp.hw_3d_lut = 1;
1744 dc->caps.color.dpp.ogam_ram = 1;
1745 // no OGAM ROM on DCN2 and later ASICs
1746 dc->caps.color.dpp.ogam_rom_caps.srgb = 0;
1747 dc->caps.color.dpp.ogam_rom_caps.bt2020 = 0;
1748 dc->caps.color.dpp.ogam_rom_caps.gamma2_2 = 0;
1749 dc->caps.color.dpp.ogam_rom_caps.pq = 0;
1750 dc->caps.color.dpp.ogam_rom_caps.hlg = 0;
1751 dc->caps.color.dpp.ocsc = 0;
1752
1753 dc->caps.color.mpc.gamut_remap = 1;
1754 dc->caps.color.mpc.num_3dluts = pool->base.res_cap->num_mpc_3dlut; //4, configurable to be before or after BLND in MPCC
1755 dc->caps.color.mpc.ogam_ram = 1;
1756 dc->caps.color.mpc.ogam_rom_caps.srgb = 0;
1757 dc->caps.color.mpc.ogam_rom_caps.bt2020 = 0;
1758 dc->caps.color.mpc.ogam_rom_caps.gamma2_2 = 0;
1759 dc->caps.color.mpc.ogam_rom_caps.pq = 0;
1760 dc->caps.color.mpc.ogam_rom_caps.hlg = 0;
1761 dc->caps.color.mpc.ocsc = 1;
1762
1763 /* read VBIOS LTTPR caps */
1764 {
1765 if (ctx->dc_bios->funcs->get_lttpr_caps) {
1766 enum bp_result bp_query_result;
1767 uint8_t is_vbios_lttpr_enable = 0;
1768
1769 bp_query_result = ctx->dc_bios->funcs->get_lttpr_caps(ctx->dc_bios, &is_vbios_lttpr_enable);
1770 dc->caps.vbios_lttpr_enable = (bp_query_result == BP_RESULT_OK) && !!is_vbios_lttpr_enable;
1771 }
1772
1773 /* interop bit is implicit */
1774 {
1775 dc->caps.vbios_lttpr_aware = true;
1776 }
1777 }
1778
1779 if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV)
1780 dc->debug = debug_defaults_drv;
1781 else if (dc->ctx->dce_environment == DCE_ENV_FPGA_MAXIMUS) {
1782 dc->debug = debug_defaults_diags;
1783 } else
1784 dc->debug = debug_defaults_diags;
1785 // Init the vm_helper
1786 if (dc->vm_helper)
1787 vm_helper_init(dc->vm_helper, 16);
1788
1789 /*************************************************
1790 * Create resources *
1791 *************************************************/
1792
1793 /* Clock Sources for Pixel Clock*/
1794 pool->base.clock_sources[DCN321_CLK_SRC_PLL0] =
1795 dcn321_clock_source_create(ctx, ctx->dc_bios,
1796 CLOCK_SOURCE_COMBO_PHY_PLL0,
1797 &clk_src_regs[0], false);
1798 pool->base.clock_sources[DCN321_CLK_SRC_PLL1] =
1799 dcn321_clock_source_create(ctx, ctx->dc_bios,
1800 CLOCK_SOURCE_COMBO_PHY_PLL1,
1801 &clk_src_regs[1], false);
1802 pool->base.clock_sources[DCN321_CLK_SRC_PLL2] =
1803 dcn321_clock_source_create(ctx, ctx->dc_bios,
1804 CLOCK_SOURCE_COMBO_PHY_PLL2,
1805 &clk_src_regs[2], false);
1806 pool->base.clock_sources[DCN321_CLK_SRC_PLL3] =
1807 dcn321_clock_source_create(ctx, ctx->dc_bios,
1808 CLOCK_SOURCE_COMBO_PHY_PLL3,
1809 &clk_src_regs[3], false);
1810 pool->base.clock_sources[DCN321_CLK_SRC_PLL4] =
1811 dcn321_clock_source_create(ctx, ctx->dc_bios,
1812 CLOCK_SOURCE_COMBO_PHY_PLL4,
1813 &clk_src_regs[4], false);
1814
1815 pool->base.clk_src_count = DCN321_CLK_SRC_TOTAL;
1816
1817 /* todo: not reuse phy_pll registers */
1818 pool->base.dp_clock_source =
1819 dcn321_clock_source_create(ctx, ctx->dc_bios,
1820 CLOCK_SOURCE_ID_DP_DTO,
1821 &clk_src_regs[0], true);
1822
1823 for (i = 0; i < pool->base.clk_src_count; i++) {
1824 if (pool->base.clock_sources[i] == NULL) {
1825 dm_error("DC: failed to create clock sources!\n");
1826 BREAK_TO_DEBUGGER();
1827 goto create_fail;
1828 }
1829 }
1830
1831 /* DCCG */
1832 pool->base.dccg = dccg32_create(ctx, &dccg_regs, &dccg_shift, &dccg_mask);
1833 if (pool->base.dccg == NULL) {
1834 dm_error("DC: failed to create dccg!\n");
1835 BREAK_TO_DEBUGGER();
1836 goto create_fail;
1837 }
1838
1839 /* DML */
1840 if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment))
1841 dml_init_instance(&dc->dml, &dcn3_21_soc, &dcn3_21_ip, DML_PROJECT_DCN32);
1842
1843 /* IRQ Service */
1844 init_data.ctx = dc->ctx;
1845 pool->base.irqs = dal_irq_service_dcn32_create(&init_data);
1846 if (!pool->base.irqs)
1847 goto create_fail;
1848
1849 /* HUBBUB */
1850 pool->base.hubbub = dcn321_hubbub_create(ctx);
1851 if (pool->base.hubbub == NULL) {
1852 BREAK_TO_DEBUGGER();
1853 dm_error("DC: failed to create hubbub!\n");
1854 goto create_fail;
1855 }
1856
1857 /* HUBPs, DPPs, OPPs, TGs, ABMs */
1858 for (i = 0, j = 0; i < pool->base.res_cap->num_timing_generator; i++) {
1859
1860 /* if pipe is disabled, skip instance of HW pipe,
1861 * i.e, skip ASIC register instance
1862 */
1863 if (pipe_fuses & 1 << i)
1864 continue;
1865
1866 pool->base.hubps[j] = dcn321_hubp_create(ctx, i);
1867 if (pool->base.hubps[j] == NULL) {
1868 BREAK_TO_DEBUGGER();
1869 dm_error(
1870 "DC: failed to create hubps!\n");
1871 goto create_fail;
1872 }
1873
1874 pool->base.dpps[j] = dcn321_dpp_create(ctx, i);
1875 if (pool->base.dpps[j] == NULL) {
1876 BREAK_TO_DEBUGGER();
1877 dm_error(
1878 "DC: failed to create dpps!\n");
1879 goto create_fail;
1880 }
1881
1882 pool->base.opps[j] = dcn321_opp_create(ctx, i);
1883 if (pool->base.opps[j] == NULL) {
1884 BREAK_TO_DEBUGGER();
1885 dm_error(
1886 "DC: failed to create output pixel processor!\n");
1887 goto create_fail;
1888 }
1889
1890 pool->base.timing_generators[j] = dcn321_timing_generator_create(
1891 ctx, i);
1892 if (pool->base.timing_generators[j] == NULL) {
1893 BREAK_TO_DEBUGGER();
1894 dm_error("DC: failed to create tg!\n");
1895 goto create_fail;
1896 }
1897
1898 pool->base.multiple_abms[j] = dmub_abm_create(ctx,
1899 &abm_regs[i],
1900 &abm_shift,
1901 &abm_mask);
1902 if (pool->base.multiple_abms[j] == NULL) {
1903 dm_error("DC: failed to create abm for pipe %d!\n", i);
1904 BREAK_TO_DEBUGGER();
1905 goto create_fail;
1906 }
1907
1908 /* index for resource pool arrays for next valid pipe */
1909 j++;
1910 }
1911
1912 /* PSR */
1913 pool->base.psr = dmub_psr_create(ctx);
1914 if (pool->base.psr == NULL) {
1915 dm_error("DC: failed to create psr obj!\n");
1916 BREAK_TO_DEBUGGER();
1917 goto create_fail;
1918 }
1919
1920 /* MPCCs */
1921 pool->base.mpc = dcn321_mpc_create(ctx, pool->base.res_cap->num_timing_generator, pool->base.res_cap->num_mpc_3dlut);
1922 if (pool->base.mpc == NULL) {
1923 BREAK_TO_DEBUGGER();
1924 dm_error("DC: failed to create mpc!\n");
1925 goto create_fail;
1926 }
1927
1928 /* DSCs */
1929 for (i = 0; i < pool->base.res_cap->num_dsc; i++) {
1930 pool->base.dscs[i] = dcn321_dsc_create(ctx, i);
1931 if (pool->base.dscs[i] == NULL) {
1932 BREAK_TO_DEBUGGER();
1933 dm_error("DC: failed to create display stream compressor %d!\n", i);
1934 goto create_fail;
1935 }
1936 }
1937
1938 /* DWB */
1939 if (!dcn321_dwbc_create(ctx, &pool->base)) {
1940 BREAK_TO_DEBUGGER();
1941 dm_error("DC: failed to create dwbc!\n");
1942 goto create_fail;
1943 }
1944
1945 /* MMHUBBUB */
1946 if (!dcn321_mmhubbub_create(ctx, &pool->base)) {
1947 BREAK_TO_DEBUGGER();
1948 dm_error("DC: failed to create mcif_wb!\n");
1949 goto create_fail;
1950 }
1951
1952 /* AUX and I2C */
1953 for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
1954 pool->base.engines[i] = dcn321_aux_engine_create(ctx, i);
1955 if (pool->base.engines[i] == NULL) {
1956 BREAK_TO_DEBUGGER();
1957 dm_error(
1958 "DC:failed to create aux engine!!\n");
1959 goto create_fail;
1960 }
1961 pool->base.hw_i2cs[i] = dcn321_i2c_hw_create(ctx, i);
1962 if (pool->base.hw_i2cs[i] == NULL) {
1963 BREAK_TO_DEBUGGER();
1964 dm_error(
1965 "DC:failed to create hw i2c!!\n");
1966 goto create_fail;
1967 }
1968 pool->base.sw_i2cs[i] = NULL;
1969 }
1970
1971 /* Audio, HWSeq, Stream Encoders including HPO and virtual, MPC 3D LUTs */
1972 if (!resource_construct(num_virtual_links, dc, &pool->base,
1973 (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment) ?
1974 &res_create_funcs : &res_create_maximus_funcs)))
1975 goto create_fail;
1976
1977 /* HW Sequencer init functions and Plane caps */
1978 dcn32_hw_sequencer_init_functions(dc);
1979
1980 dc->caps.max_planes = pool->base.pipe_count;
1981
1982 for (i = 0; i < dc->caps.max_planes; ++i)
1983 dc->caps.planes[i] = plane_cap;
1984
1985 dc->cap_funcs = cap_funcs;
1986
1987 if (dc->ctx->dc_bios->fw_info.oem_i2c_present) {
1988 ddc_init_data.ctx = dc->ctx;
1989 ddc_init_data.link = NULL;
1990 ddc_init_data.id.id = dc->ctx->dc_bios->fw_info.oem_i2c_obj_id;
1991 ddc_init_data.id.enum_id = 0;
1992 ddc_init_data.id.type = OBJECT_TYPE_GENERIC;
1993 pool->base.oem_device = dal_ddc_service_create(&ddc_init_data);
1994 } else {
1995 pool->base.oem_device = NULL;
1996 }
1997
1998 return true;
1999
2000create_fail:
2001
2002 dcn321_resource_destruct(pool);
2003
2004 return false;
2005}
2006
2007struct resource_pool *dcn321_create_resource_pool(
2008 const struct dc_init_data *init_data,
2009 struct dc *dc)
2010{
2011 struct dcn321_resource_pool *pool =
2012 kzalloc(sizeof(struct dcn321_resource_pool), GFP_KERNEL);
2013
2014 if (!pool)
2015 return NULL;
2016
2017 if (dcn321_resource_construct(init_data->num_virtual_links, dc, pool))
2018 return &pool->base;
2019
2020 BREAK_TO_DEBUGGER();
2021 kfree(pool);
2022 return NULL;
2023}