Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright 2020 Advanced Micro Devices, Inc.
0003  *
0004  * Permission is hereby granted, free of charge, to any person obtaining a
0005  * copy of this software and associated documentation files (the "Software"),
0006  * to deal in the Software without restriction, including without limitation
0007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0008  * and/or sell copies of the Software, and to permit persons to whom the
0009  * Software is furnished to do so, subject to the following conditions:
0010  *
0011  * The above copyright notice and this permission notice shall be included in
0012  * all copies or substantial portions of the Software.
0013  *
0014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0015  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
0017  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
0018  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
0019  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
0020  * OTHER DEALINGS IN THE SOFTWARE.
0021  *
0022  * Authors: AMD
0023  *
0024  */
0025 
0026 
0027 #include "dm_services.h"
0028 #include "dc.h"
0029 
0030 #include "dcn30_init.h"
0031 
0032 #include "resource.h"
0033 #include "include/irq_service_interface.h"
0034 #include "dcn20/dcn20_resource.h"
0035 
0036 #include "dcn30_resource.h"
0037 
0038 #include "dcn10/dcn10_ipp.h"
0039 #include "dcn30/dcn30_hubbub.h"
0040 #include "dcn30/dcn30_mpc.h"
0041 #include "dcn30/dcn30_hubp.h"
0042 #include "irq/dcn30/irq_service_dcn30.h"
0043 #include "dcn30/dcn30_dpp.h"
0044 #include "dcn30/dcn30_optc.h"
0045 #include "dcn20/dcn20_hwseq.h"
0046 #include "dcn30/dcn30_hwseq.h"
0047 #include "dce110/dce110_hw_sequencer.h"
0048 #include "dcn30/dcn30_opp.h"
0049 #include "dcn20/dcn20_dsc.h"
0050 #include "dcn30/dcn30_vpg.h"
0051 #include "dcn30/dcn30_afmt.h"
0052 #include "dcn30/dcn30_dio_stream_encoder.h"
0053 #include "dcn30/dcn30_dio_link_encoder.h"
0054 #include "dce/dce_clock_source.h"
0055 #include "dce/dce_audio.h"
0056 #include "dce/dce_hwseq.h"
0057 #include "clk_mgr.h"
0058 #include "virtual/virtual_stream_encoder.h"
0059 #include "dce110/dce110_resource.h"
0060 #include "dml/display_mode_vba.h"
0061 #include "dcn30/dcn30_dccg.h"
0062 #include "dcn10/dcn10_resource.h"
0063 #include "dc_link_ddc.h"
0064 #include "dce/dce_panel_cntl.h"
0065 
0066 #include "dcn30/dcn30_dwb.h"
0067 #include "dcn30/dcn30_mmhubbub.h"
0068 
0069 #include "sienna_cichlid_ip_offset.h"
0070 #include "dcn/dcn_3_0_0_offset.h"
0071 #include "dcn/dcn_3_0_0_sh_mask.h"
0072 
0073 #include "nbio/nbio_7_4_offset.h"
0074 
0075 #include "dpcs/dpcs_3_0_0_offset.h"
0076 #include "dpcs/dpcs_3_0_0_sh_mask.h"
0077 
0078 #include "mmhub/mmhub_2_0_0_offset.h"
0079 #include "mmhub/mmhub_2_0_0_sh_mask.h"
0080 
0081 #include "reg_helper.h"
0082 #include "dce/dmub_abm.h"
0083 #include "dce/dmub_psr.h"
0084 #include "dce/dce_aux.h"
0085 #include "dce/dce_i2c.h"
0086 
0087 #include "dml/dcn30/dcn30_fpu.h"
0088 #include "dml/dcn30/display_mode_vba_30.h"
0089 #include "vm_helper.h"
0090 #include "dcn20/dcn20_vmid.h"
0091 #include "amdgpu_socbb.h"
0092 #include "dc_dmub_srv.h"
0093 
0094 #define DC_LOGGER_INIT(logger)
0095 
0096 enum dcn30_clk_src_array_id {
0097     DCN30_CLK_SRC_PLL0,
0098     DCN30_CLK_SRC_PLL1,
0099     DCN30_CLK_SRC_PLL2,
0100     DCN30_CLK_SRC_PLL3,
0101     DCN30_CLK_SRC_PLL4,
0102     DCN30_CLK_SRC_PLL5,
0103     DCN30_CLK_SRC_TOTAL
0104 };
0105 
0106 /* begin *********************
0107  * macros to expend register list macro defined in HW object header file
0108  */
0109 
0110 /* DCN */
0111 /* TODO awful hack. fixup dcn20_dwb.h */
0112 #undef BASE_INNER
0113 #define BASE_INNER(seg) DCN_BASE__INST0_SEG ## seg
0114 
0115 #define BASE(seg) BASE_INNER(seg)
0116 
0117 #define SR(reg_name)\
0118         .reg_name = BASE(mm ## reg_name ## _BASE_IDX) +  \
0119                     mm ## reg_name
0120 
0121 #define SRI(reg_name, block, id)\
0122     .reg_name = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
0123                     mm ## block ## id ## _ ## reg_name
0124 
0125 #define SRI2(reg_name, block, id)\
0126     .reg_name = BASE(mm ## reg_name ## _BASE_IDX) + \
0127                     mm ## reg_name
0128 
0129 #define SRIR(var_name, reg_name, block, id)\
0130     .var_name = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
0131                     mm ## block ## id ## _ ## reg_name
0132 
0133 #define SRII(reg_name, block, id)\
0134     .reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
0135                     mm ## block ## id ## _ ## reg_name
0136 
0137 #define SRII_MPC_RMU(reg_name, block, id)\
0138     .RMU##_##reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
0139                     mm ## block ## id ## _ ## reg_name
0140 
0141 #define SRII_DWB(reg_name, temp_name, block, id)\
0142     .reg_name[id] = BASE(mm ## block ## id ## _ ## temp_name ## _BASE_IDX) + \
0143                     mm ## block ## id ## _ ## temp_name
0144 
0145 #define DCCG_SRII(reg_name, block, id)\
0146     .block ## _ ## reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
0147                     mm ## block ## id ## _ ## reg_name
0148 
0149 #define VUPDATE_SRII(reg_name, block, id)\
0150     .reg_name[id] = BASE(mm ## reg_name ## _ ## block ## id ## _BASE_IDX) + \
0151                     mm ## reg_name ## _ ## block ## id
0152 
0153 /* NBIO */
0154 #define NBIO_BASE_INNER(seg) \
0155     NBIO_BASE__INST0_SEG ## seg
0156 
0157 #define NBIO_BASE(seg) \
0158     NBIO_BASE_INNER(seg)
0159 
0160 #define NBIO_SR(reg_name)\
0161         .reg_name = NBIO_BASE(mm ## reg_name ## _BASE_IDX) + \
0162                     mm ## reg_name
0163 
0164 /* MMHUB */
0165 #define MMHUB_BASE_INNER(seg) \
0166     MMHUB_BASE__INST0_SEG ## seg
0167 
0168 #define MMHUB_BASE(seg) \
0169     MMHUB_BASE_INNER(seg)
0170 
0171 #define MMHUB_SR(reg_name)\
0172         .reg_name = MMHUB_BASE(mmMM ## reg_name ## _BASE_IDX) + \
0173                     mmMM ## reg_name
0174 
0175 /* CLOCK */
0176 #define CLK_BASE_INNER(seg) \
0177     CLK_BASE__INST0_SEG ## seg
0178 
0179 #define CLK_BASE(seg) \
0180     CLK_BASE_INNER(seg)
0181 
0182 #define CLK_SRI(reg_name, block, inst)\
0183     .reg_name = CLK_BASE(mm ## block ## _ ## inst ## _ ## reg_name ## _BASE_IDX) + \
0184                     mm ## block ## _ ## inst ## _ ## reg_name
0185 
0186 
0187 static const struct bios_registers bios_regs = {
0188         NBIO_SR(BIOS_SCRATCH_3),
0189         NBIO_SR(BIOS_SCRATCH_6)
0190 };
0191 
0192 #define clk_src_regs(index, pllid)\
0193 [index] = {\
0194     CS_COMMON_REG_LIST_DCN2_0(index, pllid),\
0195 }
0196 
0197 static const struct dce110_clk_src_regs clk_src_regs[] = {
0198     clk_src_regs(0, A),
0199     clk_src_regs(1, B),
0200     clk_src_regs(2, C),
0201     clk_src_regs(3, D),
0202     clk_src_regs(4, E),
0203     clk_src_regs(5, F)
0204 };
0205 
0206 static const struct dce110_clk_src_shift cs_shift = {
0207         CS_COMMON_MASK_SH_LIST_DCN2_0(__SHIFT)
0208 };
0209 
0210 static const struct dce110_clk_src_mask cs_mask = {
0211         CS_COMMON_MASK_SH_LIST_DCN2_0(_MASK)
0212 };
0213 
0214 #define abm_regs(id)\
0215 [id] = {\
0216         ABM_DCN30_REG_LIST(id)\
0217 }
0218 
0219 static const struct dce_abm_registers abm_regs[] = {
0220         abm_regs(0),
0221         abm_regs(1),
0222         abm_regs(2),
0223         abm_regs(3),
0224         abm_regs(4),
0225         abm_regs(5),
0226 };
0227 
0228 static const struct dce_abm_shift abm_shift = {
0229         ABM_MASK_SH_LIST_DCN30(__SHIFT)
0230 };
0231 
0232 static const struct dce_abm_mask abm_mask = {
0233         ABM_MASK_SH_LIST_DCN30(_MASK)
0234 };
0235 
0236 
0237 
0238 #define audio_regs(id)\
0239 [id] = {\
0240         AUD_COMMON_REG_LIST(id)\
0241 }
0242 
0243 static const struct dce_audio_registers audio_regs[] = {
0244     audio_regs(0),
0245     audio_regs(1),
0246     audio_regs(2),
0247     audio_regs(3),
0248     audio_regs(4),
0249     audio_regs(5),
0250     audio_regs(6)
0251 };
0252 
0253 #define DCE120_AUD_COMMON_MASK_SH_LIST(mask_sh)\
0254         SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_INDEX, AZALIA_ENDPOINT_REG_INDEX, mask_sh),\
0255         SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_DATA, AZALIA_ENDPOINT_REG_DATA, mask_sh),\
0256         AUD_COMMON_MASK_SH_LIST_BASE(mask_sh)
0257 
0258 static const struct dce_audio_shift audio_shift = {
0259         DCE120_AUD_COMMON_MASK_SH_LIST(__SHIFT)
0260 };
0261 
0262 static const struct dce_audio_mask audio_mask = {
0263         DCE120_AUD_COMMON_MASK_SH_LIST(_MASK)
0264 };
0265 
0266 #define vpg_regs(id)\
0267 [id] = {\
0268     VPG_DCN3_REG_LIST(id)\
0269 }
0270 
0271 static const struct dcn30_vpg_registers vpg_regs[] = {
0272     vpg_regs(0),
0273     vpg_regs(1),
0274     vpg_regs(2),
0275     vpg_regs(3),
0276     vpg_regs(4),
0277     vpg_regs(5),
0278     vpg_regs(6),
0279 };
0280 
0281 static const struct dcn30_vpg_shift vpg_shift = {
0282     DCN3_VPG_MASK_SH_LIST(__SHIFT)
0283 };
0284 
0285 static const struct dcn30_vpg_mask vpg_mask = {
0286     DCN3_VPG_MASK_SH_LIST(_MASK)
0287 };
0288 
0289 #define afmt_regs(id)\
0290 [id] = {\
0291     AFMT_DCN3_REG_LIST(id)\
0292 }
0293 
0294 static const struct dcn30_afmt_registers afmt_regs[] = {
0295     afmt_regs(0),
0296     afmt_regs(1),
0297     afmt_regs(2),
0298     afmt_regs(3),
0299     afmt_regs(4),
0300     afmt_regs(5),
0301     afmt_regs(6),
0302 };
0303 
0304 static const struct dcn30_afmt_shift afmt_shift = {
0305     DCN3_AFMT_MASK_SH_LIST(__SHIFT)
0306 };
0307 
0308 static const struct dcn30_afmt_mask afmt_mask = {
0309     DCN3_AFMT_MASK_SH_LIST(_MASK)
0310 };
0311 
0312 #define stream_enc_regs(id)\
0313 [id] = {\
0314     SE_DCN3_REG_LIST(id)\
0315 }
0316 
0317 static const struct dcn10_stream_enc_registers stream_enc_regs[] = {
0318     stream_enc_regs(0),
0319     stream_enc_regs(1),
0320     stream_enc_regs(2),
0321     stream_enc_regs(3),
0322     stream_enc_regs(4),
0323     stream_enc_regs(5)
0324 };
0325 
0326 static const struct dcn10_stream_encoder_shift se_shift = {
0327         SE_COMMON_MASK_SH_LIST_DCN30(__SHIFT)
0328 };
0329 
0330 static const struct dcn10_stream_encoder_mask se_mask = {
0331         SE_COMMON_MASK_SH_LIST_DCN30(_MASK)
0332 };
0333 
0334 
0335 #define aux_regs(id)\
0336 [id] = {\
0337     DCN2_AUX_REG_LIST(id)\
0338 }
0339 
0340 static const struct dcn10_link_enc_aux_registers link_enc_aux_regs[] = {
0341         aux_regs(0),
0342         aux_regs(1),
0343         aux_regs(2),
0344         aux_regs(3),
0345         aux_regs(4),
0346         aux_regs(5)
0347 };
0348 
0349 #define hpd_regs(id)\
0350 [id] = {\
0351     HPD_REG_LIST(id)\
0352 }
0353 
0354 static const struct dcn10_link_enc_hpd_registers link_enc_hpd_regs[] = {
0355         hpd_regs(0),
0356         hpd_regs(1),
0357         hpd_regs(2),
0358         hpd_regs(3),
0359         hpd_regs(4),
0360         hpd_regs(5)
0361 };
0362 
0363 #define link_regs(id, phyid)\
0364 [id] = {\
0365     LE_DCN3_REG_LIST(id), \
0366     UNIPHY_DCN2_REG_LIST(phyid), \
0367     DPCS_DCN2_REG_LIST(id), \
0368     SRI(DP_DPHY_INTERNAL_CTRL, DP, id) \
0369 }
0370 
0371 static const struct dce110_aux_registers_shift aux_shift = {
0372     DCN_AUX_MASK_SH_LIST(__SHIFT)
0373 };
0374 
0375 static const struct dce110_aux_registers_mask aux_mask = {
0376     DCN_AUX_MASK_SH_LIST(_MASK)
0377 };
0378 
0379 static const struct dcn10_link_enc_registers link_enc_regs[] = {
0380     link_regs(0, A),
0381     link_regs(1, B),
0382     link_regs(2, C),
0383     link_regs(3, D),
0384     link_regs(4, E),
0385     link_regs(5, F)
0386 };
0387 
0388 static const struct dcn10_link_enc_shift le_shift = {
0389     LINK_ENCODER_MASK_SH_LIST_DCN30(__SHIFT),\
0390     DPCS_DCN2_MASK_SH_LIST(__SHIFT)
0391 };
0392 
0393 static const struct dcn10_link_enc_mask le_mask = {
0394     LINK_ENCODER_MASK_SH_LIST_DCN30(_MASK),\
0395     DPCS_DCN2_MASK_SH_LIST(_MASK)
0396 };
0397 
0398 
0399 static const struct dce_panel_cntl_registers panel_cntl_regs[] = {
0400     { DCN_PANEL_CNTL_REG_LIST() }
0401 };
0402 
0403 static const struct dce_panel_cntl_shift panel_cntl_shift = {
0404     DCE_PANEL_CNTL_MASK_SH_LIST(__SHIFT)
0405 };
0406 
0407 static const struct dce_panel_cntl_mask panel_cntl_mask = {
0408     DCE_PANEL_CNTL_MASK_SH_LIST(_MASK)
0409 };
0410 
0411 #define dpp_regs(id)\
0412 [id] = {\
0413     DPP_REG_LIST_DCN30(id),\
0414 }
0415 
0416 static const struct dcn3_dpp_registers dpp_regs[] = {
0417     dpp_regs(0),
0418     dpp_regs(1),
0419     dpp_regs(2),
0420     dpp_regs(3),
0421     dpp_regs(4),
0422     dpp_regs(5),
0423 };
0424 
0425 static const struct dcn3_dpp_shift tf_shift = {
0426         DPP_REG_LIST_SH_MASK_DCN30(__SHIFT)
0427 };
0428 
0429 static const struct dcn3_dpp_mask tf_mask = {
0430         DPP_REG_LIST_SH_MASK_DCN30(_MASK)
0431 };
0432 
0433 #define opp_regs(id)\
0434 [id] = {\
0435     OPP_REG_LIST_DCN30(id),\
0436 }
0437 
0438 static const struct dcn20_opp_registers opp_regs[] = {
0439     opp_regs(0),
0440     opp_regs(1),
0441     opp_regs(2),
0442     opp_regs(3),
0443     opp_regs(4),
0444     opp_regs(5)
0445 };
0446 
0447 static const struct dcn20_opp_shift opp_shift = {
0448     OPP_MASK_SH_LIST_DCN20(__SHIFT)
0449 };
0450 
0451 static const struct dcn20_opp_mask opp_mask = {
0452     OPP_MASK_SH_LIST_DCN20(_MASK)
0453 };
0454 
0455 #define aux_engine_regs(id)\
0456 [id] = {\
0457     AUX_COMMON_REG_LIST0(id), \
0458     .AUXN_IMPCAL = 0, \
0459     .AUXP_IMPCAL = 0, \
0460     .AUX_RESET_MASK = DP_AUX0_AUX_CONTROL__AUX_RESET_MASK, \
0461 }
0462 
0463 static const struct dce110_aux_registers aux_engine_regs[] = {
0464         aux_engine_regs(0),
0465         aux_engine_regs(1),
0466         aux_engine_regs(2),
0467         aux_engine_regs(3),
0468         aux_engine_regs(4),
0469         aux_engine_regs(5)
0470 };
0471 
0472 #define dwbc_regs_dcn3(id)\
0473 [id] = {\
0474     DWBC_COMMON_REG_LIST_DCN30(id),\
0475 }
0476 
0477 static const struct dcn30_dwbc_registers dwbc30_regs[] = {
0478     dwbc_regs_dcn3(0),
0479 };
0480 
0481 static const struct dcn30_dwbc_shift dwbc30_shift = {
0482     DWBC_COMMON_MASK_SH_LIST_DCN30(__SHIFT)
0483 };
0484 
0485 static const struct dcn30_dwbc_mask dwbc30_mask = {
0486     DWBC_COMMON_MASK_SH_LIST_DCN30(_MASK)
0487 };
0488 
0489 #define mcif_wb_regs_dcn3(id)\
0490 [id] = {\
0491     MCIF_WB_COMMON_REG_LIST_DCN30(id),\
0492 }
0493 
0494 static const struct dcn30_mmhubbub_registers mcif_wb30_regs[] = {
0495     mcif_wb_regs_dcn3(0)
0496 };
0497 
0498 static const struct dcn30_mmhubbub_shift mcif_wb30_shift = {
0499     MCIF_WB_COMMON_MASK_SH_LIST_DCN30(__SHIFT)
0500 };
0501 
0502 static const struct dcn30_mmhubbub_mask mcif_wb30_mask = {
0503     MCIF_WB_COMMON_MASK_SH_LIST_DCN30(_MASK)
0504 };
0505 
0506 #define dsc_regsDCN20(id)\
0507 [id] = {\
0508     DSC_REG_LIST_DCN20(id)\
0509 }
0510 
0511 static const struct dcn20_dsc_registers dsc_regs[] = {
0512     dsc_regsDCN20(0),
0513     dsc_regsDCN20(1),
0514     dsc_regsDCN20(2),
0515     dsc_regsDCN20(3),
0516     dsc_regsDCN20(4),
0517     dsc_regsDCN20(5)
0518 };
0519 
0520 static const struct dcn20_dsc_shift dsc_shift = {
0521     DSC_REG_LIST_SH_MASK_DCN20(__SHIFT)
0522 };
0523 
0524 static const struct dcn20_dsc_mask dsc_mask = {
0525     DSC_REG_LIST_SH_MASK_DCN20(_MASK)
0526 };
0527 
0528 static const struct dcn30_mpc_registers mpc_regs = {
0529         MPC_REG_LIST_DCN3_0(0),
0530         MPC_REG_LIST_DCN3_0(1),
0531         MPC_REG_LIST_DCN3_0(2),
0532         MPC_REG_LIST_DCN3_0(3),
0533         MPC_REG_LIST_DCN3_0(4),
0534         MPC_REG_LIST_DCN3_0(5),
0535         MPC_OUT_MUX_REG_LIST_DCN3_0(0),
0536         MPC_OUT_MUX_REG_LIST_DCN3_0(1),
0537         MPC_OUT_MUX_REG_LIST_DCN3_0(2),
0538         MPC_OUT_MUX_REG_LIST_DCN3_0(3),
0539         MPC_OUT_MUX_REG_LIST_DCN3_0(4),
0540         MPC_OUT_MUX_REG_LIST_DCN3_0(5),
0541         MPC_RMU_GLOBAL_REG_LIST_DCN3AG,
0542         MPC_RMU_REG_LIST_DCN3AG(0),
0543         MPC_RMU_REG_LIST_DCN3AG(1),
0544         MPC_RMU_REG_LIST_DCN3AG(2),
0545         MPC_DWB_MUX_REG_LIST_DCN3_0(0),
0546 };
0547 
0548 static const struct dcn30_mpc_shift mpc_shift = {
0549     MPC_COMMON_MASK_SH_LIST_DCN30(__SHIFT)
0550 };
0551 
0552 static const struct dcn30_mpc_mask mpc_mask = {
0553     MPC_COMMON_MASK_SH_LIST_DCN30(_MASK)
0554 };
0555 
0556 #define optc_regs(id)\
0557 [id] = {OPTC_COMMON_REG_LIST_DCN3_0(id)}
0558 
0559 
0560 static const struct dcn_optc_registers optc_regs[] = {
0561     optc_regs(0),
0562     optc_regs(1),
0563     optc_regs(2),
0564     optc_regs(3),
0565     optc_regs(4),
0566     optc_regs(5)
0567 };
0568 
0569 static const struct dcn_optc_shift optc_shift = {
0570     OPTC_COMMON_MASK_SH_LIST_DCN30(__SHIFT)
0571 };
0572 
0573 static const struct dcn_optc_mask optc_mask = {
0574     OPTC_COMMON_MASK_SH_LIST_DCN30(_MASK)
0575 };
0576 
0577 #define hubp_regs(id)\
0578 [id] = {\
0579     HUBP_REG_LIST_DCN30(id)\
0580 }
0581 
0582 static const struct dcn_hubp2_registers hubp_regs[] = {
0583         hubp_regs(0),
0584         hubp_regs(1),
0585         hubp_regs(2),
0586         hubp_regs(3),
0587         hubp_regs(4),
0588         hubp_regs(5)
0589 };
0590 
0591 static const struct dcn_hubp2_shift hubp_shift = {
0592         HUBP_MASK_SH_LIST_DCN30(__SHIFT)
0593 };
0594 
0595 static const struct dcn_hubp2_mask hubp_mask = {
0596         HUBP_MASK_SH_LIST_DCN30(_MASK)
0597 };
0598 
0599 static const struct dcn_hubbub_registers hubbub_reg = {
0600         HUBBUB_REG_LIST_DCN30(0)
0601 };
0602 
0603 static const struct dcn_hubbub_shift hubbub_shift = {
0604         HUBBUB_MASK_SH_LIST_DCN30(__SHIFT)
0605 };
0606 
0607 static const struct dcn_hubbub_mask hubbub_mask = {
0608         HUBBUB_MASK_SH_LIST_DCN30(_MASK)
0609 };
0610 
0611 static const struct dccg_registers dccg_regs = {
0612         DCCG_REG_LIST_DCN30()
0613 };
0614 
0615 static const struct dccg_shift dccg_shift = {
0616         DCCG_MASK_SH_LIST_DCN3(__SHIFT)
0617 };
0618 
0619 static const struct dccg_mask dccg_mask = {
0620         DCCG_MASK_SH_LIST_DCN3(_MASK)
0621 };
0622 
0623 static const struct dce_hwseq_registers hwseq_reg = {
0624         HWSEQ_DCN30_REG_LIST()
0625 };
0626 
0627 static const struct dce_hwseq_shift hwseq_shift = {
0628         HWSEQ_DCN30_MASK_SH_LIST(__SHIFT)
0629 };
0630 
0631 static const struct dce_hwseq_mask hwseq_mask = {
0632         HWSEQ_DCN30_MASK_SH_LIST(_MASK)
0633 };
0634 #define vmid_regs(id)\
0635 [id] = {\
0636         DCN20_VMID_REG_LIST(id)\
0637 }
0638 
0639 static const struct dcn_vmid_registers vmid_regs[] = {
0640     vmid_regs(0),
0641     vmid_regs(1),
0642     vmid_regs(2),
0643     vmid_regs(3),
0644     vmid_regs(4),
0645     vmid_regs(5),
0646     vmid_regs(6),
0647     vmid_regs(7),
0648     vmid_regs(8),
0649     vmid_regs(9),
0650     vmid_regs(10),
0651     vmid_regs(11),
0652     vmid_regs(12),
0653     vmid_regs(13),
0654     vmid_regs(14),
0655     vmid_regs(15)
0656 };
0657 
0658 static const struct dcn20_vmid_shift vmid_shifts = {
0659         DCN20_VMID_MASK_SH_LIST(__SHIFT)
0660 };
0661 
0662 static const struct dcn20_vmid_mask vmid_masks = {
0663         DCN20_VMID_MASK_SH_LIST(_MASK)
0664 };
0665 
0666 static const struct resource_caps res_cap_dcn3 = {
0667     .num_timing_generator = 6,
0668     .num_opp = 6,
0669     .num_video_plane = 6,
0670     .num_audio = 6,
0671     .num_stream_encoder = 6,
0672     .num_pll = 6,
0673     .num_dwb = 1,
0674     .num_ddc = 6,
0675     .num_vmid = 16,
0676     .num_mpc_3dlut = 3,
0677     .num_dsc = 6,
0678 };
0679 
0680 static const struct dc_plane_cap plane_cap = {
0681     .type = DC_PLANE_TYPE_DCN_UNIVERSAL,
0682     .blends_with_above = true,
0683     .blends_with_below = true,
0684     .per_pixel_alpha = true,
0685 
0686     .pixel_format_support = {
0687             .argb8888 = true,
0688             .nv12 = true,
0689             .fp16 = true,
0690             .p010 = true,
0691             .ayuv = false,
0692     },
0693 
0694     .max_upscale_factor = {
0695             .argb8888 = 16000,
0696             .nv12 = 16000,
0697             .fp16 = 16000
0698     },
0699 
0700     /* 6:1 downscaling ratio: 1000/6 = 166.666 */
0701     .max_downscale_factor = {
0702             .argb8888 = 167,
0703             .nv12 = 167,
0704             .fp16 = 167
0705     }
0706 };
0707 
0708 static const struct dc_debug_options debug_defaults_drv = {
0709     .disable_dmcu = true, //No DMCU on DCN30
0710     .force_abm_enable = false,
0711     .timing_trace = false,
0712     .clock_trace = true,
0713     .disable_pplib_clock_request = true,
0714     .pipe_split_policy = MPC_SPLIT_DYNAMIC,
0715     .force_single_disp_pipe_split = false,
0716     .disable_dcc = DCC_ENABLE,
0717     .vsr_support = true,
0718     .performance_trace = false,
0719     .max_downscale_src_width = 7680,/*upto 8K*/
0720     .disable_pplib_wm_range = false,
0721     .scl_reset_length10 = true,
0722     .sanity_checks = false,
0723     .underflow_assert_delay_us = 0xFFFFFFFF,
0724     .dwb_fi_phase = -1, // -1 = disable,
0725     .dmub_command_table = true,
0726     .disable_psr = false,
0727     .use_max_lb = true
0728 };
0729 
0730 static const struct dc_debug_options debug_defaults_diags = {
0731     .disable_dmcu = true, //No dmcu on DCN30
0732     .force_abm_enable = false,
0733     .timing_trace = true,
0734     .clock_trace = true,
0735     .disable_dpp_power_gate = true,
0736     .disable_hubp_power_gate = true,
0737     .disable_clock_gate = true,
0738     .disable_pplib_clock_request = true,
0739     .disable_pplib_wm_range = true,
0740     .disable_stutter = false,
0741     .scl_reset_length10 = true,
0742     .dwb_fi_phase = -1, // -1 = disable
0743     .dmub_command_table = true,
0744     .disable_psr = true,
0745     .enable_tri_buf = true,
0746     .use_max_lb = true
0747 };
0748 
0749 static void dcn30_dpp_destroy(struct dpp **dpp)
0750 {
0751     kfree(TO_DCN20_DPP(*dpp));
0752     *dpp = NULL;
0753 }
0754 
0755 static struct dpp *dcn30_dpp_create(
0756     struct dc_context *ctx,
0757     uint32_t inst)
0758 {
0759     struct dcn3_dpp *dpp =
0760         kzalloc(sizeof(struct dcn3_dpp), GFP_KERNEL);
0761 
0762     if (!dpp)
0763         return NULL;
0764 
0765     if (dpp3_construct(dpp, ctx, inst,
0766             &dpp_regs[inst], &tf_shift, &tf_mask))
0767         return &dpp->base;
0768 
0769     BREAK_TO_DEBUGGER();
0770     kfree(dpp);
0771     return NULL;
0772 }
0773 
0774 static struct output_pixel_processor *dcn30_opp_create(
0775     struct dc_context *ctx, uint32_t inst)
0776 {
0777     struct dcn20_opp *opp =
0778         kzalloc(sizeof(struct dcn20_opp), GFP_KERNEL);
0779 
0780     if (!opp) {
0781         BREAK_TO_DEBUGGER();
0782         return NULL;
0783     }
0784 
0785     dcn20_opp_construct(opp, ctx, inst,
0786             &opp_regs[inst], &opp_shift, &opp_mask);
0787     return &opp->base;
0788 }
0789 
0790 static struct dce_aux *dcn30_aux_engine_create(
0791     struct dc_context *ctx,
0792     uint32_t inst)
0793 {
0794     struct aux_engine_dce110 *aux_engine =
0795         kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL);
0796 
0797     if (!aux_engine)
0798         return NULL;
0799 
0800     dce110_aux_engine_construct(aux_engine, ctx, inst,
0801                     SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD,
0802                     &aux_engine_regs[inst],
0803                     &aux_mask,
0804                     &aux_shift,
0805                     ctx->dc->caps.extended_aux_timeout_support);
0806 
0807     return &aux_engine->base;
0808 }
0809 
0810 #define i2c_inst_regs(id) { I2C_HW_ENGINE_COMMON_REG_LIST_DCN30(id) }
0811 
0812 static const struct dce_i2c_registers i2c_hw_regs[] = {
0813         i2c_inst_regs(1),
0814         i2c_inst_regs(2),
0815         i2c_inst_regs(3),
0816         i2c_inst_regs(4),
0817         i2c_inst_regs(5),
0818         i2c_inst_regs(6),
0819 };
0820 
0821 static const struct dce_i2c_shift i2c_shifts = {
0822         I2C_COMMON_MASK_SH_LIST_DCN30(__SHIFT)
0823 };
0824 
0825 static const struct dce_i2c_mask i2c_masks = {
0826         I2C_COMMON_MASK_SH_LIST_DCN30(_MASK)
0827 };
0828 
0829 static struct dce_i2c_hw *dcn30_i2c_hw_create(
0830     struct dc_context *ctx,
0831     uint32_t inst)
0832 {
0833     struct dce_i2c_hw *dce_i2c_hw =
0834         kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL);
0835 
0836     if (!dce_i2c_hw)
0837         return NULL;
0838 
0839     dcn2_i2c_hw_construct(dce_i2c_hw, ctx, inst,
0840                     &i2c_hw_regs[inst], &i2c_shifts, &i2c_masks);
0841 
0842     return dce_i2c_hw;
0843 }
0844 
0845 static struct mpc *dcn30_mpc_create(
0846         struct dc_context *ctx,
0847         int num_mpcc,
0848         int num_rmu)
0849 {
0850     struct dcn30_mpc *mpc30 = kzalloc(sizeof(struct dcn30_mpc),
0851                       GFP_KERNEL);
0852 
0853     if (!mpc30)
0854         return NULL;
0855 
0856     dcn30_mpc_construct(mpc30, ctx,
0857             &mpc_regs,
0858             &mpc_shift,
0859             &mpc_mask,
0860             num_mpcc,
0861             num_rmu);
0862 
0863     return &mpc30->base;
0864 }
0865 
0866 static struct hubbub *dcn30_hubbub_create(struct dc_context *ctx)
0867 {
0868     int i;
0869 
0870     struct dcn20_hubbub *hubbub3 = kzalloc(sizeof(struct dcn20_hubbub),
0871                       GFP_KERNEL);
0872 
0873     if (!hubbub3)
0874         return NULL;
0875 
0876     hubbub3_construct(hubbub3, ctx,
0877             &hubbub_reg,
0878             &hubbub_shift,
0879             &hubbub_mask);
0880 
0881 
0882     for (i = 0; i < res_cap_dcn3.num_vmid; i++) {
0883         struct dcn20_vmid *vmid = &hubbub3->vmid[i];
0884 
0885         vmid->ctx = ctx;
0886 
0887         vmid->regs = &vmid_regs[i];
0888         vmid->shifts = &vmid_shifts;
0889         vmid->masks = &vmid_masks;
0890     }
0891 
0892     return &hubbub3->base;
0893 }
0894 
0895 static struct timing_generator *dcn30_timing_generator_create(
0896         struct dc_context *ctx,
0897         uint32_t instance)
0898 {
0899     struct optc *tgn10 =
0900         kzalloc(sizeof(struct optc), GFP_KERNEL);
0901 
0902     if (!tgn10)
0903         return NULL;
0904 
0905     tgn10->base.inst = instance;
0906     tgn10->base.ctx = ctx;
0907 
0908     tgn10->tg_regs = &optc_regs[instance];
0909     tgn10->tg_shift = &optc_shift;
0910     tgn10->tg_mask = &optc_mask;
0911 
0912     dcn30_timing_generator_init(tgn10);
0913 
0914     return &tgn10->base;
0915 }
0916 
0917 static const struct encoder_feature_support link_enc_feature = {
0918         .max_hdmi_deep_color = COLOR_DEPTH_121212,
0919         .max_hdmi_pixel_clock = 600000,
0920         .hdmi_ycbcr420_supported = true,
0921         .dp_ycbcr420_supported = true,
0922         .fec_supported = true,
0923         .flags.bits.IS_HBR2_CAPABLE = true,
0924         .flags.bits.IS_HBR3_CAPABLE = true,
0925         .flags.bits.IS_TPS3_CAPABLE = true,
0926         .flags.bits.IS_TPS4_CAPABLE = true
0927 };
0928 
0929 static struct link_encoder *dcn30_link_encoder_create(
0930     struct dc_context *ctx,
0931     const struct encoder_init_data *enc_init_data)
0932 {
0933     struct dcn20_link_encoder *enc20 =
0934         kzalloc(sizeof(struct dcn20_link_encoder), GFP_KERNEL);
0935 
0936     if (!enc20)
0937         return NULL;
0938 
0939     dcn30_link_encoder_construct(enc20,
0940             enc_init_data,
0941             &link_enc_feature,
0942             &link_enc_regs[enc_init_data->transmitter],
0943             &link_enc_aux_regs[enc_init_data->channel - 1],
0944             &link_enc_hpd_regs[enc_init_data->hpd_source],
0945             &le_shift,
0946             &le_mask);
0947 
0948     return &enc20->enc10.base;
0949 }
0950 
0951 static struct panel_cntl *dcn30_panel_cntl_create(const struct panel_cntl_init_data *init_data)
0952 {
0953     struct dce_panel_cntl *panel_cntl =
0954         kzalloc(sizeof(struct dce_panel_cntl), GFP_KERNEL);
0955 
0956     if (!panel_cntl)
0957         return NULL;
0958 
0959     dce_panel_cntl_construct(panel_cntl,
0960             init_data,
0961             &panel_cntl_regs[init_data->inst],
0962             &panel_cntl_shift,
0963             &panel_cntl_mask);
0964 
0965     return &panel_cntl->base;
0966 }
0967 
0968 static void read_dce_straps(
0969     struct dc_context *ctx,
0970     struct resource_straps *straps)
0971 {
0972     generic_reg_get(ctx, mmDC_PINSTRAPS + BASE(mmDC_PINSTRAPS_BASE_IDX),
0973         FN(DC_PINSTRAPS, DC_PINSTRAPS_AUDIO), &straps->dc_pinstraps_audio);
0974 
0975 }
0976 
0977 static struct audio *dcn30_create_audio(
0978         struct dc_context *ctx, unsigned int inst)
0979 {
0980     return dce_audio_create(ctx, inst,
0981             &audio_regs[inst], &audio_shift, &audio_mask);
0982 }
0983 
0984 static struct vpg *dcn30_vpg_create(
0985     struct dc_context *ctx,
0986     uint32_t inst)
0987 {
0988     struct dcn30_vpg *vpg3 = kzalloc(sizeof(struct dcn30_vpg), GFP_KERNEL);
0989 
0990     if (!vpg3)
0991         return NULL;
0992 
0993     vpg3_construct(vpg3, ctx, inst,
0994             &vpg_regs[inst],
0995             &vpg_shift,
0996             &vpg_mask);
0997 
0998     return &vpg3->base;
0999 }
1000 
1001 static struct afmt *dcn30_afmt_create(
1002     struct dc_context *ctx,
1003     uint32_t inst)
1004 {
1005     struct dcn30_afmt *afmt3 = kzalloc(sizeof(struct dcn30_afmt), GFP_KERNEL);
1006 
1007     if (!afmt3)
1008         return NULL;
1009 
1010     afmt3_construct(afmt3, ctx, inst,
1011             &afmt_regs[inst],
1012             &afmt_shift,
1013             &afmt_mask);
1014 
1015     return &afmt3->base;
1016 }
1017 
1018 static struct stream_encoder *dcn30_stream_encoder_create(enum engine_id eng_id,
1019                               struct dc_context *ctx)
1020 {
1021     struct dcn10_stream_encoder *enc1;
1022     struct vpg *vpg;
1023     struct afmt *afmt;
1024     int vpg_inst;
1025     int afmt_inst;
1026 
1027     /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */
1028     if (eng_id <= ENGINE_ID_DIGF) {
1029         vpg_inst = eng_id;
1030         afmt_inst = eng_id;
1031     } else
1032         return NULL;
1033 
1034     enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL);
1035     vpg = dcn30_vpg_create(ctx, vpg_inst);
1036     afmt = dcn30_afmt_create(ctx, afmt_inst);
1037 
1038     if (!enc1 || !vpg || !afmt) {
1039         kfree(enc1);
1040         kfree(vpg);
1041         kfree(afmt);
1042         return NULL;
1043     }
1044 
1045     dcn30_dio_stream_encoder_construct(enc1, ctx, ctx->dc_bios,
1046                     eng_id, vpg, afmt,
1047                     &stream_enc_regs[eng_id],
1048                     &se_shift, &se_mask);
1049 
1050     return &enc1->base;
1051 }
1052 
1053 static struct dce_hwseq *dcn30_hwseq_create(struct dc_context *ctx)
1054 {
1055     struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL);
1056 
1057     if (hws) {
1058         hws->ctx = ctx;
1059         hws->regs = &hwseq_reg;
1060         hws->shifts = &hwseq_shift;
1061         hws->masks = &hwseq_mask;
1062     }
1063     return hws;
1064 }
1065 static const struct resource_create_funcs res_create_funcs = {
1066     .read_dce_straps = read_dce_straps,
1067     .create_audio = dcn30_create_audio,
1068     .create_stream_encoder = dcn30_stream_encoder_create,
1069     .create_hwseq = dcn30_hwseq_create,
1070 };
1071 
1072 static const struct resource_create_funcs res_create_maximus_funcs = {
1073     .read_dce_straps = NULL,
1074     .create_audio = NULL,
1075     .create_stream_encoder = NULL,
1076     .create_hwseq = dcn30_hwseq_create,
1077 };
1078 
1079 static void dcn30_resource_destruct(struct dcn30_resource_pool *pool)
1080 {
1081     unsigned int i;
1082 
1083     for (i = 0; i < pool->base.stream_enc_count; i++) {
1084         if (pool->base.stream_enc[i] != NULL) {
1085             if (pool->base.stream_enc[i]->vpg != NULL) {
1086                 kfree(DCN30_VPG_FROM_VPG(pool->base.stream_enc[i]->vpg));
1087                 pool->base.stream_enc[i]->vpg = NULL;
1088             }
1089             if (pool->base.stream_enc[i]->afmt != NULL) {
1090                 kfree(DCN30_AFMT_FROM_AFMT(pool->base.stream_enc[i]->afmt));
1091                 pool->base.stream_enc[i]->afmt = NULL;
1092             }
1093             kfree(DCN10STRENC_FROM_STRENC(pool->base.stream_enc[i]));
1094             pool->base.stream_enc[i] = NULL;
1095         }
1096     }
1097 
1098     for (i = 0; i < pool->base.res_cap->num_dsc; i++) {
1099         if (pool->base.dscs[i] != NULL)
1100             dcn20_dsc_destroy(&pool->base.dscs[i]);
1101     }
1102 
1103     if (pool->base.mpc != NULL) {
1104         kfree(TO_DCN20_MPC(pool->base.mpc));
1105         pool->base.mpc = NULL;
1106     }
1107     if (pool->base.hubbub != NULL) {
1108         kfree(pool->base.hubbub);
1109         pool->base.hubbub = NULL;
1110     }
1111     for (i = 0; i < pool->base.pipe_count; i++) {
1112         if (pool->base.dpps[i] != NULL)
1113             dcn30_dpp_destroy(&pool->base.dpps[i]);
1114 
1115         if (pool->base.ipps[i] != NULL)
1116             pool->base.ipps[i]->funcs->ipp_destroy(&pool->base.ipps[i]);
1117 
1118         if (pool->base.hubps[i] != NULL) {
1119             kfree(TO_DCN20_HUBP(pool->base.hubps[i]));
1120             pool->base.hubps[i] = NULL;
1121         }
1122 
1123         if (pool->base.irqs != NULL) {
1124             dal_irq_service_destroy(&pool->base.irqs);
1125         }
1126     }
1127 
1128     for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
1129         if (pool->base.engines[i] != NULL)
1130             dce110_engine_destroy(&pool->base.engines[i]);
1131         if (pool->base.hw_i2cs[i] != NULL) {
1132             kfree(pool->base.hw_i2cs[i]);
1133             pool->base.hw_i2cs[i] = NULL;
1134         }
1135         if (pool->base.sw_i2cs[i] != NULL) {
1136             kfree(pool->base.sw_i2cs[i]);
1137             pool->base.sw_i2cs[i] = NULL;
1138         }
1139     }
1140 
1141     for (i = 0; i < pool->base.res_cap->num_opp; i++) {
1142         if (pool->base.opps[i] != NULL)
1143             pool->base.opps[i]->funcs->opp_destroy(&pool->base.opps[i]);
1144     }
1145 
1146     for (i = 0; i < pool->base.res_cap->num_timing_generator; i++) {
1147         if (pool->base.timing_generators[i] != NULL)    {
1148             kfree(DCN10TG_FROM_TG(pool->base.timing_generators[i]));
1149             pool->base.timing_generators[i] = NULL;
1150         }
1151     }
1152 
1153     for (i = 0; i < pool->base.res_cap->num_dwb; i++) {
1154         if (pool->base.dwbc[i] != NULL) {
1155             kfree(TO_DCN30_DWBC(pool->base.dwbc[i]));
1156             pool->base.dwbc[i] = NULL;
1157         }
1158         if (pool->base.mcif_wb[i] != NULL) {
1159             kfree(TO_DCN30_MMHUBBUB(pool->base.mcif_wb[i]));
1160             pool->base.mcif_wb[i] = NULL;
1161         }
1162     }
1163 
1164     for (i = 0; i < pool->base.audio_count; i++) {
1165         if (pool->base.audios[i])
1166             dce_aud_destroy(&pool->base.audios[i]);
1167     }
1168 
1169     for (i = 0; i < pool->base.clk_src_count; i++) {
1170         if (pool->base.clock_sources[i] != NULL) {
1171             dcn20_clock_source_destroy(&pool->base.clock_sources[i]);
1172             pool->base.clock_sources[i] = NULL;
1173         }
1174     }
1175 
1176     for (i = 0; i < pool->base.res_cap->num_mpc_3dlut; i++) {
1177         if (pool->base.mpc_lut[i] != NULL) {
1178             dc_3dlut_func_release(pool->base.mpc_lut[i]);
1179             pool->base.mpc_lut[i] = NULL;
1180         }
1181         if (pool->base.mpc_shaper[i] != NULL) {
1182             dc_transfer_func_release(pool->base.mpc_shaper[i]);
1183             pool->base.mpc_shaper[i] = NULL;
1184         }
1185     }
1186 
1187     if (pool->base.dp_clock_source != NULL) {
1188         dcn20_clock_source_destroy(&pool->base.dp_clock_source);
1189         pool->base.dp_clock_source = NULL;
1190     }
1191 
1192     for (i = 0; i < pool->base.pipe_count; i++) {
1193         if (pool->base.multiple_abms[i] != NULL)
1194             dce_abm_destroy(&pool->base.multiple_abms[i]);
1195     }
1196 
1197     if (pool->base.psr != NULL)
1198         dmub_psr_destroy(&pool->base.psr);
1199 
1200     if (pool->base.dccg != NULL)
1201         dcn_dccg_destroy(&pool->base.dccg);
1202 
1203     if (pool->base.oem_device != NULL)
1204         dal_ddc_service_destroy(&pool->base.oem_device);
1205 }
1206 
1207 static struct hubp *dcn30_hubp_create(
1208     struct dc_context *ctx,
1209     uint32_t inst)
1210 {
1211     struct dcn20_hubp *hubp2 =
1212         kzalloc(sizeof(struct dcn20_hubp), GFP_KERNEL);
1213 
1214     if (!hubp2)
1215         return NULL;
1216 
1217     if (hubp3_construct(hubp2, ctx, inst,
1218             &hubp_regs[inst], &hubp_shift, &hubp_mask))
1219         return &hubp2->base;
1220 
1221     BREAK_TO_DEBUGGER();
1222     kfree(hubp2);
1223     return NULL;
1224 }
1225 
1226 static bool dcn30_dwbc_create(struct dc_context *ctx, struct resource_pool *pool)
1227 {
1228     int i;
1229     uint32_t pipe_count = pool->res_cap->num_dwb;
1230 
1231     for (i = 0; i < pipe_count; i++) {
1232         struct dcn30_dwbc *dwbc30 = kzalloc(sizeof(struct dcn30_dwbc),
1233                             GFP_KERNEL);
1234 
1235         if (!dwbc30) {
1236             dm_error("DC: failed to create dwbc30!\n");
1237             return false;
1238         }
1239 
1240         dcn30_dwbc_construct(dwbc30, ctx,
1241                 &dwbc30_regs[i],
1242                 &dwbc30_shift,
1243                 &dwbc30_mask,
1244                 i);
1245 
1246         pool->dwbc[i] = &dwbc30->base;
1247     }
1248     return true;
1249 }
1250 
1251 static bool dcn30_mmhubbub_create(struct dc_context *ctx, struct resource_pool *pool)
1252 {
1253     int i;
1254     uint32_t pipe_count = pool->res_cap->num_dwb;
1255 
1256     for (i = 0; i < pipe_count; i++) {
1257         struct dcn30_mmhubbub *mcif_wb30 = kzalloc(sizeof(struct dcn30_mmhubbub),
1258                             GFP_KERNEL);
1259 
1260         if (!mcif_wb30) {
1261             dm_error("DC: failed to create mcif_wb30!\n");
1262             return false;
1263         }
1264 
1265         dcn30_mmhubbub_construct(mcif_wb30, ctx,
1266                 &mcif_wb30_regs[i],
1267                 &mcif_wb30_shift,
1268                 &mcif_wb30_mask,
1269                 i);
1270 
1271         pool->mcif_wb[i] = &mcif_wb30->base;
1272     }
1273     return true;
1274 }
1275 
1276 static struct display_stream_compressor *dcn30_dsc_create(
1277     struct dc_context *ctx, uint32_t inst)
1278 {
1279     struct dcn20_dsc *dsc =
1280         kzalloc(sizeof(struct dcn20_dsc), GFP_KERNEL);
1281 
1282     if (!dsc) {
1283         BREAK_TO_DEBUGGER();
1284         return NULL;
1285     }
1286 
1287     dsc2_construct(dsc, ctx, inst, &dsc_regs[inst], &dsc_shift, &dsc_mask);
1288     return &dsc->base;
1289 }
1290 
1291 enum dc_status dcn30_add_stream_to_ctx(struct dc *dc, struct dc_state *new_ctx, struct dc_stream_state *dc_stream)
1292 {
1293 
1294     return dcn20_add_stream_to_ctx(dc, new_ctx, dc_stream);
1295 }
1296 
1297 static void dcn30_destroy_resource_pool(struct resource_pool **pool)
1298 {
1299     struct dcn30_resource_pool *dcn30_pool = TO_DCN30_RES_POOL(*pool);
1300 
1301     dcn30_resource_destruct(dcn30_pool);
1302     kfree(dcn30_pool);
1303     *pool = NULL;
1304 }
1305 
1306 static struct clock_source *dcn30_clock_source_create(
1307         struct dc_context *ctx,
1308         struct dc_bios *bios,
1309         enum clock_source_id id,
1310         const struct dce110_clk_src_regs *regs,
1311         bool dp_clk_src)
1312 {
1313     struct dce110_clk_src *clk_src =
1314         kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL);
1315 
1316     if (!clk_src)
1317         return NULL;
1318 
1319     if (dcn3_clk_src_construct(clk_src, ctx, bios, id,
1320             regs, &cs_shift, &cs_mask)) {
1321         clk_src->base.dp_clk_src = dp_clk_src;
1322         return &clk_src->base;
1323     }
1324 
1325     BREAK_TO_DEBUGGER();
1326     return NULL;
1327 }
1328 
1329 int dcn30_populate_dml_pipes_from_context(
1330     struct dc *dc, struct dc_state *context,
1331     display_e2e_pipe_params_st *pipes,
1332     bool fast_validate)
1333 {
1334     int i, pipe_cnt;
1335     struct resource_context *res_ctx = &context->res_ctx;
1336 
1337     DC_FP_START();
1338     dcn20_populate_dml_pipes_from_context(dc, context, pipes, fast_validate);
1339     DC_FP_END();
1340 
1341     for (i = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {
1342         if (!res_ctx->pipe_ctx[i].stream)
1343             continue;
1344 
1345         pipes[pipe_cnt++].pipe.scale_ratio_depth.lb_depth =
1346             dm_lb_16;
1347     }
1348 
1349     return pipe_cnt;
1350 }
1351 
1352 void dcn30_populate_dml_writeback_from_context(
1353     struct dc *dc, struct resource_context *res_ctx, display_e2e_pipe_params_st *pipes)
1354 {
1355     DC_FP_START();
1356     dcn30_fpu_populate_dml_writeback_from_context(dc, res_ctx, pipes);
1357     DC_FP_END();
1358 }
1359 
1360 unsigned int dcn30_calc_max_scaled_time(
1361         unsigned int time_per_pixel,
1362         enum mmhubbub_wbif_mode mode,
1363         unsigned int urgent_watermark)
1364 {
1365     unsigned int time_per_byte = 0;
1366     unsigned int total_free_entry = 0xb40;
1367     unsigned int buf_lh_capability;
1368     unsigned int max_scaled_time;
1369 
1370     if (mode == PACKED_444) /* packed mode 32 bpp */
1371         time_per_byte = time_per_pixel/4;
1372     else if (mode == PACKED_444_FP16) /* packed mode 64 bpp */
1373         time_per_byte = time_per_pixel/8;
1374 
1375     if (time_per_byte == 0)
1376         time_per_byte = 1;
1377 
1378     buf_lh_capability = (total_free_entry*time_per_byte*32) >> 6; /* time_per_byte is in u6.6*/
1379     max_scaled_time   = buf_lh_capability - urgent_watermark;
1380     return max_scaled_time;
1381 }
1382 
1383 void dcn30_set_mcif_arb_params(
1384         struct dc *dc,
1385         struct dc_state *context,
1386         display_e2e_pipe_params_st *pipes,
1387         int pipe_cnt)
1388 {
1389     enum mmhubbub_wbif_mode wbif_mode;
1390     struct display_mode_lib *dml = &context->bw_ctx.dml;
1391     struct mcif_arb_params *wb_arb_params;
1392     int i, j, dwb_pipe;
1393 
1394     /* Writeback MCIF_WB arbitration parameters */
1395     dwb_pipe = 0;
1396     for (i = 0; i < dc->res_pool->pipe_count; i++) {
1397 
1398         if (!context->res_ctx.pipe_ctx[i].stream)
1399             continue;
1400 
1401         for (j = 0; j < MAX_DWB_PIPES; j++) {
1402             struct dc_writeback_info *writeback_info = &context->res_ctx.pipe_ctx[i].stream->writeback_info[j];
1403 
1404             if (writeback_info->wb_enabled == false)
1405                 continue;
1406 
1407             //wb_arb_params = &context->res_ctx.pipe_ctx[i].stream->writeback_info[j].mcif_arb_params;
1408             wb_arb_params = &context->bw_ctx.bw.dcn.bw_writeback.mcif_wb_arb[dwb_pipe];
1409 
1410             if (writeback_info->dwb_params.cnv_params.fc_out_format == DWB_OUT_FORMAT_64BPP_ARGB ||
1411                 writeback_info->dwb_params.cnv_params.fc_out_format == DWB_OUT_FORMAT_64BPP_RGBA)
1412                 wbif_mode = PACKED_444_FP16;
1413             else
1414                 wbif_mode = PACKED_444;
1415 
1416             DC_FP_START();
1417             dcn30_fpu_set_mcif_arb_params(wb_arb_params, dml, pipes, pipe_cnt, j);
1418             DC_FP_END();
1419             wb_arb_params->time_per_pixel = (1000000 << 6) / context->res_ctx.pipe_ctx[i].stream->phy_pix_clk; /* time_per_pixel should be in u6.6 format */
1420             wb_arb_params->slice_lines = 32;
1421             wb_arb_params->arbitration_slice = 2; /* irrelevant since there is no YUV output */
1422             wb_arb_params->max_scaled_time = dcn30_calc_max_scaled_time(wb_arb_params->time_per_pixel,
1423                     wbif_mode,
1424                     wb_arb_params->cli_watermark[0]); /* assume 4 watermark sets have the same value */
1425 
1426             dwb_pipe++;
1427 
1428             if (dwb_pipe >= MAX_DWB_PIPES)
1429                 return;
1430         }
1431         if (dwb_pipe >= MAX_DWB_PIPES)
1432             return;
1433     }
1434 
1435 }
1436 
1437 static struct dc_cap_funcs cap_funcs = {
1438     .get_dcc_compression_cap = dcn20_get_dcc_compression_cap
1439 };
1440 
1441 bool dcn30_acquire_post_bldn_3dlut(
1442         struct resource_context *res_ctx,
1443         const struct resource_pool *pool,
1444         int mpcc_id,
1445         struct dc_3dlut **lut,
1446         struct dc_transfer_func **shaper)
1447 {
1448     int i;
1449     bool ret = false;
1450     union dc_3dlut_state *state;
1451 
1452     ASSERT(*lut == NULL && *shaper == NULL);
1453     *lut = NULL;
1454     *shaper = NULL;
1455 
1456     for (i = 0; i < pool->res_cap->num_mpc_3dlut; i++) {
1457         if (!res_ctx->is_mpc_3dlut_acquired[i]) {
1458             *lut = pool->mpc_lut[i];
1459             *shaper = pool->mpc_shaper[i];
1460             state = &pool->mpc_lut[i]->state;
1461             res_ctx->is_mpc_3dlut_acquired[i] = true;
1462             state->bits.rmu_idx_valid = 1;
1463             state->bits.rmu_mux_num = i;
1464             if (state->bits.rmu_mux_num == 0)
1465                 state->bits.mpc_rmu0_mux = mpcc_id;
1466             else if (state->bits.rmu_mux_num == 1)
1467                 state->bits.mpc_rmu1_mux = mpcc_id;
1468             else if (state->bits.rmu_mux_num == 2)
1469                 state->bits.mpc_rmu2_mux = mpcc_id;
1470             ret = true;
1471             break;
1472             }
1473         }
1474     return ret;
1475 }
1476 
1477 bool dcn30_release_post_bldn_3dlut(
1478         struct resource_context *res_ctx,
1479         const struct resource_pool *pool,
1480         struct dc_3dlut **lut,
1481         struct dc_transfer_func **shaper)
1482 {
1483     int i;
1484     bool ret = false;
1485 
1486     for (i = 0; i < pool->res_cap->num_mpc_3dlut; i++) {
1487         if (pool->mpc_lut[i] == *lut && pool->mpc_shaper[i] == *shaper) {
1488             res_ctx->is_mpc_3dlut_acquired[i] = false;
1489             pool->mpc_lut[i]->state.raw = 0;
1490             *lut = NULL;
1491             *shaper = NULL;
1492             ret = true;
1493             break;
1494         }
1495     }
1496     return ret;
1497 }
1498 
1499 static bool is_soc_bounding_box_valid(struct dc *dc)
1500 {
1501     uint32_t hw_internal_rev = dc->ctx->asic_id.hw_internal_rev;
1502 
1503     if (ASICREV_IS_SIENNA_CICHLID_P(hw_internal_rev))
1504         return true;
1505 
1506     return false;
1507 }
1508 
1509 static bool init_soc_bounding_box(struct dc *dc,
1510                   struct dcn30_resource_pool *pool)
1511 {
1512     struct _vcs_dpi_soc_bounding_box_st *loaded_bb = &dcn3_0_soc;
1513     struct _vcs_dpi_ip_params_st *loaded_ip = &dcn3_0_ip;
1514 
1515     DC_LOGGER_INIT(dc->ctx->logger);
1516 
1517     if (!is_soc_bounding_box_valid(dc)) {
1518         DC_LOG_ERROR("%s: not valid soc bounding box\n", __func__);
1519         return false;
1520     }
1521 
1522     loaded_ip->max_num_otg = pool->base.res_cap->num_timing_generator;
1523     loaded_ip->max_num_dpp = pool->base.pipe_count;
1524     loaded_ip->clamp_min_dcfclk = dc->config.clamp_min_dcfclk;
1525     dcn20_patch_bounding_box(dc, loaded_bb);
1526     DC_FP_START();
1527     patch_dcn30_soc_bounding_box(dc, &dcn3_0_soc);
1528     DC_FP_END();
1529 
1530     return true;
1531 }
1532 
1533 static bool dcn30_split_stream_for_mpc_or_odm(
1534         const struct dc *dc,
1535         struct resource_context *res_ctx,
1536         struct pipe_ctx *pri_pipe,
1537         struct pipe_ctx *sec_pipe,
1538         bool odm)
1539 {
1540     int pipe_idx = sec_pipe->pipe_idx;
1541     const struct resource_pool *pool = dc->res_pool;
1542 
1543     *sec_pipe = *pri_pipe;
1544 
1545     sec_pipe->pipe_idx = pipe_idx;
1546     sec_pipe->plane_res.mi = pool->mis[pipe_idx];
1547     sec_pipe->plane_res.hubp = pool->hubps[pipe_idx];
1548     sec_pipe->plane_res.ipp = pool->ipps[pipe_idx];
1549     sec_pipe->plane_res.xfm = pool->transforms[pipe_idx];
1550     sec_pipe->plane_res.dpp = pool->dpps[pipe_idx];
1551     sec_pipe->plane_res.mpcc_inst = pool->dpps[pipe_idx]->inst;
1552     sec_pipe->stream_res.dsc = NULL;
1553     if (odm) {
1554         if (pri_pipe->next_odm_pipe) {
1555             ASSERT(pri_pipe->next_odm_pipe != sec_pipe);
1556             sec_pipe->next_odm_pipe = pri_pipe->next_odm_pipe;
1557             sec_pipe->next_odm_pipe->prev_odm_pipe = sec_pipe;
1558         }
1559         if (pri_pipe->top_pipe && pri_pipe->top_pipe->next_odm_pipe) {
1560             pri_pipe->top_pipe->next_odm_pipe->bottom_pipe = sec_pipe;
1561             sec_pipe->top_pipe = pri_pipe->top_pipe->next_odm_pipe;
1562         }
1563         if (pri_pipe->bottom_pipe && pri_pipe->bottom_pipe->next_odm_pipe) {
1564             pri_pipe->bottom_pipe->next_odm_pipe->top_pipe = sec_pipe;
1565             sec_pipe->bottom_pipe = pri_pipe->bottom_pipe->next_odm_pipe;
1566         }
1567         pri_pipe->next_odm_pipe = sec_pipe;
1568         sec_pipe->prev_odm_pipe = pri_pipe;
1569 
1570         if (!sec_pipe->top_pipe)
1571             sec_pipe->stream_res.opp = pool->opps[pipe_idx];
1572         else
1573             sec_pipe->stream_res.opp = sec_pipe->top_pipe->stream_res.opp;
1574         if (sec_pipe->stream->timing.flags.DSC == 1) {
1575             dcn20_acquire_dsc(dc, res_ctx, &sec_pipe->stream_res.dsc, pipe_idx);
1576             ASSERT(sec_pipe->stream_res.dsc);
1577             if (sec_pipe->stream_res.dsc == NULL)
1578                 return false;
1579         }
1580     } else {
1581         if (pri_pipe->bottom_pipe) {
1582             ASSERT(pri_pipe->bottom_pipe != sec_pipe);
1583             sec_pipe->bottom_pipe = pri_pipe->bottom_pipe;
1584             sec_pipe->bottom_pipe->top_pipe = sec_pipe;
1585         }
1586         pri_pipe->bottom_pipe = sec_pipe;
1587         sec_pipe->top_pipe = pri_pipe;
1588 
1589         ASSERT(pri_pipe->plane_state);
1590     }
1591 
1592     return true;
1593 }
1594 
1595 static struct pipe_ctx *dcn30_find_split_pipe(
1596         struct dc *dc,
1597         struct dc_state *context,
1598         int old_index)
1599 {
1600     struct pipe_ctx *pipe = NULL;
1601     int i;
1602 
1603     if (old_index >= 0 && context->res_ctx.pipe_ctx[old_index].stream == NULL) {
1604         pipe = &context->res_ctx.pipe_ctx[old_index];
1605         pipe->pipe_idx = old_index;
1606     }
1607 
1608     if (!pipe)
1609         for (i = dc->res_pool->pipe_count - 1; i >= 0; i--) {
1610             if (dc->current_state->res_ctx.pipe_ctx[i].top_pipe == NULL
1611                     && dc->current_state->res_ctx.pipe_ctx[i].prev_odm_pipe == NULL) {
1612                 if (context->res_ctx.pipe_ctx[i].stream == NULL) {
1613                     pipe = &context->res_ctx.pipe_ctx[i];
1614                     pipe->pipe_idx = i;
1615                     break;
1616                 }
1617             }
1618         }
1619 
1620     /*
1621      * May need to fix pipes getting tossed from 1 opp to another on flip
1622      * Add for debugging transient underflow during topology updates:
1623      * ASSERT(pipe);
1624      */
1625     if (!pipe)
1626         for (i = dc->res_pool->pipe_count - 1; i >= 0; i--) {
1627             if (context->res_ctx.pipe_ctx[i].stream == NULL) {
1628                 pipe = &context->res_ctx.pipe_ctx[i];
1629                 pipe->pipe_idx = i;
1630                 break;
1631             }
1632         }
1633 
1634     return pipe;
1635 }
1636 
1637 noinline bool dcn30_internal_validate_bw(
1638         struct dc *dc,
1639         struct dc_state *context,
1640         display_e2e_pipe_params_st *pipes,
1641         int *pipe_cnt_out,
1642         int *vlevel_out,
1643         bool fast_validate)
1644 {
1645     bool out = false;
1646     bool repopulate_pipes = false;
1647     int split[MAX_PIPES] = { 0 };
1648     bool merge[MAX_PIPES] = { false };
1649     bool newly_split[MAX_PIPES] = { false };
1650     int pipe_cnt, i, pipe_idx, vlevel;
1651     struct vba_vars_st *vba = &context->bw_ctx.dml.vba;
1652 
1653     ASSERT(pipes);
1654     if (!pipes)
1655         return false;
1656 
1657     dc->res_pool->funcs->update_soc_for_wm_a(dc, context);
1658     pipe_cnt = dc->res_pool->funcs->populate_dml_pipes(dc, context, pipes, fast_validate);
1659 
1660     if (!pipe_cnt) {
1661         out = true;
1662         goto validate_out;
1663     }
1664 
1665     dml_log_pipe_params(&context->bw_ctx.dml, pipes, pipe_cnt);
1666 
1667     if (!fast_validate) {
1668         /*
1669          * DML favors voltage over p-state, but we're more interested in
1670          * supporting p-state over voltage. We can't support p-state in
1671          * prefetch mode > 0 so try capping the prefetch mode to start.
1672          */
1673         context->bw_ctx.dml.soc.allow_dram_self_refresh_or_dram_clock_change_in_vblank =
1674             dm_allow_self_refresh_and_mclk_switch;
1675         vlevel = dml_get_voltage_level(&context->bw_ctx.dml, pipes, pipe_cnt);
1676         /* This may adjust vlevel and maxMpcComb */
1677         if (vlevel < context->bw_ctx.dml.soc.num_states)
1678             vlevel = dcn20_validate_apply_pipe_split_flags(dc, context, vlevel, split, merge);
1679     }
1680     if (fast_validate || vlevel == context->bw_ctx.dml.soc.num_states ||
1681             vba->DRAMClockChangeSupport[vlevel][vba->maxMpcComb] == dm_dram_clock_change_unsupported) {
1682         /*
1683          * If mode is unsupported or there's still no p-state support then
1684          * fall back to favoring voltage.
1685          *
1686          * We don't actually support prefetch mode 2, so require that we
1687          * at least support prefetch mode 1.
1688          */
1689         context->bw_ctx.dml.soc.allow_dram_self_refresh_or_dram_clock_change_in_vblank =
1690             dm_allow_self_refresh;
1691 
1692         vlevel = dml_get_voltage_level(&context->bw_ctx.dml, pipes, pipe_cnt);
1693         if (vlevel < context->bw_ctx.dml.soc.num_states) {
1694             memset(split, 0, sizeof(split));
1695             memset(merge, 0, sizeof(merge));
1696             vlevel = dcn20_validate_apply_pipe_split_flags(dc, context, vlevel, split, merge);
1697         }
1698     }
1699 
1700     dml_log_mode_support_params(&context->bw_ctx.dml);
1701 
1702     if (vlevel == context->bw_ctx.dml.soc.num_states)
1703         goto validate_fail;
1704 
1705     if (!dc->config.enable_windowed_mpo_odm) {
1706         for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) {
1707             struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
1708             struct pipe_ctx *mpo_pipe = pipe->bottom_pipe;
1709 
1710             if (!pipe->stream)
1711                 continue;
1712 
1713             /* We only support full screen mpo with ODM */
1714             if (vba->ODMCombineEnabled[vba->pipe_plane[pipe_idx]] != dm_odm_combine_mode_disabled
1715                     && pipe->plane_state && mpo_pipe
1716                     && memcmp(&mpo_pipe->plane_res.scl_data.recout,
1717                             &pipe->plane_res.scl_data.recout,
1718                             sizeof(struct rect)) != 0) {
1719                 ASSERT(mpo_pipe->plane_state != pipe->plane_state);
1720                 goto validate_fail;
1721             }
1722             pipe_idx++;
1723         }
1724     }
1725 
1726     /* merge pipes if necessary */
1727     for (i = 0; i < dc->res_pool->pipe_count; i++) {
1728         struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
1729 
1730         /*skip pipes that don't need merging*/
1731         if (!merge[i])
1732             continue;
1733 
1734         /* if ODM merge we ignore mpc tree, mpo pipes will have their own flags */
1735         if (pipe->prev_odm_pipe) {
1736             /*split off odm pipe*/
1737             pipe->prev_odm_pipe->next_odm_pipe = pipe->next_odm_pipe;
1738             if (pipe->next_odm_pipe)
1739                 pipe->next_odm_pipe->prev_odm_pipe = pipe->prev_odm_pipe;
1740 
1741             pipe->bottom_pipe = NULL;
1742             pipe->next_odm_pipe = NULL;
1743             pipe->plane_state = NULL;
1744             pipe->stream = NULL;
1745             pipe->top_pipe = NULL;
1746             pipe->prev_odm_pipe = NULL;
1747             if (pipe->stream_res.dsc)
1748                 dcn20_release_dsc(&context->res_ctx, dc->res_pool, &pipe->stream_res.dsc);
1749             memset(&pipe->plane_res, 0, sizeof(pipe->plane_res));
1750             memset(&pipe->stream_res, 0, sizeof(pipe->stream_res));
1751             repopulate_pipes = true;
1752         } else if (pipe->top_pipe && pipe->top_pipe->plane_state == pipe->plane_state) {
1753             struct pipe_ctx *top_pipe = pipe->top_pipe;
1754             struct pipe_ctx *bottom_pipe = pipe->bottom_pipe;
1755 
1756             top_pipe->bottom_pipe = bottom_pipe;
1757             if (bottom_pipe)
1758                 bottom_pipe->top_pipe = top_pipe;
1759 
1760             pipe->top_pipe = NULL;
1761             pipe->bottom_pipe = NULL;
1762             pipe->plane_state = NULL;
1763             pipe->stream = NULL;
1764             memset(&pipe->plane_res, 0, sizeof(pipe->plane_res));
1765             memset(&pipe->stream_res, 0, sizeof(pipe->stream_res));
1766             repopulate_pipes = true;
1767         } else
1768             ASSERT(0); /* Should never try to merge master pipe */
1769 
1770     }
1771 
1772     for (i = 0, pipe_idx = -1; i < dc->res_pool->pipe_count; i++) {
1773         struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
1774         struct pipe_ctx *old_pipe = &dc->current_state->res_ctx.pipe_ctx[i];
1775         struct pipe_ctx *hsplit_pipe = NULL;
1776         bool odm;
1777         int old_index = -1;
1778 
1779         if (!pipe->stream || newly_split[i])
1780             continue;
1781 
1782         pipe_idx++;
1783         odm = vba->ODMCombineEnabled[vba->pipe_plane[pipe_idx]] != dm_odm_combine_mode_disabled;
1784 
1785         if (!pipe->plane_state && !odm)
1786             continue;
1787 
1788         if (split[i]) {
1789             if (odm) {
1790                 if (split[i] == 4 && old_pipe->next_odm_pipe && old_pipe->next_odm_pipe->next_odm_pipe)
1791                     old_index = old_pipe->next_odm_pipe->next_odm_pipe->pipe_idx;
1792                 else if (old_pipe->next_odm_pipe)
1793                     old_index = old_pipe->next_odm_pipe->pipe_idx;
1794             } else {
1795                 if (split[i] == 4 && old_pipe->bottom_pipe && old_pipe->bottom_pipe->bottom_pipe &&
1796                         old_pipe->bottom_pipe->bottom_pipe->plane_state == old_pipe->plane_state)
1797                     old_index = old_pipe->bottom_pipe->bottom_pipe->pipe_idx;
1798                 else if (old_pipe->bottom_pipe &&
1799                         old_pipe->bottom_pipe->plane_state == old_pipe->plane_state)
1800                     old_index = old_pipe->bottom_pipe->pipe_idx;
1801             }
1802             hsplit_pipe = dcn30_find_split_pipe(dc, context, old_index);
1803             ASSERT(hsplit_pipe);
1804             if (!hsplit_pipe)
1805                 goto validate_fail;
1806 
1807             if (!dcn30_split_stream_for_mpc_or_odm(
1808                     dc, &context->res_ctx,
1809                     pipe, hsplit_pipe, odm))
1810                 goto validate_fail;
1811 
1812             newly_split[hsplit_pipe->pipe_idx] = true;
1813             repopulate_pipes = true;
1814         }
1815         if (split[i] == 4) {
1816             struct pipe_ctx *pipe_4to1;
1817 
1818             if (odm && old_pipe->next_odm_pipe)
1819                 old_index = old_pipe->next_odm_pipe->pipe_idx;
1820             else if (!odm && old_pipe->bottom_pipe &&
1821                         old_pipe->bottom_pipe->plane_state == old_pipe->plane_state)
1822                 old_index = old_pipe->bottom_pipe->pipe_idx;
1823             else
1824                 old_index = -1;
1825             pipe_4to1 = dcn30_find_split_pipe(dc, context, old_index);
1826             ASSERT(pipe_4to1);
1827             if (!pipe_4to1)
1828                 goto validate_fail;
1829             if (!dcn30_split_stream_for_mpc_or_odm(
1830                     dc, &context->res_ctx,
1831                     pipe, pipe_4to1, odm))
1832                 goto validate_fail;
1833             newly_split[pipe_4to1->pipe_idx] = true;
1834 
1835             if (odm && old_pipe->next_odm_pipe && old_pipe->next_odm_pipe->next_odm_pipe
1836                     && old_pipe->next_odm_pipe->next_odm_pipe->next_odm_pipe)
1837                 old_index = old_pipe->next_odm_pipe->next_odm_pipe->next_odm_pipe->pipe_idx;
1838             else if (!odm && old_pipe->bottom_pipe && old_pipe->bottom_pipe->bottom_pipe &&
1839                     old_pipe->bottom_pipe->bottom_pipe->bottom_pipe &&
1840                     old_pipe->bottom_pipe->bottom_pipe->bottom_pipe->plane_state == old_pipe->plane_state)
1841                 old_index = old_pipe->bottom_pipe->bottom_pipe->bottom_pipe->pipe_idx;
1842             else
1843                 old_index = -1;
1844             pipe_4to1 = dcn30_find_split_pipe(dc, context, old_index);
1845             ASSERT(pipe_4to1);
1846             if (!pipe_4to1)
1847                 goto validate_fail;
1848             if (!dcn30_split_stream_for_mpc_or_odm(
1849                     dc, &context->res_ctx,
1850                     hsplit_pipe, pipe_4to1, odm))
1851                 goto validate_fail;
1852             newly_split[pipe_4to1->pipe_idx] = true;
1853         }
1854         if (odm)
1855             dcn20_build_mapped_resource(dc, context, pipe->stream);
1856     }
1857 
1858     for (i = 0; i < dc->res_pool->pipe_count; i++) {
1859         struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
1860 
1861         if (pipe->plane_state) {
1862             if (!resource_build_scaling_params(pipe))
1863                 goto validate_fail;
1864         }
1865     }
1866 
1867     /* Actual dsc count per stream dsc validation*/
1868     if (!dcn20_validate_dsc(dc, context)) {
1869         vba->ValidationStatus[vba->soc.num_states] = DML_FAIL_DSC_VALIDATION_FAILURE;
1870         goto validate_fail;
1871     }
1872 
1873     if (repopulate_pipes)
1874         pipe_cnt = dc->res_pool->funcs->populate_dml_pipes(dc, context, pipes, fast_validate);
1875     *vlevel_out = vlevel;
1876     *pipe_cnt_out = pipe_cnt;
1877 
1878     out = true;
1879     goto validate_out;
1880 
1881 validate_fail:
1882     out = false;
1883 
1884 validate_out:
1885     return out;
1886 }
1887 
1888 static int get_refresh_rate(struct dc_state *context)
1889 {
1890     int refresh_rate = 0;
1891     int h_v_total = 0;
1892     struct dc_crtc_timing *timing = NULL;
1893 
1894     if (context == NULL || context->streams[0] == NULL)
1895         return 0;
1896 
1897     /* check if refresh rate at least 120hz */
1898     timing = &context->streams[0]->timing;
1899     if (timing == NULL)
1900         return 0;
1901 
1902     h_v_total = timing->h_total * timing->v_total;
1903     if (h_v_total == 0)
1904         return 0;
1905 
1906     refresh_rate = ((timing->pix_clk_100hz * 100) / (h_v_total)) + 1;
1907     return refresh_rate;
1908 }
1909 
1910 #define MAX_STRETCHED_V_BLANK 500 // in micro-seconds
1911 /*
1912  * Scaling factor for v_blank stretch calculations considering timing in
1913  * micro-seconds and pixel clock in 100hz.
1914  * Note: the parenthesis are necessary to ensure the correct order of
1915  * operation where V_SCALE is used.
1916  */
1917 #define V_SCALE (10000 / MAX_STRETCHED_V_BLANK)
1918 
1919 int get_frame_rate_at_max_stretch_100hz(struct dc_state *context)
1920 {
1921     struct dc_crtc_timing *timing = NULL;
1922     uint32_t sec_per_100_lines;
1923     uint32_t max_v_blank;
1924     uint32_t curr_v_blank;
1925     uint32_t v_stretch_max;
1926     uint32_t stretched_frame_pix_cnt;
1927     uint32_t scaled_stretched_frame_pix_cnt;
1928     uint32_t scaled_refresh_rate;
1929 
1930     if (context == NULL || context->streams[0] == NULL)
1931         return 0;
1932 
1933     /* check if refresh rate at least 120hz */
1934     timing = &context->streams[0]->timing;
1935     if (timing == NULL)
1936         return 0;
1937 
1938     sec_per_100_lines = timing->pix_clk_100hz / timing->h_total + 1;
1939     max_v_blank = sec_per_100_lines / V_SCALE + 1;
1940     curr_v_blank = timing->v_total - timing->v_addressable;
1941     v_stretch_max = (max_v_blank > curr_v_blank) ? (max_v_blank - curr_v_blank) : (0);
1942     stretched_frame_pix_cnt = (v_stretch_max + timing->v_total) * timing->h_total;
1943     scaled_stretched_frame_pix_cnt = stretched_frame_pix_cnt / 10000;
1944     scaled_refresh_rate = (timing->pix_clk_100hz) / scaled_stretched_frame_pix_cnt + 1;
1945 
1946     return scaled_refresh_rate;
1947 }
1948 
1949 bool is_refresh_rate_support_mclk_switch_using_fw_based_vblank_stretch(struct dc_state *context)
1950 {
1951     int refresh_rate_max_stretch_100hz;
1952     int min_refresh_100hz;
1953 
1954     if (context == NULL || context->streams[0] == NULL)
1955         return false;
1956 
1957     refresh_rate_max_stretch_100hz = get_frame_rate_at_max_stretch_100hz(context);
1958     min_refresh_100hz = context->streams[0]->timing.min_refresh_in_uhz / 10000;
1959 
1960     if (refresh_rate_max_stretch_100hz < min_refresh_100hz)
1961         return false;
1962 
1963     return true;
1964 }
1965 
1966 bool dcn30_can_support_mclk_switch_using_fw_based_vblank_stretch(struct dc *dc, struct dc_state *context)
1967 {
1968     int refresh_rate = 0;
1969     const int minimum_refreshrate_supported = 120;
1970 
1971     if (context == NULL || context->streams[0] == NULL)
1972         return false;
1973 
1974     if (context->streams[0]->sink->edid_caps.panel_patch.disable_fams)
1975         return false;
1976 
1977     if (dc->debug.disable_fams)
1978         return false;
1979 
1980     if (!dc->caps.dmub_caps.mclk_sw)
1981         return false;
1982 
1983     if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching_shut_down)
1984         return false;
1985 
1986     /* more then 1 monitor connected */
1987     if (context->stream_count != 1)
1988         return false;
1989 
1990     refresh_rate = get_refresh_rate(context);
1991     if (refresh_rate < minimum_refreshrate_supported)
1992         return false;
1993 
1994     if (!is_refresh_rate_support_mclk_switch_using_fw_based_vblank_stretch(context))
1995         return false;
1996 
1997     // check if freesync enabled
1998     if (!context->streams[0]->allow_freesync)
1999         return false;
2000 
2001     if (context->streams[0]->vrr_active_variable)
2002         return false;
2003 
2004     return true;
2005 }
2006 
2007 /*
2008  * set up FPO watermarks, pstate, dram latency
2009  */
2010 void dcn30_setup_mclk_switch_using_fw_based_vblank_stretch(struct dc *dc, struct dc_state *context)
2011 {
2012     ASSERT(dc != NULL && context != NULL);
2013     if (dc == NULL || context == NULL)
2014         return;
2015 
2016     /* Set wm_a.pstate so high natural MCLK switches are impossible: 4 seconds */
2017     context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns = 4U * 1000U * 1000U * 1000U;
2018 }
2019 
2020 void dcn30_update_soc_for_wm_a(struct dc *dc, struct dc_state *context)
2021 {
2022     DC_FP_START();
2023     dcn30_fpu_update_soc_for_wm_a(dc, context);
2024     DC_FP_END();
2025 }
2026 
2027 void dcn30_calculate_wm_and_dlg(
2028         struct dc *dc, struct dc_state *context,
2029         display_e2e_pipe_params_st *pipes,
2030         int pipe_cnt,
2031         int vlevel)
2032 {
2033     DC_FP_START();
2034     dcn30_fpu_calculate_wm_and_dlg(dc, context, pipes, pipe_cnt, vlevel);
2035     DC_FP_END();
2036 }
2037 
2038 bool dcn30_validate_bandwidth(struct dc *dc,
2039         struct dc_state *context,
2040         bool fast_validate)
2041 {
2042     bool out = false;
2043 
2044     BW_VAL_TRACE_SETUP();
2045 
2046     int vlevel = 0;
2047     int pipe_cnt = 0;
2048     display_e2e_pipe_params_st *pipes = kzalloc(dc->res_pool->pipe_count * sizeof(display_e2e_pipe_params_st), GFP_KERNEL);
2049     DC_LOGGER_INIT(dc->ctx->logger);
2050 
2051     BW_VAL_TRACE_COUNT();
2052 
2053     DC_FP_START();
2054     out = dcn30_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel, fast_validate);
2055     DC_FP_END();
2056 
2057     if (pipe_cnt == 0)
2058         goto validate_out;
2059 
2060     if (!out)
2061         goto validate_fail;
2062 
2063     BW_VAL_TRACE_END_VOLTAGE_LEVEL();
2064 
2065     if (fast_validate) {
2066         BW_VAL_TRACE_SKIP(fast);
2067         goto validate_out;
2068     }
2069 
2070     DC_FP_START();
2071     dc->res_pool->funcs->calculate_wm_and_dlg(dc, context, pipes, pipe_cnt, vlevel);
2072     DC_FP_END();
2073 
2074     BW_VAL_TRACE_END_WATERMARKS();
2075 
2076     goto validate_out;
2077 
2078 validate_fail:
2079     DC_LOG_WARNING("Mode Validation Warning: %s failed validation.\n",
2080         dml_get_status_message(context->bw_ctx.dml.vba.ValidationStatus[context->bw_ctx.dml.vba.soc.num_states]));
2081 
2082     BW_VAL_TRACE_SKIP(fail);
2083     out = false;
2084 
2085 validate_out:
2086     kfree(pipes);
2087 
2088     BW_VAL_TRACE_FINISH();
2089 
2090     return out;
2091 }
2092 
2093 void dcn30_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params)
2094 {
2095     unsigned int i, j;
2096     unsigned int num_states = 0;
2097 
2098     unsigned int dcfclk_mhz[DC__VOLTAGE_STATES] = {0};
2099     unsigned int dram_speed_mts[DC__VOLTAGE_STATES] = {0};
2100     unsigned int optimal_uclk_for_dcfclk_sta_targets[DC__VOLTAGE_STATES] = {0};
2101     unsigned int optimal_dcfclk_for_uclk[DC__VOLTAGE_STATES] = {0};
2102 
2103     unsigned int dcfclk_sta_targets[DC__VOLTAGE_STATES] = {694, 875, 1000, 1200};
2104     unsigned int num_dcfclk_sta_targets = 4;
2105     unsigned int num_uclk_states;
2106 
2107     struct dc_bounding_box_max_clk dcn30_bb_max_clk;
2108 
2109     memset(&dcn30_bb_max_clk, 0, sizeof(dcn30_bb_max_clk));
2110 
2111     if (dc->ctx->dc_bios->vram_info.num_chans)
2112         dcn3_0_soc.num_chans = dc->ctx->dc_bios->vram_info.num_chans;
2113 
2114     DC_FP_START();
2115     dcn30_fpu_update_dram_channel_width_bytes(dc);
2116     DC_FP_END();
2117 
2118     if (bw_params->clk_table.entries[0].memclk_mhz) {
2119 
2120         for (i = 0; i < MAX_NUM_DPM_LVL; i++) {
2121             if (bw_params->clk_table.entries[i].dcfclk_mhz > dcn30_bb_max_clk.max_dcfclk_mhz)
2122                 dcn30_bb_max_clk.max_dcfclk_mhz = bw_params->clk_table.entries[i].dcfclk_mhz;
2123             if (bw_params->clk_table.entries[i].dispclk_mhz > dcn30_bb_max_clk.max_dispclk_mhz)
2124                 dcn30_bb_max_clk.max_dispclk_mhz = bw_params->clk_table.entries[i].dispclk_mhz;
2125             if (bw_params->clk_table.entries[i].dppclk_mhz > dcn30_bb_max_clk.max_dppclk_mhz)
2126                 dcn30_bb_max_clk.max_dppclk_mhz = bw_params->clk_table.entries[i].dppclk_mhz;
2127             if (bw_params->clk_table.entries[i].phyclk_mhz > dcn30_bb_max_clk.max_phyclk_mhz)
2128                 dcn30_bb_max_clk.max_phyclk_mhz = bw_params->clk_table.entries[i].phyclk_mhz;
2129         }
2130 
2131         DC_FP_START();
2132         dcn30_fpu_update_max_clk(&dcn30_bb_max_clk);
2133         DC_FP_END();
2134 
2135         if (dcn30_bb_max_clk.max_dcfclk_mhz > dcfclk_sta_targets[num_dcfclk_sta_targets-1]) {
2136             // If max DCFCLK is greater than the max DCFCLK STA target, insert into the DCFCLK STA target array
2137             dcfclk_sta_targets[num_dcfclk_sta_targets] = dcn30_bb_max_clk.max_dcfclk_mhz;
2138             num_dcfclk_sta_targets++;
2139         } else if (dcn30_bb_max_clk.max_dcfclk_mhz < dcfclk_sta_targets[num_dcfclk_sta_targets-1]) {
2140             // If max DCFCLK is less than the max DCFCLK STA target, cap values and remove duplicates
2141             for (i = 0; i < num_dcfclk_sta_targets; i++) {
2142                 if (dcfclk_sta_targets[i] > dcn30_bb_max_clk.max_dcfclk_mhz) {
2143                     dcfclk_sta_targets[i] = dcn30_bb_max_clk.max_dcfclk_mhz;
2144                     break;
2145                 }
2146             }
2147             // Update size of array since we "removed" duplicates
2148             num_dcfclk_sta_targets = i + 1;
2149         }
2150 
2151         num_uclk_states = bw_params->clk_table.num_entries;
2152 
2153         // Calculate optimal dcfclk for each uclk
2154         for (i = 0; i < num_uclk_states; i++) {
2155             DC_FP_START();
2156             dcn30_fpu_get_optimal_dcfclk_fclk_for_uclk(bw_params->clk_table.entries[i].memclk_mhz * 16,
2157                     &optimal_dcfclk_for_uclk[i], NULL);
2158             DC_FP_END();
2159             if (optimal_dcfclk_for_uclk[i] < bw_params->clk_table.entries[0].dcfclk_mhz) {
2160                 optimal_dcfclk_for_uclk[i] = bw_params->clk_table.entries[0].dcfclk_mhz;
2161             }
2162         }
2163 
2164         // Calculate optimal uclk for each dcfclk sta target
2165         for (i = 0; i < num_dcfclk_sta_targets; i++) {
2166             for (j = 0; j < num_uclk_states; j++) {
2167                 if (dcfclk_sta_targets[i] < optimal_dcfclk_for_uclk[j]) {
2168                     optimal_uclk_for_dcfclk_sta_targets[i] =
2169                             bw_params->clk_table.entries[j].memclk_mhz * 16;
2170                     break;
2171                 }
2172             }
2173         }
2174 
2175         i = 0;
2176         j = 0;
2177         // create the final dcfclk and uclk table
2178         while (i < num_dcfclk_sta_targets && j < num_uclk_states && num_states < DC__VOLTAGE_STATES) {
2179             if (dcfclk_sta_targets[i] < optimal_dcfclk_for_uclk[j] && i < num_dcfclk_sta_targets) {
2180                 dcfclk_mhz[num_states] = dcfclk_sta_targets[i];
2181                 dram_speed_mts[num_states++] = optimal_uclk_for_dcfclk_sta_targets[i++];
2182             } else {
2183                 if (j < num_uclk_states && optimal_dcfclk_for_uclk[j] <= dcn30_bb_max_clk.max_dcfclk_mhz) {
2184                     dcfclk_mhz[num_states] = optimal_dcfclk_for_uclk[j];
2185                     dram_speed_mts[num_states++] = bw_params->clk_table.entries[j++].memclk_mhz * 16;
2186                 } else {
2187                     j = num_uclk_states;
2188                 }
2189             }
2190         }
2191 
2192         while (i < num_dcfclk_sta_targets && num_states < DC__VOLTAGE_STATES) {
2193             dcfclk_mhz[num_states] = dcfclk_sta_targets[i];
2194             dram_speed_mts[num_states++] = optimal_uclk_for_dcfclk_sta_targets[i++];
2195         }
2196 
2197         while (j < num_uclk_states && num_states < DC__VOLTAGE_STATES &&
2198                 optimal_dcfclk_for_uclk[j] <= dcn30_bb_max_clk.max_dcfclk_mhz) {
2199             dcfclk_mhz[num_states] = optimal_dcfclk_for_uclk[j];
2200             dram_speed_mts[num_states++] = bw_params->clk_table.entries[j++].memclk_mhz * 16;
2201         }
2202 
2203         dcn3_0_soc.num_states = num_states;
2204         DC_FP_START();
2205         dcn30_fpu_update_bw_bounding_box(dc, bw_params, &dcn30_bb_max_clk, dcfclk_mhz, dram_speed_mts);
2206         DC_FP_END();
2207     }
2208 }
2209 
2210 static const struct resource_funcs dcn30_res_pool_funcs = {
2211     .destroy = dcn30_destroy_resource_pool,
2212     .link_enc_create = dcn30_link_encoder_create,
2213     .panel_cntl_create = dcn30_panel_cntl_create,
2214     .validate_bandwidth = dcn30_validate_bandwidth,
2215     .calculate_wm_and_dlg = dcn30_calculate_wm_and_dlg,
2216     .update_soc_for_wm_a = dcn30_update_soc_for_wm_a,
2217     .populate_dml_pipes = dcn30_populate_dml_pipes_from_context,
2218     .acquire_idle_pipe_for_layer = dcn20_acquire_idle_pipe_for_layer,
2219     .add_stream_to_ctx = dcn30_add_stream_to_ctx,
2220     .add_dsc_to_stream_resource = dcn20_add_dsc_to_stream_resource,
2221     .remove_stream_from_ctx = dcn20_remove_stream_from_ctx,
2222     .populate_dml_writeback_from_context = dcn30_populate_dml_writeback_from_context,
2223     .set_mcif_arb_params = dcn30_set_mcif_arb_params,
2224     .find_first_free_match_stream_enc_for_link = dcn10_find_first_free_match_stream_enc_for_link,
2225     .acquire_post_bldn_3dlut = dcn30_acquire_post_bldn_3dlut,
2226     .release_post_bldn_3dlut = dcn30_release_post_bldn_3dlut,
2227     .update_bw_bounding_box = dcn30_update_bw_bounding_box,
2228     .patch_unknown_plane_state = dcn20_patch_unknown_plane_state,
2229 };
2230 
2231 #define CTX ctx
2232 
2233 #define REG(reg_name) \
2234     (DCN_BASE.instance[0].segment[mm ## reg_name ## _BASE_IDX] + mm ## reg_name)
2235 
2236 static uint32_t read_pipe_fuses(struct dc_context *ctx)
2237 {
2238     uint32_t value = REG_READ(CC_DC_PIPE_DIS);
2239     /* Support for max 6 pipes */
2240     value = value & 0x3f;
2241     return value;
2242 }
2243 
2244 static bool dcn30_resource_construct(
2245     uint8_t num_virtual_links,
2246     struct dc *dc,
2247     struct dcn30_resource_pool *pool)
2248 {
2249     int i;
2250     struct dc_context *ctx = dc->ctx;
2251     struct irq_service_init_data init_data;
2252     struct ddc_service_init_data ddc_init_data = {0};
2253     uint32_t pipe_fuses = read_pipe_fuses(ctx);
2254     uint32_t num_pipes = 0;
2255 
2256     if (!(pipe_fuses == 0 || pipe_fuses == 0x3e)) {
2257         BREAK_TO_DEBUGGER();
2258         dm_error("DC: Unexpected fuse recipe for navi2x !\n");
2259         /* fault to single pipe */
2260         pipe_fuses = 0x3e;
2261     }
2262 
2263     DC_FP_START();
2264 
2265     ctx->dc_bios->regs = &bios_regs;
2266 
2267     pool->base.res_cap = &res_cap_dcn3;
2268 
2269     pool->base.funcs = &dcn30_res_pool_funcs;
2270 
2271     /*************************************************
2272      *  Resource + asic cap harcoding                *
2273      *************************************************/
2274     pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE;
2275     pool->base.pipe_count = pool->base.res_cap->num_timing_generator;
2276     pool->base.mpcc_count = pool->base.res_cap->num_timing_generator;
2277     dc->caps.max_downscale_ratio = 600;
2278     dc->caps.i2c_speed_in_khz = 100;
2279     dc->caps.i2c_speed_in_khz_hdcp = 100; /*1.4 w/a not applied by default*/
2280     dc->caps.max_cursor_size = 256;
2281     dc->caps.min_horizontal_blanking_period = 80;
2282     dc->caps.dmdata_alloc_size = 2048;
2283     dc->caps.mall_size_per_mem_channel = 8;
2284     /* total size = mall per channel * num channels * 1024 * 1024 */
2285     dc->caps.mall_size_total = dc->caps.mall_size_per_mem_channel * dc->ctx->dc_bios->vram_info.num_chans * 1048576;
2286     dc->caps.cursor_cache_size = dc->caps.max_cursor_size * dc->caps.max_cursor_size * 8;
2287 
2288     dc->caps.max_slave_planes = 2;
2289     dc->caps.max_slave_yuv_planes = 2;
2290     dc->caps.max_slave_rgb_planes = 2;
2291     dc->caps.post_blend_color_processing = true;
2292     dc->caps.force_dp_tps4_for_cp2520 = true;
2293     dc->caps.extended_aux_timeout_support = true;
2294     dc->caps.dmcub_support = true;
2295 
2296     /* Color pipeline capabilities */
2297     dc->caps.color.dpp.dcn_arch = 1;
2298     dc->caps.color.dpp.input_lut_shared = 0;
2299     dc->caps.color.dpp.icsc = 1;
2300     dc->caps.color.dpp.dgam_ram = 0; // must use gamma_corr
2301     dc->caps.color.dpp.dgam_rom_caps.srgb = 1;
2302     dc->caps.color.dpp.dgam_rom_caps.bt2020 = 1;
2303     dc->caps.color.dpp.dgam_rom_caps.gamma2_2 = 1;
2304     dc->caps.color.dpp.dgam_rom_caps.pq = 1;
2305     dc->caps.color.dpp.dgam_rom_caps.hlg = 1;
2306     dc->caps.color.dpp.post_csc = 1;
2307     dc->caps.color.dpp.gamma_corr = 1;
2308     dc->caps.color.dpp.dgam_rom_for_yuv = 0;
2309 
2310     dc->caps.color.dpp.hw_3d_lut = 1;
2311     dc->caps.color.dpp.ogam_ram = 1;
2312     // no OGAM ROM on DCN3
2313     dc->caps.color.dpp.ogam_rom_caps.srgb = 0;
2314     dc->caps.color.dpp.ogam_rom_caps.bt2020 = 0;
2315     dc->caps.color.dpp.ogam_rom_caps.gamma2_2 = 0;
2316     dc->caps.color.dpp.ogam_rom_caps.pq = 0;
2317     dc->caps.color.dpp.ogam_rom_caps.hlg = 0;
2318     dc->caps.color.dpp.ocsc = 0;
2319 
2320     dc->caps.color.mpc.gamut_remap = 1;
2321     dc->caps.color.mpc.num_3dluts = pool->base.res_cap->num_mpc_3dlut; //3
2322     dc->caps.color.mpc.ogam_ram = 1;
2323     dc->caps.color.mpc.ogam_rom_caps.srgb = 0;
2324     dc->caps.color.mpc.ogam_rom_caps.bt2020 = 0;
2325     dc->caps.color.mpc.ogam_rom_caps.gamma2_2 = 0;
2326     dc->caps.color.mpc.ogam_rom_caps.pq = 0;
2327     dc->caps.color.mpc.ogam_rom_caps.hlg = 0;
2328     dc->caps.color.mpc.ocsc = 1;
2329 
2330     dc->caps.dp_hdmi21_pcon_support = true;
2331 
2332     /* read VBIOS LTTPR caps */
2333     {
2334         if (ctx->dc_bios->funcs->get_lttpr_caps) {
2335             enum bp_result bp_query_result;
2336             uint8_t is_vbios_lttpr_enable = 0;
2337 
2338             bp_query_result = ctx->dc_bios->funcs->get_lttpr_caps(ctx->dc_bios, &is_vbios_lttpr_enable);
2339             dc->caps.vbios_lttpr_enable = (bp_query_result == BP_RESULT_OK) && !!is_vbios_lttpr_enable;
2340         }
2341 
2342         if (ctx->dc_bios->funcs->get_lttpr_interop) {
2343             enum bp_result bp_query_result;
2344             uint8_t is_vbios_interop_enabled = 0;
2345 
2346             bp_query_result = ctx->dc_bios->funcs->get_lttpr_interop(ctx->dc_bios,
2347                     &is_vbios_interop_enabled);
2348             dc->caps.vbios_lttpr_aware = (bp_query_result == BP_RESULT_OK) && !!is_vbios_interop_enabled;
2349         }
2350     }
2351 
2352     if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV)
2353         dc->debug = debug_defaults_drv;
2354     else if (dc->ctx->dce_environment == DCE_ENV_FPGA_MAXIMUS) {
2355         dc->debug = debug_defaults_diags;
2356     } else
2357         dc->debug = debug_defaults_diags;
2358     // Init the vm_helper
2359     if (dc->vm_helper)
2360         vm_helper_init(dc->vm_helper, 16);
2361 
2362     /*************************************************
2363      *  Create resources                             *
2364      *************************************************/
2365 
2366     /* Clock Sources for Pixel Clock*/
2367     pool->base.clock_sources[DCN30_CLK_SRC_PLL0] =
2368             dcn30_clock_source_create(ctx, ctx->dc_bios,
2369                 CLOCK_SOURCE_COMBO_PHY_PLL0,
2370                 &clk_src_regs[0], false);
2371     pool->base.clock_sources[DCN30_CLK_SRC_PLL1] =
2372             dcn30_clock_source_create(ctx, ctx->dc_bios,
2373                 CLOCK_SOURCE_COMBO_PHY_PLL1,
2374                 &clk_src_regs[1], false);
2375     pool->base.clock_sources[DCN30_CLK_SRC_PLL2] =
2376             dcn30_clock_source_create(ctx, ctx->dc_bios,
2377                 CLOCK_SOURCE_COMBO_PHY_PLL2,
2378                 &clk_src_regs[2], false);
2379     pool->base.clock_sources[DCN30_CLK_SRC_PLL3] =
2380             dcn30_clock_source_create(ctx, ctx->dc_bios,
2381                 CLOCK_SOURCE_COMBO_PHY_PLL3,
2382                 &clk_src_regs[3], false);
2383     pool->base.clock_sources[DCN30_CLK_SRC_PLL4] =
2384             dcn30_clock_source_create(ctx, ctx->dc_bios,
2385                 CLOCK_SOURCE_COMBO_PHY_PLL4,
2386                 &clk_src_regs[4], false);
2387     pool->base.clock_sources[DCN30_CLK_SRC_PLL5] =
2388             dcn30_clock_source_create(ctx, ctx->dc_bios,
2389                 CLOCK_SOURCE_COMBO_PHY_PLL5,
2390                 &clk_src_regs[5], false);
2391 
2392     pool->base.clk_src_count = DCN30_CLK_SRC_TOTAL;
2393 
2394     /* todo: not reuse phy_pll registers */
2395     pool->base.dp_clock_source =
2396             dcn30_clock_source_create(ctx, ctx->dc_bios,
2397                 CLOCK_SOURCE_ID_DP_DTO,
2398                 &clk_src_regs[0], true);
2399 
2400     for (i = 0; i < pool->base.clk_src_count; i++) {
2401         if (pool->base.clock_sources[i] == NULL) {
2402             dm_error("DC: failed to create clock sources!\n");
2403             BREAK_TO_DEBUGGER();
2404             goto create_fail;
2405         }
2406     }
2407 
2408     /* DCCG */
2409     pool->base.dccg = dccg30_create(ctx, &dccg_regs, &dccg_shift, &dccg_mask);
2410     if (pool->base.dccg == NULL) {
2411         dm_error("DC: failed to create dccg!\n");
2412         BREAK_TO_DEBUGGER();
2413         goto create_fail;
2414     }
2415 
2416     /* PP Lib and SMU interfaces */
2417     init_soc_bounding_box(dc, pool);
2418 
2419     num_pipes = dcn3_0_ip.max_num_dpp;
2420 
2421     for (i = 0; i < dcn3_0_ip.max_num_dpp; i++)
2422         if (pipe_fuses & 1 << i)
2423             num_pipes--;
2424 
2425     dcn3_0_ip.max_num_dpp = num_pipes;
2426     dcn3_0_ip.max_num_otg = num_pipes;
2427 
2428     dml_init_instance(&dc->dml, &dcn3_0_soc, &dcn3_0_ip, DML_PROJECT_DCN30);
2429 
2430     /* IRQ */
2431     init_data.ctx = dc->ctx;
2432     pool->base.irqs = dal_irq_service_dcn30_create(&init_data);
2433     if (!pool->base.irqs)
2434         goto create_fail;
2435 
2436     /* HUBBUB */
2437     pool->base.hubbub = dcn30_hubbub_create(ctx);
2438     if (pool->base.hubbub == NULL) {
2439         BREAK_TO_DEBUGGER();
2440         dm_error("DC: failed to create hubbub!\n");
2441         goto create_fail;
2442     }
2443 
2444     /* HUBPs, DPPs, OPPs and TGs */
2445     for (i = 0; i < pool->base.pipe_count; i++) {
2446         pool->base.hubps[i] = dcn30_hubp_create(ctx, i);
2447         if (pool->base.hubps[i] == NULL) {
2448             BREAK_TO_DEBUGGER();
2449             dm_error(
2450                 "DC: failed to create hubps!\n");
2451             goto create_fail;
2452         }
2453 
2454         pool->base.dpps[i] = dcn30_dpp_create(ctx, i);
2455         if (pool->base.dpps[i] == NULL) {
2456             BREAK_TO_DEBUGGER();
2457             dm_error(
2458                 "DC: failed to create dpps!\n");
2459             goto create_fail;
2460         }
2461     }
2462 
2463     for (i = 0; i < pool->base.res_cap->num_opp; i++) {
2464         pool->base.opps[i] = dcn30_opp_create(ctx, i);
2465         if (pool->base.opps[i] == NULL) {
2466             BREAK_TO_DEBUGGER();
2467             dm_error(
2468                 "DC: failed to create output pixel processor!\n");
2469             goto create_fail;
2470         }
2471     }
2472 
2473     for (i = 0; i < pool->base.res_cap->num_timing_generator; i++) {
2474         pool->base.timing_generators[i] = dcn30_timing_generator_create(
2475                 ctx, i);
2476         if (pool->base.timing_generators[i] == NULL) {
2477             BREAK_TO_DEBUGGER();
2478             dm_error("DC: failed to create tg!\n");
2479             goto create_fail;
2480         }
2481     }
2482     pool->base.timing_generator_count = i;
2483     /* PSR */
2484     pool->base.psr = dmub_psr_create(ctx);
2485 
2486     if (pool->base.psr == NULL) {
2487         dm_error("DC: failed to create PSR obj!\n");
2488         BREAK_TO_DEBUGGER();
2489         goto create_fail;
2490     }
2491 
2492     /* ABM */
2493     for (i = 0; i < pool->base.res_cap->num_timing_generator; i++) {
2494         pool->base.multiple_abms[i] = dmub_abm_create(ctx,
2495                 &abm_regs[i],
2496                 &abm_shift,
2497                 &abm_mask);
2498         if (pool->base.multiple_abms[i] == NULL) {
2499             dm_error("DC: failed to create abm for pipe %d!\n", i);
2500             BREAK_TO_DEBUGGER();
2501             goto create_fail;
2502         }
2503     }
2504     /* MPC and DSC */
2505     pool->base.mpc = dcn30_mpc_create(ctx, pool->base.mpcc_count, pool->base.res_cap->num_mpc_3dlut);
2506     if (pool->base.mpc == NULL) {
2507         BREAK_TO_DEBUGGER();
2508         dm_error("DC: failed to create mpc!\n");
2509         goto create_fail;
2510     }
2511 
2512     for (i = 0; i < pool->base.res_cap->num_dsc; i++) {
2513         pool->base.dscs[i] = dcn30_dsc_create(ctx, i);
2514         if (pool->base.dscs[i] == NULL) {
2515             BREAK_TO_DEBUGGER();
2516             dm_error("DC: failed to create display stream compressor %d!\n", i);
2517             goto create_fail;
2518         }
2519     }
2520 
2521     /* DWB and MMHUBBUB */
2522     if (!dcn30_dwbc_create(ctx, &pool->base)) {
2523         BREAK_TO_DEBUGGER();
2524         dm_error("DC: failed to create dwbc!\n");
2525         goto create_fail;
2526     }
2527 
2528     if (!dcn30_mmhubbub_create(ctx, &pool->base)) {
2529         BREAK_TO_DEBUGGER();
2530         dm_error("DC: failed to create mcif_wb!\n");
2531         goto create_fail;
2532     }
2533 
2534     /* AUX and I2C */
2535     for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
2536         pool->base.engines[i] = dcn30_aux_engine_create(ctx, i);
2537         if (pool->base.engines[i] == NULL) {
2538             BREAK_TO_DEBUGGER();
2539             dm_error(
2540                 "DC:failed to create aux engine!!\n");
2541             goto create_fail;
2542         }
2543         pool->base.hw_i2cs[i] = dcn30_i2c_hw_create(ctx, i);
2544         if (pool->base.hw_i2cs[i] == NULL) {
2545             BREAK_TO_DEBUGGER();
2546             dm_error(
2547                 "DC:failed to create hw i2c!!\n");
2548             goto create_fail;
2549         }
2550         pool->base.sw_i2cs[i] = NULL;
2551     }
2552 
2553     /* Audio, Stream Encoders including DIG and virtual, MPC 3D LUTs */
2554     if (!resource_construct(num_virtual_links, dc, &pool->base,
2555             (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment) ?
2556             &res_create_funcs : &res_create_maximus_funcs)))
2557         goto create_fail;
2558 
2559     /* HW Sequencer and Plane caps */
2560     dcn30_hw_sequencer_construct(dc);
2561 
2562     dc->caps.max_planes =  pool->base.pipe_count;
2563 
2564     for (i = 0; i < dc->caps.max_planes; ++i)
2565         dc->caps.planes[i] = plane_cap;
2566 
2567     dc->cap_funcs = cap_funcs;
2568 
2569     if (dc->ctx->dc_bios->fw_info.oem_i2c_present) {
2570         ddc_init_data.ctx = dc->ctx;
2571         ddc_init_data.link = NULL;
2572         ddc_init_data.id.id = dc->ctx->dc_bios->fw_info.oem_i2c_obj_id;
2573         ddc_init_data.id.enum_id = 0;
2574         ddc_init_data.id.type = OBJECT_TYPE_GENERIC;
2575         pool->base.oem_device = dal_ddc_service_create(&ddc_init_data);
2576     } else {
2577         pool->base.oem_device = NULL;
2578     }
2579 
2580     DC_FP_END();
2581 
2582     return true;
2583 
2584 create_fail:
2585 
2586     DC_FP_END();
2587     dcn30_resource_destruct(pool);
2588 
2589     return false;
2590 }
2591 
2592 struct resource_pool *dcn30_create_resource_pool(
2593         const struct dc_init_data *init_data,
2594         struct dc *dc)
2595 {
2596     struct dcn30_resource_pool *pool =
2597         kzalloc(sizeof(struct dcn30_resource_pool), GFP_KERNEL);
2598 
2599     if (!pool)
2600         return NULL;
2601 
2602     if (dcn30_resource_construct(init_data->num_virtual_links, dc, pool))
2603         return &pool->base;
2604 
2605     BREAK_TO_DEBUGGER();
2606     kfree(pool);
2607     return NULL;
2608 }