LCOV - code coverage report
Current view: top level - drivers/gpu/drm/amd/display/dc/dcn32 - dcn32_resource.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 856 0.0 %
Date: 2022-12-09 01:23:36 Functions: 0 39 0.0 %

          Line data    Source code
       1             : // SPDX-License-Identifier: MIT
       2             : /*
       3             :  * Copyright 2022 Advanced Micro Devices, Inc.
       4             :  *
       5             :  * Permission is hereby granted, free of charge, to any person obtaining a
       6             :  * copy of this software and associated documentation files (the "Software"),
       7             :  * to deal in the Software without restriction, including without limitation
       8             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
       9             :  * and/or sell copies of the Software, and to permit persons to whom the
      10             :  * Software is furnished to do so, subject to the following conditions:
      11             :  *
      12             :  * The above copyright notice and this permission notice shall be included in
      13             :  * all copies or substantial portions of the Software.
      14             :  *
      15             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      16             :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      17             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
      18             :  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
      19             :  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
      20             :  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
      21             :  * OTHER DEALINGS IN THE SOFTWARE.
      22             :  *
      23             :  * Authors: AMD
      24             :  *
      25             :  */
      26             : 
      27             : #include "dm_services.h"
      28             : #include "dc.h"
      29             : 
      30             : #include "dcn32_init.h"
      31             : 
      32             : #include "resource.h"
      33             : #include "include/irq_service_interface.h"
      34             : #include "dcn32_resource.h"
      35             : 
      36             : #include "dcn20/dcn20_resource.h"
      37             : #include "dcn30/dcn30_resource.h"
      38             : 
      39             : #include "dcn10/dcn10_ipp.h"
      40             : #include "dcn30/dcn30_hubbub.h"
      41             : #include "dcn31/dcn31_hubbub.h"
      42             : #include "dcn32/dcn32_hubbub.h"
      43             : #include "dcn32/dcn32_mpc.h"
      44             : #include "dcn32_hubp.h"
      45             : #include "irq/dcn32/irq_service_dcn32.h"
      46             : #include "dcn32/dcn32_dpp.h"
      47             : #include "dcn32/dcn32_optc.h"
      48             : #include "dcn20/dcn20_hwseq.h"
      49             : #include "dcn30/dcn30_hwseq.h"
      50             : #include "dce110/dce110_hw_sequencer.h"
      51             : #include "dcn30/dcn30_opp.h"
      52             : #include "dcn20/dcn20_dsc.h"
      53             : #include "dcn30/dcn30_vpg.h"
      54             : #include "dcn30/dcn30_afmt.h"
      55             : #include "dcn30/dcn30_dio_stream_encoder.h"
      56             : #include "dcn32/dcn32_dio_stream_encoder.h"
      57             : #include "dcn31/dcn31_hpo_dp_stream_encoder.h"
      58             : #include "dcn31/dcn31_hpo_dp_link_encoder.h"
      59             : #include "dcn32/dcn32_hpo_dp_link_encoder.h"
      60             : #include "dc_link_dp.h"
      61             : #include "dcn31/dcn31_apg.h"
      62             : #include "dcn31/dcn31_dio_link_encoder.h"
      63             : #include "dcn32/dcn32_dio_link_encoder.h"
      64             : #include "dce/dce_clock_source.h"
      65             : #include "dce/dce_audio.h"
      66             : #include "dce/dce_hwseq.h"
      67             : #include "clk_mgr.h"
      68             : #include "virtual/virtual_stream_encoder.h"
      69             : #include "dml/display_mode_vba.h"
      70             : #include "dcn32/dcn32_dccg.h"
      71             : #include "dcn10/dcn10_resource.h"
      72             : #include "dc_link_ddc.h"
      73             : #include "dcn31/dcn31_panel_cntl.h"
      74             : 
      75             : #include "dcn30/dcn30_dwb.h"
      76             : #include "dcn32/dcn32_mmhubbub.h"
      77             : 
      78             : #include "dcn/dcn_3_2_0_offset.h"
      79             : #include "dcn/dcn_3_2_0_sh_mask.h"
      80             : #include "nbio/nbio_4_3_0_offset.h"
      81             : 
      82             : #include "reg_helper.h"
      83             : #include "dce/dmub_abm.h"
      84             : #include "dce/dmub_psr.h"
      85             : #include "dce/dce_aux.h"
      86             : #include "dce/dce_i2c.h"
      87             : 
      88             : #include "dml/dcn30/display_mode_vba_30.h"
      89             : #include "vm_helper.h"
      90             : #include "dcn20/dcn20_vmid.h"
      91             : #include "dml/dcn32/dcn32_fpu.h"
      92             : 
      93             : #define DCN_BASE__INST0_SEG1                       0x000000C0
      94             : #define DCN_BASE__INST0_SEG2                       0x000034C0
      95             : #define DCN_BASE__INST0_SEG3                       0x00009000
      96             : #define NBIO_BASE__INST0_SEG1                      0x00000014
      97             : 
      98             : #define MAX_INSTANCE                                        6
      99             : #define MAX_SEGMENT                                         6
     100             : 
     101             : struct IP_BASE_INSTANCE {
     102             :         unsigned int segment[MAX_SEGMENT];
     103             : };
     104             : 
     105             : struct IP_BASE {
     106             :         struct IP_BASE_INSTANCE instance[MAX_INSTANCE];
     107             : };
     108             : 
     109             : static const struct IP_BASE DCN_BASE = { { { { 0x00000012, 0x000000C0, 0x000034C0, 0x00009000, 0x02403C00, 0 } },
     110             :                                         { { 0, 0, 0, 0, 0, 0 } },
     111             :                                         { { 0, 0, 0, 0, 0, 0 } },
     112             :                                         { { 0, 0, 0, 0, 0, 0 } },
     113             :                                         { { 0, 0, 0, 0, 0, 0 } },
     114             :                                         { { 0, 0, 0, 0, 0, 0 } } } };
     115             : 
     116             : #define DC_LOGGER_INIT(logger)
     117             : 
     118             : enum dcn32_clk_src_array_id {
     119             :         DCN32_CLK_SRC_PLL0,
     120             :         DCN32_CLK_SRC_PLL1,
     121             :         DCN32_CLK_SRC_PLL2,
     122             :         DCN32_CLK_SRC_PLL3,
     123             :         DCN32_CLK_SRC_PLL4,
     124             :         DCN32_CLK_SRC_TOTAL
     125             : };
     126             : 
     127             : /* begin *********************
     128             :  * macros to expend register list macro defined in HW object header file
     129             :  */
     130             : 
     131             : /* DCN */
     132             : /* TODO awful hack. fixup dcn20_dwb.h */
     133             : #undef BASE_INNER
     134             : #define BASE_INNER(seg) ctx->dcn_reg_offsets[seg]
     135             : 
     136             : #define BASE(seg) BASE_INNER(seg)
     137             : 
     138             : #define SR(reg_name)\
     139             :                 REG_STRUCT.reg_name = BASE(reg ## reg_name ## _BASE_IDX) +  \
     140             :                                         reg ## reg_name
     141             : #define SR_ARR(reg_name, id) \
     142             :         REG_STRUCT[id].reg_name = BASE(reg##reg_name##_BASE_IDX) + reg##reg_name
     143             : 
     144             : #define SR_ARR_INIT(reg_name, id, value) \
     145             :         REG_STRUCT[id].reg_name = value
     146             : 
     147             : #define SRI(reg_name, block, id)\
     148             :         REG_STRUCT.reg_name = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
     149             :                 reg ## block ## id ## _ ## reg_name
     150             : 
     151             : #define SRI_ARR(reg_name, block, id)\
     152             :         REG_STRUCT[id].reg_name = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
     153             :                 reg ## block ## id ## _ ## reg_name
     154             : 
     155             : #define SRI_ARR_ALPHABET(reg_name, block, index, id)\
     156             :         REG_STRUCT[index].reg_name = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
     157             :                 reg ## block ## id ## _ ## reg_name
     158             : 
     159             : #define SRI2(reg_name, block, id)\
     160             :         .reg_name = BASE(reg ## reg_name ## _BASE_IDX) +        \
     161             :                 reg ## reg_name
     162             : #define SRI2_ARR(reg_name, block, id)\
     163             :         REG_STRUCT[id].reg_name = BASE(reg ## reg_name ## _BASE_IDX) +  \
     164             :                 reg ## reg_name
     165             : 
     166             : #define SRIR(var_name, reg_name, block, id)\
     167             :         .var_name = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
     168             :                 reg ## block ## id ## _ ## reg_name
     169             : 
     170             : #define SRII(reg_name, block, id)\
     171             :         REG_STRUCT.reg_name[id] = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
     172             :                                         reg ## block ## id ## _ ## reg_name
     173             : 
     174             : #define SRII_ARR_2(reg_name, block, id, inst)\
     175             :         REG_STRUCT[inst].reg_name[id] = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
     176             :                 reg ## block ## id ## _ ## reg_name
     177             : 
     178             : #define SRII_MPC_RMU(reg_name, block, id)\
     179             :         .RMU##_##reg_name[id] = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
     180             :                 reg ## block ## id ## _ ## reg_name
     181             : 
     182             : #define SRII_DWB(reg_name, temp_name, block, id)\
     183             :         REG_STRUCT.reg_name[id] = BASE(reg ## block ## id ## _ ## temp_name ## _BASE_IDX) + \
     184             :                 reg ## block ## id ## _ ## temp_name
     185             : 
     186             : #define DCCG_SRII(reg_name, block, id)\
     187             :         REG_STRUCT.block ## _ ## reg_name[id] = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
     188             :                 reg ## block ## id ## _ ## reg_name
     189             : 
     190             : #define VUPDATE_SRII(reg_name, block, id)\
     191             :         REG_STRUCT.reg_name[id] = BASE(reg ## reg_name ## _ ## block ## id ## _BASE_IDX) + \
     192             :                 reg ## reg_name ## _ ## block ## id
     193             : 
     194             : /* NBIO */
     195             : #define NBIO_BASE_INNER(seg) ctx->nbio_reg_offsets[seg]
     196             : 
     197             : #define NBIO_BASE(seg) \
     198             :         NBIO_BASE_INNER(seg)
     199             : 
     200             : #define NBIO_SR(reg_name)\
     201             :         REG_STRUCT.reg_name = NBIO_BASE(regBIF_BX0_ ## reg_name ## _BASE_IDX) + \
     202             :                         regBIF_BX0_ ## reg_name
     203             : #define NBIO_SR_ARR(reg_name, id)\
     204             :         REG_STRUCT[id].reg_name = NBIO_BASE(regBIF_BX0_ ## reg_name ## _BASE_IDX) + \
     205             :                 regBIF_BX0_ ## reg_name
     206             : 
     207             : #undef CTX
     208             : #define CTX ctx
     209             : #define REG(reg_name) \
     210             :         (ctx->dcn_reg_offsets[reg ## reg_name ## _BASE_IDX] + reg ## reg_name)
     211             : 
     212             : static struct bios_registers bios_regs;
     213             : 
     214             : #define bios_regs_init() \
     215             :                 ( \
     216             :                 NBIO_SR(BIOS_SCRATCH_3),\
     217             :                 NBIO_SR(BIOS_SCRATCH_6)\
     218             :                 )
     219             : 
     220             : #define clk_src_regs_init(index, pllid)\
     221             :         CS_COMMON_REG_LIST_DCN3_0_RI(index, pllid)
     222             : 
     223             : static struct dce110_clk_src_regs clk_src_regs[5];
     224             : 
     225             : static const struct dce110_clk_src_shift cs_shift = {
     226             :                 CS_COMMON_MASK_SH_LIST_DCN3_2(__SHIFT)
     227             : };
     228             : 
     229             : static const struct dce110_clk_src_mask cs_mask = {
     230             :                 CS_COMMON_MASK_SH_LIST_DCN3_2(_MASK)
     231             : };
     232             : 
     233             : #define abm_regs_init(id)\
     234             :                 ABM_DCN32_REG_LIST_RI(id)
     235             : 
     236             : static struct dce_abm_registers abm_regs[4];
     237             : 
     238             : static const struct dce_abm_shift abm_shift = {
     239             :                 ABM_MASK_SH_LIST_DCN32(__SHIFT)
     240             : };
     241             : 
     242             : static const struct dce_abm_mask abm_mask = {
     243             :                 ABM_MASK_SH_LIST_DCN32(_MASK)
     244             : };
     245             : 
     246             : #define audio_regs_init(id)\
     247             :                 AUD_COMMON_REG_LIST_RI(id)
     248             : 
     249             : static struct dce_audio_registers audio_regs[5];
     250             : 
     251             : #define DCE120_AUD_COMMON_MASK_SH_LIST(mask_sh)\
     252             :                 SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_INDEX, AZALIA_ENDPOINT_REG_INDEX, mask_sh),\
     253             :                 SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_DATA, AZALIA_ENDPOINT_REG_DATA, mask_sh),\
     254             :                 AUD_COMMON_MASK_SH_LIST_BASE(mask_sh)
     255             : 
     256             : static const struct dce_audio_shift audio_shift = {
     257             :                 DCE120_AUD_COMMON_MASK_SH_LIST(__SHIFT)
     258             : };
     259             : 
     260             : static const struct dce_audio_mask audio_mask = {
     261             :                 DCE120_AUD_COMMON_MASK_SH_LIST(_MASK)
     262             : };
     263             : 
     264             : #define vpg_regs_init(id)\
     265             :         VPG_DCN3_REG_LIST_RI(id)
     266             : 
     267             : static struct dcn30_vpg_registers vpg_regs[10];
     268             : 
     269             : static const struct dcn30_vpg_shift vpg_shift = {
     270             :         DCN3_VPG_MASK_SH_LIST(__SHIFT)
     271             : };
     272             : 
     273             : static const struct dcn30_vpg_mask vpg_mask = {
     274             :         DCN3_VPG_MASK_SH_LIST(_MASK)
     275             : };
     276             : 
     277             : #define afmt_regs_init(id)\
     278             :         AFMT_DCN3_REG_LIST_RI(id)
     279             : 
     280             : static struct dcn30_afmt_registers afmt_regs[6];
     281             : 
     282             : static const struct dcn30_afmt_shift afmt_shift = {
     283             :         DCN3_AFMT_MASK_SH_LIST(__SHIFT)
     284             : };
     285             : 
     286             : static const struct dcn30_afmt_mask afmt_mask = {
     287             :         DCN3_AFMT_MASK_SH_LIST(_MASK)
     288             : };
     289             : 
     290             : #define apg_regs_init(id)\
     291             :         APG_DCN31_REG_LIST_RI(id)
     292             : 
     293             : static struct dcn31_apg_registers apg_regs[4];
     294             : 
     295             : static const struct dcn31_apg_shift apg_shift = {
     296             :         DCN31_APG_MASK_SH_LIST(__SHIFT)
     297             : };
     298             : 
     299             : static const struct dcn31_apg_mask apg_mask = {
     300             :                 DCN31_APG_MASK_SH_LIST(_MASK)
     301             : };
     302             : 
     303             : #define stream_enc_regs_init(id)\
     304             :         SE_DCN32_REG_LIST_RI(id)
     305             : 
     306             : static struct dcn10_stream_enc_registers stream_enc_regs[5];
     307             : 
     308             : static const struct dcn10_stream_encoder_shift se_shift = {
     309             :                 SE_COMMON_MASK_SH_LIST_DCN32(__SHIFT)
     310             : };
     311             : 
     312             : static const struct dcn10_stream_encoder_mask se_mask = {
     313             :                 SE_COMMON_MASK_SH_LIST_DCN32(_MASK)
     314             : };
     315             : 
     316             : 
     317             : #define aux_regs_init(id)\
     318             :         DCN2_AUX_REG_LIST_RI(id)
     319             : 
     320             : static struct dcn10_link_enc_aux_registers link_enc_aux_regs[5];
     321             : 
     322             : #define hpd_regs_init(id)\
     323             :         HPD_REG_LIST_RI(id)
     324             : 
     325             : static struct dcn10_link_enc_hpd_registers link_enc_hpd_regs[5];
     326             : 
     327             : #define link_regs_init(id, phyid)\
     328             :         ( \
     329             :         LE_DCN31_REG_LIST_RI(id), \
     330             :         UNIPHY_DCN2_REG_LIST_RI(id, phyid)\
     331             :         )
     332             :         /*DPCS_DCN31_REG_LIST(id),*/ \
     333             : 
     334             : static struct dcn10_link_enc_registers link_enc_regs[5];
     335             : 
     336             : static const struct dcn10_link_enc_shift le_shift = {
     337             :         LINK_ENCODER_MASK_SH_LIST_DCN31(__SHIFT), \
     338             :         //DPCS_DCN31_MASK_SH_LIST(__SHIFT)
     339             : };
     340             : 
     341             : static const struct dcn10_link_enc_mask le_mask = {
     342             :         LINK_ENCODER_MASK_SH_LIST_DCN31(_MASK), \
     343             : 
     344             :         //DPCS_DCN31_MASK_SH_LIST(_MASK)
     345             : };
     346             : 
     347             : #define hpo_dp_stream_encoder_reg_init(id)\
     348             :         DCN3_1_HPO_DP_STREAM_ENC_REG_LIST_RI(id)
     349             : 
     350             : static struct dcn31_hpo_dp_stream_encoder_registers hpo_dp_stream_enc_regs[4];
     351             : 
     352             : static const struct dcn31_hpo_dp_stream_encoder_shift hpo_dp_se_shift = {
     353             :         DCN3_1_HPO_DP_STREAM_ENC_MASK_SH_LIST(__SHIFT)
     354             : };
     355             : 
     356             : static const struct dcn31_hpo_dp_stream_encoder_mask hpo_dp_se_mask = {
     357             :         DCN3_1_HPO_DP_STREAM_ENC_MASK_SH_LIST(_MASK)
     358             : };
     359             : 
     360             : 
     361             : #define hpo_dp_link_encoder_reg_init(id)\
     362             :         DCN3_1_HPO_DP_LINK_ENC_REG_LIST_RI(id)
     363             :         /*DCN3_1_RDPCSTX_REG_LIST(0),*/
     364             :         /*DCN3_1_RDPCSTX_REG_LIST(1),*/
     365             :         /*DCN3_1_RDPCSTX_REG_LIST(2),*/
     366             :         /*DCN3_1_RDPCSTX_REG_LIST(3),*/
     367             : 
     368             : static struct dcn31_hpo_dp_link_encoder_registers hpo_dp_link_enc_regs[2];
     369             : 
     370             : static const struct dcn31_hpo_dp_link_encoder_shift hpo_dp_le_shift = {
     371             :         DCN3_2_HPO_DP_LINK_ENC_MASK_SH_LIST(__SHIFT)
     372             : };
     373             : 
     374             : static const struct dcn31_hpo_dp_link_encoder_mask hpo_dp_le_mask = {
     375             :         DCN3_2_HPO_DP_LINK_ENC_MASK_SH_LIST(_MASK)
     376             : };
     377             : 
     378             : #define dpp_regs_init(id)\
     379             :         DPP_REG_LIST_DCN30_COMMON_RI(id)
     380             : 
     381             : static struct dcn3_dpp_registers dpp_regs[4];
     382             : 
     383             : static const struct dcn3_dpp_shift tf_shift = {
     384             :                 DPP_REG_LIST_SH_MASK_DCN30_COMMON(__SHIFT)
     385             : };
     386             : 
     387             : static const struct dcn3_dpp_mask tf_mask = {
     388             :                 DPP_REG_LIST_SH_MASK_DCN30_COMMON(_MASK)
     389             : };
     390             : 
     391             : 
     392             : #define opp_regs_init(id)\
     393             :         OPP_REG_LIST_DCN30_RI(id)
     394             : 
     395             : static struct dcn20_opp_registers opp_regs[4];
     396             : 
     397             : static const struct dcn20_opp_shift opp_shift = {
     398             :         OPP_MASK_SH_LIST_DCN20(__SHIFT)
     399             : };
     400             : 
     401             : static const struct dcn20_opp_mask opp_mask = {
     402             :         OPP_MASK_SH_LIST_DCN20(_MASK)
     403             : };
     404             : 
     405             : #define aux_engine_regs_init(id)\
     406             :         ( \
     407             :         AUX_COMMON_REG_LIST0_RI(id), \
     408             :         SR_ARR_INIT(AUXN_IMPCAL, id, 0), \
     409             :         SR_ARR_INIT(AUXP_IMPCAL, id, 0), \
     410             :         SR_ARR_INIT(AUX_RESET_MASK, id, DP_AUX0_AUX_CONTROL__AUX_RESET_MASK), \
     411             :         SR_ARR_INIT(AUX_RESET_MASK, id, DP_AUX0_AUX_CONTROL__AUX_RESET_MASK)\
     412             :         )
     413             : 
     414             : static struct dce110_aux_registers aux_engine_regs[5];
     415             : 
     416             : static const struct dce110_aux_registers_shift aux_shift = {
     417             :         DCN_AUX_MASK_SH_LIST(__SHIFT)
     418             : };
     419             : 
     420             : static const struct dce110_aux_registers_mask aux_mask = {
     421             :         DCN_AUX_MASK_SH_LIST(_MASK)
     422             : };
     423             : 
     424             : #define dwbc_regs_dcn3_init(id)\
     425             :         DWBC_COMMON_REG_LIST_DCN30_RI(id)
     426             : 
     427             : static struct dcn30_dwbc_registers dwbc30_regs[1];
     428             : 
     429             : static const struct dcn30_dwbc_shift dwbc30_shift = {
     430             :         DWBC_COMMON_MASK_SH_LIST_DCN30(__SHIFT)
     431             : };
     432             : 
     433             : static const struct dcn30_dwbc_mask dwbc30_mask = {
     434             :         DWBC_COMMON_MASK_SH_LIST_DCN30(_MASK)
     435             : };
     436             : 
     437             : #define mcif_wb_regs_dcn3_init(id)\
     438             :         MCIF_WB_COMMON_REG_LIST_DCN32_RI(id)
     439             : 
     440             : static struct dcn30_mmhubbub_registers mcif_wb30_regs[1];
     441             : 
     442             : static const struct dcn30_mmhubbub_shift mcif_wb30_shift = {
     443             :         MCIF_WB_COMMON_MASK_SH_LIST_DCN32(__SHIFT)
     444             : };
     445             : 
     446             : static const struct dcn30_mmhubbub_mask mcif_wb30_mask = {
     447             :         MCIF_WB_COMMON_MASK_SH_LIST_DCN32(_MASK)
     448             : };
     449             : 
     450             : #define dsc_regsDCN20_init(id)\
     451             :         DSC_REG_LIST_DCN20_RI(id)
     452             : 
     453             : static struct dcn20_dsc_registers dsc_regs[4];
     454             : 
     455             : static const struct dcn20_dsc_shift dsc_shift = {
     456             :         DSC_REG_LIST_SH_MASK_DCN20(__SHIFT)
     457             : };
     458             : 
     459             : static const struct dcn20_dsc_mask dsc_mask = {
     460             :         DSC_REG_LIST_SH_MASK_DCN20(_MASK)
     461             : };
     462             : 
     463             : static struct dcn30_mpc_registers mpc_regs;
     464             : #define dcn_mpc_regs_init()\
     465             :                 ( \
     466             :                 MPC_REG_LIST_DCN3_0_RI(0),\
     467             :                 MPC_REG_LIST_DCN3_0_RI(1),\
     468             :                 MPC_REG_LIST_DCN3_0_RI(2),\
     469             :                 MPC_REG_LIST_DCN3_0_RI(3),\
     470             :                 MPC_OUT_MUX_REG_LIST_DCN3_0_RI(0),\
     471             :                 MPC_OUT_MUX_REG_LIST_DCN3_0_RI(1),\
     472             :                 MPC_OUT_MUX_REG_LIST_DCN3_0_RI(2),\
     473             :                 MPC_OUT_MUX_REG_LIST_DCN3_0_RI(3),\
     474             :                 MPC_MCM_REG_LIST_DCN32_RI(0),\
     475             :                 MPC_MCM_REG_LIST_DCN32_RI(1),\
     476             :                 MPC_MCM_REG_LIST_DCN32_RI(2),\
     477             :                 MPC_MCM_REG_LIST_DCN32_RI(3),\
     478             :                 MPC_DWB_MUX_REG_LIST_DCN3_0_RI(0)\
     479             :                 )
     480             : 
     481             : static const struct dcn30_mpc_shift mpc_shift = {
     482             :         MPC_COMMON_MASK_SH_LIST_DCN32(__SHIFT)
     483             : };
     484             : 
     485             : static const struct dcn30_mpc_mask mpc_mask = {
     486             :         MPC_COMMON_MASK_SH_LIST_DCN32(_MASK)
     487             : };
     488             : 
     489             : #define optc_regs_init(id)\
     490             :         OPTC_COMMON_REG_LIST_DCN3_2_RI(id)
     491             : 
     492             : static struct dcn_optc_registers optc_regs[4];
     493             : 
     494             : static const struct dcn_optc_shift optc_shift = {
     495             :         OPTC_COMMON_MASK_SH_LIST_DCN3_2(__SHIFT)
     496             : };
     497             : 
     498             : static const struct dcn_optc_mask optc_mask = {
     499             :         OPTC_COMMON_MASK_SH_LIST_DCN3_2(_MASK)
     500             : };
     501             : 
     502             : #define hubp_regs_init(id)\
     503             :         HUBP_REG_LIST_DCN32_RI(id)
     504             : 
     505             : static struct dcn_hubp2_registers hubp_regs[4];
     506             : 
     507             : 
     508             : static const struct dcn_hubp2_shift hubp_shift = {
     509             :                 HUBP_MASK_SH_LIST_DCN32(__SHIFT)
     510             : };
     511             : 
     512             : static const struct dcn_hubp2_mask hubp_mask = {
     513             :                 HUBP_MASK_SH_LIST_DCN32(_MASK)
     514             : };
     515             : 
     516             : static struct dcn_hubbub_registers hubbub_reg;
     517             : #define hubbub_reg_init()\
     518             :                 HUBBUB_REG_LIST_DCN32_RI(0)
     519             : 
     520             : static const struct dcn_hubbub_shift hubbub_shift = {
     521             :                 HUBBUB_MASK_SH_LIST_DCN32(__SHIFT)
     522             : };
     523             : 
     524             : static const struct dcn_hubbub_mask hubbub_mask = {
     525             :                 HUBBUB_MASK_SH_LIST_DCN32(_MASK)
     526             : };
     527             : 
     528             : static struct dccg_registers dccg_regs;
     529             : 
     530             : #define dccg_regs_init()\
     531             :         DCCG_REG_LIST_DCN32_RI()
     532             : 
     533             : static const struct dccg_shift dccg_shift = {
     534             :                 DCCG_MASK_SH_LIST_DCN32(__SHIFT)
     535             : };
     536             : 
     537             : static const struct dccg_mask dccg_mask = {
     538             :                 DCCG_MASK_SH_LIST_DCN32(_MASK)
     539             : };
     540             : 
     541             : 
     542             : #define SRII2(reg_name_pre, reg_name_post, id)\
     543             :         .reg_name_pre ## _ ##  reg_name_post[id] = BASE(reg ## reg_name_pre \
     544             :                         ## id ## _ ## reg_name_post ## _BASE_IDX) + \
     545             :                         reg ## reg_name_pre ## id ## _ ## reg_name_post
     546             : 
     547             : 
     548             : #define HWSEQ_DCN32_REG_LIST()\
     549             :         SR(DCHUBBUB_GLOBAL_TIMER_CNTL), \
     550             :         SR(DIO_MEM_PWR_CTRL), \
     551             :         SR(ODM_MEM_PWR_CTRL3), \
     552             :         SR(MMHUBBUB_MEM_PWR_CNTL), \
     553             :         SR(DCCG_GATE_DISABLE_CNTL), \
     554             :         SR(DCCG_GATE_DISABLE_CNTL2), \
     555             :         SR(DCFCLK_CNTL),\
     556             :         SR(DC_MEM_GLOBAL_PWR_REQ_CNTL), \
     557             :         SRII(PIXEL_RATE_CNTL, OTG, 0), \
     558             :         SRII(PIXEL_RATE_CNTL, OTG, 1),\
     559             :         SRII(PIXEL_RATE_CNTL, OTG, 2),\
     560             :         SRII(PIXEL_RATE_CNTL, OTG, 3),\
     561             :         SRII(PHYPLL_PIXEL_RATE_CNTL, OTG, 0),\
     562             :         SRII(PHYPLL_PIXEL_RATE_CNTL, OTG, 1),\
     563             :         SRII(PHYPLL_PIXEL_RATE_CNTL, OTG, 2),\
     564             :         SRII(PHYPLL_PIXEL_RATE_CNTL, OTG, 3),\
     565             :         SR(MICROSECOND_TIME_BASE_DIV), \
     566             :         SR(MILLISECOND_TIME_BASE_DIV), \
     567             :         SR(DISPCLK_FREQ_CHANGE_CNTL), \
     568             :         SR(RBBMIF_TIMEOUT_DIS), \
     569             :         SR(RBBMIF_TIMEOUT_DIS_2), \
     570             :         SR(DCHUBBUB_CRC_CTRL), \
     571             :         SR(DPP_TOP0_DPP_CRC_CTRL), \
     572             :         SR(DPP_TOP0_DPP_CRC_VAL_B_A), \
     573             :         SR(DPP_TOP0_DPP_CRC_VAL_R_G), \
     574             :         SR(MPC_CRC_CTRL), \
     575             :         SR(MPC_CRC_RESULT_GB), \
     576             :         SR(MPC_CRC_RESULT_C), \
     577             :         SR(MPC_CRC_RESULT_AR), \
     578             :         SR(DOMAIN0_PG_CONFIG), \
     579             :         SR(DOMAIN1_PG_CONFIG), \
     580             :         SR(DOMAIN2_PG_CONFIG), \
     581             :         SR(DOMAIN3_PG_CONFIG), \
     582             :         SR(DOMAIN16_PG_CONFIG), \
     583             :         SR(DOMAIN17_PG_CONFIG), \
     584             :         SR(DOMAIN18_PG_CONFIG), \
     585             :         SR(DOMAIN19_PG_CONFIG), \
     586             :         SR(DOMAIN0_PG_STATUS), \
     587             :         SR(DOMAIN1_PG_STATUS), \
     588             :         SR(DOMAIN2_PG_STATUS), \
     589             :         SR(DOMAIN3_PG_STATUS), \
     590             :         SR(DOMAIN16_PG_STATUS), \
     591             :         SR(DOMAIN17_PG_STATUS), \
     592             :         SR(DOMAIN18_PG_STATUS), \
     593             :         SR(DOMAIN19_PG_STATUS), \
     594             :         SR(D1VGA_CONTROL), \
     595             :         SR(D2VGA_CONTROL), \
     596             :         SR(D3VGA_CONTROL), \
     597             :         SR(D4VGA_CONTROL), \
     598             :         SR(D5VGA_CONTROL), \
     599             :         SR(D6VGA_CONTROL), \
     600             :         SR(DC_IP_REQUEST_CNTL), \
     601             :         SR(AZALIA_AUDIO_DTO), \
     602             :         SR(AZALIA_CONTROLLER_CLOCK_GATING)
     603             : 
     604             : static struct dce_hwseq_registers hwseq_reg;
     605             : 
     606             : #define hwseq_reg_init()\
     607             :         HWSEQ_DCN32_REG_LIST()
     608             : 
     609             : #define HWSEQ_DCN32_MASK_SH_LIST(mask_sh)\
     610             :         HWSEQ_DCN_MASK_SH_LIST(mask_sh), \
     611             :         HWS_SF(, DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, mask_sh), \
     612             :         HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \
     613             :         HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \
     614             :         HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \
     615             :         HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \
     616             :         HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \
     617             :         HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \
     618             :         HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \
     619             :         HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \
     620             :         HWS_SF(, DOMAIN16_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \
     621             :         HWS_SF(, DOMAIN16_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \
     622             :         HWS_SF(, DOMAIN17_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \
     623             :         HWS_SF(, DOMAIN17_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \
     624             :         HWS_SF(, DOMAIN18_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \
     625             :         HWS_SF(, DOMAIN18_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \
     626             :         HWS_SF(, DOMAIN19_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \
     627             :         HWS_SF(, DOMAIN19_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \
     628             :         HWS_SF(, DOMAIN0_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \
     629             :         HWS_SF(, DOMAIN1_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \
     630             :         HWS_SF(, DOMAIN2_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \
     631             :         HWS_SF(, DOMAIN3_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \
     632             :         HWS_SF(, DOMAIN16_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \
     633             :         HWS_SF(, DOMAIN17_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \
     634             :         HWS_SF(, DOMAIN18_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \
     635             :         HWS_SF(, DOMAIN19_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \
     636             :         HWS_SF(, DC_IP_REQUEST_CNTL, IP_REQUEST_EN, mask_sh), \
     637             :         HWS_SF(, AZALIA_AUDIO_DTO, AZALIA_AUDIO_DTO_MODULE, mask_sh), \
     638             :         HWS_SF(, HPO_TOP_CLOCK_CONTROL, HPO_HDMISTREAMCLK_G_GATE_DIS, mask_sh), \
     639             :         HWS_SF(, ODM_MEM_PWR_CTRL3, ODM_MEM_UNASSIGNED_PWR_MODE, mask_sh), \
     640             :         HWS_SF(, ODM_MEM_PWR_CTRL3, ODM_MEM_VBLANK_PWR_MODE, mask_sh), \
     641             :         HWS_SF(, MMHUBBUB_MEM_PWR_CNTL, VGA_MEM_PWR_FORCE, mask_sh)
     642             : 
     643             : static const struct dce_hwseq_shift hwseq_shift = {
     644             :                 HWSEQ_DCN32_MASK_SH_LIST(__SHIFT)
     645             : };
     646             : 
     647             : static const struct dce_hwseq_mask hwseq_mask = {
     648             :                 HWSEQ_DCN32_MASK_SH_LIST(_MASK)
     649             : };
     650             : #define vmid_regs_init(id)\
     651             :                 DCN20_VMID_REG_LIST_RI(id)
     652             : 
     653             : static struct dcn_vmid_registers vmid_regs[16];
     654             : 
     655             : static const struct dcn20_vmid_shift vmid_shifts = {
     656             :                 DCN20_VMID_MASK_SH_LIST(__SHIFT)
     657             : };
     658             : 
     659             : static const struct dcn20_vmid_mask vmid_masks = {
     660             :                 DCN20_VMID_MASK_SH_LIST(_MASK)
     661             : };
     662             : 
     663             : static const struct resource_caps res_cap_dcn32 = {
     664             :         .num_timing_generator = 4,
     665             :         .num_opp = 4,
     666             :         .num_video_plane = 4,
     667             :         .num_audio = 5,
     668             :         .num_stream_encoder = 5,
     669             :         .num_hpo_dp_stream_encoder = 4,
     670             :         .num_hpo_dp_link_encoder = 2,
     671             :         .num_pll = 5,
     672             :         .num_dwb = 1,
     673             :         .num_ddc = 5,
     674             :         .num_vmid = 16,
     675             :         .num_mpc_3dlut = 4,
     676             :         .num_dsc = 4,
     677             : };
     678             : 
     679             : static const struct dc_plane_cap plane_cap = {
     680             :         .type = DC_PLANE_TYPE_DCN_UNIVERSAL,
     681             :         .blends_with_above = true,
     682             :         .blends_with_below = true,
     683             :         .per_pixel_alpha = true,
     684             : 
     685             :         .pixel_format_support = {
     686             :                         .argb8888 = true,
     687             :                         .nv12 = true,
     688             :                         .fp16 = true,
     689             :                         .p010 = true,
     690             :                         .ayuv = false,
     691             :         },
     692             : 
     693             :         .max_upscale_factor = {
     694             :                         .argb8888 = 16000,
     695             :                         .nv12 = 16000,
     696             :                         .fp16 = 16000
     697             :         },
     698             : 
     699             :         // 6:1 downscaling ratio: 1000/6 = 166.666
     700             :         .max_downscale_factor = {
     701             :                         .argb8888 = 167,
     702             :                         .nv12 = 167,
     703             :                         .fp16 = 167
     704             :         },
     705             :         64,
     706             :         64
     707             : };
     708             : 
     709             : static const struct dc_debug_options debug_defaults_drv = {
     710             :         .disable_dmcu = true,
     711             :         .force_abm_enable = false,
     712             :         .timing_trace = false,
     713             :         .clock_trace = true,
     714             :         .disable_pplib_clock_request = false,
     715             :         .pipe_split_policy = MPC_SPLIT_AVOID, // Due to CRB, no need to MPC split anymore
     716             :         .force_single_disp_pipe_split = false,
     717             :         .disable_dcc = DCC_ENABLE,
     718             :         .vsr_support = true,
     719             :         .performance_trace = false,
     720             :         .max_downscale_src_width = 7680,/*upto 8K*/
     721             :         .disable_pplib_wm_range = false,
     722             :         .scl_reset_length10 = true,
     723             :         .sanity_checks = false,
     724             :         .underflow_assert_delay_us = 0xFFFFFFFF,
     725             :         .dwb_fi_phase = -1, // -1 = disable,
     726             :         .dmub_command_table = true,
     727             :         .enable_mem_low_power = {
     728             :                 .bits = {
     729             :                         .vga = false,
     730             :                         .i2c = false,
     731             :                         .dmcu = false, // This is previously known to cause hang on S3 cycles if enabled
     732             :                         .dscl = false,
     733             :                         .cm = false,
     734             :                         .mpc = false,
     735             :                         .optc = true,
     736             :                 }
     737             :         },
     738             :         .use_max_lb = true,
     739             :         .force_disable_subvp = false,
     740             :         .exit_idle_opt_for_cursor_updates = true,
     741             :         .enable_single_display_2to1_odm_policy = true,
     742             :         .enable_dp_dig_pixel_rate_div_policy = 1,
     743             : };
     744             : 
     745             : static const struct dc_debug_options debug_defaults_diags = {
     746             :         .disable_dmcu = true,
     747             :         .force_abm_enable = false,
     748             :         .timing_trace = true,
     749             :         .clock_trace = true,
     750             :         .disable_dpp_power_gate = true,
     751             :         .disable_hubp_power_gate = true,
     752             :         .disable_dsc_power_gate = true,
     753             :         .disable_clock_gate = true,
     754             :         .disable_pplib_clock_request = true,
     755             :         .disable_pplib_wm_range = true,
     756             :         .disable_stutter = false,
     757             :         .scl_reset_length10 = true,
     758             :         .dwb_fi_phase = -1, // -1 = disable
     759             :         .dmub_command_table = true,
     760             :         .enable_tri_buf = true,
     761             :         .use_max_lb = true,
     762             :         .force_disable_subvp = true
     763             : };
     764             : 
     765           0 : static struct dce_aux *dcn32_aux_engine_create(
     766             :         struct dc_context *ctx,
     767             :         uint32_t inst)
     768             : {
     769           0 :         struct aux_engine_dce110 *aux_engine =
     770             :                 kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL);
     771             : 
     772           0 :         if (!aux_engine)
     773             :                 return NULL;
     774             : 
     775             : #undef REG_STRUCT
     776             : #define REG_STRUCT aux_engine_regs
     777           0 :         aux_engine_regs_init(0),
     778           0 :         aux_engine_regs_init(1),
     779           0 :         aux_engine_regs_init(2),
     780           0 :         aux_engine_regs_init(3),
     781           0 :         aux_engine_regs_init(4);
     782             : 
     783           0 :         dce110_aux_engine_construct(aux_engine, ctx, inst,
     784             :                                     SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD,
     785           0 :                                     &aux_engine_regs[inst],
     786             :                                         &aux_mask,
     787             :                                         &aux_shift,
     788           0 :                                         ctx->dc->caps.extended_aux_timeout_support);
     789             : 
     790           0 :         return &aux_engine->base;
     791             : }
     792             : #define i2c_inst_regs_init(id)\
     793             :         I2C_HW_ENGINE_COMMON_REG_LIST_DCN30_RI(id)
     794             : 
     795             : static struct dce_i2c_registers i2c_hw_regs[6];
     796             : 
     797             : static const struct dce_i2c_shift i2c_shifts = {
     798             :                 I2C_COMMON_MASK_SH_LIST_DCN30(__SHIFT)
     799             : };
     800             : 
     801             : static const struct dce_i2c_mask i2c_masks = {
     802             :                 I2C_COMMON_MASK_SH_LIST_DCN30(_MASK)
     803             : };
     804             : 
     805           0 : static struct dce_i2c_hw *dcn32_i2c_hw_create(
     806             :         struct dc_context *ctx,
     807             :         uint32_t inst)
     808             : {
     809           0 :         struct dce_i2c_hw *dce_i2c_hw =
     810             :                 kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL);
     811             : 
     812           0 :         if (!dce_i2c_hw)
     813             :                 return NULL;
     814             : 
     815             : #undef REG_STRUCT
     816             : #define REG_STRUCT i2c_hw_regs
     817           0 :         i2c_inst_regs_init(1),
     818           0 :         i2c_inst_regs_init(2),
     819           0 :         i2c_inst_regs_init(3),
     820           0 :         i2c_inst_regs_init(4),
     821           0 :         i2c_inst_regs_init(5);
     822             : 
     823           0 :         dcn2_i2c_hw_construct(dce_i2c_hw, ctx, inst,
     824           0 :                                     &i2c_hw_regs[inst], &i2c_shifts, &i2c_masks);
     825             : 
     826           0 :         return dce_i2c_hw;
     827             : }
     828             : 
     829           0 : static struct clock_source *dcn32_clock_source_create(
     830             :                 struct dc_context *ctx,
     831             :                 struct dc_bios *bios,
     832             :                 enum clock_source_id id,
     833             :                 const struct dce110_clk_src_regs *regs,
     834             :                 bool dp_clk_src)
     835             : {
     836           0 :         struct dce110_clk_src *clk_src =
     837             :                 kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL);
     838             : 
     839           0 :         if (!clk_src)
     840             :                 return NULL;
     841             : 
     842           0 :         if (dcn31_clk_src_construct(clk_src, ctx, bios, id,
     843             :                         regs, &cs_shift, &cs_mask)) {
     844           0 :                 clk_src->base.dp_clk_src = dp_clk_src;
     845           0 :                 return &clk_src->base;
     846             :         }
     847             : 
     848           0 :         BREAK_TO_DEBUGGER();
     849           0 :         return NULL;
     850             : }
     851             : 
     852           0 : static struct hubbub *dcn32_hubbub_create(struct dc_context *ctx)
     853             : {
     854             :         int i;
     855             : 
     856           0 :         struct dcn20_hubbub *hubbub2 = kzalloc(sizeof(struct dcn20_hubbub),
     857             :                                           GFP_KERNEL);
     858             : 
     859           0 :         if (!hubbub2)
     860             :                 return NULL;
     861             : 
     862             : #undef REG_STRUCT
     863             : #define REG_STRUCT hubbub_reg
     864           0 :         hubbub_reg_init();
     865             : 
     866             : #undef REG_STRUCT
     867             : #define REG_STRUCT vmid_regs
     868           0 :         vmid_regs_init(0),
     869           0 :         vmid_regs_init(1),
     870           0 :         vmid_regs_init(2),
     871           0 :         vmid_regs_init(3),
     872           0 :         vmid_regs_init(4),
     873           0 :         vmid_regs_init(5),
     874           0 :         vmid_regs_init(6),
     875           0 :         vmid_regs_init(7),
     876           0 :         vmid_regs_init(8),
     877           0 :         vmid_regs_init(9),
     878           0 :         vmid_regs_init(10),
     879           0 :         vmid_regs_init(11),
     880           0 :         vmid_regs_init(12),
     881           0 :         vmid_regs_init(13),
     882           0 :         vmid_regs_init(14),
     883           0 :         vmid_regs_init(15);
     884             : 
     885           0 :         hubbub32_construct(hubbub2, ctx,
     886             :                         &hubbub_reg,
     887             :                         &hubbub_shift,
     888             :                         &hubbub_mask,
     889           0 :                         ctx->dc->dml.ip.det_buffer_size_kbytes,
     890           0 :                         ctx->dc->dml.ip.pixel_chunk_size_kbytes,
     891           0 :                         ctx->dc->dml.ip.config_return_buffer_size_in_kbytes);
     892             : 
     893             : 
     894           0 :         for (i = 0; i < res_cap_dcn32.num_vmid; i++) {
     895           0 :                 struct dcn20_vmid *vmid = &hubbub2->vmid[i];
     896             : 
     897           0 :                 vmid->ctx = ctx;
     898             : 
     899           0 :                 vmid->regs = &vmid_regs[i];
     900           0 :                 vmid->shifts = &vmid_shifts;
     901           0 :                 vmid->masks = &vmid_masks;
     902             :         }
     903             : 
     904           0 :         return &hubbub2->base;
     905             : }
     906             : 
     907           0 : static struct hubp *dcn32_hubp_create(
     908             :         struct dc_context *ctx,
     909             :         uint32_t inst)
     910             : {
     911           0 :         struct dcn20_hubp *hubp2 =
     912             :                 kzalloc(sizeof(struct dcn20_hubp), GFP_KERNEL);
     913             : 
     914           0 :         if (!hubp2)
     915             :                 return NULL;
     916             : 
     917             : #undef REG_STRUCT
     918             : #define REG_STRUCT hubp_regs
     919           0 :                 hubp_regs_init(0),
     920           0 :                 hubp_regs_init(1),
     921           0 :                 hubp_regs_init(2),
     922           0 :                 hubp_regs_init(3);
     923             : 
     924           0 :         if (hubp32_construct(hubp2, ctx, inst,
     925           0 :                         &hubp_regs[inst], &hubp_shift, &hubp_mask))
     926           0 :                 return &hubp2->base;
     927             : 
     928           0 :         BREAK_TO_DEBUGGER();
     929           0 :         kfree(hubp2);
     930           0 :         return NULL;
     931             : }
     932             : 
     933             : static void dcn32_dpp_destroy(struct dpp **dpp)
     934             : {
     935           0 :         kfree(TO_DCN30_DPP(*dpp));
     936           0 :         *dpp = NULL;
     937             : }
     938             : 
     939           0 : static struct dpp *dcn32_dpp_create(
     940             :         struct dc_context *ctx,
     941             :         uint32_t inst)
     942             : {
     943           0 :         struct dcn3_dpp *dpp3 =
     944             :                 kzalloc(sizeof(struct dcn3_dpp), GFP_KERNEL);
     945             : 
     946           0 :         if (!dpp3)
     947             :                 return NULL;
     948             : 
     949             : #undef REG_STRUCT
     950             : #define REG_STRUCT dpp_regs
     951           0 :         dpp_regs_init(0),
     952           0 :         dpp_regs_init(1),
     953           0 :         dpp_regs_init(2),
     954           0 :         dpp_regs_init(3);
     955             : 
     956           0 :         if (dpp32_construct(dpp3, ctx, inst,
     957           0 :                         &dpp_regs[inst], &tf_shift, &tf_mask))
     958           0 :                 return &dpp3->base;
     959             : 
     960           0 :         BREAK_TO_DEBUGGER();
     961           0 :         kfree(dpp3);
     962           0 :         return NULL;
     963             : }
     964             : 
     965           0 : static struct mpc *dcn32_mpc_create(
     966             :                 struct dc_context *ctx,
     967             :                 int num_mpcc,
     968             :                 int num_rmu)
     969             : {
     970           0 :         struct dcn30_mpc *mpc30 = kzalloc(sizeof(struct dcn30_mpc),
     971             :                                           GFP_KERNEL);
     972             : 
     973           0 :         if (!mpc30)
     974             :                 return NULL;
     975             : 
     976             : #undef REG_STRUCT
     977             : #define REG_STRUCT mpc_regs
     978           0 :         dcn_mpc_regs_init();
     979             : 
     980           0 :         dcn32_mpc_construct(mpc30, ctx,
     981             :                         &mpc_regs,
     982             :                         &mpc_shift,
     983             :                         &mpc_mask,
     984             :                         num_mpcc,
     985             :                         num_rmu);
     986             : 
     987           0 :         return &mpc30->base;
     988             : }
     989             : 
     990           0 : static struct output_pixel_processor *dcn32_opp_create(
     991             :         struct dc_context *ctx, uint32_t inst)
     992             : {
     993           0 :         struct dcn20_opp *opp2 =
     994             :                 kzalloc(sizeof(struct dcn20_opp), GFP_KERNEL);
     995             : 
     996           0 :         if (!opp2) {
     997           0 :                 BREAK_TO_DEBUGGER();
     998           0 :                 return NULL;
     999             :         }
    1000             : 
    1001             : #undef REG_STRUCT
    1002             : #define REG_STRUCT opp_regs
    1003           0 :         opp_regs_init(0),
    1004           0 :         opp_regs_init(1),
    1005           0 :         opp_regs_init(2),
    1006           0 :         opp_regs_init(3);
    1007             : 
    1008           0 :         dcn20_opp_construct(opp2, ctx, inst,
    1009           0 :                         &opp_regs[inst], &opp_shift, &opp_mask);
    1010           0 :         return &opp2->base;
    1011             : }
    1012             : 
    1013             : 
    1014           0 : static struct timing_generator *dcn32_timing_generator_create(
    1015             :                 struct dc_context *ctx,
    1016             :                 uint32_t instance)
    1017             : {
    1018           0 :         struct optc *tgn10 =
    1019             :                 kzalloc(sizeof(struct optc), GFP_KERNEL);
    1020             : 
    1021           0 :         if (!tgn10)
    1022             :                 return NULL;
    1023             : 
    1024             : #undef REG_STRUCT
    1025             : #define REG_STRUCT optc_regs
    1026           0 :         optc_regs_init(0),
    1027           0 :         optc_regs_init(1),
    1028           0 :         optc_regs_init(2),
    1029           0 :         optc_regs_init(3);
    1030             : 
    1031           0 :         tgn10->base.inst = instance;
    1032           0 :         tgn10->base.ctx = ctx;
    1033             : 
    1034           0 :         tgn10->tg_regs = &optc_regs[instance];
    1035           0 :         tgn10->tg_shift = &optc_shift;
    1036           0 :         tgn10->tg_mask = &optc_mask;
    1037             : 
    1038           0 :         dcn32_timing_generator_init(tgn10);
    1039             : 
    1040           0 :         return &tgn10->base;
    1041             : }
    1042             : 
    1043             : static const struct encoder_feature_support link_enc_feature = {
    1044             :                 .max_hdmi_deep_color = COLOR_DEPTH_121212,
    1045             :                 .max_hdmi_pixel_clock = 600000,
    1046             :                 .hdmi_ycbcr420_supported = true,
    1047             :                 .dp_ycbcr420_supported = true,
    1048             :                 .fec_supported = true,
    1049             :                 .flags.bits.IS_HBR2_CAPABLE = true,
    1050             :                 .flags.bits.IS_HBR3_CAPABLE = true,
    1051             :                 .flags.bits.IS_TPS3_CAPABLE = true,
    1052             :                 .flags.bits.IS_TPS4_CAPABLE = true
    1053             : };
    1054             : 
    1055           0 : static struct link_encoder *dcn32_link_encoder_create(
    1056             :         struct dc_context *ctx,
    1057             :         const struct encoder_init_data *enc_init_data)
    1058             : {
    1059           0 :         struct dcn20_link_encoder *enc20 =
    1060             :                 kzalloc(sizeof(struct dcn20_link_encoder), GFP_KERNEL);
    1061             : 
    1062           0 :         if (!enc20)
    1063             :                 return NULL;
    1064             : 
    1065             : #undef REG_STRUCT
    1066             : #define REG_STRUCT link_enc_aux_regs
    1067           0 :         aux_regs_init(0),
    1068           0 :         aux_regs_init(1),
    1069           0 :         aux_regs_init(2),
    1070           0 :         aux_regs_init(3),
    1071           0 :         aux_regs_init(4);
    1072             : 
    1073             : #undef REG_STRUCT
    1074             : #define REG_STRUCT link_enc_hpd_regs
    1075           0 :         hpd_regs_init(0),
    1076           0 :         hpd_regs_init(1),
    1077           0 :         hpd_regs_init(2),
    1078           0 :         hpd_regs_init(3),
    1079           0 :         hpd_regs_init(4);
    1080             : 
    1081             : #undef REG_STRUCT
    1082             : #define REG_STRUCT link_enc_regs
    1083           0 :         link_regs_init(0, A),
    1084           0 :         link_regs_init(1, B),
    1085           0 :         link_regs_init(2, C),
    1086           0 :         link_regs_init(3, D),
    1087           0 :         link_regs_init(4, E);
    1088             : 
    1089           0 :         dcn32_link_encoder_construct(enc20,
    1090             :                         enc_init_data,
    1091             :                         &link_enc_feature,
    1092           0 :                         &link_enc_regs[enc_init_data->transmitter],
    1093           0 :                         &link_enc_aux_regs[enc_init_data->channel - 1],
    1094           0 :                         &link_enc_hpd_regs[enc_init_data->hpd_source],
    1095             :                         &le_shift,
    1096             :                         &le_mask);
    1097             : 
    1098           0 :         return &enc20->enc10.base;
    1099             : }
    1100             : 
    1101           0 : struct panel_cntl *dcn32_panel_cntl_create(const struct panel_cntl_init_data *init_data)
    1102             : {
    1103           0 :         struct dcn31_panel_cntl *panel_cntl =
    1104             :                 kzalloc(sizeof(struct dcn31_panel_cntl), GFP_KERNEL);
    1105             : 
    1106           0 :         if (!panel_cntl)
    1107             :                 return NULL;
    1108             : 
    1109           0 :         dcn31_panel_cntl_construct(panel_cntl, init_data);
    1110             : 
    1111           0 :         return &panel_cntl->base;
    1112             : }
    1113             : 
    1114           0 : static void read_dce_straps(
    1115             :         struct dc_context *ctx,
    1116             :         struct resource_straps *straps)
    1117             : {
    1118           0 :         generic_reg_get(ctx, ctx->dcn_reg_offsets[regDC_PINSTRAPS_BASE_IDX] + regDC_PINSTRAPS,
    1119             :                 FN(DC_PINSTRAPS, DC_PINSTRAPS_AUDIO), &straps->dc_pinstraps_audio);
    1120             : 
    1121           0 : }
    1122             : 
    1123           0 : static struct audio *dcn32_create_audio(
    1124             :                 struct dc_context *ctx, unsigned int inst)
    1125             : {
    1126             : 
    1127             : #undef REG_STRUCT
    1128             : #define REG_STRUCT audio_regs
    1129           0 :         audio_regs_init(0),
    1130           0 :         audio_regs_init(1),
    1131           0 :         audio_regs_init(2),
    1132           0 :         audio_regs_init(3),
    1133           0 :         audio_regs_init(4);
    1134             : 
    1135           0 :         return dce_audio_create(ctx, inst,
    1136           0 :                         &audio_regs[inst], &audio_shift, &audio_mask);
    1137             : }
    1138             : 
    1139           0 : static struct vpg *dcn32_vpg_create(
    1140             :         struct dc_context *ctx,
    1141             :         uint32_t inst)
    1142             : {
    1143           0 :         struct dcn30_vpg *vpg3 = kzalloc(sizeof(struct dcn30_vpg), GFP_KERNEL);
    1144             : 
    1145           0 :         if (!vpg3)
    1146             :                 return NULL;
    1147             : 
    1148             : #undef REG_STRUCT
    1149             : #define REG_STRUCT vpg_regs
    1150           0 :         vpg_regs_init(0),
    1151           0 :         vpg_regs_init(1),
    1152           0 :         vpg_regs_init(2),
    1153           0 :         vpg_regs_init(3),
    1154           0 :         vpg_regs_init(4),
    1155           0 :         vpg_regs_init(5),
    1156           0 :         vpg_regs_init(6),
    1157           0 :         vpg_regs_init(7),
    1158           0 :         vpg_regs_init(8),
    1159           0 :         vpg_regs_init(9);
    1160             : 
    1161           0 :         vpg3_construct(vpg3, ctx, inst,
    1162           0 :                         &vpg_regs[inst],
    1163             :                         &vpg_shift,
    1164             :                         &vpg_mask);
    1165             : 
    1166           0 :         return &vpg3->base;
    1167             : }
    1168             : 
    1169           0 : static struct afmt *dcn32_afmt_create(
    1170             :         struct dc_context *ctx,
    1171             :         uint32_t inst)
    1172             : {
    1173           0 :         struct dcn30_afmt *afmt3 = kzalloc(sizeof(struct dcn30_afmt), GFP_KERNEL);
    1174             : 
    1175           0 :         if (!afmt3)
    1176             :                 return NULL;
    1177             : 
    1178             : #undef REG_STRUCT
    1179             : #define REG_STRUCT afmt_regs
    1180           0 :         afmt_regs_init(0),
    1181           0 :         afmt_regs_init(1),
    1182           0 :         afmt_regs_init(2),
    1183           0 :         afmt_regs_init(3),
    1184           0 :         afmt_regs_init(4),
    1185           0 :         afmt_regs_init(5);
    1186             : 
    1187           0 :         afmt3_construct(afmt3, ctx, inst,
    1188           0 :                         &afmt_regs[inst],
    1189             :                         &afmt_shift,
    1190             :                         &afmt_mask);
    1191             : 
    1192           0 :         return &afmt3->base;
    1193             : }
    1194             : 
    1195           0 : static struct apg *dcn31_apg_create(
    1196             :         struct dc_context *ctx,
    1197             :         uint32_t inst)
    1198             : {
    1199           0 :         struct dcn31_apg *apg31 = kzalloc(sizeof(struct dcn31_apg), GFP_KERNEL);
    1200             : 
    1201           0 :         if (!apg31)
    1202             :                 return NULL;
    1203             : 
    1204             : #undef REG_STRUCT
    1205             : #define REG_STRUCT apg_regs
    1206           0 :         apg_regs_init(0),
    1207           0 :         apg_regs_init(1),
    1208           0 :         apg_regs_init(2),
    1209           0 :         apg_regs_init(3);
    1210             : 
    1211           0 :         apg31_construct(apg31, ctx, inst,
    1212           0 :                         &apg_regs[inst],
    1213             :                         &apg_shift,
    1214             :                         &apg_mask);
    1215             : 
    1216           0 :         return &apg31->base;
    1217             : }
    1218             : 
    1219           0 : static struct stream_encoder *dcn32_stream_encoder_create(
    1220             :         enum engine_id eng_id,
    1221             :         struct dc_context *ctx)
    1222             : {
    1223             :         struct dcn10_stream_encoder *enc1;
    1224             :         struct vpg *vpg;
    1225             :         struct afmt *afmt;
    1226             :         int vpg_inst;
    1227             :         int afmt_inst;
    1228             : 
    1229             :         /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */
    1230           0 :         if (eng_id <= ENGINE_ID_DIGF) {
    1231           0 :                 vpg_inst = eng_id;
    1232           0 :                 afmt_inst = eng_id;
    1233             :         } else
    1234             :                 return NULL;
    1235             : 
    1236           0 :         enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL);
    1237           0 :         vpg = dcn32_vpg_create(ctx, vpg_inst);
    1238           0 :         afmt = dcn32_afmt_create(ctx, afmt_inst);
    1239             : 
    1240           0 :         if (!enc1 || !vpg || !afmt) {
    1241           0 :                 kfree(enc1);
    1242           0 :                 kfree(vpg);
    1243           0 :                 kfree(afmt);
    1244           0 :                 return NULL;
    1245             :         }
    1246             : 
    1247             : #undef REG_STRUCT
    1248             : #define REG_STRUCT stream_enc_regs
    1249           0 :         stream_enc_regs_init(0),
    1250           0 :         stream_enc_regs_init(1),
    1251           0 :         stream_enc_regs_init(2),
    1252           0 :         stream_enc_regs_init(3),
    1253           0 :         stream_enc_regs_init(4);
    1254             : 
    1255           0 :         dcn32_dio_stream_encoder_construct(enc1, ctx, ctx->dc_bios,
    1256             :                                         eng_id, vpg, afmt,
    1257           0 :                                         &stream_enc_regs[eng_id],
    1258             :                                         &se_shift, &se_mask);
    1259             : 
    1260           0 :         return &enc1->base;
    1261             : }
    1262             : 
    1263           0 : static struct hpo_dp_stream_encoder *dcn32_hpo_dp_stream_encoder_create(
    1264             :         enum engine_id eng_id,
    1265             :         struct dc_context *ctx)
    1266             : {
    1267             :         struct dcn31_hpo_dp_stream_encoder *hpo_dp_enc31;
    1268             :         struct vpg *vpg;
    1269             :         struct apg *apg;
    1270             :         uint32_t hpo_dp_inst;
    1271             :         uint32_t vpg_inst;
    1272             :         uint32_t apg_inst;
    1273             : 
    1274           0 :         ASSERT((eng_id >= ENGINE_ID_HPO_DP_0) && (eng_id <= ENGINE_ID_HPO_DP_3));
    1275           0 :         hpo_dp_inst = eng_id - ENGINE_ID_HPO_DP_0;
    1276             : 
    1277             :         /* Mapping of VPG register blocks to HPO DP block instance:
    1278             :          * VPG[6] -> HPO_DP[0]
    1279             :          * VPG[7] -> HPO_DP[1]
    1280             :          * VPG[8] -> HPO_DP[2]
    1281             :          * VPG[9] -> HPO_DP[3]
    1282             :          */
    1283           0 :         vpg_inst = hpo_dp_inst + 6;
    1284             : 
    1285             :         /* Mapping of APG register blocks to HPO DP block instance:
    1286             :          * APG[0] -> HPO_DP[0]
    1287             :          * APG[1] -> HPO_DP[1]
    1288             :          * APG[2] -> HPO_DP[2]
    1289             :          * APG[3] -> HPO_DP[3]
    1290             :          */
    1291           0 :         apg_inst = hpo_dp_inst;
    1292             : 
    1293             :         /* allocate HPO stream encoder and create VPG sub-block */
    1294           0 :         hpo_dp_enc31 = kzalloc(sizeof(struct dcn31_hpo_dp_stream_encoder), GFP_KERNEL);
    1295           0 :         vpg = dcn32_vpg_create(ctx, vpg_inst);
    1296           0 :         apg = dcn31_apg_create(ctx, apg_inst);
    1297             : 
    1298           0 :         if (!hpo_dp_enc31 || !vpg || !apg) {
    1299           0 :                 kfree(hpo_dp_enc31);
    1300           0 :                 kfree(vpg);
    1301           0 :                 kfree(apg);
    1302           0 :                 return NULL;
    1303             :         }
    1304             : 
    1305             : #undef REG_STRUCT
    1306             : #define REG_STRUCT hpo_dp_stream_enc_regs
    1307           0 :         hpo_dp_stream_encoder_reg_init(0),
    1308           0 :         hpo_dp_stream_encoder_reg_init(1),
    1309           0 :         hpo_dp_stream_encoder_reg_init(2),
    1310           0 :         hpo_dp_stream_encoder_reg_init(3);
    1311             : 
    1312           0 :         dcn31_hpo_dp_stream_encoder_construct(hpo_dp_enc31, ctx, ctx->dc_bios,
    1313             :                                         hpo_dp_inst, eng_id, vpg, apg,
    1314           0 :                                         &hpo_dp_stream_enc_regs[hpo_dp_inst],
    1315             :                                         &hpo_dp_se_shift, &hpo_dp_se_mask);
    1316             : 
    1317           0 :         return &hpo_dp_enc31->base;
    1318             : }
    1319             : 
    1320           0 : static struct hpo_dp_link_encoder *dcn32_hpo_dp_link_encoder_create(
    1321             :         uint8_t inst,
    1322             :         struct dc_context *ctx)
    1323             : {
    1324             :         struct dcn31_hpo_dp_link_encoder *hpo_dp_enc31;
    1325             : 
    1326             :         /* allocate HPO link encoder */
    1327           0 :         hpo_dp_enc31 = kzalloc(sizeof(struct dcn31_hpo_dp_link_encoder), GFP_KERNEL);
    1328             : 
    1329             : #undef REG_STRUCT
    1330             : #define REG_STRUCT hpo_dp_link_enc_regs
    1331           0 :         hpo_dp_link_encoder_reg_init(0),
    1332           0 :         hpo_dp_link_encoder_reg_init(1);
    1333             : 
    1334           0 :         hpo_dp_link_encoder32_construct(hpo_dp_enc31, ctx, inst,
    1335           0 :                                         &hpo_dp_link_enc_regs[inst],
    1336             :                                         &hpo_dp_le_shift, &hpo_dp_le_mask);
    1337             : 
    1338           0 :         return &hpo_dp_enc31->base;
    1339             : }
    1340             : 
    1341           0 : static struct dce_hwseq *dcn32_hwseq_create(
    1342             :         struct dc_context *ctx)
    1343             : {
    1344           0 :         struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL);
    1345             : 
    1346             : #undef REG_STRUCT
    1347             : #define REG_STRUCT hwseq_reg
    1348           0 :         hwseq_reg_init();
    1349             : 
    1350           0 :         if (hws) {
    1351           0 :                 hws->ctx = ctx;
    1352           0 :                 hws->regs = &hwseq_reg;
    1353           0 :                 hws->shifts = &hwseq_shift;
    1354           0 :                 hws->masks = &hwseq_mask;
    1355             :         }
    1356           0 :         return hws;
    1357             : }
    1358             : static const struct resource_create_funcs res_create_funcs = {
    1359             :         .read_dce_straps = read_dce_straps,
    1360             :         .create_audio = dcn32_create_audio,
    1361             :         .create_stream_encoder = dcn32_stream_encoder_create,
    1362             :         .create_hpo_dp_stream_encoder = dcn32_hpo_dp_stream_encoder_create,
    1363             :         .create_hpo_dp_link_encoder = dcn32_hpo_dp_link_encoder_create,
    1364             :         .create_hwseq = dcn32_hwseq_create,
    1365             : };
    1366             : 
    1367             : static const struct resource_create_funcs res_create_maximus_funcs = {
    1368             :         .read_dce_straps = NULL,
    1369             :         .create_audio = NULL,
    1370             :         .create_stream_encoder = NULL,
    1371             :         .create_hpo_dp_stream_encoder = dcn32_hpo_dp_stream_encoder_create,
    1372             :         .create_hpo_dp_link_encoder = dcn32_hpo_dp_link_encoder_create,
    1373             :         .create_hwseq = dcn32_hwseq_create,
    1374             : };
    1375             : 
    1376           0 : static void dcn32_resource_destruct(struct dcn32_resource_pool *pool)
    1377             : {
    1378             :         unsigned int i;
    1379             : 
    1380           0 :         for (i = 0; i < pool->base.stream_enc_count; i++) {
    1381           0 :                 if (pool->base.stream_enc[i] != NULL) {
    1382           0 :                         if (pool->base.stream_enc[i]->vpg != NULL) {
    1383           0 :                                 kfree(DCN30_VPG_FROM_VPG(pool->base.stream_enc[i]->vpg));
    1384           0 :                                 pool->base.stream_enc[i]->vpg = NULL;
    1385             :                         }
    1386           0 :                         if (pool->base.stream_enc[i]->afmt != NULL) {
    1387           0 :                                 kfree(DCN30_AFMT_FROM_AFMT(pool->base.stream_enc[i]->afmt));
    1388           0 :                                 pool->base.stream_enc[i]->afmt = NULL;
    1389             :                         }
    1390           0 :                         kfree(DCN10STRENC_FROM_STRENC(pool->base.stream_enc[i]));
    1391           0 :                         pool->base.stream_enc[i] = NULL;
    1392             :                 }
    1393             :         }
    1394             : 
    1395           0 :         for (i = 0; i < pool->base.hpo_dp_stream_enc_count; i++) {
    1396           0 :                 if (pool->base.hpo_dp_stream_enc[i] != NULL) {
    1397           0 :                         if (pool->base.hpo_dp_stream_enc[i]->vpg != NULL) {
    1398           0 :                                 kfree(DCN30_VPG_FROM_VPG(pool->base.hpo_dp_stream_enc[i]->vpg));
    1399           0 :                                 pool->base.hpo_dp_stream_enc[i]->vpg = NULL;
    1400             :                         }
    1401           0 :                         if (pool->base.hpo_dp_stream_enc[i]->apg != NULL) {
    1402           0 :                                 kfree(DCN31_APG_FROM_APG(pool->base.hpo_dp_stream_enc[i]->apg));
    1403           0 :                                 pool->base.hpo_dp_stream_enc[i]->apg = NULL;
    1404             :                         }
    1405           0 :                         kfree(DCN3_1_HPO_DP_STREAM_ENC_FROM_HPO_STREAM_ENC(pool->base.hpo_dp_stream_enc[i]));
    1406           0 :                         pool->base.hpo_dp_stream_enc[i] = NULL;
    1407             :                 }
    1408             :         }
    1409             : 
    1410           0 :         for (i = 0; i < pool->base.hpo_dp_link_enc_count; i++) {
    1411           0 :                 if (pool->base.hpo_dp_link_enc[i] != NULL) {
    1412           0 :                         kfree(DCN3_1_HPO_DP_LINK_ENC_FROM_HPO_LINK_ENC(pool->base.hpo_dp_link_enc[i]));
    1413           0 :                         pool->base.hpo_dp_link_enc[i] = NULL;
    1414             :                 }
    1415             :         }
    1416             : 
    1417           0 :         for (i = 0; i < pool->base.res_cap->num_dsc; i++) {
    1418           0 :                 if (pool->base.dscs[i] != NULL)
    1419           0 :                         dcn20_dsc_destroy(&pool->base.dscs[i]);
    1420             :         }
    1421             : 
    1422           0 :         if (pool->base.mpc != NULL) {
    1423           0 :                 kfree(TO_DCN20_MPC(pool->base.mpc));
    1424           0 :                 pool->base.mpc = NULL;
    1425             :         }
    1426           0 :         if (pool->base.hubbub != NULL) {
    1427           0 :                 kfree(TO_DCN20_HUBBUB(pool->base.hubbub));
    1428           0 :                 pool->base.hubbub = NULL;
    1429             :         }
    1430           0 :         for (i = 0; i < pool->base.pipe_count; i++) {
    1431           0 :                 if (pool->base.dpps[i] != NULL)
    1432           0 :                         dcn32_dpp_destroy(&pool->base.dpps[i]);
    1433             : 
    1434           0 :                 if (pool->base.ipps[i] != NULL)
    1435           0 :                         pool->base.ipps[i]->funcs->ipp_destroy(&pool->base.ipps[i]);
    1436             : 
    1437           0 :                 if (pool->base.hubps[i] != NULL) {
    1438           0 :                         kfree(TO_DCN20_HUBP(pool->base.hubps[i]));
    1439           0 :                         pool->base.hubps[i] = NULL;
    1440             :                 }
    1441             : 
    1442           0 :                 if (pool->base.irqs != NULL) {
    1443           0 :                         dal_irq_service_destroy(&pool->base.irqs);
    1444             :                 }
    1445             :         }
    1446             : 
    1447           0 :         for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
    1448           0 :                 if (pool->base.engines[i] != NULL)
    1449           0 :                         dce110_engine_destroy(&pool->base.engines[i]);
    1450           0 :                 if (pool->base.hw_i2cs[i] != NULL) {
    1451           0 :                         kfree(pool->base.hw_i2cs[i]);
    1452           0 :                         pool->base.hw_i2cs[i] = NULL;
    1453             :                 }
    1454           0 :                 if (pool->base.sw_i2cs[i] != NULL) {
    1455           0 :                         kfree(pool->base.sw_i2cs[i]);
    1456           0 :                         pool->base.sw_i2cs[i] = NULL;
    1457             :                 }
    1458             :         }
    1459             : 
    1460           0 :         for (i = 0; i < pool->base.res_cap->num_opp; i++) {
    1461           0 :                 if (pool->base.opps[i] != NULL)
    1462           0 :                         pool->base.opps[i]->funcs->opp_destroy(&pool->base.opps[i]);
    1463             :         }
    1464             : 
    1465           0 :         for (i = 0; i < pool->base.res_cap->num_timing_generator; i++) {
    1466           0 :                 if (pool->base.timing_generators[i] != NULL) {
    1467           0 :                         kfree(DCN10TG_FROM_TG(pool->base.timing_generators[i]));
    1468           0 :                         pool->base.timing_generators[i] = NULL;
    1469             :                 }
    1470             :         }
    1471             : 
    1472           0 :         for (i = 0; i < pool->base.res_cap->num_dwb; i++) {
    1473           0 :                 if (pool->base.dwbc[i] != NULL) {
    1474           0 :                         kfree(TO_DCN30_DWBC(pool->base.dwbc[i]));
    1475           0 :                         pool->base.dwbc[i] = NULL;
    1476             :                 }
    1477           0 :                 if (pool->base.mcif_wb[i] != NULL) {
    1478           0 :                         kfree(TO_DCN30_MMHUBBUB(pool->base.mcif_wb[i]));
    1479           0 :                         pool->base.mcif_wb[i] = NULL;
    1480             :                 }
    1481             :         }
    1482             : 
    1483           0 :         for (i = 0; i < pool->base.audio_count; i++) {
    1484           0 :                 if (pool->base.audios[i])
    1485           0 :                         dce_aud_destroy(&pool->base.audios[i]);
    1486             :         }
    1487             : 
    1488           0 :         for (i = 0; i < pool->base.clk_src_count; i++) {
    1489           0 :                 if (pool->base.clock_sources[i] != NULL) {
    1490           0 :                         dcn20_clock_source_destroy(&pool->base.clock_sources[i]);
    1491           0 :                         pool->base.clock_sources[i] = NULL;
    1492             :                 }
    1493             :         }
    1494             : 
    1495           0 :         for (i = 0; i < pool->base.res_cap->num_mpc_3dlut; i++) {
    1496           0 :                 if (pool->base.mpc_lut[i] != NULL) {
    1497           0 :                         dc_3dlut_func_release(pool->base.mpc_lut[i]);
    1498           0 :                         pool->base.mpc_lut[i] = NULL;
    1499             :                 }
    1500           0 :                 if (pool->base.mpc_shaper[i] != NULL) {
    1501           0 :                         dc_transfer_func_release(pool->base.mpc_shaper[i]);
    1502           0 :                         pool->base.mpc_shaper[i] = NULL;
    1503             :                 }
    1504             :         }
    1505             : 
    1506           0 :         if (pool->base.dp_clock_source != NULL) {
    1507           0 :                 dcn20_clock_source_destroy(&pool->base.dp_clock_source);
    1508           0 :                 pool->base.dp_clock_source = NULL;
    1509             :         }
    1510             : 
    1511           0 :         for (i = 0; i < pool->base.res_cap->num_timing_generator; i++) {
    1512           0 :                 if (pool->base.multiple_abms[i] != NULL)
    1513           0 :                         dce_abm_destroy(&pool->base.multiple_abms[i]);
    1514             :         }
    1515             : 
    1516           0 :         if (pool->base.psr != NULL)
    1517           0 :                 dmub_psr_destroy(&pool->base.psr);
    1518             : 
    1519           0 :         if (pool->base.dccg != NULL)
    1520           0 :                 dcn_dccg_destroy(&pool->base.dccg);
    1521             : 
    1522           0 :         if (pool->base.oem_device != NULL)
    1523           0 :                 dal_ddc_service_destroy(&pool->base.oem_device);
    1524           0 : }
    1525             : 
    1526             : 
    1527           0 : static bool dcn32_dwbc_create(struct dc_context *ctx, struct resource_pool *pool)
    1528             : {
    1529             :         int i;
    1530           0 :         uint32_t dwb_count = pool->res_cap->num_dwb;
    1531             : 
    1532           0 :         for (i = 0; i < dwb_count; i++) {
    1533           0 :                 struct dcn30_dwbc *dwbc30 = kzalloc(sizeof(struct dcn30_dwbc),
    1534             :                                                     GFP_KERNEL);
    1535             : 
    1536           0 :                 if (!dwbc30) {
    1537           0 :                         dm_error("DC: failed to create dwbc30!\n");
    1538             :                         return false;
    1539             :                 }
    1540             : 
    1541             : #undef REG_STRUCT
    1542             : #define REG_STRUCT dwbc30_regs
    1543           0 :                 dwbc_regs_dcn3_init(0);
    1544             : 
    1545           0 :                 dcn30_dwbc_construct(dwbc30, ctx,
    1546           0 :                                 &dwbc30_regs[i],
    1547             :                                 &dwbc30_shift,
    1548             :                                 &dwbc30_mask,
    1549             :                                 i);
    1550             : 
    1551           0 :                 pool->dwbc[i] = &dwbc30->base;
    1552             :         }
    1553             :         return true;
    1554             : }
    1555             : 
    1556           0 : static bool dcn32_mmhubbub_create(struct dc_context *ctx, struct resource_pool *pool)
    1557             : {
    1558             :         int i;
    1559           0 :         uint32_t dwb_count = pool->res_cap->num_dwb;
    1560             : 
    1561           0 :         for (i = 0; i < dwb_count; i++) {
    1562           0 :                 struct dcn30_mmhubbub *mcif_wb30 = kzalloc(sizeof(struct dcn30_mmhubbub),
    1563             :                                                     GFP_KERNEL);
    1564             : 
    1565           0 :                 if (!mcif_wb30) {
    1566           0 :                         dm_error("DC: failed to create mcif_wb30!\n");
    1567             :                         return false;
    1568             :                 }
    1569             : 
    1570             : #undef REG_STRUCT
    1571             : #define REG_STRUCT mcif_wb30_regs
    1572           0 :                 mcif_wb_regs_dcn3_init(0);
    1573             : 
    1574           0 :                 dcn32_mmhubbub_construct(mcif_wb30, ctx,
    1575           0 :                                 &mcif_wb30_regs[i],
    1576             :                                 &mcif_wb30_shift,
    1577             :                                 &mcif_wb30_mask,
    1578             :                                 i);
    1579             : 
    1580           0 :                 pool->mcif_wb[i] = &mcif_wb30->base;
    1581             :         }
    1582             :         return true;
    1583             : }
    1584             : 
    1585           0 : static struct display_stream_compressor *dcn32_dsc_create(
    1586             :         struct dc_context *ctx, uint32_t inst)
    1587             : {
    1588           0 :         struct dcn20_dsc *dsc =
    1589             :                 kzalloc(sizeof(struct dcn20_dsc), GFP_KERNEL);
    1590             : 
    1591           0 :         if (!dsc) {
    1592           0 :                 BREAK_TO_DEBUGGER();
    1593           0 :                 return NULL;
    1594             :         }
    1595             : 
    1596             : #undef REG_STRUCT
    1597             : #define REG_STRUCT dsc_regs
    1598           0 :         dsc_regsDCN20_init(0),
    1599           0 :         dsc_regsDCN20_init(1),
    1600           0 :         dsc_regsDCN20_init(2),
    1601           0 :         dsc_regsDCN20_init(3);
    1602             : 
    1603           0 :         dsc2_construct(dsc, ctx, inst, &dsc_regs[inst], &dsc_shift, &dsc_mask);
    1604             : 
    1605           0 :         dsc->max_image_width = 6016;
    1606             : 
    1607           0 :         return &dsc->base;
    1608             : }
    1609             : 
    1610           0 : static void dcn32_destroy_resource_pool(struct resource_pool **pool)
    1611             : {
    1612           0 :         struct dcn32_resource_pool *dcn32_pool = TO_DCN32_RES_POOL(*pool);
    1613             : 
    1614           0 :         dcn32_resource_destruct(dcn32_pool);
    1615           0 :         kfree(dcn32_pool);
    1616           0 :         *pool = NULL;
    1617           0 : }
    1618             : 
    1619           0 : bool dcn32_acquire_post_bldn_3dlut(
    1620             :                 struct resource_context *res_ctx,
    1621             :                 const struct resource_pool *pool,
    1622             :                 int mpcc_id,
    1623             :                 struct dc_3dlut **lut,
    1624             :                 struct dc_transfer_func **shaper)
    1625             : {
    1626           0 :         bool ret = false;
    1627             :         union dc_3dlut_state *state;
    1628             : 
    1629           0 :         ASSERT(*lut == NULL && *shaper == NULL);
    1630           0 :         *lut = NULL;
    1631           0 :         *shaper = NULL;
    1632             : 
    1633           0 :         if (!res_ctx->is_mpc_3dlut_acquired[mpcc_id]) {
    1634           0 :                 *lut = pool->mpc_lut[mpcc_id];
    1635           0 :                 *shaper = pool->mpc_shaper[mpcc_id];
    1636           0 :                 state = &pool->mpc_lut[mpcc_id]->state;
    1637           0 :                 res_ctx->is_mpc_3dlut_acquired[mpcc_id] = true;
    1638           0 :                 ret = true;
    1639             :         }
    1640           0 :         return ret;
    1641             : }
    1642             : 
    1643           0 : bool dcn32_release_post_bldn_3dlut(
    1644             :                 struct resource_context *res_ctx,
    1645             :                 const struct resource_pool *pool,
    1646             :                 struct dc_3dlut **lut,
    1647             :                 struct dc_transfer_func **shaper)
    1648             : {
    1649             :         int i;
    1650           0 :         bool ret = false;
    1651             : 
    1652           0 :         for (i = 0; i < pool->res_cap->num_mpc_3dlut; i++) {
    1653           0 :                 if (pool->mpc_lut[i] == *lut && pool->mpc_shaper[i] == *shaper) {
    1654           0 :                         res_ctx->is_mpc_3dlut_acquired[i] = false;
    1655           0 :                         pool->mpc_lut[i]->state.raw = 0;
    1656           0 :                         *lut = NULL;
    1657           0 :                         *shaper = NULL;
    1658           0 :                         ret = true;
    1659           0 :                         break;
    1660             :                 }
    1661             :         }
    1662           0 :         return ret;
    1663             : }
    1664             : 
    1665           0 : static void dcn32_enable_phantom_plane(struct dc *dc,
    1666             :                 struct dc_state *context,
    1667             :                 struct dc_stream_state *phantom_stream,
    1668             :                 unsigned int dc_pipe_idx)
    1669             : {
    1670           0 :         struct dc_plane_state *phantom_plane = NULL;
    1671           0 :         struct dc_plane_state *prev_phantom_plane = NULL;
    1672           0 :         struct pipe_ctx *curr_pipe = &context->res_ctx.pipe_ctx[dc_pipe_idx];
    1673             : 
    1674           0 :         while (curr_pipe) {
    1675           0 :                 if (curr_pipe->top_pipe && curr_pipe->top_pipe->plane_state == curr_pipe->plane_state)
    1676             :                         phantom_plane = prev_phantom_plane;
    1677             :                 else
    1678           0 :                         phantom_plane = dc_create_plane_state(dc);
    1679             : 
    1680           0 :                 memcpy(&phantom_plane->address, &curr_pipe->plane_state->address, sizeof(phantom_plane->address));
    1681           0 :                 memcpy(&phantom_plane->scaling_quality, &curr_pipe->plane_state->scaling_quality,
    1682             :                                 sizeof(phantom_plane->scaling_quality));
    1683           0 :                 memcpy(&phantom_plane->src_rect, &curr_pipe->plane_state->src_rect, sizeof(phantom_plane->src_rect));
    1684           0 :                 memcpy(&phantom_plane->dst_rect, &curr_pipe->plane_state->dst_rect, sizeof(phantom_plane->dst_rect));
    1685           0 :                 memcpy(&phantom_plane->clip_rect, &curr_pipe->plane_state->clip_rect, sizeof(phantom_plane->clip_rect));
    1686           0 :                 memcpy(&phantom_plane->plane_size, &curr_pipe->plane_state->plane_size,
    1687             :                                 sizeof(phantom_plane->plane_size));
    1688           0 :                 memcpy(&phantom_plane->tiling_info, &curr_pipe->plane_state->tiling_info,
    1689             :                                 sizeof(phantom_plane->tiling_info));
    1690           0 :                 memcpy(&phantom_plane->dcc, &curr_pipe->plane_state->dcc, sizeof(phantom_plane->dcc));
    1691           0 :                 phantom_plane->format = curr_pipe->plane_state->format;
    1692           0 :                 phantom_plane->rotation = curr_pipe->plane_state->rotation;
    1693           0 :                 phantom_plane->visible = curr_pipe->plane_state->visible;
    1694             : 
    1695             :                 /* Shadow pipe has small viewport. */
    1696           0 :                 phantom_plane->clip_rect.y = 0;
    1697           0 :                 phantom_plane->clip_rect.height = phantom_stream->timing.v_addressable;
    1698             : 
    1699           0 :                 dc_add_plane_to_context(dc, phantom_stream, phantom_plane, context);
    1700             : 
    1701           0 :                 curr_pipe = curr_pipe->bottom_pipe;
    1702           0 :                 prev_phantom_plane = phantom_plane;
    1703             :         }
    1704           0 : }
    1705             : 
    1706           0 : static struct dc_stream_state *dcn32_enable_phantom_stream(struct dc *dc,
    1707             :                 struct dc_state *context,
    1708             :                 display_e2e_pipe_params_st *pipes,
    1709             :                 unsigned int pipe_cnt,
    1710             :                 unsigned int dc_pipe_idx)
    1711             : {
    1712           0 :         struct dc_stream_state *phantom_stream = NULL;
    1713           0 :         struct pipe_ctx *ref_pipe = &context->res_ctx.pipe_ctx[dc_pipe_idx];
    1714             : 
    1715           0 :         phantom_stream = dc_create_stream_for_sink(ref_pipe->stream->sink);
    1716           0 :         phantom_stream->signal = SIGNAL_TYPE_VIRTUAL;
    1717           0 :         phantom_stream->dpms_off = true;
    1718           0 :         phantom_stream->mall_stream_config.type = SUBVP_PHANTOM;
    1719           0 :         phantom_stream->mall_stream_config.paired_stream = ref_pipe->stream;
    1720           0 :         ref_pipe->stream->mall_stream_config.type = SUBVP_MAIN;
    1721           0 :         ref_pipe->stream->mall_stream_config.paired_stream = phantom_stream;
    1722             : 
    1723             :         /* stream has limited viewport and small timing */
    1724           0 :         memcpy(&phantom_stream->timing, &ref_pipe->stream->timing, sizeof(phantom_stream->timing));
    1725           0 :         memcpy(&phantom_stream->src, &ref_pipe->stream->src, sizeof(phantom_stream->src));
    1726           0 :         memcpy(&phantom_stream->dst, &ref_pipe->stream->dst, sizeof(phantom_stream->dst));
    1727           0 :         DC_FP_START();
    1728           0 :         dcn32_set_phantom_stream_timing(dc, context, ref_pipe, phantom_stream, pipes, pipe_cnt, dc_pipe_idx);
    1729           0 :         DC_FP_END();
    1730             : 
    1731           0 :         dc_add_stream_to_ctx(dc, context, phantom_stream);
    1732           0 :         return phantom_stream;
    1733             : }
    1734             : 
    1735             : // return true if removed piped from ctx, false otherwise
    1736           0 : bool dcn32_remove_phantom_pipes(struct dc *dc, struct dc_state *context)
    1737             : {
    1738             :         int i;
    1739           0 :         bool removed_pipe = false;
    1740           0 :         struct dc_plane_state *phantom_plane = NULL;
    1741           0 :         struct dc_stream_state *phantom_stream = NULL;
    1742             : 
    1743           0 :         for (i = 0; i < dc->res_pool->pipe_count; i++) {
    1744           0 :                 struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
    1745             :                 // build scaling params for phantom pipes
    1746           0 :                 if (pipe->plane_state && pipe->stream && pipe->stream->mall_stream_config.type == SUBVP_PHANTOM) {
    1747           0 :                         phantom_plane = pipe->plane_state;
    1748           0 :                         phantom_stream = pipe->stream;
    1749             : 
    1750           0 :                         dc_rem_all_planes_for_stream(dc, pipe->stream, context);
    1751           0 :                         dc_remove_stream_from_ctx(dc, context, pipe->stream);
    1752             : 
    1753             :                         /* Ref count is incremented on allocation and also when added to the context.
    1754             :                          * Therefore we must call release for the the phantom plane and stream once
    1755             :                          * they are removed from the ctx to finally decrement the refcount to 0 to free.
    1756             :                          */
    1757           0 :                         dc_plane_state_release(phantom_plane);
    1758           0 :                         dc_stream_release(phantom_stream);
    1759             : 
    1760           0 :                         removed_pipe = true;
    1761             :                 }
    1762             : 
    1763             :                 // Clear all phantom stream info
    1764           0 :                 if (pipe->stream) {
    1765           0 :                         pipe->stream->mall_stream_config.type = SUBVP_NONE;
    1766           0 :                         pipe->stream->mall_stream_config.paired_stream = NULL;
    1767             :                 }
    1768             :         }
    1769           0 :         return removed_pipe;
    1770             : }
    1771             : 
    1772             : /* TODO: Input to this function should indicate which pipe indexes (or streams)
    1773             :  * require a phantom pipe / stream
    1774             :  */
    1775           0 : void dcn32_add_phantom_pipes(struct dc *dc, struct dc_state *context,
    1776             :                 display_e2e_pipe_params_st *pipes,
    1777             :                 unsigned int pipe_cnt,
    1778             :                 unsigned int index)
    1779             : {
    1780           0 :         struct dc_stream_state *phantom_stream = NULL;
    1781             :         unsigned int i;
    1782             : 
    1783             :         // The index of the DC pipe passed into this function is guarenteed to
    1784             :         // be a valid candidate for SubVP (i.e. has a plane, stream, doesn't
    1785             :         // already have phantom pipe assigned, etc.) by previous checks.
    1786           0 :         phantom_stream = dcn32_enable_phantom_stream(dc, context, pipes, pipe_cnt, index);
    1787           0 :         dcn32_enable_phantom_plane(dc, context, phantom_stream, index);
    1788             : 
    1789           0 :         for (i = 0; i < dc->res_pool->pipe_count; i++) {
    1790           0 :                 struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
    1791             : 
    1792             :                 // Build scaling params for phantom pipes which were newly added.
    1793             :                 // We determine which phantom pipes were added by comparing with
    1794             :                 // the phantom stream.
    1795           0 :                 if (pipe->plane_state && pipe->stream && pipe->stream == phantom_stream &&
    1796           0 :                                 pipe->stream->mall_stream_config.type == SUBVP_PHANTOM) {
    1797           0 :                         pipe->stream->use_dynamic_meta = false;
    1798           0 :                         pipe->plane_state->flip_immediate = false;
    1799           0 :                         if (!resource_build_scaling_params(pipe)) {
    1800             :                                 // Log / remove phantom pipes since failed to build scaling params
    1801             :                         }
    1802             :                 }
    1803             :         }
    1804           0 : }
    1805             : 
    1806           0 : bool dcn32_validate_bandwidth(struct dc *dc,
    1807             :                 struct dc_state *context,
    1808             :                 bool fast_validate)
    1809             : {
    1810           0 :         bool out = false;
    1811             : 
    1812           0 :         BW_VAL_TRACE_SETUP();
    1813             : 
    1814           0 :         int vlevel = 0;
    1815           0 :         int pipe_cnt = 0;
    1816           0 :         display_e2e_pipe_params_st *pipes = kzalloc(dc->res_pool->pipe_count * sizeof(display_e2e_pipe_params_st), GFP_KERNEL);
    1817             :         DC_LOGGER_INIT(dc->ctx->logger);
    1818             : 
    1819           0 :         BW_VAL_TRACE_COUNT();
    1820             : 
    1821           0 :         DC_FP_START();
    1822           0 :         out = dcn32_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel, fast_validate);
    1823           0 :         DC_FP_END();
    1824             : 
    1825           0 :         if (pipe_cnt == 0)
    1826             :                 goto validate_out;
    1827             : 
    1828           0 :         if (!out)
    1829             :                 goto validate_fail;
    1830             : 
    1831           0 :         BW_VAL_TRACE_END_VOLTAGE_LEVEL();
    1832             : 
    1833           0 :         if (fast_validate) {
    1834           0 :                 BW_VAL_TRACE_SKIP(fast);
    1835             :                 goto validate_out;
    1836             :         }
    1837             : 
    1838           0 :         dc->res_pool->funcs->calculate_wm_and_dlg(dc, context, pipes, pipe_cnt, vlevel);
    1839             : 
    1840           0 :         BW_VAL_TRACE_END_WATERMARKS();
    1841             : 
    1842             :         goto validate_out;
    1843             : 
    1844             : validate_fail:
    1845           0 :         DC_LOG_WARNING("Mode Validation Warning: %s failed validation.\n",
    1846             :                 dml_get_status_message(context->bw_ctx.dml.vba.ValidationStatus[context->bw_ctx.dml.vba.soc.num_states]));
    1847             : 
    1848           0 :         BW_VAL_TRACE_SKIP(fail);
    1849             :         out = false;
    1850             : 
    1851             : validate_out:
    1852           0 :         kfree(pipes);
    1853             : 
    1854           0 :         BW_VAL_TRACE_FINISH();
    1855             : 
    1856           0 :         return out;
    1857             : }
    1858             : 
    1859             : 
    1860             : static bool is_dual_plane(enum surface_pixel_format format)
    1861             : {
    1862             :         return format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN || format == SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA;
    1863             : }
    1864             : 
    1865           0 : int dcn32_populate_dml_pipes_from_context(
    1866             :         struct dc *dc, struct dc_state *context,
    1867             :         display_e2e_pipe_params_st *pipes,
    1868             :         bool fast_validate)
    1869             : {
    1870             :         int i, pipe_cnt;
    1871           0 :         struct resource_context *res_ctx = &context->res_ctx;
    1872             :         struct pipe_ctx *pipe;
    1873           0 :         bool subvp_in_use = false, is_pipe_split_expected[MAX_PIPES];
    1874           0 :         int plane_count = 0;
    1875             :         struct dc_crtc_timing *timing;
    1876             : 
    1877           0 :         dcn20_populate_dml_pipes_from_context(dc, context, pipes, fast_validate);
    1878             : 
    1879           0 :         for (i = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {
    1880             : 
    1881           0 :                 if (!res_ctx->pipe_ctx[i].stream)
    1882           0 :                         continue;
    1883           0 :                 pipe = &res_ctx->pipe_ctx[i];
    1884           0 :                 timing = &pipe->stream->timing;
    1885             : 
    1886           0 :                 pipes[pipe_cnt].pipe.src.gpuvm = true;
    1887           0 :                 pipes[pipe_cnt].pipe.src.dcc_fraction_of_zs_req_luma = 0;
    1888           0 :                 pipes[pipe_cnt].pipe.src.dcc_fraction_of_zs_req_chroma = 0;
    1889           0 :                 pipes[pipe_cnt].pipe.dest.vfront_porch = timing->v_front_porch;
    1890           0 :                 pipes[pipe_cnt].pipe.src.gpuvm_min_page_size_kbytes = 256; // according to spreadsheet
    1891           0 :                 pipes[pipe_cnt].pipe.src.unbounded_req_mode = false;
    1892           0 :                 pipes[pipe_cnt].pipe.scale_ratio_depth.lb_depth = dm_lb_19;
    1893             : 
    1894           0 :                 switch (pipe->stream->mall_stream_config.type) {
    1895             :                 case SUBVP_MAIN:
    1896           0 :                         pipes[pipe_cnt].pipe.src.use_mall_for_pstate_change = dm_use_mall_pstate_change_sub_viewport;
    1897           0 :                         subvp_in_use = true;
    1898           0 :                         break;
    1899             :                 case SUBVP_PHANTOM:
    1900           0 :                         pipes[pipe_cnt].pipe.src.use_mall_for_pstate_change = dm_use_mall_pstate_change_phantom_pipe;
    1901           0 :                         pipes[pipe_cnt].pipe.src.use_mall_for_static_screen = dm_use_mall_static_screen_disable;
    1902             :                         // Disallow unbounded req for SubVP according to DCHUB programming guide
    1903             :                         pipes[pipe_cnt].pipe.src.unbounded_req_mode = false;
    1904           0 :                         break;
    1905             :                 case SUBVP_NONE:
    1906           0 :                         pipes[pipe_cnt].pipe.src.use_mall_for_pstate_change = dm_use_mall_pstate_change_disable;
    1907           0 :                         pipes[pipe_cnt].pipe.src.use_mall_for_static_screen = dm_use_mall_static_screen_disable;
    1908           0 :                         break;
    1909             :                 default:
    1910             :                         break;
    1911             :                 }
    1912             : 
    1913           0 :                 pipes[pipe_cnt].dout.dsc_input_bpc = 0;
    1914           0 :                 if (pipes[pipe_cnt].dout.dsc_enable) {
    1915           0 :                         switch (timing->display_color_depth) {
    1916             :                         case COLOR_DEPTH_888:
    1917           0 :                                 pipes[pipe_cnt].dout.dsc_input_bpc = 8;
    1918           0 :                                 break;
    1919             :                         case COLOR_DEPTH_101010:
    1920           0 :                                 pipes[pipe_cnt].dout.dsc_input_bpc = 10;
    1921           0 :                                 break;
    1922             :                         case COLOR_DEPTH_121212:
    1923           0 :                                 pipes[pipe_cnt].dout.dsc_input_bpc = 12;
    1924           0 :                                 break;
    1925             :                         default:
    1926           0 :                                 ASSERT(0);
    1927             :                                 break;
    1928             :                         }
    1929             :                 }
    1930             : 
    1931             :                 /* Calculate the number of planes we have so we can determine
    1932             :                  *  whether to apply ODM 2to1 policy or not
    1933             :                  */
    1934           0 :                 if (pipe->stream && !pipe->prev_odm_pipe &&
    1935           0 :                                 (!pipe->top_pipe || pipe->top_pipe->plane_state != pipe->plane_state))
    1936           0 :                         ++plane_count;
    1937             : 
    1938           0 :                 DC_FP_START();
    1939           0 :                 is_pipe_split_expected[i] = dcn32_predict_pipe_split(context, pipes[i].pipe, i);
    1940           0 :                 DC_FP_END();
    1941             : 
    1942           0 :                 pipe_cnt++;
    1943             :         }
    1944             : 
    1945             :         /* Determine whether we will apply ODM 2to1 policy
    1946             :          * Applies to single display and where the number of planes is less than 3
    1947             :          * For 3 plane case ( 2 MPO planes ), we will not set the policy for the MPO pipes
    1948             :          */
    1949           0 :         for (i = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {
    1950           0 :                 if (!res_ctx->pipe_ctx[i].stream)
    1951           0 :                         continue;
    1952           0 :                 pipe = &res_ctx->pipe_ctx[i];
    1953           0 :                 timing = &pipe->stream->timing;
    1954             : 
    1955           0 :                 pipes[pipe_cnt].pipe.dest.odm_combine_policy = dm_odm_combine_policy_dal;
    1956           0 :                 if (context->stream_count == 1 && !dc_is_hdmi_signal(res_ctx->pipe_ctx[i].stream->signal)) {
    1957           0 :                         if (dc->debug.enable_single_display_2to1_odm_policy) {
    1958           0 :                                 if (!((plane_count > 2) && pipe->top_pipe))
    1959           0 :                                         pipes[pipe_cnt].pipe.dest.odm_combine_policy = dm_odm_combine_policy_2to1;
    1960             :                         }
    1961             :                 }
    1962           0 :                 pipe_cnt++;
    1963             :         }
    1964             : 
    1965             :         /* For DET allocation, we don't want to use DML policy (not optimal for utilizing all
    1966             :          * the DET available for each pipe). Use the DET override input to maintain our driver
    1967             :          * policy.
    1968             :          */
    1969           0 :         if (pipe_cnt == 1 && !is_pipe_split_expected[0]) {
    1970           0 :                 pipes[0].pipe.src.det_size_override = DCN3_2_MAX_DET_SIZE;
    1971           0 :                 if (pipe->plane_state && !dc->debug.disable_z9_mpc) {
    1972           0 :                         if (!is_dual_plane(pipe->plane_state->format)) {
    1973           0 :                                 pipes[0].pipe.src.det_size_override = DCN3_2_DEFAULT_DET_SIZE;
    1974           0 :                                 pipes[0].pipe.src.unbounded_req_mode = true;
    1975           0 :                                 if (pipe->plane_state->src_rect.width >= 5120 &&
    1976           0 :                                         pipe->plane_state->src_rect.height >= 2880)
    1977           0 :                                         pipes[0].pipe.src.det_size_override = 320; // 5K or higher
    1978             :                         }
    1979             :                 }
    1980             :         } else
    1981           0 :                 dcn32_determine_det_override(context, pipes, is_pipe_split_expected, dc->res_pool->pipe_count);
    1982             : 
    1983             :         // In general cases we want to keep the dram clock change requirement
    1984             :         // (prefer configs that support MCLK switch). Only override to false
    1985             :         // for SubVP
    1986           0 :         if (subvp_in_use)
    1987           0 :                 context->bw_ctx.dml.soc.dram_clock_change_requirement_final = false;
    1988             :         else
    1989           0 :                 context->bw_ctx.dml.soc.dram_clock_change_requirement_final = true;
    1990             : 
    1991           0 :         return pipe_cnt;
    1992             : }
    1993             : 
    1994             : static struct dc_cap_funcs cap_funcs = {
    1995             :         .get_dcc_compression_cap = dcn20_get_dcc_compression_cap
    1996             : };
    1997             : 
    1998           0 : void dcn32_calculate_wm_and_dlg(struct dc *dc, struct dc_state *context,
    1999             :                                 display_e2e_pipe_params_st *pipes,
    2000             :                                 int pipe_cnt,
    2001             :                                 int vlevel)
    2002             : {
    2003           0 :     DC_FP_START();
    2004           0 :     dcn32_calculate_wm_and_dlg_fpu(dc, context, pipes, pipe_cnt, vlevel);
    2005           0 :     DC_FP_END();
    2006           0 : }
    2007             : 
    2008           0 : static void dcn32_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params)
    2009             : {
    2010           0 :         DC_FP_START();
    2011           0 :         dcn32_update_bw_bounding_box_fpu(dc, bw_params);
    2012           0 :         DC_FP_END();
    2013           0 : }
    2014             : 
    2015             : static struct resource_funcs dcn32_res_pool_funcs = {
    2016             :         .destroy = dcn32_destroy_resource_pool,
    2017             :         .link_enc_create = dcn32_link_encoder_create,
    2018             :         .link_enc_create_minimal = NULL,
    2019             :         .panel_cntl_create = dcn32_panel_cntl_create,
    2020             :         .validate_bandwidth = dcn32_validate_bandwidth,
    2021             :         .calculate_wm_and_dlg = dcn32_calculate_wm_and_dlg,
    2022             :         .populate_dml_pipes = dcn32_populate_dml_pipes_from_context,
    2023             :         .acquire_idle_pipe_for_head_pipe_in_layer = dcn32_acquire_idle_pipe_for_head_pipe_in_layer,
    2024             :         .add_stream_to_ctx = dcn30_add_stream_to_ctx,
    2025             :         .add_dsc_to_stream_resource = dcn20_add_dsc_to_stream_resource,
    2026             :         .remove_stream_from_ctx = dcn20_remove_stream_from_ctx,
    2027             :         .populate_dml_writeback_from_context = dcn30_populate_dml_writeback_from_context,
    2028             :         .set_mcif_arb_params = dcn30_set_mcif_arb_params,
    2029             :         .find_first_free_match_stream_enc_for_link = dcn10_find_first_free_match_stream_enc_for_link,
    2030             :         .acquire_post_bldn_3dlut = dcn32_acquire_post_bldn_3dlut,
    2031             :         .release_post_bldn_3dlut = dcn32_release_post_bldn_3dlut,
    2032             :         .update_bw_bounding_box = dcn32_update_bw_bounding_box,
    2033             :         .patch_unknown_plane_state = dcn20_patch_unknown_plane_state,
    2034             :         .update_soc_for_wm_a = dcn30_update_soc_for_wm_a,
    2035             :         .add_phantom_pipes = dcn32_add_phantom_pipes,
    2036             :         .remove_phantom_pipes = dcn32_remove_phantom_pipes,
    2037             : };
    2038             : 
    2039             : 
    2040           0 : static bool dcn32_resource_construct(
    2041             :         uint8_t num_virtual_links,
    2042             :         struct dc *dc,
    2043             :         struct dcn32_resource_pool *pool)
    2044             : {
    2045             :         int i, j;
    2046           0 :         struct dc_context *ctx = dc->ctx;
    2047             :         struct irq_service_init_data init_data;
    2048           0 :         struct ddc_service_init_data ddc_init_data = {0};
    2049           0 :         uint32_t pipe_fuses = 0;
    2050           0 :         uint32_t num_pipes  = 4;
    2051             : 
    2052             :         #undef REG_STRUCT
    2053             :         #define REG_STRUCT bios_regs
    2054           0 :                 bios_regs_init();
    2055             : 
    2056             :         #undef REG_STRUCT
    2057             :         #define REG_STRUCT clk_src_regs
    2058           0 :                 clk_src_regs_init(0, A),
    2059           0 :                 clk_src_regs_init(1, B),
    2060           0 :                 clk_src_regs_init(2, C),
    2061           0 :                 clk_src_regs_init(3, D),
    2062           0 :                 clk_src_regs_init(4, E);
    2063             :         #undef REG_STRUCT
    2064             :         #define REG_STRUCT abm_regs
    2065           0 :                 abm_regs_init(0),
    2066           0 :                 abm_regs_init(1),
    2067           0 :                 abm_regs_init(2),
    2068           0 :                 abm_regs_init(3);
    2069             : 
    2070             :         #undef REG_STRUCT
    2071             :         #define REG_STRUCT dccg_regs
    2072           0 :                 dccg_regs_init();
    2073             : 
    2074           0 :         DC_FP_START();
    2075             : 
    2076           0 :         ctx->dc_bios->regs = &bios_regs;
    2077             : 
    2078           0 :         pool->base.res_cap = &res_cap_dcn32;
    2079             :         /* max number of pipes for ASIC before checking for pipe fuses */
    2080           0 :         num_pipes  = pool->base.res_cap->num_timing_generator;
    2081           0 :         pipe_fuses = REG_READ(CC_DC_PIPE_DIS);
    2082             : 
    2083           0 :         for (i = 0; i < pool->base.res_cap->num_timing_generator; i++)
    2084           0 :                 if (pipe_fuses & 1 << i)
    2085           0 :                         num_pipes--;
    2086             : 
    2087           0 :         if (pipe_fuses & 1)
    2088           0 :                 ASSERT(0); //Unexpected - Pipe 0 should always be fully functional!
    2089             : 
    2090           0 :         if (pipe_fuses & CC_DC_PIPE_DIS__DC_FULL_DIS_MASK)
    2091           0 :                 ASSERT(0); //Entire DCN is harvested!
    2092             : 
    2093             :         /* within dml lib, initial value is hard coded, if ASIC pipe is fused, the
    2094             :          * value will be changed, update max_num_dpp and max_num_otg for dml.
    2095             :          */
    2096           0 :         dcn3_2_ip.max_num_dpp = num_pipes;
    2097           0 :         dcn3_2_ip.max_num_otg = num_pipes;
    2098             : 
    2099           0 :         pool->base.funcs = &dcn32_res_pool_funcs;
    2100             : 
    2101             :         /*************************************************
    2102             :          *  Resource + asic cap harcoding                *
    2103             :          *************************************************/
    2104           0 :         pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE;
    2105           0 :         pool->base.timing_generator_count = num_pipes;
    2106           0 :         pool->base.pipe_count = num_pipes;
    2107           0 :         pool->base.mpcc_count = num_pipes;
    2108           0 :         dc->caps.max_downscale_ratio = 600;
    2109           0 :         dc->caps.i2c_speed_in_khz = 100;
    2110           0 :         dc->caps.i2c_speed_in_khz_hdcp = 100; /*1.4 w/a applied by default*/
    2111           0 :         dc->caps.max_cursor_size = 256;
    2112           0 :         dc->caps.min_horizontal_blanking_period = 80;
    2113           0 :         dc->caps.dmdata_alloc_size = 2048;
    2114           0 :         dc->caps.mall_size_per_mem_channel = 0;
    2115           0 :         dc->caps.mall_size_total = 0;
    2116           0 :         dc->caps.cursor_cache_size = dc->caps.max_cursor_size * dc->caps.max_cursor_size * 8;
    2117             : 
    2118           0 :         dc->caps.cache_line_size = 64;
    2119           0 :         dc->caps.cache_num_ways = 16;
    2120           0 :         dc->caps.max_cab_allocation_bytes = 67108864; // 64MB = 1024 * 1024 * 64
    2121           0 :         dc->caps.subvp_fw_processing_delay_us = 15;
    2122           0 :         dc->caps.subvp_prefetch_end_to_mall_start_us = 15;
    2123           0 :         dc->caps.subvp_swath_height_margin_lines = 16;
    2124           0 :         dc->caps.subvp_pstate_allow_width_us = 20;
    2125           0 :         dc->caps.subvp_vertical_int_margin_us = 30;
    2126             : 
    2127           0 :         dc->caps.max_slave_planes = 2;
    2128           0 :         dc->caps.max_slave_yuv_planes = 2;
    2129           0 :         dc->caps.max_slave_rgb_planes = 2;
    2130           0 :         dc->caps.post_blend_color_processing = true;
    2131           0 :         dc->caps.force_dp_tps4_for_cp2520 = true;
    2132           0 :         dc->caps.dp_hpo = true;
    2133           0 :         dc->caps.dp_hdmi21_pcon_support = true;
    2134           0 :         dc->caps.edp_dsc_support = true;
    2135           0 :         dc->caps.extended_aux_timeout_support = true;
    2136           0 :         dc->caps.dmcub_support = true;
    2137             : 
    2138             :         /* Color pipeline capabilities */
    2139           0 :         dc->caps.color.dpp.dcn_arch = 1;
    2140           0 :         dc->caps.color.dpp.input_lut_shared = 0;
    2141           0 :         dc->caps.color.dpp.icsc = 1;
    2142           0 :         dc->caps.color.dpp.dgam_ram = 0; // must use gamma_corr
    2143           0 :         dc->caps.color.dpp.dgam_rom_caps.srgb = 1;
    2144           0 :         dc->caps.color.dpp.dgam_rom_caps.bt2020 = 1;
    2145           0 :         dc->caps.color.dpp.dgam_rom_caps.gamma2_2 = 1;
    2146           0 :         dc->caps.color.dpp.dgam_rom_caps.pq = 1;
    2147           0 :         dc->caps.color.dpp.dgam_rom_caps.hlg = 1;
    2148           0 :         dc->caps.color.dpp.post_csc = 1;
    2149           0 :         dc->caps.color.dpp.gamma_corr = 1;
    2150           0 :         dc->caps.color.dpp.dgam_rom_for_yuv = 0;
    2151             : 
    2152           0 :         dc->caps.color.dpp.hw_3d_lut = 1;
    2153           0 :         dc->caps.color.dpp.ogam_ram = 0;  // no OGAM in DPP since DCN1
    2154             :         // no OGAM ROM on DCN2 and later ASICs
    2155           0 :         dc->caps.color.dpp.ogam_rom_caps.srgb = 0;
    2156           0 :         dc->caps.color.dpp.ogam_rom_caps.bt2020 = 0;
    2157           0 :         dc->caps.color.dpp.ogam_rom_caps.gamma2_2 = 0;
    2158           0 :         dc->caps.color.dpp.ogam_rom_caps.pq = 0;
    2159           0 :         dc->caps.color.dpp.ogam_rom_caps.hlg = 0;
    2160           0 :         dc->caps.color.dpp.ocsc = 0;
    2161             : 
    2162           0 :         dc->caps.color.mpc.gamut_remap = 1;
    2163           0 :         dc->caps.color.mpc.num_3dluts = pool->base.res_cap->num_mpc_3dlut; //4, configurable to be before or after BLND in MPCC
    2164           0 :         dc->caps.color.mpc.ogam_ram = 1;
    2165           0 :         dc->caps.color.mpc.ogam_rom_caps.srgb = 0;
    2166           0 :         dc->caps.color.mpc.ogam_rom_caps.bt2020 = 0;
    2167           0 :         dc->caps.color.mpc.ogam_rom_caps.gamma2_2 = 0;
    2168           0 :         dc->caps.color.mpc.ogam_rom_caps.pq = 0;
    2169           0 :         dc->caps.color.mpc.ogam_rom_caps.hlg = 0;
    2170           0 :         dc->caps.color.mpc.ocsc = 1;
    2171             : 
    2172             :         /* Use pipe context based otg sync logic */
    2173           0 :         dc->config.use_pipe_ctx_sync_logic = true;
    2174             : 
    2175             :         /* read VBIOS LTTPR caps */
    2176             :         {
    2177           0 :                 if (ctx->dc_bios->funcs->get_lttpr_caps) {
    2178             :                         enum bp_result bp_query_result;
    2179           0 :                         uint8_t is_vbios_lttpr_enable = 0;
    2180             : 
    2181           0 :                         bp_query_result = ctx->dc_bios->funcs->get_lttpr_caps(ctx->dc_bios, &is_vbios_lttpr_enable);
    2182           0 :                         dc->caps.vbios_lttpr_enable = (bp_query_result == BP_RESULT_OK) && !!is_vbios_lttpr_enable;
    2183             :                 }
    2184             : 
    2185             :                 /* interop bit is implicit */
    2186             :                 {
    2187           0 :                         dc->caps.vbios_lttpr_aware = true;
    2188             :                 }
    2189             :         }
    2190             : 
    2191           0 :         if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV)
    2192           0 :                 dc->debug = debug_defaults_drv;
    2193           0 :         else if (dc->ctx->dce_environment == DCE_ENV_FPGA_MAXIMUS) {
    2194           0 :                 dc->debug = debug_defaults_diags;
    2195             :         } else
    2196           0 :                 dc->debug = debug_defaults_diags;
    2197             :         // Init the vm_helper
    2198           0 :         if (dc->vm_helper)
    2199           0 :                 vm_helper_init(dc->vm_helper, 16);
    2200             : 
    2201             :         /*************************************************
    2202             :          *  Create resources                             *
    2203             :          *************************************************/
    2204             : 
    2205             :         /* Clock Sources for Pixel Clock*/
    2206           0 :         pool->base.clock_sources[DCN32_CLK_SRC_PLL0] =
    2207           0 :                         dcn32_clock_source_create(ctx, ctx->dc_bios,
    2208             :                                 CLOCK_SOURCE_COMBO_PHY_PLL0,
    2209             :                                 &clk_src_regs[0], false);
    2210           0 :         pool->base.clock_sources[DCN32_CLK_SRC_PLL1] =
    2211           0 :                         dcn32_clock_source_create(ctx, ctx->dc_bios,
    2212             :                                 CLOCK_SOURCE_COMBO_PHY_PLL1,
    2213             :                                 &clk_src_regs[1], false);
    2214           0 :         pool->base.clock_sources[DCN32_CLK_SRC_PLL2] =
    2215           0 :                         dcn32_clock_source_create(ctx, ctx->dc_bios,
    2216             :                                 CLOCK_SOURCE_COMBO_PHY_PLL2,
    2217             :                                 &clk_src_regs[2], false);
    2218           0 :         pool->base.clock_sources[DCN32_CLK_SRC_PLL3] =
    2219           0 :                         dcn32_clock_source_create(ctx, ctx->dc_bios,
    2220             :                                 CLOCK_SOURCE_COMBO_PHY_PLL3,
    2221             :                                 &clk_src_regs[3], false);
    2222           0 :         pool->base.clock_sources[DCN32_CLK_SRC_PLL4] =
    2223           0 :                         dcn32_clock_source_create(ctx, ctx->dc_bios,
    2224             :                                 CLOCK_SOURCE_COMBO_PHY_PLL4,
    2225             :                                 &clk_src_regs[4], false);
    2226             : 
    2227           0 :         pool->base.clk_src_count = DCN32_CLK_SRC_TOTAL;
    2228             : 
    2229             :         /* todo: not reuse phy_pll registers */
    2230           0 :         pool->base.dp_clock_source =
    2231           0 :                         dcn32_clock_source_create(ctx, ctx->dc_bios,
    2232             :                                 CLOCK_SOURCE_ID_DP_DTO,
    2233             :                                 &clk_src_regs[0], true);
    2234             : 
    2235           0 :         for (i = 0; i < pool->base.clk_src_count; i++) {
    2236           0 :                 if (pool->base.clock_sources[i] == NULL) {
    2237           0 :                         dm_error("DC: failed to create clock sources!\n");
    2238           0 :                         BREAK_TO_DEBUGGER();
    2239           0 :                         goto create_fail;
    2240             :                 }
    2241             :         }
    2242             : 
    2243             :         /* DCCG */
    2244           0 :         pool->base.dccg = dccg32_create(ctx, &dccg_regs, &dccg_shift, &dccg_mask);
    2245           0 :         if (pool->base.dccg == NULL) {
    2246           0 :                 dm_error("DC: failed to create dccg!\n");
    2247           0 :                 BREAK_TO_DEBUGGER();
    2248           0 :                 goto create_fail;
    2249             :         }
    2250             : 
    2251             :         /* DML */
    2252           0 :         if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment))
    2253           0 :                 dml_init_instance(&dc->dml, &dcn3_2_soc, &dcn3_2_ip, DML_PROJECT_DCN32);
    2254             : 
    2255             :         /* IRQ Service */
    2256           0 :         init_data.ctx = dc->ctx;
    2257           0 :         pool->base.irqs = dal_irq_service_dcn32_create(&init_data);
    2258           0 :         if (!pool->base.irqs)
    2259             :                 goto create_fail;
    2260             : 
    2261             :         /* HUBBUB */
    2262           0 :         pool->base.hubbub = dcn32_hubbub_create(ctx);
    2263           0 :         if (pool->base.hubbub == NULL) {
    2264           0 :                 BREAK_TO_DEBUGGER();
    2265           0 :                 dm_error("DC: failed to create hubbub!\n");
    2266           0 :                 goto create_fail;
    2267             :         }
    2268             : 
    2269             :         /* HUBPs, DPPs, OPPs, TGs, ABMs */
    2270           0 :         for (i = 0, j = 0; i < pool->base.res_cap->num_timing_generator; i++) {
    2271             : 
    2272             :                 /* if pipe is disabled, skip instance of HW pipe,
    2273             :                  * i.e, skip ASIC register instance
    2274             :                  */
    2275           0 :                 if (pipe_fuses & 1 << i)
    2276           0 :                         continue;
    2277             : 
    2278             :                 /* HUBPs */
    2279           0 :                 pool->base.hubps[j] = dcn32_hubp_create(ctx, i);
    2280           0 :                 if (pool->base.hubps[j] == NULL) {
    2281           0 :                         BREAK_TO_DEBUGGER();
    2282           0 :                         dm_error(
    2283             :                                 "DC: failed to create hubps!\n");
    2284           0 :                         goto create_fail;
    2285             :                 }
    2286             : 
    2287             :                 /* DPPs */
    2288           0 :                 pool->base.dpps[j] = dcn32_dpp_create(ctx, i);
    2289           0 :                 if (pool->base.dpps[j] == NULL) {
    2290           0 :                         BREAK_TO_DEBUGGER();
    2291           0 :                         dm_error(
    2292             :                                 "DC: failed to create dpps!\n");
    2293           0 :                         goto create_fail;
    2294             :                 }
    2295             : 
    2296             :                 /* OPPs */
    2297           0 :                 pool->base.opps[j] = dcn32_opp_create(ctx, i);
    2298           0 :                 if (pool->base.opps[j] == NULL) {
    2299           0 :                         BREAK_TO_DEBUGGER();
    2300           0 :                         dm_error(
    2301             :                                 "DC: failed to create output pixel processor!\n");
    2302           0 :                         goto create_fail;
    2303             :                 }
    2304             : 
    2305             :                 /* TGs */
    2306           0 :                 pool->base.timing_generators[j] = dcn32_timing_generator_create(
    2307             :                                 ctx, i);
    2308           0 :                 if (pool->base.timing_generators[j] == NULL) {
    2309           0 :                         BREAK_TO_DEBUGGER();
    2310           0 :                         dm_error("DC: failed to create tg!\n");
    2311           0 :                         goto create_fail;
    2312             :                 }
    2313             : 
    2314             :                 /* ABMs */
    2315           0 :                 pool->base.multiple_abms[j] = dmub_abm_create(ctx,
    2316           0 :                                 &abm_regs[i],
    2317             :                                 &abm_shift,
    2318             :                                 &abm_mask);
    2319           0 :                 if (pool->base.multiple_abms[j] == NULL) {
    2320           0 :                         dm_error("DC: failed to create abm for pipe %d!\n", i);
    2321           0 :                         BREAK_TO_DEBUGGER();
    2322           0 :                         goto create_fail;
    2323             :                 }
    2324             : 
    2325             :                 /* index for resource pool arrays for next valid pipe */
    2326           0 :                 j++;
    2327             :         }
    2328             : 
    2329             :         /* PSR */
    2330           0 :         pool->base.psr = dmub_psr_create(ctx);
    2331           0 :         if (pool->base.psr == NULL) {
    2332           0 :                 dm_error("DC: failed to create psr obj!\n");
    2333           0 :                 BREAK_TO_DEBUGGER();
    2334           0 :                 goto create_fail;
    2335             :         }
    2336             : 
    2337             :         /* MPCCs */
    2338           0 :         pool->base.mpc = dcn32_mpc_create(ctx, pool->base.res_cap->num_timing_generator, pool->base.res_cap->num_mpc_3dlut);
    2339           0 :         if (pool->base.mpc == NULL) {
    2340           0 :                 BREAK_TO_DEBUGGER();
    2341           0 :                 dm_error("DC: failed to create mpc!\n");
    2342           0 :                 goto create_fail;
    2343             :         }
    2344             : 
    2345             :         /* DSCs */
    2346           0 :         for (i = 0; i < pool->base.res_cap->num_dsc; i++) {
    2347           0 :                 pool->base.dscs[i] = dcn32_dsc_create(ctx, i);
    2348           0 :                 if (pool->base.dscs[i] == NULL) {
    2349           0 :                         BREAK_TO_DEBUGGER();
    2350           0 :                         dm_error("DC: failed to create display stream compressor %d!\n", i);
    2351           0 :                         goto create_fail;
    2352             :                 }
    2353             :         }
    2354             : 
    2355             :         /* DWB */
    2356           0 :         if (!dcn32_dwbc_create(ctx, &pool->base)) {
    2357           0 :                 BREAK_TO_DEBUGGER();
    2358           0 :                 dm_error("DC: failed to create dwbc!\n");
    2359           0 :                 goto create_fail;
    2360             :         }
    2361             : 
    2362             :         /* MMHUBBUB */
    2363           0 :         if (!dcn32_mmhubbub_create(ctx, &pool->base)) {
    2364           0 :                 BREAK_TO_DEBUGGER();
    2365           0 :                 dm_error("DC: failed to create mcif_wb!\n");
    2366           0 :                 goto create_fail;
    2367             :         }
    2368             : 
    2369             :         /* AUX and I2C */
    2370           0 :         for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
    2371           0 :                 pool->base.engines[i] = dcn32_aux_engine_create(ctx, i);
    2372           0 :                 if (pool->base.engines[i] == NULL) {
    2373           0 :                         BREAK_TO_DEBUGGER();
    2374           0 :                         dm_error(
    2375             :                                 "DC:failed to create aux engine!!\n");
    2376           0 :                         goto create_fail;
    2377             :                 }
    2378           0 :                 pool->base.hw_i2cs[i] = dcn32_i2c_hw_create(ctx, i);
    2379           0 :                 if (pool->base.hw_i2cs[i] == NULL) {
    2380           0 :                         BREAK_TO_DEBUGGER();
    2381           0 :                         dm_error(
    2382             :                                 "DC:failed to create hw i2c!!\n");
    2383           0 :                         goto create_fail;
    2384             :                 }
    2385           0 :                 pool->base.sw_i2cs[i] = NULL;
    2386             :         }
    2387             : 
    2388             :         /* Audio, HWSeq, Stream Encoders including HPO and virtual, MPC 3D LUTs */
    2389           0 :         if (!resource_construct(num_virtual_links, dc, &pool->base,
    2390           0 :                         (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment) ?
    2391             :                         &res_create_funcs : &res_create_maximus_funcs)))
    2392             :                         goto create_fail;
    2393             : 
    2394             :         /* HW Sequencer init functions and Plane caps */
    2395           0 :         dcn32_hw_sequencer_init_functions(dc);
    2396             : 
    2397           0 :         dc->caps.max_planes =  pool->base.pipe_count;
    2398             : 
    2399           0 :         for (i = 0; i < dc->caps.max_planes; ++i)
    2400           0 :                 dc->caps.planes[i] = plane_cap;
    2401             : 
    2402           0 :         dc->cap_funcs = cap_funcs;
    2403             : 
    2404           0 :         if (dc->ctx->dc_bios->fw_info.oem_i2c_present) {
    2405           0 :                 ddc_init_data.ctx = dc->ctx;
    2406           0 :                 ddc_init_data.link = NULL;
    2407           0 :                 ddc_init_data.id.id = dc->ctx->dc_bios->fw_info.oem_i2c_obj_id;
    2408           0 :                 ddc_init_data.id.enum_id = 0;
    2409           0 :                 ddc_init_data.id.type = OBJECT_TYPE_GENERIC;
    2410           0 :                 pool->base.oem_device = dal_ddc_service_create(&ddc_init_data);
    2411             :         } else {
    2412           0 :                 pool->base.oem_device = NULL;
    2413             :         }
    2414             : 
    2415           0 :         DC_FP_END();
    2416             : 
    2417           0 :         return true;
    2418             : 
    2419             : create_fail:
    2420             : 
    2421           0 :         DC_FP_END();
    2422             : 
    2423           0 :         dcn32_resource_destruct(pool);
    2424             : 
    2425           0 :         return false;
    2426             : }
    2427             : 
    2428           0 : struct resource_pool *dcn32_create_resource_pool(
    2429             :                 const struct dc_init_data *init_data,
    2430             :                 struct dc *dc)
    2431             : {
    2432           0 :         struct dcn32_resource_pool *pool =
    2433             :                 kzalloc(sizeof(struct dcn32_resource_pool), GFP_KERNEL);
    2434             : 
    2435           0 :         if (!pool)
    2436             :                 return NULL;
    2437             : 
    2438           0 :         if (dcn32_resource_construct(init_data->num_virtual_links, dc, pool))
    2439           0 :                 return &pool->base;
    2440             : 
    2441           0 :         BREAK_TO_DEBUGGER();
    2442           0 :         kfree(pool);
    2443           0 :         return NULL;
    2444             : }
    2445             : 
    2446           0 : static struct pipe_ctx *find_idle_secondary_pipe_check_mpo(
    2447             :                 struct resource_context *res_ctx,
    2448             :                 const struct resource_pool *pool,
    2449             :                 const struct pipe_ctx *primary_pipe)
    2450             : {
    2451             :         int i;
    2452           0 :         struct pipe_ctx *secondary_pipe = NULL;
    2453           0 :         struct pipe_ctx *next_odm_mpo_pipe = NULL;
    2454             :         int primary_index, preferred_pipe_idx;
    2455           0 :         struct pipe_ctx *old_primary_pipe = NULL;
    2456             : 
    2457             :         /*
    2458             :          * Modified from find_idle_secondary_pipe
    2459             :          * With windowed MPO and ODM, we want to avoid the case where we want a
    2460             :          *  free pipe for the left side but the free pipe is being used on the
    2461             :          *  right side.
    2462             :          * Add check on current_state if the primary_pipe is the left side,
    2463             :          *  to check the right side ( primary_pipe->next_odm_pipe ) to see if
    2464             :          *  it is using a pipe for MPO ( primary_pipe->next_odm_pipe->bottom_pipe )
    2465             :          * - If so, then don't use this pipe
    2466             :          * EXCEPTION - 3 plane ( 2 MPO plane ) case
    2467             :          * - in this case, the primary pipe has already gotten a free pipe for the
    2468             :          *  MPO window in the left
    2469             :          * - when it tries to get a free pipe for the MPO window on the right,
    2470             :          *  it will see that it is already assigned to the right side
    2471             :          *  ( primary_pipe->next_odm_pipe ).  But in this case, we want this
    2472             :          *  free pipe, since it will be for the right side.  So add an
    2473             :          *  additional condition, that skipping the free pipe on the right only
    2474             :          *  applies if the primary pipe has no bottom pipe currently assigned
    2475             :          */
    2476           0 :         if (primary_pipe) {
    2477           0 :                 primary_index = primary_pipe->pipe_idx;
    2478           0 :                 old_primary_pipe = &primary_pipe->stream->ctx->dc->current_state->res_ctx.pipe_ctx[primary_index];
    2479           0 :                 if ((old_primary_pipe->next_odm_pipe) && (old_primary_pipe->next_odm_pipe->bottom_pipe)
    2480           0 :                         && (!primary_pipe->bottom_pipe))
    2481           0 :                         next_odm_mpo_pipe = old_primary_pipe->next_odm_pipe->bottom_pipe;
    2482             : 
    2483           0 :                 preferred_pipe_idx = (pool->pipe_count - 1) - primary_pipe->pipe_idx;
    2484           0 :                 if ((res_ctx->pipe_ctx[preferred_pipe_idx].stream == NULL) &&
    2485           0 :                         !(next_odm_mpo_pipe && next_odm_mpo_pipe->pipe_idx == preferred_pipe_idx)) {
    2486           0 :                         secondary_pipe = &res_ctx->pipe_ctx[preferred_pipe_idx];
    2487           0 :                         secondary_pipe->pipe_idx = preferred_pipe_idx;
    2488             :                 }
    2489             :         }
    2490             : 
    2491             :         /*
    2492             :          * search backwards for the second pipe to keep pipe
    2493             :          * assignment more consistent
    2494             :          */
    2495           0 :         if (!secondary_pipe)
    2496           0 :                 for (i = pool->pipe_count - 1; i >= 0; i--) {
    2497           0 :                         if ((res_ctx->pipe_ctx[i].stream == NULL) &&
    2498           0 :                                 !(next_odm_mpo_pipe && next_odm_mpo_pipe->pipe_idx == i)) {
    2499           0 :                                 secondary_pipe = &res_ctx->pipe_ctx[i];
    2500           0 :                                 secondary_pipe->pipe_idx = i;
    2501             :                                 break;
    2502             :                         }
    2503             :                 }
    2504             : 
    2505           0 :         return secondary_pipe;
    2506             : }
    2507             : 
    2508           0 : struct pipe_ctx *dcn32_acquire_idle_pipe_for_head_pipe_in_layer(
    2509             :                 struct dc_state *state,
    2510             :                 const struct resource_pool *pool,
    2511             :                 struct dc_stream_state *stream,
    2512             :                 struct pipe_ctx *head_pipe)
    2513             : {
    2514           0 :         struct resource_context *res_ctx = &state->res_ctx;
    2515             :         struct pipe_ctx *idle_pipe, *pipe;
    2516           0 :         struct resource_context *old_ctx = &stream->ctx->dc->current_state->res_ctx;
    2517             :         int head_index;
    2518             : 
    2519           0 :         if (!head_pipe)
    2520           0 :                 ASSERT(0);
    2521             : 
    2522             :         /*
    2523             :          * Modified from dcn20_acquire_idle_pipe_for_layer
    2524             :          * Check if head_pipe in old_context already has bottom_pipe allocated.
    2525             :          * - If so, check if that pipe is available in the current context.
    2526             :          * --  If so, reuse pipe from old_context
    2527             :          */
    2528           0 :         head_index = head_pipe->pipe_idx;
    2529           0 :         pipe = &old_ctx->pipe_ctx[head_index];
    2530           0 :         if (pipe->bottom_pipe && res_ctx->pipe_ctx[pipe->bottom_pipe->pipe_idx].stream == NULL) {
    2531           0 :                 idle_pipe = &res_ctx->pipe_ctx[pipe->bottom_pipe->pipe_idx];
    2532           0 :                 idle_pipe->pipe_idx = pipe->bottom_pipe->pipe_idx;
    2533             :         } else {
    2534           0 :                 idle_pipe = find_idle_secondary_pipe_check_mpo(res_ctx, pool, head_pipe);
    2535           0 :                 if (!idle_pipe)
    2536             :                         return NULL;
    2537             :         }
    2538             : 
    2539           0 :         idle_pipe->stream = head_pipe->stream;
    2540           0 :         idle_pipe->stream_res.tg = head_pipe->stream_res.tg;
    2541           0 :         idle_pipe->stream_res.opp = head_pipe->stream_res.opp;
    2542             : 
    2543           0 :         idle_pipe->plane_res.hubp = pool->hubps[idle_pipe->pipe_idx];
    2544           0 :         idle_pipe->plane_res.ipp = pool->ipps[idle_pipe->pipe_idx];
    2545           0 :         idle_pipe->plane_res.dpp = pool->dpps[idle_pipe->pipe_idx];
    2546           0 :         idle_pipe->plane_res.mpcc_inst = pool->dpps[idle_pipe->pipe_idx]->inst;
    2547             : 
    2548           0 :         return idle_pipe;
    2549             : }

Generated by: LCOV version 1.14