Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: MIT
0002 /*
0003  * Copyright 2022 Advanced Micro Devices, Inc.
0004  *
0005  * Permission is hereby granted, free of charge, to any person obtaining a
0006  * copy of this software and associated documentation files (the "Software"),
0007  * to deal in the Software without restriction, including without limitation
0008  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0009  * and/or sell copies of the Software, and to permit persons to whom the
0010  * Software is furnished to do so, subject to the following conditions:
0011  *
0012  * The above copyright notice and this permission notice shall be included in
0013  * all copies or substantial portions of the Software.
0014  *
0015  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0016  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0017  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
0018  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
0019  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
0020  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
0021  * OTHER DEALINGS IN THE SOFTWARE.
0022  *
0023  * Authors: AMD
0024  *
0025  */
0026 
0027 #include "dm_services.h"
0028 #include "dc.h"
0029 
0030 #include "dcn32_init.h"
0031 
0032 #include "resource.h"
0033 #include "include/irq_service_interface.h"
0034 #include "dcn32_resource.h"
0035 
0036 #include "dcn20/dcn20_resource.h"
0037 #include "dcn30/dcn30_resource.h"
0038 
0039 #include "dcn10/dcn10_ipp.h"
0040 #include "dcn30/dcn30_hubbub.h"
0041 #include "dcn31/dcn31_hubbub.h"
0042 #include "dcn32/dcn32_hubbub.h"
0043 #include "dcn32/dcn32_mpc.h"
0044 #include "dcn32_hubp.h"
0045 #include "irq/dcn32/irq_service_dcn32.h"
0046 #include "dcn32/dcn32_dpp.h"
0047 #include "dcn32/dcn32_optc.h"
0048 #include "dcn20/dcn20_hwseq.h"
0049 #include "dcn30/dcn30_hwseq.h"
0050 #include "dce110/dce110_hw_sequencer.h"
0051 #include "dcn30/dcn30_opp.h"
0052 #include "dcn20/dcn20_dsc.h"
0053 #include "dcn30/dcn30_vpg.h"
0054 #include "dcn30/dcn30_afmt.h"
0055 #include "dcn30/dcn30_dio_stream_encoder.h"
0056 #include "dcn32/dcn32_dio_stream_encoder.h"
0057 #include "dcn31/dcn31_hpo_dp_stream_encoder.h"
0058 #include "dcn31/dcn31_hpo_dp_link_encoder.h"
0059 #include "dcn32/dcn32_hpo_dp_link_encoder.h"
0060 #include "dc_link_dp.h"
0061 #include "dcn31/dcn31_apg.h"
0062 #include "dcn31/dcn31_dio_link_encoder.h"
0063 #include "dcn32/dcn32_dio_link_encoder.h"
0064 #include "dce/dce_clock_source.h"
0065 #include "dce/dce_audio.h"
0066 #include "dce/dce_hwseq.h"
0067 #include "clk_mgr.h"
0068 #include "virtual/virtual_stream_encoder.h"
0069 #include "dml/display_mode_vba.h"
0070 #include "dcn32/dcn32_dccg.h"
0071 #include "dcn10/dcn10_resource.h"
0072 #include "dc_link_ddc.h"
0073 #include "dcn31/dcn31_panel_cntl.h"
0074 
0075 #include "dcn30/dcn30_dwb.h"
0076 #include "dcn32/dcn32_mmhubbub.h"
0077 
0078 #include "dcn/dcn_3_2_0_offset.h"
0079 #include "dcn/dcn_3_2_0_sh_mask.h"
0080 #include "nbio/nbio_4_3_0_offset.h"
0081 
0082 #include "reg_helper.h"
0083 #include "dce/dmub_abm.h"
0084 #include "dce/dmub_psr.h"
0085 #include "dce/dce_aux.h"
0086 #include "dce/dce_i2c.h"
0087 
0088 #include "dml/dcn30/display_mode_vba_30.h"
0089 #include "vm_helper.h"
0090 #include "dcn20/dcn20_vmid.h"
0091 #include "dml/dcn32/dcn32_fpu.h"
0092 
0093 #define DCN_BASE__INST0_SEG1                       0x000000C0
0094 #define DCN_BASE__INST0_SEG2                       0x000034C0
0095 #define DCN_BASE__INST0_SEG3                       0x00009000
0096 #define NBIO_BASE__INST0_SEG1                      0x00000014
0097 
0098 #define MAX_INSTANCE                                        6
0099 #define MAX_SEGMENT                                         6
0100 
0101 struct IP_BASE_INSTANCE {
0102     unsigned int segment[MAX_SEGMENT];
0103 };
0104 
0105 struct IP_BASE {
0106     struct IP_BASE_INSTANCE instance[MAX_INSTANCE];
0107 };
0108 
0109 static const struct IP_BASE DCN_BASE = { { { { 0x00000012, 0x000000C0, 0x000034C0, 0x00009000, 0x02403C00, 0 } },
0110                     { { 0, 0, 0, 0, 0, 0 } },
0111                     { { 0, 0, 0, 0, 0, 0 } },
0112                     { { 0, 0, 0, 0, 0, 0 } },
0113                     { { 0, 0, 0, 0, 0, 0 } },
0114                     { { 0, 0, 0, 0, 0, 0 } } } };
0115 
0116 #define DC_LOGGER_INIT(logger)
0117 
0118 enum dcn32_clk_src_array_id {
0119     DCN32_CLK_SRC_PLL0,
0120     DCN32_CLK_SRC_PLL1,
0121     DCN32_CLK_SRC_PLL2,
0122     DCN32_CLK_SRC_PLL3,
0123     DCN32_CLK_SRC_PLL4,
0124     DCN32_CLK_SRC_TOTAL
0125 };
0126 
0127 /* begin *********************
0128  * macros to expend register list macro defined in HW object header file
0129  */
0130 
0131 /* DCN */
0132 /* TODO awful hack. fixup dcn20_dwb.h */
0133 #undef BASE_INNER
0134 #define BASE_INNER(seg) DCN_BASE__INST0_SEG ## seg
0135 
0136 #define BASE(seg) BASE_INNER(seg)
0137 
0138 #define SR(reg_name)\
0139         .reg_name = BASE(reg ## reg_name ## _BASE_IDX) +  \
0140                     reg ## reg_name
0141 
0142 #define SRI(reg_name, block, id)\
0143     .reg_name = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
0144                     reg ## block ## id ## _ ## reg_name
0145 
0146 #define SRI2(reg_name, block, id)\
0147     .reg_name = BASE(reg ## reg_name ## _BASE_IDX) + \
0148                     reg ## reg_name
0149 
0150 #define SRIR(var_name, reg_name, block, id)\
0151     .var_name = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
0152                     reg ## block ## id ## _ ## reg_name
0153 
0154 #define SRII(reg_name, block, id)\
0155     .reg_name[id] = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
0156                     reg ## block ## id ## _ ## reg_name
0157 
0158 #define SRII_MPC_RMU(reg_name, block, id)\
0159     .RMU##_##reg_name[id] = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
0160                     reg ## block ## id ## _ ## reg_name
0161 
0162 #define SRII_DWB(reg_name, temp_name, block, id)\
0163     .reg_name[id] = BASE(reg ## block ## id ## _ ## temp_name ## _BASE_IDX) + \
0164                     reg ## block ## id ## _ ## temp_name
0165 
0166 #define DCCG_SRII(reg_name, block, id)\
0167     .block ## _ ## reg_name[id] = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
0168                     reg ## block ## id ## _ ## reg_name
0169 
0170 #define VUPDATE_SRII(reg_name, block, id)\
0171     .reg_name[id] = BASE(reg ## reg_name ## _ ## block ## id ## _BASE_IDX) + \
0172                     reg ## reg_name ## _ ## block ## id
0173 
0174 /* NBIO */
0175 #define NBIO_BASE_INNER(seg) \
0176     NBIO_BASE__INST0_SEG ## seg
0177 
0178 #define NBIO_BASE(seg) \
0179     NBIO_BASE_INNER(seg)
0180 
0181 #define NBIO_SR(reg_name)\
0182         .reg_name = NBIO_BASE(regBIF_BX0_ ## reg_name ## _BASE_IDX) + \
0183                     regBIF_BX0_ ## reg_name
0184 
0185 #undef CTX
0186 #define CTX ctx
0187 #define REG(reg_name) \
0188     (DCN_BASE.instance[0].segment[reg ## reg_name ## _BASE_IDX] + reg ## reg_name)
0189 
0190 static const struct bios_registers bios_regs = {
0191         NBIO_SR(BIOS_SCRATCH_3),
0192         NBIO_SR(BIOS_SCRATCH_6)
0193 };
0194 
0195 #define clk_src_regs(index, pllid)\
0196 [index] = {\
0197     CS_COMMON_REG_LIST_DCN3_0(index, pllid),\
0198 }
0199 
0200 static const struct dce110_clk_src_regs clk_src_regs[] = {
0201     clk_src_regs(0, A),
0202     clk_src_regs(1, B),
0203     clk_src_regs(2, C),
0204     clk_src_regs(3, D),
0205     clk_src_regs(4, E)
0206 };
0207 
0208 static const struct dce110_clk_src_shift cs_shift = {
0209         CS_COMMON_MASK_SH_LIST_DCN3_2(__SHIFT)
0210 };
0211 
0212 static const struct dce110_clk_src_mask cs_mask = {
0213         CS_COMMON_MASK_SH_LIST_DCN3_2(_MASK)
0214 };
0215 
0216 #define abm_regs(id)\
0217 [id] = {\
0218         ABM_DCN32_REG_LIST(id)\
0219 }
0220 
0221 static const struct dce_abm_registers abm_regs[] = {
0222         abm_regs(0),
0223         abm_regs(1),
0224         abm_regs(2),
0225         abm_regs(3),
0226 };
0227 
0228 static const struct dce_abm_shift abm_shift = {
0229         ABM_MASK_SH_LIST_DCN32(__SHIFT)
0230 };
0231 
0232 static const struct dce_abm_mask abm_mask = {
0233         ABM_MASK_SH_LIST_DCN32(_MASK)
0234 };
0235 
0236 #define audio_regs(id)\
0237 [id] = {\
0238         AUD_COMMON_REG_LIST(id)\
0239 }
0240 
0241 static const struct dce_audio_registers audio_regs[] = {
0242     audio_regs(0),
0243     audio_regs(1),
0244     audio_regs(2),
0245     audio_regs(3),
0246     audio_regs(4)
0247 };
0248 
0249 #define DCE120_AUD_COMMON_MASK_SH_LIST(mask_sh)\
0250         SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_INDEX, AZALIA_ENDPOINT_REG_INDEX, mask_sh),\
0251         SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_DATA, AZALIA_ENDPOINT_REG_DATA, mask_sh),\
0252         AUD_COMMON_MASK_SH_LIST_BASE(mask_sh)
0253 
0254 static const struct dce_audio_shift audio_shift = {
0255         DCE120_AUD_COMMON_MASK_SH_LIST(__SHIFT)
0256 };
0257 
0258 static const struct dce_audio_mask audio_mask = {
0259         DCE120_AUD_COMMON_MASK_SH_LIST(_MASK)
0260 };
0261 
0262 #define vpg_regs(id)\
0263 [id] = {\
0264     VPG_DCN3_REG_LIST(id)\
0265 }
0266 
0267 static const struct dcn30_vpg_registers vpg_regs[] = {
0268     vpg_regs(0),
0269     vpg_regs(1),
0270     vpg_regs(2),
0271     vpg_regs(3),
0272     vpg_regs(4),
0273     vpg_regs(5),
0274     vpg_regs(6),
0275     vpg_regs(7),
0276     vpg_regs(8),
0277     vpg_regs(9),
0278 };
0279 
0280 static const struct dcn30_vpg_shift vpg_shift = {
0281     DCN3_VPG_MASK_SH_LIST(__SHIFT)
0282 };
0283 
0284 static const struct dcn30_vpg_mask vpg_mask = {
0285     DCN3_VPG_MASK_SH_LIST(_MASK)
0286 };
0287 
0288 #define afmt_regs(id)\
0289 [id] = {\
0290     AFMT_DCN3_REG_LIST(id)\
0291 }
0292 
0293 static const struct dcn30_afmt_registers afmt_regs[] = {
0294     afmt_regs(0),
0295     afmt_regs(1),
0296     afmt_regs(2),
0297     afmt_regs(3),
0298     afmt_regs(4),
0299     afmt_regs(5)
0300 };
0301 
0302 static const struct dcn30_afmt_shift afmt_shift = {
0303     DCN3_AFMT_MASK_SH_LIST(__SHIFT)
0304 };
0305 
0306 static const struct dcn30_afmt_mask afmt_mask = {
0307     DCN3_AFMT_MASK_SH_LIST(_MASK)
0308 };
0309 
0310 #define apg_regs(id)\
0311 [id] = {\
0312     APG_DCN31_REG_LIST(id)\
0313 }
0314 
0315 static const struct dcn31_apg_registers apg_regs[] = {
0316     apg_regs(0),
0317     apg_regs(1),
0318     apg_regs(2),
0319     apg_regs(3)
0320 };
0321 
0322 static const struct dcn31_apg_shift apg_shift = {
0323     DCN31_APG_MASK_SH_LIST(__SHIFT)
0324 };
0325 
0326 static const struct dcn31_apg_mask apg_mask = {
0327         DCN31_APG_MASK_SH_LIST(_MASK)
0328 };
0329 
0330 #define stream_enc_regs(id)\
0331 [id] = {\
0332     SE_DCN32_REG_LIST(id)\
0333 }
0334 
0335 static const struct dcn10_stream_enc_registers stream_enc_regs[] = {
0336     stream_enc_regs(0),
0337     stream_enc_regs(1),
0338     stream_enc_regs(2),
0339     stream_enc_regs(3),
0340     stream_enc_regs(4)
0341 };
0342 
0343 static const struct dcn10_stream_encoder_shift se_shift = {
0344         SE_COMMON_MASK_SH_LIST_DCN32(__SHIFT)
0345 };
0346 
0347 static const struct dcn10_stream_encoder_mask se_mask = {
0348         SE_COMMON_MASK_SH_LIST_DCN32(_MASK)
0349 };
0350 
0351 
0352 #define aux_regs(id)\
0353 [id] = {\
0354     DCN2_AUX_REG_LIST(id)\
0355 }
0356 
0357 static const struct dcn10_link_enc_aux_registers link_enc_aux_regs[] = {
0358         aux_regs(0),
0359         aux_regs(1),
0360         aux_regs(2),
0361         aux_regs(3),
0362         aux_regs(4)
0363 };
0364 
0365 #define hpd_regs(id)\
0366 [id] = {\
0367     HPD_REG_LIST(id)\
0368 }
0369 
0370 static const struct dcn10_link_enc_hpd_registers link_enc_hpd_regs[] = {
0371         hpd_regs(0),
0372         hpd_regs(1),
0373         hpd_regs(2),
0374         hpd_regs(3),
0375         hpd_regs(4)
0376 };
0377 
0378 #define link_regs(id, phyid)\
0379 [id] = {\
0380     LE_DCN31_REG_LIST(id), \
0381     UNIPHY_DCN2_REG_LIST(phyid), \
0382     /*DPCS_DCN31_REG_LIST(id),*/ \
0383 }
0384 
0385 static const struct dcn10_link_enc_registers link_enc_regs[] = {
0386     link_regs(0, A),
0387     link_regs(1, B),
0388     link_regs(2, C),
0389     link_regs(3, D),
0390     link_regs(4, E)
0391 };
0392 
0393 static const struct dcn10_link_enc_shift le_shift = {
0394     LINK_ENCODER_MASK_SH_LIST_DCN31(__SHIFT), \
0395     //DPCS_DCN31_MASK_SH_LIST(__SHIFT)
0396 };
0397 
0398 static const struct dcn10_link_enc_mask le_mask = {
0399     LINK_ENCODER_MASK_SH_LIST_DCN31(_MASK), \
0400 
0401     //DPCS_DCN31_MASK_SH_LIST(_MASK)
0402 };
0403 
0404 #define hpo_dp_stream_encoder_reg_list(id)\
0405 [id] = {\
0406     DCN3_1_HPO_DP_STREAM_ENC_REG_LIST(id)\
0407 }
0408 
0409 static const struct dcn31_hpo_dp_stream_encoder_registers hpo_dp_stream_enc_regs[] = {
0410     hpo_dp_stream_encoder_reg_list(0),
0411     hpo_dp_stream_encoder_reg_list(1),
0412     hpo_dp_stream_encoder_reg_list(2),
0413     hpo_dp_stream_encoder_reg_list(3),
0414 };
0415 
0416 static const struct dcn31_hpo_dp_stream_encoder_shift hpo_dp_se_shift = {
0417     DCN3_1_HPO_DP_STREAM_ENC_MASK_SH_LIST(__SHIFT)
0418 };
0419 
0420 static const struct dcn31_hpo_dp_stream_encoder_mask hpo_dp_se_mask = {
0421     DCN3_1_HPO_DP_STREAM_ENC_MASK_SH_LIST(_MASK)
0422 };
0423 
0424 
0425 #define hpo_dp_link_encoder_reg_list(id)\
0426 [id] = {\
0427     DCN3_1_HPO_DP_LINK_ENC_REG_LIST(id),\
0428     /*DCN3_1_RDPCSTX_REG_LIST(0),*/\
0429     /*DCN3_1_RDPCSTX_REG_LIST(1),*/\
0430     /*DCN3_1_RDPCSTX_REG_LIST(2),*/\
0431     /*DCN3_1_RDPCSTX_REG_LIST(3),*/\
0432     /*DCN3_1_RDPCSTX_REG_LIST(4)*/\
0433 }
0434 
0435 static const struct dcn31_hpo_dp_link_encoder_registers hpo_dp_link_enc_regs[] = {
0436     hpo_dp_link_encoder_reg_list(0),
0437     hpo_dp_link_encoder_reg_list(1),
0438 };
0439 
0440 static const struct dcn31_hpo_dp_link_encoder_shift hpo_dp_le_shift = {
0441     DCN3_2_HPO_DP_LINK_ENC_MASK_SH_LIST(__SHIFT)
0442 };
0443 
0444 static const struct dcn31_hpo_dp_link_encoder_mask hpo_dp_le_mask = {
0445     DCN3_2_HPO_DP_LINK_ENC_MASK_SH_LIST(_MASK)
0446 };
0447 
0448 #define dpp_regs(id)\
0449 [id] = {\
0450     DPP_REG_LIST_DCN30_COMMON(id),\
0451 }
0452 
0453 static const struct dcn3_dpp_registers dpp_regs[] = {
0454     dpp_regs(0),
0455     dpp_regs(1),
0456     dpp_regs(2),
0457     dpp_regs(3)
0458 };
0459 
0460 static const struct dcn3_dpp_shift tf_shift = {
0461         DPP_REG_LIST_SH_MASK_DCN30_COMMON(__SHIFT)
0462 };
0463 
0464 static const struct dcn3_dpp_mask tf_mask = {
0465         DPP_REG_LIST_SH_MASK_DCN30_COMMON(_MASK)
0466 };
0467 
0468 
0469 #define opp_regs(id)\
0470 [id] = {\
0471     OPP_REG_LIST_DCN30(id),\
0472 }
0473 
0474 static const struct dcn20_opp_registers opp_regs[] = {
0475     opp_regs(0),
0476     opp_regs(1),
0477     opp_regs(2),
0478     opp_regs(3)
0479 };
0480 
0481 static const struct dcn20_opp_shift opp_shift = {
0482     OPP_MASK_SH_LIST_DCN20(__SHIFT)
0483 };
0484 
0485 static const struct dcn20_opp_mask opp_mask = {
0486     OPP_MASK_SH_LIST_DCN20(_MASK)
0487 };
0488 
0489 #define aux_engine_regs(id)\
0490 [id] = {\
0491     AUX_COMMON_REG_LIST0(id), \
0492     .AUXN_IMPCAL = 0, \
0493     .AUXP_IMPCAL = 0, \
0494     .AUX_RESET_MASK = DP_AUX0_AUX_CONTROL__AUX_RESET_MASK, \
0495 }
0496 
0497 static const struct dce110_aux_registers aux_engine_regs[] = {
0498         aux_engine_regs(0),
0499         aux_engine_regs(1),
0500         aux_engine_regs(2),
0501         aux_engine_regs(3),
0502         aux_engine_regs(4)
0503 };
0504 
0505 static const struct dce110_aux_registers_shift aux_shift = {
0506     DCN_AUX_MASK_SH_LIST(__SHIFT)
0507 };
0508 
0509 static const struct dce110_aux_registers_mask aux_mask = {
0510     DCN_AUX_MASK_SH_LIST(_MASK)
0511 };
0512 
0513 
0514 #define dwbc_regs_dcn3(id)\
0515 [id] = {\
0516     DWBC_COMMON_REG_LIST_DCN30(id),\
0517 }
0518 
0519 static const struct dcn30_dwbc_registers dwbc30_regs[] = {
0520     dwbc_regs_dcn3(0),
0521 };
0522 
0523 static const struct dcn30_dwbc_shift dwbc30_shift = {
0524     DWBC_COMMON_MASK_SH_LIST_DCN30(__SHIFT)
0525 };
0526 
0527 static const struct dcn30_dwbc_mask dwbc30_mask = {
0528     DWBC_COMMON_MASK_SH_LIST_DCN30(_MASK)
0529 };
0530 
0531 #define mcif_wb_regs_dcn3(id)\
0532 [id] = {\
0533     MCIF_WB_COMMON_REG_LIST_DCN32(id),\
0534 }
0535 
0536 static const struct dcn30_mmhubbub_registers mcif_wb30_regs[] = {
0537     mcif_wb_regs_dcn3(0)
0538 };
0539 
0540 static const struct dcn30_mmhubbub_shift mcif_wb30_shift = {
0541     MCIF_WB_COMMON_MASK_SH_LIST_DCN32(__SHIFT)
0542 };
0543 
0544 static const struct dcn30_mmhubbub_mask mcif_wb30_mask = {
0545     MCIF_WB_COMMON_MASK_SH_LIST_DCN32(_MASK)
0546 };
0547 
0548 #define dsc_regsDCN20(id)\
0549 [id] = {\
0550     DSC_REG_LIST_DCN20(id)\
0551 }
0552 
0553 static const struct dcn20_dsc_registers dsc_regs[] = {
0554     dsc_regsDCN20(0),
0555     dsc_regsDCN20(1),
0556     dsc_regsDCN20(2),
0557     dsc_regsDCN20(3)
0558 };
0559 
0560 static const struct dcn20_dsc_shift dsc_shift = {
0561     DSC_REG_LIST_SH_MASK_DCN20(__SHIFT)
0562 };
0563 
0564 static const struct dcn20_dsc_mask dsc_mask = {
0565     DSC_REG_LIST_SH_MASK_DCN20(_MASK)
0566 };
0567 
0568 static const struct dcn30_mpc_registers mpc_regs = {
0569         MPC_REG_LIST_DCN3_2(0),
0570         MPC_REG_LIST_DCN3_2(1),
0571         MPC_REG_LIST_DCN3_2(2),
0572         MPC_REG_LIST_DCN3_2(3),
0573         MPC_OUT_MUX_REG_LIST_DCN3_0(0),
0574         MPC_OUT_MUX_REG_LIST_DCN3_0(1),
0575         MPC_OUT_MUX_REG_LIST_DCN3_0(2),
0576         MPC_OUT_MUX_REG_LIST_DCN3_0(3),
0577         MPC_DWB_MUX_REG_LIST_DCN3_0(0),
0578 };
0579 
0580 static const struct dcn30_mpc_shift mpc_shift = {
0581     MPC_COMMON_MASK_SH_LIST_DCN32(__SHIFT)
0582 };
0583 
0584 static const struct dcn30_mpc_mask mpc_mask = {
0585     MPC_COMMON_MASK_SH_LIST_DCN32(_MASK)
0586 };
0587 
0588 #define optc_regs(id)\
0589 [id] = {OPTC_COMMON_REG_LIST_DCN3_2(id)}
0590 
0591 //#ifdef DIAGS_BUILD
0592 //static struct dcn_optc_registers optc_regs[] = {
0593 //#else
0594 static const struct dcn_optc_registers optc_regs[] = {
0595 //#endif
0596     optc_regs(0),
0597     optc_regs(1),
0598     optc_regs(2),
0599     optc_regs(3)
0600 };
0601 
0602 static const struct dcn_optc_shift optc_shift = {
0603     OPTC_COMMON_MASK_SH_LIST_DCN3_2(__SHIFT)
0604 };
0605 
0606 static const struct dcn_optc_mask optc_mask = {
0607     OPTC_COMMON_MASK_SH_LIST_DCN3_2(_MASK)
0608 };
0609 
0610 #define hubp_regs(id)\
0611 [id] = {\
0612     HUBP_REG_LIST_DCN32(id)\
0613 }
0614 
0615 static const struct dcn_hubp2_registers hubp_regs[] = {
0616         hubp_regs(0),
0617         hubp_regs(1),
0618         hubp_regs(2),
0619         hubp_regs(3)
0620 };
0621 
0622 
0623 static const struct dcn_hubp2_shift hubp_shift = {
0624         HUBP_MASK_SH_LIST_DCN32(__SHIFT)
0625 };
0626 
0627 static const struct dcn_hubp2_mask hubp_mask = {
0628         HUBP_MASK_SH_LIST_DCN32(_MASK)
0629 };
0630 static const struct dcn_hubbub_registers hubbub_reg = {
0631         HUBBUB_REG_LIST_DCN32(0)
0632 };
0633 
0634 static const struct dcn_hubbub_shift hubbub_shift = {
0635         HUBBUB_MASK_SH_LIST_DCN32(__SHIFT)
0636 };
0637 
0638 static const struct dcn_hubbub_mask hubbub_mask = {
0639         HUBBUB_MASK_SH_LIST_DCN32(_MASK)
0640 };
0641 
0642 static const struct dccg_registers dccg_regs = {
0643         DCCG_REG_LIST_DCN32()
0644 };
0645 
0646 static const struct dccg_shift dccg_shift = {
0647         DCCG_MASK_SH_LIST_DCN32(__SHIFT)
0648 };
0649 
0650 static const struct dccg_mask dccg_mask = {
0651         DCCG_MASK_SH_LIST_DCN32(_MASK)
0652 };
0653 
0654 
0655 #define SRII2(reg_name_pre, reg_name_post, id)\
0656     .reg_name_pre ## _ ##  reg_name_post[id] = BASE(reg ## reg_name_pre \
0657             ## id ## _ ## reg_name_post ## _BASE_IDX) + \
0658             reg ## reg_name_pre ## id ## _ ## reg_name_post
0659 
0660 
0661 #define HWSEQ_DCN32_REG_LIST()\
0662     SR(DCHUBBUB_GLOBAL_TIMER_CNTL), \
0663     SR(DIO_MEM_PWR_CTRL), \
0664     SR(ODM_MEM_PWR_CTRL3), \
0665     SR(MMHUBBUB_MEM_PWR_CNTL), \
0666     SR(DCCG_GATE_DISABLE_CNTL), \
0667     SR(DCCG_GATE_DISABLE_CNTL2), \
0668     SR(DCFCLK_CNTL),\
0669     SR(DC_MEM_GLOBAL_PWR_REQ_CNTL), \
0670     SRII(PIXEL_RATE_CNTL, OTG, 0), \
0671     SRII(PIXEL_RATE_CNTL, OTG, 1),\
0672     SRII(PIXEL_RATE_CNTL, OTG, 2),\
0673     SRII(PIXEL_RATE_CNTL, OTG, 3),\
0674     SRII(PHYPLL_PIXEL_RATE_CNTL, OTG, 0),\
0675     SRII(PHYPLL_PIXEL_RATE_CNTL, OTG, 1),\
0676     SRII(PHYPLL_PIXEL_RATE_CNTL, OTG, 2),\
0677     SRII(PHYPLL_PIXEL_RATE_CNTL, OTG, 3),\
0678     SR(MICROSECOND_TIME_BASE_DIV), \
0679     SR(MILLISECOND_TIME_BASE_DIV), \
0680     SR(DISPCLK_FREQ_CHANGE_CNTL), \
0681     SR(RBBMIF_TIMEOUT_DIS), \
0682     SR(RBBMIF_TIMEOUT_DIS_2), \
0683     SR(DCHUBBUB_CRC_CTRL), \
0684     SR(DPP_TOP0_DPP_CRC_CTRL), \
0685     SR(DPP_TOP0_DPP_CRC_VAL_B_A), \
0686     SR(DPP_TOP0_DPP_CRC_VAL_R_G), \
0687     SR(MPC_CRC_CTRL), \
0688     SR(MPC_CRC_RESULT_GB), \
0689     SR(MPC_CRC_RESULT_C), \
0690     SR(MPC_CRC_RESULT_AR), \
0691     SR(DOMAIN0_PG_CONFIG), \
0692     SR(DOMAIN1_PG_CONFIG), \
0693     SR(DOMAIN2_PG_CONFIG), \
0694     SR(DOMAIN3_PG_CONFIG), \
0695     SR(DOMAIN16_PG_CONFIG), \
0696     SR(DOMAIN17_PG_CONFIG), \
0697     SR(DOMAIN18_PG_CONFIG), \
0698     SR(DOMAIN19_PG_CONFIG), \
0699     SR(DOMAIN0_PG_STATUS), \
0700     SR(DOMAIN1_PG_STATUS), \
0701     SR(DOMAIN2_PG_STATUS), \
0702     SR(DOMAIN3_PG_STATUS), \
0703     SR(DOMAIN16_PG_STATUS), \
0704     SR(DOMAIN17_PG_STATUS), \
0705     SR(DOMAIN18_PG_STATUS), \
0706     SR(DOMAIN19_PG_STATUS), \
0707     SR(D1VGA_CONTROL), \
0708     SR(D2VGA_CONTROL), \
0709     SR(D3VGA_CONTROL), \
0710     SR(D4VGA_CONTROL), \
0711     SR(D5VGA_CONTROL), \
0712     SR(D6VGA_CONTROL), \
0713     SR(DC_IP_REQUEST_CNTL), \
0714     SR(AZALIA_AUDIO_DTO), \
0715     SR(AZALIA_CONTROLLER_CLOCK_GATING)
0716 
0717 static const struct dce_hwseq_registers hwseq_reg = {
0718         HWSEQ_DCN32_REG_LIST()
0719 };
0720 
0721 #define HWSEQ_DCN32_MASK_SH_LIST(mask_sh)\
0722     HWSEQ_DCN_MASK_SH_LIST(mask_sh), \
0723     HWS_SF(, DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, mask_sh), \
0724     HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \
0725     HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \
0726     HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \
0727     HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \
0728     HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \
0729     HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \
0730     HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \
0731     HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \
0732     HWS_SF(, DOMAIN16_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \
0733     HWS_SF(, DOMAIN16_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \
0734     HWS_SF(, DOMAIN17_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \
0735     HWS_SF(, DOMAIN17_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \
0736     HWS_SF(, DOMAIN18_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \
0737     HWS_SF(, DOMAIN18_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \
0738     HWS_SF(, DOMAIN19_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \
0739     HWS_SF(, DOMAIN19_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \
0740     HWS_SF(, DOMAIN0_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \
0741     HWS_SF(, DOMAIN1_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \
0742     HWS_SF(, DOMAIN2_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \
0743     HWS_SF(, DOMAIN3_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \
0744     HWS_SF(, DOMAIN16_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \
0745     HWS_SF(, DOMAIN17_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \
0746     HWS_SF(, DOMAIN18_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \
0747     HWS_SF(, DOMAIN19_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \
0748     HWS_SF(, DC_IP_REQUEST_CNTL, IP_REQUEST_EN, mask_sh), \
0749     HWS_SF(, AZALIA_AUDIO_DTO, AZALIA_AUDIO_DTO_MODULE, mask_sh), \
0750     HWS_SF(, HPO_TOP_CLOCK_CONTROL, HPO_HDMISTREAMCLK_G_GATE_DIS, mask_sh), \
0751     HWS_SF(, ODM_MEM_PWR_CTRL3, ODM_MEM_UNASSIGNED_PWR_MODE, mask_sh), \
0752     HWS_SF(, ODM_MEM_PWR_CTRL3, ODM_MEM_VBLANK_PWR_MODE, mask_sh), \
0753     HWS_SF(, MMHUBBUB_MEM_PWR_CNTL, VGA_MEM_PWR_FORCE, mask_sh)
0754 
0755 static const struct dce_hwseq_shift hwseq_shift = {
0756         HWSEQ_DCN32_MASK_SH_LIST(__SHIFT)
0757 };
0758 
0759 static const struct dce_hwseq_mask hwseq_mask = {
0760         HWSEQ_DCN32_MASK_SH_LIST(_MASK)
0761 };
0762 #define vmid_regs(id)\
0763 [id] = {\
0764         DCN20_VMID_REG_LIST(id)\
0765 }
0766 
0767 static const struct dcn_vmid_registers vmid_regs[] = {
0768     vmid_regs(0),
0769     vmid_regs(1),
0770     vmid_regs(2),
0771     vmid_regs(3),
0772     vmid_regs(4),
0773     vmid_regs(5),
0774     vmid_regs(6),
0775     vmid_regs(7),
0776     vmid_regs(8),
0777     vmid_regs(9),
0778     vmid_regs(10),
0779     vmid_regs(11),
0780     vmid_regs(12),
0781     vmid_regs(13),
0782     vmid_regs(14),
0783     vmid_regs(15)
0784 };
0785 
0786 static const struct dcn20_vmid_shift vmid_shifts = {
0787         DCN20_VMID_MASK_SH_LIST(__SHIFT)
0788 };
0789 
0790 static const struct dcn20_vmid_mask vmid_masks = {
0791         DCN20_VMID_MASK_SH_LIST(_MASK)
0792 };
0793 
0794 static const struct resource_caps res_cap_dcn32 = {
0795     .num_timing_generator = 4,
0796     .num_opp = 4,
0797     .num_video_plane = 4,
0798     .num_audio = 5,
0799     .num_stream_encoder = 5,
0800     .num_hpo_dp_stream_encoder = 4,
0801     .num_hpo_dp_link_encoder = 2,
0802     .num_pll = 5,
0803     .num_dwb = 1,
0804     .num_ddc = 5,
0805     .num_vmid = 16,
0806     .num_mpc_3dlut = 4,
0807     .num_dsc = 4,
0808 };
0809 
0810 static const struct dc_plane_cap plane_cap = {
0811     .type = DC_PLANE_TYPE_DCN_UNIVERSAL,
0812     .blends_with_above = true,
0813     .blends_with_below = true,
0814     .per_pixel_alpha = true,
0815 
0816     .pixel_format_support = {
0817             .argb8888 = true,
0818             .nv12 = true,
0819             .fp16 = true,
0820             .p010 = true,
0821             .ayuv = false,
0822     },
0823 
0824     .max_upscale_factor = {
0825             .argb8888 = 16000,
0826             .nv12 = 16000,
0827             .fp16 = 16000
0828     },
0829 
0830     // 6:1 downscaling ratio: 1000/6 = 166.666
0831     .max_downscale_factor = {
0832             .argb8888 = 167,
0833             .nv12 = 167,
0834             .fp16 = 167
0835     },
0836     64,
0837     64
0838 };
0839 
0840 static const struct dc_debug_options debug_defaults_drv = {
0841     .disable_dmcu = true,
0842     .force_abm_enable = false,
0843     .timing_trace = false,
0844     .clock_trace = true,
0845     .disable_pplib_clock_request = false,
0846     .pipe_split_policy = MPC_SPLIT_AVOID, // Due to CRB, no need to MPC split anymore
0847     .force_single_disp_pipe_split = false,
0848     .disable_dcc = DCC_ENABLE,
0849     .vsr_support = true,
0850     .performance_trace = false,
0851     .max_downscale_src_width = 7680,/*upto 8K*/
0852     .disable_pplib_wm_range = false,
0853     .scl_reset_length10 = true,
0854     .sanity_checks = false,
0855     .underflow_assert_delay_us = 0xFFFFFFFF,
0856     .dwb_fi_phase = -1, // -1 = disable,
0857     .dmub_command_table = true,
0858     .enable_mem_low_power = {
0859         .bits = {
0860             .vga = false,
0861             .i2c = false,
0862             .dmcu = false, // This is previously known to cause hang on S3 cycles if enabled
0863             .dscl = false,
0864             .cm = false,
0865             .mpc = false,
0866             .optc = true,
0867         }
0868     },
0869     .use_max_lb = true,
0870     .force_disable_subvp = false,
0871     .exit_idle_opt_for_cursor_updates = true,
0872     .enable_single_display_2to1_odm_policy = true,
0873     .enable_dp_dig_pixel_rate_div_policy = 1,
0874     .allow_sw_cursor_fallback = false,
0875 };
0876 
0877 static const struct dc_debug_options debug_defaults_diags = {
0878     .disable_dmcu = true,
0879     .force_abm_enable = false,
0880     .timing_trace = true,
0881     .clock_trace = true,
0882     .disable_dpp_power_gate = true,
0883     .disable_hubp_power_gate = true,
0884     .disable_dsc_power_gate = true,
0885     .disable_clock_gate = true,
0886     .disable_pplib_clock_request = true,
0887     .disable_pplib_wm_range = true,
0888     .disable_stutter = false,
0889     .scl_reset_length10 = true,
0890     .dwb_fi_phase = -1, // -1 = disable
0891     .dmub_command_table = true,
0892     .enable_tri_buf = true,
0893     .use_max_lb = true,
0894     .force_disable_subvp = true
0895 };
0896 
0897 static struct dce_aux *dcn32_aux_engine_create(
0898     struct dc_context *ctx,
0899     uint32_t inst)
0900 {
0901     struct aux_engine_dce110 *aux_engine =
0902         kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL);
0903 
0904     if (!aux_engine)
0905         return NULL;
0906 
0907     dce110_aux_engine_construct(aux_engine, ctx, inst,
0908                     SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD,
0909                     &aux_engine_regs[inst],
0910                     &aux_mask,
0911                     &aux_shift,
0912                     ctx->dc->caps.extended_aux_timeout_support);
0913 
0914     return &aux_engine->base;
0915 }
0916 #define i2c_inst_regs(id) { I2C_HW_ENGINE_COMMON_REG_LIST_DCN30(id) }
0917 
0918 static const struct dce_i2c_registers i2c_hw_regs[] = {
0919         i2c_inst_regs(1),
0920         i2c_inst_regs(2),
0921         i2c_inst_regs(3),
0922         i2c_inst_regs(4),
0923         i2c_inst_regs(5),
0924 };
0925 
0926 static const struct dce_i2c_shift i2c_shifts = {
0927         I2C_COMMON_MASK_SH_LIST_DCN30(__SHIFT)
0928 };
0929 
0930 static const struct dce_i2c_mask i2c_masks = {
0931         I2C_COMMON_MASK_SH_LIST_DCN30(_MASK)
0932 };
0933 
0934 static struct dce_i2c_hw *dcn32_i2c_hw_create(
0935     struct dc_context *ctx,
0936     uint32_t inst)
0937 {
0938     struct dce_i2c_hw *dce_i2c_hw =
0939         kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL);
0940 
0941     if (!dce_i2c_hw)
0942         return NULL;
0943 
0944     dcn2_i2c_hw_construct(dce_i2c_hw, ctx, inst,
0945                     &i2c_hw_regs[inst], &i2c_shifts, &i2c_masks);
0946 
0947     return dce_i2c_hw;
0948 }
0949 
0950 static struct clock_source *dcn32_clock_source_create(
0951         struct dc_context *ctx,
0952         struct dc_bios *bios,
0953         enum clock_source_id id,
0954         const struct dce110_clk_src_regs *regs,
0955         bool dp_clk_src)
0956 {
0957     struct dce110_clk_src *clk_src =
0958         kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL);
0959 
0960     if (!clk_src)
0961         return NULL;
0962 
0963     if (dcn31_clk_src_construct(clk_src, ctx, bios, id,
0964             regs, &cs_shift, &cs_mask)) {
0965         clk_src->base.dp_clk_src = dp_clk_src;
0966         return &clk_src->base;
0967     }
0968 
0969     BREAK_TO_DEBUGGER();
0970     return NULL;
0971 }
0972 
0973 static struct hubbub *dcn32_hubbub_create(struct dc_context *ctx)
0974 {
0975     int i;
0976 
0977     struct dcn20_hubbub *hubbub2 = kzalloc(sizeof(struct dcn20_hubbub),
0978                       GFP_KERNEL);
0979 
0980     if (!hubbub2)
0981         return NULL;
0982 
0983     hubbub32_construct(hubbub2, ctx,
0984             &hubbub_reg,
0985             &hubbub_shift,
0986             &hubbub_mask,
0987             ctx->dc->dml.ip.det_buffer_size_kbytes,
0988             ctx->dc->dml.ip.pixel_chunk_size_kbytes,
0989             ctx->dc->dml.ip.config_return_buffer_size_in_kbytes);
0990 
0991 
0992     for (i = 0; i < res_cap_dcn32.num_vmid; i++) {
0993         struct dcn20_vmid *vmid = &hubbub2->vmid[i];
0994 
0995         vmid->ctx = ctx;
0996 
0997         vmid->regs = &vmid_regs[i];
0998         vmid->shifts = &vmid_shifts;
0999         vmid->masks = &vmid_masks;
1000     }
1001 
1002     return &hubbub2->base;
1003 }
1004 
1005 static struct hubp *dcn32_hubp_create(
1006     struct dc_context *ctx,
1007     uint32_t inst)
1008 {
1009     struct dcn20_hubp *hubp2 =
1010         kzalloc(sizeof(struct dcn20_hubp), GFP_KERNEL);
1011 
1012     if (!hubp2)
1013         return NULL;
1014 
1015     if (hubp32_construct(hubp2, ctx, inst,
1016             &hubp_regs[inst], &hubp_shift, &hubp_mask))
1017         return &hubp2->base;
1018 
1019     BREAK_TO_DEBUGGER();
1020     kfree(hubp2);
1021     return NULL;
1022 }
1023 
1024 static void dcn32_dpp_destroy(struct dpp **dpp)
1025 {
1026     kfree(TO_DCN30_DPP(*dpp));
1027     *dpp = NULL;
1028 }
1029 
1030 static struct dpp *dcn32_dpp_create(
1031     struct dc_context *ctx,
1032     uint32_t inst)
1033 {
1034     struct dcn3_dpp *dpp3 =
1035         kzalloc(sizeof(struct dcn3_dpp), GFP_KERNEL);
1036 
1037     if (!dpp3)
1038         return NULL;
1039 
1040     if (dpp32_construct(dpp3, ctx, inst,
1041             &dpp_regs[inst], &tf_shift, &tf_mask))
1042         return &dpp3->base;
1043 
1044     BREAK_TO_DEBUGGER();
1045     kfree(dpp3);
1046     return NULL;
1047 }
1048 
1049 static struct mpc *dcn32_mpc_create(
1050         struct dc_context *ctx,
1051         int num_mpcc,
1052         int num_rmu)
1053 {
1054     struct dcn30_mpc *mpc30 = kzalloc(sizeof(struct dcn30_mpc),
1055                       GFP_KERNEL);
1056 
1057     if (!mpc30)
1058         return NULL;
1059 
1060     dcn32_mpc_construct(mpc30, ctx,
1061             &mpc_regs,
1062             &mpc_shift,
1063             &mpc_mask,
1064             num_mpcc,
1065             num_rmu);
1066 
1067     return &mpc30->base;
1068 }
1069 
1070 static struct output_pixel_processor *dcn32_opp_create(
1071     struct dc_context *ctx, uint32_t inst)
1072 {
1073     struct dcn20_opp *opp2 =
1074         kzalloc(sizeof(struct dcn20_opp), GFP_KERNEL);
1075 
1076     if (!opp2) {
1077         BREAK_TO_DEBUGGER();
1078         return NULL;
1079     }
1080 
1081     dcn20_opp_construct(opp2, ctx, inst,
1082             &opp_regs[inst], &opp_shift, &opp_mask);
1083     return &opp2->base;
1084 }
1085 
1086 
1087 static struct timing_generator *dcn32_timing_generator_create(
1088         struct dc_context *ctx,
1089         uint32_t instance)
1090 {
1091     struct optc *tgn10 =
1092         kzalloc(sizeof(struct optc), GFP_KERNEL);
1093 
1094     if (!tgn10)
1095         return NULL;
1096 
1097     tgn10->base.inst = instance;
1098     tgn10->base.ctx = ctx;
1099 
1100     tgn10->tg_regs = &optc_regs[instance];
1101     tgn10->tg_shift = &optc_shift;
1102     tgn10->tg_mask = &optc_mask;
1103 
1104     dcn32_timing_generator_init(tgn10);
1105 
1106     return &tgn10->base;
1107 }
1108 
1109 static const struct encoder_feature_support link_enc_feature = {
1110         .max_hdmi_deep_color = COLOR_DEPTH_121212,
1111         .max_hdmi_pixel_clock = 600000,
1112         .hdmi_ycbcr420_supported = true,
1113         .dp_ycbcr420_supported = true,
1114         .fec_supported = true,
1115         .flags.bits.IS_HBR2_CAPABLE = true,
1116         .flags.bits.IS_HBR3_CAPABLE = true,
1117         .flags.bits.IS_TPS3_CAPABLE = true,
1118         .flags.bits.IS_TPS4_CAPABLE = true
1119 };
1120 
1121 static struct link_encoder *dcn32_link_encoder_create(
1122     struct dc_context *ctx,
1123     const struct encoder_init_data *enc_init_data)
1124 {
1125     struct dcn20_link_encoder *enc20 =
1126         kzalloc(sizeof(struct dcn20_link_encoder), GFP_KERNEL);
1127 
1128     if (!enc20)
1129         return NULL;
1130 
1131     dcn32_link_encoder_construct(enc20,
1132             enc_init_data,
1133             &link_enc_feature,
1134             &link_enc_regs[enc_init_data->transmitter],
1135             &link_enc_aux_regs[enc_init_data->channel - 1],
1136             &link_enc_hpd_regs[enc_init_data->hpd_source],
1137             &le_shift,
1138             &le_mask);
1139 
1140     return &enc20->enc10.base;
1141 }
1142 
1143 struct panel_cntl *dcn32_panel_cntl_create(const struct panel_cntl_init_data *init_data)
1144 {
1145     struct dcn31_panel_cntl *panel_cntl =
1146         kzalloc(sizeof(struct dcn31_panel_cntl), GFP_KERNEL);
1147 
1148     if (!panel_cntl)
1149         return NULL;
1150 
1151     dcn31_panel_cntl_construct(panel_cntl, init_data);
1152 
1153     return &panel_cntl->base;
1154 }
1155 
1156 static void read_dce_straps(
1157     struct dc_context *ctx,
1158     struct resource_straps *straps)
1159 {
1160     generic_reg_get(ctx, regDC_PINSTRAPS + BASE(regDC_PINSTRAPS_BASE_IDX),
1161         FN(DC_PINSTRAPS, DC_PINSTRAPS_AUDIO), &straps->dc_pinstraps_audio);
1162 
1163 }
1164 
1165 static struct audio *dcn32_create_audio(
1166         struct dc_context *ctx, unsigned int inst)
1167 {
1168     return dce_audio_create(ctx, inst,
1169             &audio_regs[inst], &audio_shift, &audio_mask);
1170 }
1171 
1172 static struct vpg *dcn32_vpg_create(
1173     struct dc_context *ctx,
1174     uint32_t inst)
1175 {
1176     struct dcn30_vpg *vpg3 = kzalloc(sizeof(struct dcn30_vpg), GFP_KERNEL);
1177 
1178     if (!vpg3)
1179         return NULL;
1180 
1181     vpg3_construct(vpg3, ctx, inst,
1182             &vpg_regs[inst],
1183             &vpg_shift,
1184             &vpg_mask);
1185 
1186     return &vpg3->base;
1187 }
1188 
1189 static struct afmt *dcn32_afmt_create(
1190     struct dc_context *ctx,
1191     uint32_t inst)
1192 {
1193     struct dcn30_afmt *afmt3 = kzalloc(sizeof(struct dcn30_afmt), GFP_KERNEL);
1194 
1195     if (!afmt3)
1196         return NULL;
1197 
1198     afmt3_construct(afmt3, ctx, inst,
1199             &afmt_regs[inst],
1200             &afmt_shift,
1201             &afmt_mask);
1202 
1203     return &afmt3->base;
1204 }
1205 
1206 static struct apg *dcn31_apg_create(
1207     struct dc_context *ctx,
1208     uint32_t inst)
1209 {
1210     struct dcn31_apg *apg31 = kzalloc(sizeof(struct dcn31_apg), GFP_KERNEL);
1211 
1212     if (!apg31)
1213         return NULL;
1214 
1215     apg31_construct(apg31, ctx, inst,
1216             &apg_regs[inst],
1217             &apg_shift,
1218             &apg_mask);
1219 
1220     return &apg31->base;
1221 }
1222 
1223 static struct stream_encoder *dcn32_stream_encoder_create(
1224     enum engine_id eng_id,
1225     struct dc_context *ctx)
1226 {
1227     struct dcn10_stream_encoder *enc1;
1228     struct vpg *vpg;
1229     struct afmt *afmt;
1230     int vpg_inst;
1231     int afmt_inst;
1232 
1233     /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */
1234     if (eng_id <= ENGINE_ID_DIGF) {
1235         vpg_inst = eng_id;
1236         afmt_inst = eng_id;
1237     } else
1238         return NULL;
1239 
1240     enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL);
1241     vpg = dcn32_vpg_create(ctx, vpg_inst);
1242     afmt = dcn32_afmt_create(ctx, afmt_inst);
1243 
1244     if (!enc1 || !vpg || !afmt) {
1245         kfree(enc1);
1246         kfree(vpg);
1247         kfree(afmt);
1248         return NULL;
1249     }
1250 
1251     dcn32_dio_stream_encoder_construct(enc1, ctx, ctx->dc_bios,
1252                     eng_id, vpg, afmt,
1253                     &stream_enc_regs[eng_id],
1254                     &se_shift, &se_mask);
1255 
1256     return &enc1->base;
1257 }
1258 
1259 static struct hpo_dp_stream_encoder *dcn32_hpo_dp_stream_encoder_create(
1260     enum engine_id eng_id,
1261     struct dc_context *ctx)
1262 {
1263     struct dcn31_hpo_dp_stream_encoder *hpo_dp_enc31;
1264     struct vpg *vpg;
1265     struct apg *apg;
1266     uint32_t hpo_dp_inst;
1267     uint32_t vpg_inst;
1268     uint32_t apg_inst;
1269 
1270     ASSERT((eng_id >= ENGINE_ID_HPO_DP_0) && (eng_id <= ENGINE_ID_HPO_DP_3));
1271     hpo_dp_inst = eng_id - ENGINE_ID_HPO_DP_0;
1272 
1273     /* Mapping of VPG register blocks to HPO DP block instance:
1274      * VPG[6] -> HPO_DP[0]
1275      * VPG[7] -> HPO_DP[1]
1276      * VPG[8] -> HPO_DP[2]
1277      * VPG[9] -> HPO_DP[3]
1278      */
1279     vpg_inst = hpo_dp_inst + 6;
1280 
1281     /* Mapping of APG register blocks to HPO DP block instance:
1282      * APG[0] -> HPO_DP[0]
1283      * APG[1] -> HPO_DP[1]
1284      * APG[2] -> HPO_DP[2]
1285      * APG[3] -> HPO_DP[3]
1286      */
1287     apg_inst = hpo_dp_inst;
1288 
1289     /* allocate HPO stream encoder and create VPG sub-block */
1290     hpo_dp_enc31 = kzalloc(sizeof(struct dcn31_hpo_dp_stream_encoder), GFP_KERNEL);
1291     vpg = dcn32_vpg_create(ctx, vpg_inst);
1292     apg = dcn31_apg_create(ctx, apg_inst);
1293 
1294     if (!hpo_dp_enc31 || !vpg || !apg) {
1295         kfree(hpo_dp_enc31);
1296         kfree(vpg);
1297         kfree(apg);
1298         return NULL;
1299     }
1300 
1301     dcn31_hpo_dp_stream_encoder_construct(hpo_dp_enc31, ctx, ctx->dc_bios,
1302                     hpo_dp_inst, eng_id, vpg, apg,
1303                     &hpo_dp_stream_enc_regs[hpo_dp_inst],
1304                     &hpo_dp_se_shift, &hpo_dp_se_mask);
1305 
1306     return &hpo_dp_enc31->base;
1307 }
1308 
1309 static struct hpo_dp_link_encoder *dcn32_hpo_dp_link_encoder_create(
1310     uint8_t inst,
1311     struct dc_context *ctx)
1312 {
1313     struct dcn31_hpo_dp_link_encoder *hpo_dp_enc31;
1314 
1315     /* allocate HPO link encoder */
1316     hpo_dp_enc31 = kzalloc(sizeof(struct dcn31_hpo_dp_link_encoder), GFP_KERNEL);
1317 
1318     hpo_dp_link_encoder32_construct(hpo_dp_enc31, ctx, inst,
1319                     &hpo_dp_link_enc_regs[inst],
1320                     &hpo_dp_le_shift, &hpo_dp_le_mask);
1321 
1322     return &hpo_dp_enc31->base;
1323 }
1324 
1325 static struct dce_hwseq *dcn32_hwseq_create(
1326     struct dc_context *ctx)
1327 {
1328     struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL);
1329 
1330     if (hws) {
1331         hws->ctx = ctx;
1332         hws->regs = &hwseq_reg;
1333         hws->shifts = &hwseq_shift;
1334         hws->masks = &hwseq_mask;
1335     }
1336     return hws;
1337 }
1338 static const struct resource_create_funcs res_create_funcs = {
1339     .read_dce_straps = read_dce_straps,
1340     .create_audio = dcn32_create_audio,
1341     .create_stream_encoder = dcn32_stream_encoder_create,
1342     .create_hpo_dp_stream_encoder = dcn32_hpo_dp_stream_encoder_create,
1343     .create_hpo_dp_link_encoder = dcn32_hpo_dp_link_encoder_create,
1344     .create_hwseq = dcn32_hwseq_create,
1345 };
1346 
1347 static const struct resource_create_funcs res_create_maximus_funcs = {
1348     .read_dce_straps = NULL,
1349     .create_audio = NULL,
1350     .create_stream_encoder = NULL,
1351     .create_hpo_dp_stream_encoder = dcn32_hpo_dp_stream_encoder_create,
1352     .create_hpo_dp_link_encoder = dcn32_hpo_dp_link_encoder_create,
1353     .create_hwseq = dcn32_hwseq_create,
1354 };
1355 
1356 static void dcn32_resource_destruct(struct dcn32_resource_pool *pool)
1357 {
1358     unsigned int i;
1359 
1360     for (i = 0; i < pool->base.stream_enc_count; i++) {
1361         if (pool->base.stream_enc[i] != NULL) {
1362             if (pool->base.stream_enc[i]->vpg != NULL) {
1363                 kfree(DCN30_VPG_FROM_VPG(pool->base.stream_enc[i]->vpg));
1364                 pool->base.stream_enc[i]->vpg = NULL;
1365             }
1366             if (pool->base.stream_enc[i]->afmt != NULL) {
1367                 kfree(DCN30_AFMT_FROM_AFMT(pool->base.stream_enc[i]->afmt));
1368                 pool->base.stream_enc[i]->afmt = NULL;
1369             }
1370             kfree(DCN10STRENC_FROM_STRENC(pool->base.stream_enc[i]));
1371             pool->base.stream_enc[i] = NULL;
1372         }
1373     }
1374 
1375     for (i = 0; i < pool->base.hpo_dp_stream_enc_count; i++) {
1376         if (pool->base.hpo_dp_stream_enc[i] != NULL) {
1377             if (pool->base.hpo_dp_stream_enc[i]->vpg != NULL) {
1378                 kfree(DCN30_VPG_FROM_VPG(pool->base.hpo_dp_stream_enc[i]->vpg));
1379                 pool->base.hpo_dp_stream_enc[i]->vpg = NULL;
1380             }
1381             if (pool->base.hpo_dp_stream_enc[i]->apg != NULL) {
1382                 kfree(DCN31_APG_FROM_APG(pool->base.hpo_dp_stream_enc[i]->apg));
1383                 pool->base.hpo_dp_stream_enc[i]->apg = NULL;
1384             }
1385             kfree(DCN3_1_HPO_DP_STREAM_ENC_FROM_HPO_STREAM_ENC(pool->base.hpo_dp_stream_enc[i]));
1386             pool->base.hpo_dp_stream_enc[i] = NULL;
1387         }
1388     }
1389 
1390     for (i = 0; i < pool->base.hpo_dp_link_enc_count; i++) {
1391         if (pool->base.hpo_dp_link_enc[i] != NULL) {
1392             kfree(DCN3_1_HPO_DP_LINK_ENC_FROM_HPO_LINK_ENC(pool->base.hpo_dp_link_enc[i]));
1393             pool->base.hpo_dp_link_enc[i] = NULL;
1394         }
1395     }
1396 
1397     for (i = 0; i < pool->base.res_cap->num_dsc; i++) {
1398         if (pool->base.dscs[i] != NULL)
1399             dcn20_dsc_destroy(&pool->base.dscs[i]);
1400     }
1401 
1402     if (pool->base.mpc != NULL) {
1403         kfree(TO_DCN20_MPC(pool->base.mpc));
1404         pool->base.mpc = NULL;
1405     }
1406     if (pool->base.hubbub != NULL) {
1407         kfree(TO_DCN20_HUBBUB(pool->base.hubbub));
1408         pool->base.hubbub = NULL;
1409     }
1410     for (i = 0; i < pool->base.pipe_count; i++) {
1411         if (pool->base.dpps[i] != NULL)
1412             dcn32_dpp_destroy(&pool->base.dpps[i]);
1413 
1414         if (pool->base.ipps[i] != NULL)
1415             pool->base.ipps[i]->funcs->ipp_destroy(&pool->base.ipps[i]);
1416 
1417         if (pool->base.hubps[i] != NULL) {
1418             kfree(TO_DCN20_HUBP(pool->base.hubps[i]));
1419             pool->base.hubps[i] = NULL;
1420         }
1421 
1422         if (pool->base.irqs != NULL) {
1423             dal_irq_service_destroy(&pool->base.irqs);
1424         }
1425     }
1426 
1427     for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
1428         if (pool->base.engines[i] != NULL)
1429             dce110_engine_destroy(&pool->base.engines[i]);
1430         if (pool->base.hw_i2cs[i] != NULL) {
1431             kfree(pool->base.hw_i2cs[i]);
1432             pool->base.hw_i2cs[i] = NULL;
1433         }
1434         if (pool->base.sw_i2cs[i] != NULL) {
1435             kfree(pool->base.sw_i2cs[i]);
1436             pool->base.sw_i2cs[i] = NULL;
1437         }
1438     }
1439 
1440     for (i = 0; i < pool->base.res_cap->num_opp; i++) {
1441         if (pool->base.opps[i] != NULL)
1442             pool->base.opps[i]->funcs->opp_destroy(&pool->base.opps[i]);
1443     }
1444 
1445     for (i = 0; i < pool->base.res_cap->num_timing_generator; i++) {
1446         if (pool->base.timing_generators[i] != NULL)    {
1447             kfree(DCN10TG_FROM_TG(pool->base.timing_generators[i]));
1448             pool->base.timing_generators[i] = NULL;
1449         }
1450     }
1451 
1452     for (i = 0; i < pool->base.res_cap->num_dwb; i++) {
1453         if (pool->base.dwbc[i] != NULL) {
1454             kfree(TO_DCN30_DWBC(pool->base.dwbc[i]));
1455             pool->base.dwbc[i] = NULL;
1456         }
1457         if (pool->base.mcif_wb[i] != NULL) {
1458             kfree(TO_DCN30_MMHUBBUB(pool->base.mcif_wb[i]));
1459             pool->base.mcif_wb[i] = NULL;
1460         }
1461     }
1462 
1463     for (i = 0; i < pool->base.audio_count; i++) {
1464         if (pool->base.audios[i])
1465             dce_aud_destroy(&pool->base.audios[i]);
1466     }
1467 
1468     for (i = 0; i < pool->base.clk_src_count; i++) {
1469         if (pool->base.clock_sources[i] != NULL) {
1470             dcn20_clock_source_destroy(&pool->base.clock_sources[i]);
1471             pool->base.clock_sources[i] = NULL;
1472         }
1473     }
1474 
1475     for (i = 0; i < pool->base.res_cap->num_mpc_3dlut; i++) {
1476         if (pool->base.mpc_lut[i] != NULL) {
1477             dc_3dlut_func_release(pool->base.mpc_lut[i]);
1478             pool->base.mpc_lut[i] = NULL;
1479         }
1480         if (pool->base.mpc_shaper[i] != NULL) {
1481             dc_transfer_func_release(pool->base.mpc_shaper[i]);
1482             pool->base.mpc_shaper[i] = NULL;
1483         }
1484     }
1485 
1486     if (pool->base.dp_clock_source != NULL) {
1487         dcn20_clock_source_destroy(&pool->base.dp_clock_source);
1488         pool->base.dp_clock_source = NULL;
1489     }
1490 
1491     for (i = 0; i < pool->base.res_cap->num_timing_generator; i++) {
1492         if (pool->base.multiple_abms[i] != NULL)
1493             dce_abm_destroy(&pool->base.multiple_abms[i]);
1494     }
1495 
1496     if (pool->base.psr != NULL)
1497         dmub_psr_destroy(&pool->base.psr);
1498 
1499     if (pool->base.dccg != NULL)
1500         dcn_dccg_destroy(&pool->base.dccg);
1501 
1502     if (pool->base.oem_device != NULL)
1503         dal_ddc_service_destroy(&pool->base.oem_device);
1504 }
1505 
1506 
1507 static bool dcn32_dwbc_create(struct dc_context *ctx, struct resource_pool *pool)
1508 {
1509     int i;
1510     uint32_t dwb_count = pool->res_cap->num_dwb;
1511 
1512     for (i = 0; i < dwb_count; i++) {
1513         struct dcn30_dwbc *dwbc30 = kzalloc(sizeof(struct dcn30_dwbc),
1514                             GFP_KERNEL);
1515 
1516         if (!dwbc30) {
1517             dm_error("DC: failed to create dwbc30!\n");
1518             return false;
1519         }
1520 
1521         dcn30_dwbc_construct(dwbc30, ctx,
1522                 &dwbc30_regs[i],
1523                 &dwbc30_shift,
1524                 &dwbc30_mask,
1525                 i);
1526 
1527         pool->dwbc[i] = &dwbc30->base;
1528     }
1529     return true;
1530 }
1531 
1532 static bool dcn32_mmhubbub_create(struct dc_context *ctx, struct resource_pool *pool)
1533 {
1534     int i;
1535     uint32_t dwb_count = pool->res_cap->num_dwb;
1536 
1537     for (i = 0; i < dwb_count; i++) {
1538         struct dcn30_mmhubbub *mcif_wb30 = kzalloc(sizeof(struct dcn30_mmhubbub),
1539                             GFP_KERNEL);
1540 
1541         if (!mcif_wb30) {
1542             dm_error("DC: failed to create mcif_wb30!\n");
1543             return false;
1544         }
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 
1557 static struct display_stream_compressor *dcn32_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     dsc2_construct(dsc, ctx, inst, &dsc_regs[inst], &dsc_shift, &dsc_mask);
1569 
1570     dsc->max_image_width = 6016;
1571 
1572     return &dsc->base;
1573 }
1574 
1575 static void dcn32_destroy_resource_pool(struct resource_pool **pool)
1576 {
1577     struct dcn32_resource_pool *dcn32_pool = TO_DCN32_RES_POOL(*pool);
1578 
1579     dcn32_resource_destruct(dcn32_pool);
1580     kfree(dcn32_pool);
1581     *pool = NULL;
1582 }
1583 
1584 bool dcn32_acquire_post_bldn_3dlut(
1585         struct resource_context *res_ctx,
1586         const struct resource_pool *pool,
1587         int mpcc_id,
1588         struct dc_3dlut **lut,
1589         struct dc_transfer_func **shaper)
1590 {
1591     bool ret = false;
1592     union dc_3dlut_state *state;
1593 
1594     ASSERT(*lut == NULL && *shaper == NULL);
1595     *lut = NULL;
1596     *shaper = NULL;
1597 
1598     if (!res_ctx->is_mpc_3dlut_acquired[mpcc_id]) {
1599         *lut = pool->mpc_lut[mpcc_id];
1600         *shaper = pool->mpc_shaper[mpcc_id];
1601         state = &pool->mpc_lut[mpcc_id]->state;
1602         res_ctx->is_mpc_3dlut_acquired[mpcc_id] = true;
1603         ret = true;
1604     }
1605     return ret;
1606 }
1607 
1608 bool dcn32_release_post_bldn_3dlut(
1609         struct resource_context *res_ctx,
1610         const struct resource_pool *pool,
1611         struct dc_3dlut **lut,
1612         struct dc_transfer_func **shaper)
1613 {
1614     int i;
1615     bool ret = false;
1616 
1617     for (i = 0; i < pool->res_cap->num_mpc_3dlut; i++) {
1618         if (pool->mpc_lut[i] == *lut && pool->mpc_shaper[i] == *shaper) {
1619             res_ctx->is_mpc_3dlut_acquired[i] = false;
1620             pool->mpc_lut[i]->state.raw = 0;
1621             *lut = NULL;
1622             *shaper = NULL;
1623             ret = true;
1624             break;
1625         }
1626     }
1627     return ret;
1628 }
1629 
1630 static void dcn32_enable_phantom_plane(struct dc *dc,
1631         struct dc_state *context,
1632         struct dc_stream_state *phantom_stream,
1633         unsigned int dc_pipe_idx)
1634 {
1635     struct dc_plane_state *phantom_plane = NULL;
1636     struct dc_plane_state *prev_phantom_plane = NULL;
1637     struct pipe_ctx *curr_pipe = &context->res_ctx.pipe_ctx[dc_pipe_idx];
1638 
1639     while (curr_pipe) {
1640         if (curr_pipe->top_pipe && curr_pipe->top_pipe->plane_state == curr_pipe->plane_state)
1641             phantom_plane = prev_phantom_plane;
1642         else
1643             phantom_plane = dc_create_plane_state(dc);
1644 
1645         memcpy(&phantom_plane->address, &curr_pipe->plane_state->address, sizeof(phantom_plane->address));
1646         memcpy(&phantom_plane->scaling_quality, &curr_pipe->plane_state->scaling_quality,
1647                 sizeof(phantom_plane->scaling_quality));
1648         memcpy(&phantom_plane->src_rect, &curr_pipe->plane_state->src_rect, sizeof(phantom_plane->src_rect));
1649         memcpy(&phantom_plane->dst_rect, &curr_pipe->plane_state->dst_rect, sizeof(phantom_plane->dst_rect));
1650         memcpy(&phantom_plane->clip_rect, &curr_pipe->plane_state->clip_rect, sizeof(phantom_plane->clip_rect));
1651         memcpy(&phantom_plane->plane_size, &curr_pipe->plane_state->plane_size,
1652                 sizeof(phantom_plane->plane_size));
1653         memcpy(&phantom_plane->tiling_info, &curr_pipe->plane_state->tiling_info,
1654                 sizeof(phantom_plane->tiling_info));
1655         memcpy(&phantom_plane->dcc, &curr_pipe->plane_state->dcc, sizeof(phantom_plane->dcc));
1656         phantom_plane->format = curr_pipe->plane_state->format;
1657         phantom_plane->rotation = curr_pipe->plane_state->rotation;
1658         phantom_plane->visible = curr_pipe->plane_state->visible;
1659 
1660         /* Shadow pipe has small viewport. */
1661         phantom_plane->clip_rect.y = 0;
1662         phantom_plane->clip_rect.height = phantom_stream->timing.v_addressable;
1663 
1664         dc_add_plane_to_context(dc, phantom_stream, phantom_plane, context);
1665 
1666         curr_pipe = curr_pipe->bottom_pipe;
1667         prev_phantom_plane = phantom_plane;
1668     }
1669 }
1670 
1671 static struct dc_stream_state *dcn32_enable_phantom_stream(struct dc *dc,
1672         struct dc_state *context,
1673         display_e2e_pipe_params_st *pipes,
1674         unsigned int pipe_cnt,
1675         unsigned int dc_pipe_idx)
1676 {
1677     struct dc_stream_state *phantom_stream = NULL;
1678     struct pipe_ctx *ref_pipe = &context->res_ctx.pipe_ctx[dc_pipe_idx];
1679 
1680     phantom_stream = dc_create_stream_for_sink(ref_pipe->stream->sink);
1681     phantom_stream->signal = SIGNAL_TYPE_VIRTUAL;
1682     phantom_stream->dpms_off = true;
1683     phantom_stream->mall_stream_config.type = SUBVP_PHANTOM;
1684     phantom_stream->mall_stream_config.paired_stream = ref_pipe->stream;
1685     ref_pipe->stream->mall_stream_config.type = SUBVP_MAIN;
1686     ref_pipe->stream->mall_stream_config.paired_stream = phantom_stream;
1687 
1688     /* stream has limited viewport and small timing */
1689     memcpy(&phantom_stream->timing, &ref_pipe->stream->timing, sizeof(phantom_stream->timing));
1690     memcpy(&phantom_stream->src, &ref_pipe->stream->src, sizeof(phantom_stream->src));
1691     memcpy(&phantom_stream->dst, &ref_pipe->stream->dst, sizeof(phantom_stream->dst));
1692     DC_FP_START();
1693     dcn32_set_phantom_stream_timing(dc, context, ref_pipe, phantom_stream, pipes, pipe_cnt, dc_pipe_idx);
1694     DC_FP_END();
1695 
1696     dc_add_stream_to_ctx(dc, context, phantom_stream);
1697     return phantom_stream;
1698 }
1699 
1700 // return true if removed piped from ctx, false otherwise
1701 bool dcn32_remove_phantom_pipes(struct dc *dc, struct dc_state *context)
1702 {
1703     int i;
1704     bool removed_pipe = false;
1705 
1706     for (i = 0; i < dc->res_pool->pipe_count; i++) {
1707         struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
1708         // build scaling params for phantom pipes
1709         if (pipe->plane_state && pipe->stream && pipe->stream->mall_stream_config.type == SUBVP_PHANTOM) {
1710             dc_rem_all_planes_for_stream(dc, pipe->stream, context);
1711             dc_remove_stream_from_ctx(dc, context, pipe->stream);
1712             removed_pipe = true;
1713         }
1714 
1715         // Clear all phantom stream info
1716         if (pipe->stream) {
1717             pipe->stream->mall_stream_config.type = SUBVP_NONE;
1718             pipe->stream->mall_stream_config.paired_stream = NULL;
1719         }
1720     }
1721     return removed_pipe;
1722 }
1723 
1724 /* TODO: Input to this function should indicate which pipe indexes (or streams)
1725  * require a phantom pipe / stream
1726  */
1727 void dcn32_add_phantom_pipes(struct dc *dc, struct dc_state *context,
1728         display_e2e_pipe_params_st *pipes,
1729         unsigned int pipe_cnt,
1730         unsigned int index)
1731 {
1732     struct dc_stream_state *phantom_stream = NULL;
1733     unsigned int i;
1734 
1735     // The index of the DC pipe passed into this function is guarenteed to
1736     // be a valid candidate for SubVP (i.e. has a plane, stream, doesn't
1737     // already have phantom pipe assigned, etc.) by previous checks.
1738     phantom_stream = dcn32_enable_phantom_stream(dc, context, pipes, pipe_cnt, index);
1739     dcn32_enable_phantom_plane(dc, context, phantom_stream, index);
1740 
1741     for (i = 0; i < dc->res_pool->pipe_count; i++) {
1742         struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
1743 
1744         // Build scaling params for phantom pipes which were newly added.
1745         // We determine which phantom pipes were added by comparing with
1746         // the phantom stream.
1747         if (pipe->plane_state && pipe->stream && pipe->stream == phantom_stream &&
1748                 pipe->stream->mall_stream_config.type == SUBVP_PHANTOM) {
1749             pipe->stream->use_dynamic_meta = false;
1750             pipe->plane_state->flip_immediate = false;
1751             if (!resource_build_scaling_params(pipe)) {
1752                 // Log / remove phantom pipes since failed to build scaling params
1753             }
1754         }
1755     }
1756 }
1757 
1758 bool dcn32_validate_bandwidth(struct dc *dc,
1759         struct dc_state *context,
1760         bool fast_validate)
1761 {
1762     bool out = false;
1763 
1764     BW_VAL_TRACE_SETUP();
1765 
1766     int vlevel = 0;
1767     int pipe_cnt = 0;
1768     display_e2e_pipe_params_st *pipes = kzalloc(dc->res_pool->pipe_count * sizeof(display_e2e_pipe_params_st), GFP_KERNEL);
1769     DC_LOGGER_INIT(dc->ctx->logger);
1770 
1771     BW_VAL_TRACE_COUNT();
1772 
1773     DC_FP_START();
1774     out = dcn32_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel, fast_validate);
1775     DC_FP_END();
1776 
1777     if (pipe_cnt == 0)
1778         goto validate_out;
1779 
1780     if (!out)
1781         goto validate_fail;
1782 
1783     BW_VAL_TRACE_END_VOLTAGE_LEVEL();
1784 
1785     if (fast_validate) {
1786         BW_VAL_TRACE_SKIP(fast);
1787         goto validate_out;
1788     }
1789 
1790     dc->res_pool->funcs->calculate_wm_and_dlg(dc, context, pipes, pipe_cnt, vlevel);
1791 
1792     BW_VAL_TRACE_END_WATERMARKS();
1793 
1794     goto validate_out;
1795 
1796 validate_fail:
1797     DC_LOG_WARNING("Mode Validation Warning: %s failed validation.\n",
1798         dml_get_status_message(context->bw_ctx.dml.vba.ValidationStatus[context->bw_ctx.dml.vba.soc.num_states]));
1799 
1800     BW_VAL_TRACE_SKIP(fail);
1801     out = false;
1802 
1803 validate_out:
1804     kfree(pipes);
1805 
1806     BW_VAL_TRACE_FINISH();
1807 
1808     return out;
1809 }
1810 
1811 
1812 static bool is_dual_plane(enum surface_pixel_format format)
1813 {
1814     return format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN || format == SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA;
1815 }
1816 
1817 int dcn32_populate_dml_pipes_from_context(
1818     struct dc *dc, struct dc_state *context,
1819     display_e2e_pipe_params_st *pipes,
1820     bool fast_validate)
1821 {
1822     int i, pipe_cnt;
1823     struct resource_context *res_ctx = &context->res_ctx;
1824     struct pipe_ctx *pipe;
1825     bool subvp_in_use = false, is_pipe_split_expected[MAX_PIPES];
1826     int plane_count = 0;
1827     struct dc_crtc_timing *timing;
1828 
1829     dcn20_populate_dml_pipes_from_context(dc, context, pipes, fast_validate);
1830 
1831     for (i = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {
1832 
1833         if (!res_ctx->pipe_ctx[i].stream)
1834             continue;
1835         pipe = &res_ctx->pipe_ctx[i];
1836         timing = &pipe->stream->timing;
1837 
1838         pipes[pipe_cnt].pipe.src.gpuvm = true;
1839         pipes[pipe_cnt].pipe.src.dcc_fraction_of_zs_req_luma = 0;
1840         pipes[pipe_cnt].pipe.src.dcc_fraction_of_zs_req_chroma = 0;
1841         pipes[pipe_cnt].pipe.dest.vfront_porch = timing->v_front_porch;
1842         pipes[pipe_cnt].pipe.src.gpuvm_min_page_size_kbytes = 256; // according to spreadsheet
1843         pipes[pipe_cnt].pipe.src.unbounded_req_mode = false;
1844         pipes[pipe_cnt].pipe.scale_ratio_depth.lb_depth = dm_lb_19;
1845 
1846         switch (pipe->stream->mall_stream_config.type) {
1847         case SUBVP_MAIN:
1848             pipes[pipe_cnt].pipe.src.use_mall_for_pstate_change = dm_use_mall_pstate_change_sub_viewport;
1849             subvp_in_use = true;
1850             break;
1851         case SUBVP_PHANTOM:
1852             pipes[pipe_cnt].pipe.src.use_mall_for_pstate_change = dm_use_mall_pstate_change_phantom_pipe;
1853             pipes[pipe_cnt].pipe.src.use_mall_for_static_screen = dm_use_mall_static_screen_disable;
1854             // Disallow unbounded req for SubVP according to DCHUB programming guide
1855             pipes[pipe_cnt].pipe.src.unbounded_req_mode = false;
1856             break;
1857         case SUBVP_NONE:
1858             pipes[pipe_cnt].pipe.src.use_mall_for_pstate_change = dm_use_mall_pstate_change_disable;
1859             pipes[pipe_cnt].pipe.src.use_mall_for_static_screen = dm_use_mall_static_screen_disable;
1860             break;
1861         default:
1862             break;
1863         }
1864 
1865         pipes[pipe_cnt].dout.dsc_input_bpc = 0;
1866         if (pipes[pipe_cnt].dout.dsc_enable) {
1867             switch (timing->display_color_depth) {
1868             case COLOR_DEPTH_888:
1869                 pipes[pipe_cnt].dout.dsc_input_bpc = 8;
1870                 break;
1871             case COLOR_DEPTH_101010:
1872                 pipes[pipe_cnt].dout.dsc_input_bpc = 10;
1873                 break;
1874             case COLOR_DEPTH_121212:
1875                 pipes[pipe_cnt].dout.dsc_input_bpc = 12;
1876                 break;
1877             default:
1878                 ASSERT(0);
1879                 break;
1880             }
1881         }
1882 
1883         /* Calculate the number of planes we have so we can determine
1884          *  whether to apply ODM 2to1 policy or not
1885          */
1886         if (pipe->stream && !pipe->prev_odm_pipe &&
1887                 (!pipe->top_pipe || pipe->top_pipe->plane_state != pipe->plane_state))
1888             ++plane_count;
1889 
1890         DC_FP_START();
1891         is_pipe_split_expected[i] = dcn32_predict_pipe_split(context, pipes[i].pipe, i);
1892         DC_FP_END();
1893 
1894         pipe_cnt++;
1895     }
1896 
1897     /* Determine whether we will apply ODM 2to1 policy
1898      * Applies to single display and where the number of planes is less than 3
1899      * For 3 plane case ( 2 MPO planes ), we will not set the policy for the MPO pipes
1900      */
1901     for (i = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {
1902         if (!res_ctx->pipe_ctx[i].stream)
1903             continue;
1904         pipe = &res_ctx->pipe_ctx[i];
1905         timing = &pipe->stream->timing;
1906 
1907         pipes[pipe_cnt].pipe.dest.odm_combine_policy = dm_odm_combine_policy_dal;
1908         res_ctx->pipe_ctx[i].stream->odm_2to1_policy_applied  = false;
1909         if (context->stream_count == 1 && timing->dsc_cfg.num_slices_h != 1) {
1910             if (dc->debug.enable_single_display_2to1_odm_policy) {
1911                 if (!((plane_count > 2) && pipe->top_pipe))
1912                     pipes[pipe_cnt].pipe.dest.odm_combine_policy = dm_odm_combine_policy_2to1;
1913             }
1914             res_ctx->pipe_ctx[i].stream->odm_2to1_policy_applied = true;
1915         }
1916         pipe_cnt++;
1917     }
1918 
1919     /* For DET allocation, we don't want to use DML policy (not optimal for utilizing all
1920      * the DET available for each pipe). Use the DET override input to maintain our driver
1921      * policy.
1922      */
1923     if (pipe_cnt == 1 && !is_pipe_split_expected[0]) {
1924         pipes[0].pipe.src.det_size_override = DCN3_2_MAX_DET_SIZE;
1925         if (pipe->plane_state && !dc->debug.disable_z9_mpc) {
1926             if (!is_dual_plane(pipe->plane_state->format)) {
1927                 pipes[0].pipe.src.det_size_override = DCN3_2_DEFAULT_DET_SIZE;
1928                 pipes[0].pipe.src.unbounded_req_mode = true;
1929                 if (pipe->plane_state->src_rect.width >= 5120 &&
1930                     pipe->plane_state->src_rect.height >= 2880)
1931                     pipes[0].pipe.src.det_size_override = 320; // 5K or higher
1932             }
1933         }
1934     } else
1935         dcn32_determine_det_override(context, pipes, is_pipe_split_expected, dc->res_pool->pipe_count);
1936 
1937     // In general cases we want to keep the dram clock change requirement
1938     // (prefer configs that support MCLK switch). Only override to false
1939     // for SubVP
1940     if (subvp_in_use)
1941         context->bw_ctx.dml.soc.dram_clock_change_requirement_final = false;
1942     else
1943         context->bw_ctx.dml.soc.dram_clock_change_requirement_final = true;
1944 
1945     return pipe_cnt;
1946 }
1947 
1948 static struct dc_cap_funcs cap_funcs = {
1949     .get_dcc_compression_cap = dcn20_get_dcc_compression_cap
1950 };
1951 
1952 void dcn32_calculate_wm_and_dlg(struct dc *dc, struct dc_state *context,
1953                 display_e2e_pipe_params_st *pipes,
1954                 int pipe_cnt,
1955                 int vlevel)
1956 {
1957     DC_FP_START();
1958     dcn32_calculate_wm_and_dlg_fpu(dc, context, pipes, pipe_cnt, vlevel);
1959     DC_FP_END();
1960 }
1961 
1962 static void dcn32_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params)
1963 {
1964     DC_FP_START();
1965     dcn32_update_bw_bounding_box_fpu(dc, bw_params);
1966     DC_FP_END();
1967 }
1968 
1969 static struct resource_funcs dcn32_res_pool_funcs = {
1970     .destroy = dcn32_destroy_resource_pool,
1971     .link_enc_create = dcn32_link_encoder_create,
1972     .link_enc_create_minimal = NULL,
1973     .panel_cntl_create = dcn32_panel_cntl_create,
1974     .validate_bandwidth = dcn32_validate_bandwidth,
1975     .calculate_wm_and_dlg = dcn32_calculate_wm_and_dlg,
1976     .populate_dml_pipes = dcn32_populate_dml_pipes_from_context,
1977     .acquire_idle_pipe_for_head_pipe_in_layer = dcn32_acquire_idle_pipe_for_head_pipe_in_layer,
1978     .add_stream_to_ctx = dcn30_add_stream_to_ctx,
1979     .add_dsc_to_stream_resource = dcn20_add_dsc_to_stream_resource,
1980     .remove_stream_from_ctx = dcn20_remove_stream_from_ctx,
1981     .populate_dml_writeback_from_context = dcn30_populate_dml_writeback_from_context,
1982     .set_mcif_arb_params = dcn30_set_mcif_arb_params,
1983     .find_first_free_match_stream_enc_for_link = dcn10_find_first_free_match_stream_enc_for_link,
1984     .acquire_post_bldn_3dlut = dcn32_acquire_post_bldn_3dlut,
1985     .release_post_bldn_3dlut = dcn32_release_post_bldn_3dlut,
1986     .update_bw_bounding_box = dcn32_update_bw_bounding_box,
1987     .patch_unknown_plane_state = dcn20_patch_unknown_plane_state,
1988     .update_soc_for_wm_a = dcn30_update_soc_for_wm_a,
1989     .add_phantom_pipes = dcn32_add_phantom_pipes,
1990     .remove_phantom_pipes = dcn32_remove_phantom_pipes,
1991 };
1992 
1993 
1994 static bool dcn32_resource_construct(
1995     uint8_t num_virtual_links,
1996     struct dc *dc,
1997     struct dcn32_resource_pool *pool)
1998 {
1999     int i, j;
2000     struct dc_context *ctx = dc->ctx;
2001     struct irq_service_init_data init_data;
2002     struct ddc_service_init_data ddc_init_data = {0};
2003     uint32_t pipe_fuses = 0;
2004     uint32_t num_pipes  = 4;
2005 
2006     DC_FP_START();
2007 
2008     ctx->dc_bios->regs = &bios_regs;
2009 
2010     pool->base.res_cap = &res_cap_dcn32;
2011     /* max number of pipes for ASIC before checking for pipe fuses */
2012     num_pipes  = pool->base.res_cap->num_timing_generator;
2013     pipe_fuses = REG_READ(CC_DC_PIPE_DIS);
2014 
2015     for (i = 0; i < pool->base.res_cap->num_timing_generator; i++)
2016         if (pipe_fuses & 1 << i)
2017             num_pipes--;
2018 
2019     if (pipe_fuses & 1)
2020         ASSERT(0); //Unexpected - Pipe 0 should always be fully functional!
2021 
2022     if (pipe_fuses & CC_DC_PIPE_DIS__DC_FULL_DIS_MASK)
2023         ASSERT(0); //Entire DCN is harvested!
2024 
2025     /* within dml lib, initial value is hard coded, if ASIC pipe is fused, the
2026      * value will be changed, update max_num_dpp and max_num_otg for dml.
2027      */
2028     dcn3_2_ip.max_num_dpp = num_pipes;
2029     dcn3_2_ip.max_num_otg = num_pipes;
2030 
2031     pool->base.funcs = &dcn32_res_pool_funcs;
2032 
2033     /*************************************************
2034      *  Resource + asic cap harcoding                *
2035      *************************************************/
2036     pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE;
2037     pool->base.timing_generator_count = num_pipes;
2038     pool->base.pipe_count = num_pipes;
2039     pool->base.mpcc_count = num_pipes;
2040     dc->caps.max_downscale_ratio = 600;
2041     dc->caps.i2c_speed_in_khz = 100;
2042     dc->caps.i2c_speed_in_khz_hdcp = 100; /*1.4 w/a applied by default*/
2043     /* TODO: Bring max_cursor_size back to 256 after subvp cursor corruption is fixed*/
2044     dc->caps.max_cursor_size = 64;
2045     dc->caps.min_horizontal_blanking_period = 80;
2046     dc->caps.dmdata_alloc_size = 2048;
2047     dc->caps.mall_size_per_mem_channel = 0;
2048     dc->caps.mall_size_total = 0;
2049     dc->caps.cursor_cache_size = dc->caps.max_cursor_size * dc->caps.max_cursor_size * 8;
2050 
2051     dc->caps.cache_line_size = 64;
2052     dc->caps.cache_num_ways = 16;
2053     dc->caps.max_cab_allocation_bytes = 67108864; // 64MB = 1024 * 1024 * 64
2054     dc->caps.subvp_fw_processing_delay_us = 15;
2055     dc->caps.subvp_prefetch_end_to_mall_start_us = 15;
2056     dc->caps.subvp_swath_height_margin_lines = 16;
2057     dc->caps.subvp_pstate_allow_width_us = 20;
2058     dc->caps.subvp_vertical_int_margin_us = 30;
2059 
2060     dc->caps.max_slave_planes = 2;
2061     dc->caps.max_slave_yuv_planes = 2;
2062     dc->caps.max_slave_rgb_planes = 2;
2063     dc->caps.post_blend_color_processing = true;
2064     dc->caps.force_dp_tps4_for_cp2520 = true;
2065     dc->caps.dp_hpo = true;
2066     dc->caps.dp_hdmi21_pcon_support = true;
2067     dc->caps.edp_dsc_support = true;
2068     dc->caps.extended_aux_timeout_support = true;
2069     dc->caps.dmcub_support = true;
2070 
2071     /* Color pipeline capabilities */
2072     dc->caps.color.dpp.dcn_arch = 1;
2073     dc->caps.color.dpp.input_lut_shared = 0;
2074     dc->caps.color.dpp.icsc = 1;
2075     dc->caps.color.dpp.dgam_ram = 0; // must use gamma_corr
2076     dc->caps.color.dpp.dgam_rom_caps.srgb = 1;
2077     dc->caps.color.dpp.dgam_rom_caps.bt2020 = 1;
2078     dc->caps.color.dpp.dgam_rom_caps.gamma2_2 = 1;
2079     dc->caps.color.dpp.dgam_rom_caps.pq = 1;
2080     dc->caps.color.dpp.dgam_rom_caps.hlg = 1;
2081     dc->caps.color.dpp.post_csc = 1;
2082     dc->caps.color.dpp.gamma_corr = 1;
2083     dc->caps.color.dpp.dgam_rom_for_yuv = 0;
2084 
2085     dc->caps.color.dpp.hw_3d_lut = 1;
2086     dc->caps.color.dpp.ogam_ram = 0;  // no OGAM in DPP since DCN1
2087     // no OGAM ROM on DCN2 and later ASICs
2088     dc->caps.color.dpp.ogam_rom_caps.srgb = 0;
2089     dc->caps.color.dpp.ogam_rom_caps.bt2020 = 0;
2090     dc->caps.color.dpp.ogam_rom_caps.gamma2_2 = 0;
2091     dc->caps.color.dpp.ogam_rom_caps.pq = 0;
2092     dc->caps.color.dpp.ogam_rom_caps.hlg = 0;
2093     dc->caps.color.dpp.ocsc = 0;
2094 
2095     dc->caps.color.mpc.gamut_remap = 1;
2096     dc->caps.color.mpc.num_3dluts = pool->base.res_cap->num_mpc_3dlut; //4, configurable to be before or after BLND in MPCC
2097     dc->caps.color.mpc.ogam_ram = 1;
2098     dc->caps.color.mpc.ogam_rom_caps.srgb = 0;
2099     dc->caps.color.mpc.ogam_rom_caps.bt2020 = 0;
2100     dc->caps.color.mpc.ogam_rom_caps.gamma2_2 = 0;
2101     dc->caps.color.mpc.ogam_rom_caps.pq = 0;
2102     dc->caps.color.mpc.ogam_rom_caps.hlg = 0;
2103     dc->caps.color.mpc.ocsc = 1;
2104 
2105     /* Use pipe context based otg sync logic */
2106     dc->config.use_pipe_ctx_sync_logic = true;
2107 
2108     /* read VBIOS LTTPR caps */
2109     {
2110         if (ctx->dc_bios->funcs->get_lttpr_caps) {
2111             enum bp_result bp_query_result;
2112             uint8_t is_vbios_lttpr_enable = 0;
2113 
2114             bp_query_result = ctx->dc_bios->funcs->get_lttpr_caps(ctx->dc_bios, &is_vbios_lttpr_enable);
2115             dc->caps.vbios_lttpr_enable = (bp_query_result == BP_RESULT_OK) && !!is_vbios_lttpr_enable;
2116         }
2117 
2118         /* interop bit is implicit */
2119         {
2120             dc->caps.vbios_lttpr_aware = true;
2121         }
2122     }
2123 
2124     if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV)
2125         dc->debug = debug_defaults_drv;
2126     else if (dc->ctx->dce_environment == DCE_ENV_FPGA_MAXIMUS) {
2127         dc->debug = debug_defaults_diags;
2128     } else
2129         dc->debug = debug_defaults_diags;
2130     // Init the vm_helper
2131     if (dc->vm_helper)
2132         vm_helper_init(dc->vm_helper, 16);
2133 
2134     /*************************************************
2135      *  Create resources                             *
2136      *************************************************/
2137 
2138     /* Clock Sources for Pixel Clock*/
2139     pool->base.clock_sources[DCN32_CLK_SRC_PLL0] =
2140             dcn32_clock_source_create(ctx, ctx->dc_bios,
2141                 CLOCK_SOURCE_COMBO_PHY_PLL0,
2142                 &clk_src_regs[0], false);
2143     pool->base.clock_sources[DCN32_CLK_SRC_PLL1] =
2144             dcn32_clock_source_create(ctx, ctx->dc_bios,
2145                 CLOCK_SOURCE_COMBO_PHY_PLL1,
2146                 &clk_src_regs[1], false);
2147     pool->base.clock_sources[DCN32_CLK_SRC_PLL2] =
2148             dcn32_clock_source_create(ctx, ctx->dc_bios,
2149                 CLOCK_SOURCE_COMBO_PHY_PLL2,
2150                 &clk_src_regs[2], false);
2151     pool->base.clock_sources[DCN32_CLK_SRC_PLL3] =
2152             dcn32_clock_source_create(ctx, ctx->dc_bios,
2153                 CLOCK_SOURCE_COMBO_PHY_PLL3,
2154                 &clk_src_regs[3], false);
2155     pool->base.clock_sources[DCN32_CLK_SRC_PLL4] =
2156             dcn32_clock_source_create(ctx, ctx->dc_bios,
2157                 CLOCK_SOURCE_COMBO_PHY_PLL4,
2158                 &clk_src_regs[4], false);
2159 
2160     pool->base.clk_src_count = DCN32_CLK_SRC_TOTAL;
2161 
2162     /* todo: not reuse phy_pll registers */
2163     pool->base.dp_clock_source =
2164             dcn32_clock_source_create(ctx, ctx->dc_bios,
2165                 CLOCK_SOURCE_ID_DP_DTO,
2166                 &clk_src_regs[0], true);
2167 
2168     for (i = 0; i < pool->base.clk_src_count; i++) {
2169         if (pool->base.clock_sources[i] == NULL) {
2170             dm_error("DC: failed to create clock sources!\n");
2171             BREAK_TO_DEBUGGER();
2172             goto create_fail;
2173         }
2174     }
2175 
2176     /* DCCG */
2177     pool->base.dccg = dccg32_create(ctx, &dccg_regs, &dccg_shift, &dccg_mask);
2178     if (pool->base.dccg == NULL) {
2179         dm_error("DC: failed to create dccg!\n");
2180         BREAK_TO_DEBUGGER();
2181         goto create_fail;
2182     }
2183 
2184     /* DML */
2185     if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment))
2186         dml_init_instance(&dc->dml, &dcn3_2_soc, &dcn3_2_ip, DML_PROJECT_DCN32);
2187 
2188     /* IRQ Service */
2189     init_data.ctx = dc->ctx;
2190     pool->base.irqs = dal_irq_service_dcn32_create(&init_data);
2191     if (!pool->base.irqs)
2192         goto create_fail;
2193 
2194     /* HUBBUB */
2195     pool->base.hubbub = dcn32_hubbub_create(ctx);
2196     if (pool->base.hubbub == NULL) {
2197         BREAK_TO_DEBUGGER();
2198         dm_error("DC: failed to create hubbub!\n");
2199         goto create_fail;
2200     }
2201 
2202     /* HUBPs, DPPs, OPPs, TGs, ABMs */
2203     for (i = 0, j = 0; i < pool->base.res_cap->num_timing_generator; i++) {
2204 
2205         /* if pipe is disabled, skip instance of HW pipe,
2206          * i.e, skip ASIC register instance
2207          */
2208         if (pipe_fuses & 1 << i)
2209             continue;
2210 
2211         /* HUBPs */
2212         pool->base.hubps[j] = dcn32_hubp_create(ctx, i);
2213         if (pool->base.hubps[j] == NULL) {
2214             BREAK_TO_DEBUGGER();
2215             dm_error(
2216                 "DC: failed to create hubps!\n");
2217             goto create_fail;
2218         }
2219 
2220         /* DPPs */
2221         pool->base.dpps[j] = dcn32_dpp_create(ctx, i);
2222         if (pool->base.dpps[j] == NULL) {
2223             BREAK_TO_DEBUGGER();
2224             dm_error(
2225                 "DC: failed to create dpps!\n");
2226             goto create_fail;
2227         }
2228 
2229         /* OPPs */
2230         pool->base.opps[j] = dcn32_opp_create(ctx, i);
2231         if (pool->base.opps[j] == NULL) {
2232             BREAK_TO_DEBUGGER();
2233             dm_error(
2234                 "DC: failed to create output pixel processor!\n");
2235             goto create_fail;
2236         }
2237 
2238         /* TGs */
2239         pool->base.timing_generators[j] = dcn32_timing_generator_create(
2240                 ctx, i);
2241         if (pool->base.timing_generators[j] == NULL) {
2242             BREAK_TO_DEBUGGER();
2243             dm_error("DC: failed to create tg!\n");
2244             goto create_fail;
2245         }
2246 
2247         /* ABMs */
2248         pool->base.multiple_abms[j] = dmub_abm_create(ctx,
2249                 &abm_regs[i],
2250                 &abm_shift,
2251                 &abm_mask);
2252         if (pool->base.multiple_abms[j] == NULL) {
2253             dm_error("DC: failed to create abm for pipe %d!\n", i);
2254             BREAK_TO_DEBUGGER();
2255             goto create_fail;
2256         }
2257 
2258         /* index for resource pool arrays for next valid pipe */
2259         j++;
2260     }
2261 
2262     /* PSR */
2263     pool->base.psr = dmub_psr_create(ctx);
2264     if (pool->base.psr == NULL) {
2265         dm_error("DC: failed to create psr obj!\n");
2266         BREAK_TO_DEBUGGER();
2267         goto create_fail;
2268     }
2269 
2270     /* MPCCs */
2271     pool->base.mpc = dcn32_mpc_create(ctx, pool->base.res_cap->num_timing_generator, pool->base.res_cap->num_mpc_3dlut);
2272     if (pool->base.mpc == NULL) {
2273         BREAK_TO_DEBUGGER();
2274         dm_error("DC: failed to create mpc!\n");
2275         goto create_fail;
2276     }
2277 
2278     /* DSCs */
2279     for (i = 0; i < pool->base.res_cap->num_dsc; i++) {
2280         pool->base.dscs[i] = dcn32_dsc_create(ctx, i);
2281         if (pool->base.dscs[i] == NULL) {
2282             BREAK_TO_DEBUGGER();
2283             dm_error("DC: failed to create display stream compressor %d!\n", i);
2284             goto create_fail;
2285         }
2286     }
2287 
2288     /* DWB */
2289     if (!dcn32_dwbc_create(ctx, &pool->base)) {
2290         BREAK_TO_DEBUGGER();
2291         dm_error("DC: failed to create dwbc!\n");
2292         goto create_fail;
2293     }
2294 
2295     /* MMHUBBUB */
2296     if (!dcn32_mmhubbub_create(ctx, &pool->base)) {
2297         BREAK_TO_DEBUGGER();
2298         dm_error("DC: failed to create mcif_wb!\n");
2299         goto create_fail;
2300     }
2301 
2302     /* AUX and I2C */
2303     for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
2304         pool->base.engines[i] = dcn32_aux_engine_create(ctx, i);
2305         if (pool->base.engines[i] == NULL) {
2306             BREAK_TO_DEBUGGER();
2307             dm_error(
2308                 "DC:failed to create aux engine!!\n");
2309             goto create_fail;
2310         }
2311         pool->base.hw_i2cs[i] = dcn32_i2c_hw_create(ctx, i);
2312         if (pool->base.hw_i2cs[i] == NULL) {
2313             BREAK_TO_DEBUGGER();
2314             dm_error(
2315                 "DC:failed to create hw i2c!!\n");
2316             goto create_fail;
2317         }
2318         pool->base.sw_i2cs[i] = NULL;
2319     }
2320 
2321     /* Audio, HWSeq, Stream Encoders including HPO and virtual, MPC 3D LUTs */
2322     if (!resource_construct(num_virtual_links, dc, &pool->base,
2323             (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment) ?
2324             &res_create_funcs : &res_create_maximus_funcs)))
2325             goto create_fail;
2326 
2327     /* HW Sequencer init functions and Plane caps */
2328     dcn32_hw_sequencer_init_functions(dc);
2329 
2330     dc->caps.max_planes =  pool->base.pipe_count;
2331 
2332     for (i = 0; i < dc->caps.max_planes; ++i)
2333         dc->caps.planes[i] = plane_cap;
2334 
2335     dc->cap_funcs = cap_funcs;
2336 
2337     if (dc->ctx->dc_bios->fw_info.oem_i2c_present) {
2338         ddc_init_data.ctx = dc->ctx;
2339         ddc_init_data.link = NULL;
2340         ddc_init_data.id.id = dc->ctx->dc_bios->fw_info.oem_i2c_obj_id;
2341         ddc_init_data.id.enum_id = 0;
2342         ddc_init_data.id.type = OBJECT_TYPE_GENERIC;
2343         pool->base.oem_device = dal_ddc_service_create(&ddc_init_data);
2344     } else {
2345         pool->base.oem_device = NULL;
2346     }
2347 
2348     DC_FP_END();
2349 
2350     return true;
2351 
2352 create_fail:
2353 
2354     DC_FP_END();
2355 
2356     dcn32_resource_destruct(pool);
2357 
2358     return false;
2359 }
2360 
2361 struct resource_pool *dcn32_create_resource_pool(
2362         const struct dc_init_data *init_data,
2363         struct dc *dc)
2364 {
2365     struct dcn32_resource_pool *pool =
2366         kzalloc(sizeof(struct dcn32_resource_pool), GFP_KERNEL);
2367 
2368     if (!pool)
2369         return NULL;
2370 
2371     if (dcn32_resource_construct(init_data->num_virtual_links, dc, pool))
2372         return &pool->base;
2373 
2374     BREAK_TO_DEBUGGER();
2375     kfree(pool);
2376     return NULL;
2377 }
2378 
2379 static struct pipe_ctx *find_idle_secondary_pipe_check_mpo(
2380         struct resource_context *res_ctx,
2381         const struct resource_pool *pool,
2382         const struct pipe_ctx *primary_pipe)
2383 {
2384     int i;
2385     struct pipe_ctx *secondary_pipe = NULL;
2386     struct pipe_ctx *next_odm_mpo_pipe = NULL;
2387     int primary_index, preferred_pipe_idx;
2388     struct pipe_ctx *old_primary_pipe = NULL;
2389 
2390     /*
2391      * Modified from find_idle_secondary_pipe
2392      * With windowed MPO and ODM, we want to avoid the case where we want a
2393      *  free pipe for the left side but the free pipe is being used on the
2394      *  right side.
2395      * Add check on current_state if the primary_pipe is the left side,
2396      *  to check the right side ( primary_pipe->next_odm_pipe ) to see if
2397      *  it is using a pipe for MPO ( primary_pipe->next_odm_pipe->bottom_pipe )
2398      * - If so, then don't use this pipe
2399      * EXCEPTION - 3 plane ( 2 MPO plane ) case
2400      * - in this case, the primary pipe has already gotten a free pipe for the
2401      *  MPO window in the left
2402      * - when it tries to get a free pipe for the MPO window on the right,
2403      *  it will see that it is already assigned to the right side
2404      *  ( primary_pipe->next_odm_pipe ).  But in this case, we want this
2405      *  free pipe, since it will be for the right side.  So add an
2406      *  additional condition, that skipping the free pipe on the right only
2407      *  applies if the primary pipe has no bottom pipe currently assigned
2408      */
2409     if (primary_pipe) {
2410         primary_index = primary_pipe->pipe_idx;
2411         old_primary_pipe = &primary_pipe->stream->ctx->dc->current_state->res_ctx.pipe_ctx[primary_index];
2412         if ((old_primary_pipe->next_odm_pipe) && (old_primary_pipe->next_odm_pipe->bottom_pipe)
2413             && (!primary_pipe->bottom_pipe))
2414             next_odm_mpo_pipe = old_primary_pipe->next_odm_pipe->bottom_pipe;
2415 
2416         preferred_pipe_idx = (pool->pipe_count - 1) - primary_pipe->pipe_idx;
2417         if ((res_ctx->pipe_ctx[preferred_pipe_idx].stream == NULL) &&
2418             !(next_odm_mpo_pipe && next_odm_mpo_pipe->pipe_idx == preferred_pipe_idx)) {
2419             secondary_pipe = &res_ctx->pipe_ctx[preferred_pipe_idx];
2420             secondary_pipe->pipe_idx = preferred_pipe_idx;
2421         }
2422     }
2423 
2424     /*
2425      * search backwards for the second pipe to keep pipe
2426      * assignment more consistent
2427      */
2428     if (!secondary_pipe)
2429         for (i = pool->pipe_count - 1; i >= 0; i--) {
2430             if ((res_ctx->pipe_ctx[i].stream == NULL) &&
2431                 !(next_odm_mpo_pipe && next_odm_mpo_pipe->pipe_idx == i)) {
2432                 secondary_pipe = &res_ctx->pipe_ctx[i];
2433                 secondary_pipe->pipe_idx = i;
2434                 break;
2435             }
2436         }
2437 
2438     return secondary_pipe;
2439 }
2440 
2441 struct pipe_ctx *dcn32_acquire_idle_pipe_for_head_pipe_in_layer(
2442         struct dc_state *state,
2443         const struct resource_pool *pool,
2444         struct dc_stream_state *stream,
2445         struct pipe_ctx *head_pipe)
2446 {
2447     struct resource_context *res_ctx = &state->res_ctx;
2448     struct pipe_ctx *idle_pipe, *pipe;
2449     struct resource_context *old_ctx = &stream->ctx->dc->current_state->res_ctx;
2450     int head_index;
2451 
2452     if (!head_pipe)
2453         ASSERT(0);
2454 
2455     /*
2456      * Modified from dcn20_acquire_idle_pipe_for_layer
2457      * Check if head_pipe in old_context already has bottom_pipe allocated.
2458      * - If so, check if that pipe is available in the current context.
2459      * --  If so, reuse pipe from old_context
2460      */
2461     head_index = head_pipe->pipe_idx;
2462     pipe = &old_ctx->pipe_ctx[head_index];
2463     if (pipe->bottom_pipe && res_ctx->pipe_ctx[pipe->bottom_pipe->pipe_idx].stream == NULL) {
2464         idle_pipe = &res_ctx->pipe_ctx[pipe->bottom_pipe->pipe_idx];
2465         idle_pipe->pipe_idx = pipe->bottom_pipe->pipe_idx;
2466     } else {
2467         idle_pipe = find_idle_secondary_pipe_check_mpo(res_ctx, pool, head_pipe);
2468         if (!idle_pipe)
2469             return NULL;
2470     }
2471 
2472     idle_pipe->stream = head_pipe->stream;
2473     idle_pipe->stream_res.tg = head_pipe->stream_res.tg;
2474     idle_pipe->stream_res.opp = head_pipe->stream_res.opp;
2475 
2476     idle_pipe->plane_res.hubp = pool->hubps[idle_pipe->pipe_idx];
2477     idle_pipe->plane_res.ipp = pool->ipps[idle_pipe->pipe_idx];
2478     idle_pipe->plane_res.dpp = pool->dpps[idle_pipe->pipe_idx];
2479     idle_pipe->plane_res.mpcc_inst = pool->dpps[idle_pipe->pipe_idx]->inst;
2480 
2481     return idle_pipe;
2482 }