cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

dcn30_resource.c (66166B)


      1/*
      2 * Copyright 2020 Advanced Micro Devices, Inc.
      3 *
      4 * Permission is hereby granted, free of charge, to any person obtaining a
      5 * copy of this software and associated documentation files (the "Software"),
      6 * to deal in the Software without restriction, including without limitation
      7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      8 * and/or sell copies of the Software, and to permit persons to whom the
      9 * Software is furnished to do so, subject to the following conditions:
     10 *
     11 * The above copyright notice and this permission notice shall be included in
     12 * all copies or substantial portions of the Software.
     13 *
     14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
     18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     20 * OTHER DEALINGS IN THE SOFTWARE.
     21 *
     22 * Authors: AMD
     23 *
     24 */
     25
     26
     27#include "dm_services.h"
     28#include "dc.h"
     29
     30#include "dcn30_init.h"
     31
     32#include "resource.h"
     33#include "include/irq_service_interface.h"
     34#include "dcn20/dcn20_resource.h"
     35
     36#include "dcn30_resource.h"
     37
     38#include "dcn10/dcn10_ipp.h"
     39#include "dcn30/dcn30_hubbub.h"
     40#include "dcn30/dcn30_mpc.h"
     41#include "dcn30/dcn30_hubp.h"
     42#include "irq/dcn30/irq_service_dcn30.h"
     43#include "dcn30/dcn30_dpp.h"
     44#include "dcn30/dcn30_optc.h"
     45#include "dcn20/dcn20_hwseq.h"
     46#include "dcn30/dcn30_hwseq.h"
     47#include "dce110/dce110_hw_sequencer.h"
     48#include "dcn30/dcn30_opp.h"
     49#include "dcn20/dcn20_dsc.h"
     50#include "dcn30/dcn30_vpg.h"
     51#include "dcn30/dcn30_afmt.h"
     52#include "dcn30/dcn30_dio_stream_encoder.h"
     53#include "dcn30/dcn30_dio_link_encoder.h"
     54#include "dce/dce_clock_source.h"
     55#include "dce/dce_audio.h"
     56#include "dce/dce_hwseq.h"
     57#include "clk_mgr.h"
     58#include "virtual/virtual_stream_encoder.h"
     59#include "dce110/dce110_resource.h"
     60#include "dml/display_mode_vba.h"
     61#include "dcn30/dcn30_dccg.h"
     62#include "dcn10/dcn10_resource.h"
     63#include "dc_link_ddc.h"
     64#include "dce/dce_panel_cntl.h"
     65
     66#include "dcn30/dcn30_dwb.h"
     67#include "dcn30/dcn30_mmhubbub.h"
     68
     69#include "sienna_cichlid_ip_offset.h"
     70#include "dcn/dcn_3_0_0_offset.h"
     71#include "dcn/dcn_3_0_0_sh_mask.h"
     72
     73#include "nbio/nbio_7_4_offset.h"
     74
     75#include "dpcs/dpcs_3_0_0_offset.h"
     76#include "dpcs/dpcs_3_0_0_sh_mask.h"
     77
     78#include "mmhub/mmhub_2_0_0_offset.h"
     79#include "mmhub/mmhub_2_0_0_sh_mask.h"
     80
     81#include "reg_helper.h"
     82#include "dce/dmub_abm.h"
     83#include "dce/dmub_psr.h"
     84#include "dce/dce_aux.h"
     85#include "dce/dce_i2c.h"
     86
     87#include "dml/dcn30/dcn30_fpu.h"
     88#include "dml/dcn30/display_mode_vba_30.h"
     89#include "vm_helper.h"
     90#include "dcn20/dcn20_vmid.h"
     91#include "amdgpu_socbb.h"
     92
     93#define DC_LOGGER_INIT(logger)
     94
     95enum dcn30_clk_src_array_id {
     96	DCN30_CLK_SRC_PLL0,
     97	DCN30_CLK_SRC_PLL1,
     98	DCN30_CLK_SRC_PLL2,
     99	DCN30_CLK_SRC_PLL3,
    100	DCN30_CLK_SRC_PLL4,
    101	DCN30_CLK_SRC_PLL5,
    102	DCN30_CLK_SRC_TOTAL
    103};
    104
    105/* begin *********************
    106 * macros to expend register list macro defined in HW object header file
    107 */
    108
    109/* DCN */
    110/* TODO awful hack. fixup dcn20_dwb.h */
    111#undef BASE_INNER
    112#define BASE_INNER(seg) DCN_BASE__INST0_SEG ## seg
    113
    114#define BASE(seg) BASE_INNER(seg)
    115
    116#define SR(reg_name)\
    117		.reg_name = BASE(mm ## reg_name ## _BASE_IDX) +  \
    118					mm ## reg_name
    119
    120#define SRI(reg_name, block, id)\
    121	.reg_name = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
    122					mm ## block ## id ## _ ## reg_name
    123
    124#define SRI2(reg_name, block, id)\
    125	.reg_name = BASE(mm ## reg_name ## _BASE_IDX) + \
    126					mm ## reg_name
    127
    128#define SRIR(var_name, reg_name, block, id)\
    129	.var_name = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
    130					mm ## block ## id ## _ ## reg_name
    131
    132#define SRII(reg_name, block, id)\
    133	.reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
    134					mm ## block ## id ## _ ## reg_name
    135
    136#define SRII_MPC_RMU(reg_name, block, id)\
    137	.RMU##_##reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
    138					mm ## block ## id ## _ ## reg_name
    139
    140#define SRII_DWB(reg_name, temp_name, block, id)\
    141	.reg_name[id] = BASE(mm ## block ## id ## _ ## temp_name ## _BASE_IDX) + \
    142					mm ## block ## id ## _ ## temp_name
    143
    144#define DCCG_SRII(reg_name, block, id)\
    145	.block ## _ ## reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
    146					mm ## block ## id ## _ ## reg_name
    147
    148#define VUPDATE_SRII(reg_name, block, id)\
    149	.reg_name[id] = BASE(mm ## reg_name ## _ ## block ## id ## _BASE_IDX) + \
    150					mm ## reg_name ## _ ## block ## id
    151
    152/* NBIO */
    153#define NBIO_BASE_INNER(seg) \
    154	NBIO_BASE__INST0_SEG ## seg
    155
    156#define NBIO_BASE(seg) \
    157	NBIO_BASE_INNER(seg)
    158
    159#define NBIO_SR(reg_name)\
    160		.reg_name = NBIO_BASE(mm ## reg_name ## _BASE_IDX) + \
    161					mm ## reg_name
    162
    163/* MMHUB */
    164#define MMHUB_BASE_INNER(seg) \
    165	MMHUB_BASE__INST0_SEG ## seg
    166
    167#define MMHUB_BASE(seg) \
    168	MMHUB_BASE_INNER(seg)
    169
    170#define MMHUB_SR(reg_name)\
    171		.reg_name = MMHUB_BASE(mmMM ## reg_name ## _BASE_IDX) + \
    172					mmMM ## reg_name
    173
    174/* CLOCK */
    175#define CLK_BASE_INNER(seg) \
    176	CLK_BASE__INST0_SEG ## seg
    177
    178#define CLK_BASE(seg) \
    179	CLK_BASE_INNER(seg)
    180
    181#define CLK_SRI(reg_name, block, inst)\
    182	.reg_name = CLK_BASE(mm ## block ## _ ## inst ## _ ## reg_name ## _BASE_IDX) + \
    183					mm ## block ## _ ## inst ## _ ## reg_name
    184
    185
    186static const struct bios_registers bios_regs = {
    187		NBIO_SR(BIOS_SCRATCH_3),
    188		NBIO_SR(BIOS_SCRATCH_6)
    189};
    190
    191#define clk_src_regs(index, pllid)\
    192[index] = {\
    193	CS_COMMON_REG_LIST_DCN2_0(index, pllid),\
    194}
    195
    196static const struct dce110_clk_src_regs clk_src_regs[] = {
    197	clk_src_regs(0, A),
    198	clk_src_regs(1, B),
    199	clk_src_regs(2, C),
    200	clk_src_regs(3, D),
    201	clk_src_regs(4, E),
    202	clk_src_regs(5, F)
    203};
    204
    205static const struct dce110_clk_src_shift cs_shift = {
    206		CS_COMMON_MASK_SH_LIST_DCN2_0(__SHIFT)
    207};
    208
    209static const struct dce110_clk_src_mask cs_mask = {
    210		CS_COMMON_MASK_SH_LIST_DCN2_0(_MASK)
    211};
    212
    213#define abm_regs(id)\
    214[id] = {\
    215		ABM_DCN30_REG_LIST(id)\
    216}
    217
    218static const struct dce_abm_registers abm_regs[] = {
    219		abm_regs(0),
    220		abm_regs(1),
    221		abm_regs(2),
    222		abm_regs(3),
    223		abm_regs(4),
    224		abm_regs(5),
    225};
    226
    227static const struct dce_abm_shift abm_shift = {
    228		ABM_MASK_SH_LIST_DCN30(__SHIFT)
    229};
    230
    231static const struct dce_abm_mask abm_mask = {
    232		ABM_MASK_SH_LIST_DCN30(_MASK)
    233};
    234
    235
    236
    237#define audio_regs(id)\
    238[id] = {\
    239		AUD_COMMON_REG_LIST(id)\
    240}
    241
    242static const struct dce_audio_registers audio_regs[] = {
    243	audio_regs(0),
    244	audio_regs(1),
    245	audio_regs(2),
    246	audio_regs(3),
    247	audio_regs(4),
    248	audio_regs(5),
    249	audio_regs(6)
    250};
    251
    252#define DCE120_AUD_COMMON_MASK_SH_LIST(mask_sh)\
    253		SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_INDEX, AZALIA_ENDPOINT_REG_INDEX, mask_sh),\
    254		SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_DATA, AZALIA_ENDPOINT_REG_DATA, mask_sh),\
    255		AUD_COMMON_MASK_SH_LIST_BASE(mask_sh)
    256
    257static const struct dce_audio_shift audio_shift = {
    258		DCE120_AUD_COMMON_MASK_SH_LIST(__SHIFT)
    259};
    260
    261static const struct dce_audio_mask audio_mask = {
    262		DCE120_AUD_COMMON_MASK_SH_LIST(_MASK)
    263};
    264
    265#define vpg_regs(id)\
    266[id] = {\
    267	VPG_DCN3_REG_LIST(id)\
    268}
    269
    270static const struct dcn30_vpg_registers vpg_regs[] = {
    271	vpg_regs(0),
    272	vpg_regs(1),
    273	vpg_regs(2),
    274	vpg_regs(3),
    275	vpg_regs(4),
    276	vpg_regs(5),
    277	vpg_regs(6),
    278};
    279
    280static const struct dcn30_vpg_shift vpg_shift = {
    281	DCN3_VPG_MASK_SH_LIST(__SHIFT)
    282};
    283
    284static const struct dcn30_vpg_mask vpg_mask = {
    285	DCN3_VPG_MASK_SH_LIST(_MASK)
    286};
    287
    288#define afmt_regs(id)\
    289[id] = {\
    290	AFMT_DCN3_REG_LIST(id)\
    291}
    292
    293static const struct dcn30_afmt_registers afmt_regs[] = {
    294	afmt_regs(0),
    295	afmt_regs(1),
    296	afmt_regs(2),
    297	afmt_regs(3),
    298	afmt_regs(4),
    299	afmt_regs(5),
    300	afmt_regs(6),
    301};
    302
    303static const struct dcn30_afmt_shift afmt_shift = {
    304	DCN3_AFMT_MASK_SH_LIST(__SHIFT)
    305};
    306
    307static const struct dcn30_afmt_mask afmt_mask = {
    308	DCN3_AFMT_MASK_SH_LIST(_MASK)
    309};
    310
    311#define stream_enc_regs(id)\
    312[id] = {\
    313	SE_DCN3_REG_LIST(id)\
    314}
    315
    316static const struct dcn10_stream_enc_registers stream_enc_regs[] = {
    317	stream_enc_regs(0),
    318	stream_enc_regs(1),
    319	stream_enc_regs(2),
    320	stream_enc_regs(3),
    321	stream_enc_regs(4),
    322	stream_enc_regs(5)
    323};
    324
    325static const struct dcn10_stream_encoder_shift se_shift = {
    326		SE_COMMON_MASK_SH_LIST_DCN30(__SHIFT)
    327};
    328
    329static const struct dcn10_stream_encoder_mask se_mask = {
    330		SE_COMMON_MASK_SH_LIST_DCN30(_MASK)
    331};
    332
    333
    334#define aux_regs(id)\
    335[id] = {\
    336	DCN2_AUX_REG_LIST(id)\
    337}
    338
    339static const struct dcn10_link_enc_aux_registers link_enc_aux_regs[] = {
    340		aux_regs(0),
    341		aux_regs(1),
    342		aux_regs(2),
    343		aux_regs(3),
    344		aux_regs(4),
    345		aux_regs(5)
    346};
    347
    348#define hpd_regs(id)\
    349[id] = {\
    350	HPD_REG_LIST(id)\
    351}
    352
    353static const struct dcn10_link_enc_hpd_registers link_enc_hpd_regs[] = {
    354		hpd_regs(0),
    355		hpd_regs(1),
    356		hpd_regs(2),
    357		hpd_regs(3),
    358		hpd_regs(4),
    359		hpd_regs(5)
    360};
    361
    362#define link_regs(id, phyid)\
    363[id] = {\
    364	LE_DCN3_REG_LIST(id), \
    365	UNIPHY_DCN2_REG_LIST(phyid), \
    366	DPCS_DCN2_REG_LIST(id), \
    367	SRI(DP_DPHY_INTERNAL_CTRL, DP, id) \
    368}
    369
    370static const struct dce110_aux_registers_shift aux_shift = {
    371	DCN_AUX_MASK_SH_LIST(__SHIFT)
    372};
    373
    374static const struct dce110_aux_registers_mask aux_mask = {
    375	DCN_AUX_MASK_SH_LIST(_MASK)
    376};
    377
    378static const struct dcn10_link_enc_registers link_enc_regs[] = {
    379	link_regs(0, A),
    380	link_regs(1, B),
    381	link_regs(2, C),
    382	link_regs(3, D),
    383	link_regs(4, E),
    384	link_regs(5, F)
    385};
    386
    387static const struct dcn10_link_enc_shift le_shift = {
    388	LINK_ENCODER_MASK_SH_LIST_DCN30(__SHIFT),\
    389	DPCS_DCN2_MASK_SH_LIST(__SHIFT)
    390};
    391
    392static const struct dcn10_link_enc_mask le_mask = {
    393	LINK_ENCODER_MASK_SH_LIST_DCN30(_MASK),\
    394	DPCS_DCN2_MASK_SH_LIST(_MASK)
    395};
    396
    397
    398static const struct dce_panel_cntl_registers panel_cntl_regs[] = {
    399	{ DCN_PANEL_CNTL_REG_LIST() }
    400};
    401
    402static const struct dce_panel_cntl_shift panel_cntl_shift = {
    403	DCE_PANEL_CNTL_MASK_SH_LIST(__SHIFT)
    404};
    405
    406static const struct dce_panel_cntl_mask panel_cntl_mask = {
    407	DCE_PANEL_CNTL_MASK_SH_LIST(_MASK)
    408};
    409
    410#define dpp_regs(id)\
    411[id] = {\
    412	DPP_REG_LIST_DCN30(id),\
    413}
    414
    415static const struct dcn3_dpp_registers dpp_regs[] = {
    416	dpp_regs(0),
    417	dpp_regs(1),
    418	dpp_regs(2),
    419	dpp_regs(3),
    420	dpp_regs(4),
    421	dpp_regs(5),
    422};
    423
    424static const struct dcn3_dpp_shift tf_shift = {
    425		DPP_REG_LIST_SH_MASK_DCN30(__SHIFT)
    426};
    427
    428static const struct dcn3_dpp_mask tf_mask = {
    429		DPP_REG_LIST_SH_MASK_DCN30(_MASK)
    430};
    431
    432#define opp_regs(id)\
    433[id] = {\
    434	OPP_REG_LIST_DCN30(id),\
    435}
    436
    437static const struct dcn20_opp_registers opp_regs[] = {
    438	opp_regs(0),
    439	opp_regs(1),
    440	opp_regs(2),
    441	opp_regs(3),
    442	opp_regs(4),
    443	opp_regs(5)
    444};
    445
    446static const struct dcn20_opp_shift opp_shift = {
    447	OPP_MASK_SH_LIST_DCN20(__SHIFT)
    448};
    449
    450static const struct dcn20_opp_mask opp_mask = {
    451	OPP_MASK_SH_LIST_DCN20(_MASK)
    452};
    453
    454#define aux_engine_regs(id)\
    455[id] = {\
    456	AUX_COMMON_REG_LIST0(id), \
    457	.AUXN_IMPCAL = 0, \
    458	.AUXP_IMPCAL = 0, \
    459	.AUX_RESET_MASK = DP_AUX0_AUX_CONTROL__AUX_RESET_MASK, \
    460}
    461
    462static const struct dce110_aux_registers aux_engine_regs[] = {
    463		aux_engine_regs(0),
    464		aux_engine_regs(1),
    465		aux_engine_regs(2),
    466		aux_engine_regs(3),
    467		aux_engine_regs(4),
    468		aux_engine_regs(5)
    469};
    470
    471#define dwbc_regs_dcn3(id)\
    472[id] = {\
    473	DWBC_COMMON_REG_LIST_DCN30(id),\
    474}
    475
    476static const struct dcn30_dwbc_registers dwbc30_regs[] = {
    477	dwbc_regs_dcn3(0),
    478};
    479
    480static const struct dcn30_dwbc_shift dwbc30_shift = {
    481	DWBC_COMMON_MASK_SH_LIST_DCN30(__SHIFT)
    482};
    483
    484static const struct dcn30_dwbc_mask dwbc30_mask = {
    485	DWBC_COMMON_MASK_SH_LIST_DCN30(_MASK)
    486};
    487
    488#define mcif_wb_regs_dcn3(id)\
    489[id] = {\
    490	MCIF_WB_COMMON_REG_LIST_DCN30(id),\
    491}
    492
    493static const struct dcn30_mmhubbub_registers mcif_wb30_regs[] = {
    494	mcif_wb_regs_dcn3(0)
    495};
    496
    497static const struct dcn30_mmhubbub_shift mcif_wb30_shift = {
    498	MCIF_WB_COMMON_MASK_SH_LIST_DCN30(__SHIFT)
    499};
    500
    501static const struct dcn30_mmhubbub_mask mcif_wb30_mask = {
    502	MCIF_WB_COMMON_MASK_SH_LIST_DCN30(_MASK)
    503};
    504
    505#define dsc_regsDCN20(id)\
    506[id] = {\
    507	DSC_REG_LIST_DCN20(id)\
    508}
    509
    510static const struct dcn20_dsc_registers dsc_regs[] = {
    511	dsc_regsDCN20(0),
    512	dsc_regsDCN20(1),
    513	dsc_regsDCN20(2),
    514	dsc_regsDCN20(3),
    515	dsc_regsDCN20(4),
    516	dsc_regsDCN20(5)
    517};
    518
    519static const struct dcn20_dsc_shift dsc_shift = {
    520	DSC_REG_LIST_SH_MASK_DCN20(__SHIFT)
    521};
    522
    523static const struct dcn20_dsc_mask dsc_mask = {
    524	DSC_REG_LIST_SH_MASK_DCN20(_MASK)
    525};
    526
    527static const struct dcn30_mpc_registers mpc_regs = {
    528		MPC_REG_LIST_DCN3_0(0),
    529		MPC_REG_LIST_DCN3_0(1),
    530		MPC_REG_LIST_DCN3_0(2),
    531		MPC_REG_LIST_DCN3_0(3),
    532		MPC_REG_LIST_DCN3_0(4),
    533		MPC_REG_LIST_DCN3_0(5),
    534		MPC_OUT_MUX_REG_LIST_DCN3_0(0),
    535		MPC_OUT_MUX_REG_LIST_DCN3_0(1),
    536		MPC_OUT_MUX_REG_LIST_DCN3_0(2),
    537		MPC_OUT_MUX_REG_LIST_DCN3_0(3),
    538		MPC_OUT_MUX_REG_LIST_DCN3_0(4),
    539		MPC_OUT_MUX_REG_LIST_DCN3_0(5),
    540		MPC_RMU_GLOBAL_REG_LIST_DCN3AG,
    541		MPC_RMU_REG_LIST_DCN3AG(0),
    542		MPC_RMU_REG_LIST_DCN3AG(1),
    543		MPC_RMU_REG_LIST_DCN3AG(2),
    544		MPC_DWB_MUX_REG_LIST_DCN3_0(0),
    545};
    546
    547static const struct dcn30_mpc_shift mpc_shift = {
    548	MPC_COMMON_MASK_SH_LIST_DCN30(__SHIFT)
    549};
    550
    551static const struct dcn30_mpc_mask mpc_mask = {
    552	MPC_COMMON_MASK_SH_LIST_DCN30(_MASK)
    553};
    554
    555#define optc_regs(id)\
    556[id] = {OPTC_COMMON_REG_LIST_DCN3_0(id)}
    557
    558
    559static const struct dcn_optc_registers optc_regs[] = {
    560	optc_regs(0),
    561	optc_regs(1),
    562	optc_regs(2),
    563	optc_regs(3),
    564	optc_regs(4),
    565	optc_regs(5)
    566};
    567
    568static const struct dcn_optc_shift optc_shift = {
    569	OPTC_COMMON_MASK_SH_LIST_DCN30(__SHIFT)
    570};
    571
    572static const struct dcn_optc_mask optc_mask = {
    573	OPTC_COMMON_MASK_SH_LIST_DCN30(_MASK)
    574};
    575
    576#define hubp_regs(id)\
    577[id] = {\
    578	HUBP_REG_LIST_DCN30(id)\
    579}
    580
    581static const struct dcn_hubp2_registers hubp_regs[] = {
    582		hubp_regs(0),
    583		hubp_regs(1),
    584		hubp_regs(2),
    585		hubp_regs(3),
    586		hubp_regs(4),
    587		hubp_regs(5)
    588};
    589
    590static const struct dcn_hubp2_shift hubp_shift = {
    591		HUBP_MASK_SH_LIST_DCN30(__SHIFT)
    592};
    593
    594static const struct dcn_hubp2_mask hubp_mask = {
    595		HUBP_MASK_SH_LIST_DCN30(_MASK)
    596};
    597
    598static const struct dcn_hubbub_registers hubbub_reg = {
    599		HUBBUB_REG_LIST_DCN30(0)
    600};
    601
    602static const struct dcn_hubbub_shift hubbub_shift = {
    603		HUBBUB_MASK_SH_LIST_DCN30(__SHIFT)
    604};
    605
    606static const struct dcn_hubbub_mask hubbub_mask = {
    607		HUBBUB_MASK_SH_LIST_DCN30(_MASK)
    608};
    609
    610static const struct dccg_registers dccg_regs = {
    611		DCCG_REG_LIST_DCN30()
    612};
    613
    614static const struct dccg_shift dccg_shift = {
    615		DCCG_MASK_SH_LIST_DCN3(__SHIFT)
    616};
    617
    618static const struct dccg_mask dccg_mask = {
    619		DCCG_MASK_SH_LIST_DCN3(_MASK)
    620};
    621
    622static const struct dce_hwseq_registers hwseq_reg = {
    623		HWSEQ_DCN30_REG_LIST()
    624};
    625
    626static const struct dce_hwseq_shift hwseq_shift = {
    627		HWSEQ_DCN30_MASK_SH_LIST(__SHIFT)
    628};
    629
    630static const struct dce_hwseq_mask hwseq_mask = {
    631		HWSEQ_DCN30_MASK_SH_LIST(_MASK)
    632};
    633#define vmid_regs(id)\
    634[id] = {\
    635		DCN20_VMID_REG_LIST(id)\
    636}
    637
    638static const struct dcn_vmid_registers vmid_regs[] = {
    639	vmid_regs(0),
    640	vmid_regs(1),
    641	vmid_regs(2),
    642	vmid_regs(3),
    643	vmid_regs(4),
    644	vmid_regs(5),
    645	vmid_regs(6),
    646	vmid_regs(7),
    647	vmid_regs(8),
    648	vmid_regs(9),
    649	vmid_regs(10),
    650	vmid_regs(11),
    651	vmid_regs(12),
    652	vmid_regs(13),
    653	vmid_regs(14),
    654	vmid_regs(15)
    655};
    656
    657static const struct dcn20_vmid_shift vmid_shifts = {
    658		DCN20_VMID_MASK_SH_LIST(__SHIFT)
    659};
    660
    661static const struct dcn20_vmid_mask vmid_masks = {
    662		DCN20_VMID_MASK_SH_LIST(_MASK)
    663};
    664
    665static const struct resource_caps res_cap_dcn3 = {
    666	.num_timing_generator = 6,
    667	.num_opp = 6,
    668	.num_video_plane = 6,
    669	.num_audio = 6,
    670	.num_stream_encoder = 6,
    671	.num_pll = 6,
    672	.num_dwb = 1,
    673	.num_ddc = 6,
    674	.num_vmid = 16,
    675	.num_mpc_3dlut = 3,
    676	.num_dsc = 6,
    677};
    678
    679static 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};
    706
    707static const struct dc_debug_options debug_defaults_drv = {
    708	.disable_dmcu = true, //No DMCU on DCN30
    709	.force_abm_enable = false,
    710	.timing_trace = false,
    711	.clock_trace = true,
    712	.disable_pplib_clock_request = true,
    713	.pipe_split_policy = MPC_SPLIT_DYNAMIC,
    714	.force_single_disp_pipe_split = false,
    715	.disable_dcc = DCC_ENABLE,
    716	.vsr_support = true,
    717	.performance_trace = false,
    718	.max_downscale_src_width = 7680,/*upto 8K*/
    719	.disable_pplib_wm_range = false,
    720	.scl_reset_length10 = true,
    721	.sanity_checks = false,
    722	.underflow_assert_delay_us = 0xFFFFFFFF,
    723	.dwb_fi_phase = -1, // -1 = disable,
    724	.dmub_command_table = true,
    725	.disable_psr = false,
    726	.use_max_lb = true
    727};
    728
    729static const struct dc_debug_options debug_defaults_diags = {
    730	.disable_dmcu = true, //No dmcu on DCN30
    731	.force_abm_enable = false,
    732	.timing_trace = true,
    733	.clock_trace = true,
    734	.disable_dpp_power_gate = true,
    735	.disable_hubp_power_gate = true,
    736	.disable_clock_gate = true,
    737	.disable_pplib_clock_request = true,
    738	.disable_pplib_wm_range = true,
    739	.disable_stutter = false,
    740	.scl_reset_length10 = true,
    741	.dwb_fi_phase = -1, // -1 = disable
    742	.dmub_command_table = true,
    743	.disable_psr = true,
    744	.enable_tri_buf = true,
    745	.use_max_lb = true
    746};
    747
    748static void dcn30_dpp_destroy(struct dpp **dpp)
    749{
    750	kfree(TO_DCN20_DPP(*dpp));
    751	*dpp = NULL;
    752}
    753
    754static struct dpp *dcn30_dpp_create(
    755	struct dc_context *ctx,
    756	uint32_t inst)
    757{
    758	struct dcn3_dpp *dpp =
    759		kzalloc(sizeof(struct dcn3_dpp), GFP_KERNEL);
    760
    761	if (!dpp)
    762		return NULL;
    763
    764	if (dpp3_construct(dpp, ctx, inst,
    765			&dpp_regs[inst], &tf_shift, &tf_mask))
    766		return &dpp->base;
    767
    768	BREAK_TO_DEBUGGER();
    769	kfree(dpp);
    770	return NULL;
    771}
    772
    773static struct output_pixel_processor *dcn30_opp_create(
    774	struct dc_context *ctx, uint32_t inst)
    775{
    776	struct dcn20_opp *opp =
    777		kzalloc(sizeof(struct dcn20_opp), GFP_KERNEL);
    778
    779	if (!opp) {
    780		BREAK_TO_DEBUGGER();
    781		return NULL;
    782	}
    783
    784	dcn20_opp_construct(opp, ctx, inst,
    785			&opp_regs[inst], &opp_shift, &opp_mask);
    786	return &opp->base;
    787}
    788
    789static struct dce_aux *dcn30_aux_engine_create(
    790	struct dc_context *ctx,
    791	uint32_t inst)
    792{
    793	struct aux_engine_dce110 *aux_engine =
    794		kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL);
    795
    796	if (!aux_engine)
    797		return NULL;
    798
    799	dce110_aux_engine_construct(aux_engine, ctx, inst,
    800				    SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD,
    801				    &aux_engine_regs[inst],
    802					&aux_mask,
    803					&aux_shift,
    804					ctx->dc->caps.extended_aux_timeout_support);
    805
    806	return &aux_engine->base;
    807}
    808
    809#define i2c_inst_regs(id) { I2C_HW_ENGINE_COMMON_REG_LIST_DCN30(id) }
    810
    811static const struct dce_i2c_registers i2c_hw_regs[] = {
    812		i2c_inst_regs(1),
    813		i2c_inst_regs(2),
    814		i2c_inst_regs(3),
    815		i2c_inst_regs(4),
    816		i2c_inst_regs(5),
    817		i2c_inst_regs(6),
    818};
    819
    820static const struct dce_i2c_shift i2c_shifts = {
    821		I2C_COMMON_MASK_SH_LIST_DCN30(__SHIFT)
    822};
    823
    824static const struct dce_i2c_mask i2c_masks = {
    825		I2C_COMMON_MASK_SH_LIST_DCN30(_MASK)
    826};
    827
    828static struct dce_i2c_hw *dcn30_i2c_hw_create(
    829	struct dc_context *ctx,
    830	uint32_t inst)
    831{
    832	struct dce_i2c_hw *dce_i2c_hw =
    833		kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL);
    834
    835	if (!dce_i2c_hw)
    836		return NULL;
    837
    838	dcn2_i2c_hw_construct(dce_i2c_hw, ctx, inst,
    839				    &i2c_hw_regs[inst], &i2c_shifts, &i2c_masks);
    840
    841	return dce_i2c_hw;
    842}
    843
    844static struct mpc *dcn30_mpc_create(
    845		struct dc_context *ctx,
    846		int num_mpcc,
    847		int num_rmu)
    848{
    849	struct dcn30_mpc *mpc30 = kzalloc(sizeof(struct dcn30_mpc),
    850					  GFP_KERNEL);
    851
    852	if (!mpc30)
    853		return NULL;
    854
    855	dcn30_mpc_construct(mpc30, ctx,
    856			&mpc_regs,
    857			&mpc_shift,
    858			&mpc_mask,
    859			num_mpcc,
    860			num_rmu);
    861
    862	return &mpc30->base;
    863}
    864
    865static struct hubbub *dcn30_hubbub_create(struct dc_context *ctx)
    866{
    867	int i;
    868
    869	struct dcn20_hubbub *hubbub3 = kzalloc(sizeof(struct dcn20_hubbub),
    870					  GFP_KERNEL);
    871
    872	if (!hubbub3)
    873		return NULL;
    874
    875	hubbub3_construct(hubbub3, ctx,
    876			&hubbub_reg,
    877			&hubbub_shift,
    878			&hubbub_mask);
    879
    880
    881	for (i = 0; i < res_cap_dcn3.num_vmid; i++) {
    882		struct dcn20_vmid *vmid = &hubbub3->vmid[i];
    883
    884		vmid->ctx = ctx;
    885
    886		vmid->regs = &vmid_regs[i];
    887		vmid->shifts = &vmid_shifts;
    888		vmid->masks = &vmid_masks;
    889	}
    890
    891	return &hubbub3->base;
    892}
    893
    894static struct timing_generator *dcn30_timing_generator_create(
    895		struct dc_context *ctx,
    896		uint32_t instance)
    897{
    898	struct optc *tgn10 =
    899		kzalloc(sizeof(struct optc), GFP_KERNEL);
    900
    901	if (!tgn10)
    902		return NULL;
    903
    904	tgn10->base.inst = instance;
    905	tgn10->base.ctx = ctx;
    906
    907	tgn10->tg_regs = &optc_regs[instance];
    908	tgn10->tg_shift = &optc_shift;
    909	tgn10->tg_mask = &optc_mask;
    910
    911	dcn30_timing_generator_init(tgn10);
    912
    913	return &tgn10->base;
    914}
    915
    916static const struct encoder_feature_support link_enc_feature = {
    917		.max_hdmi_deep_color = COLOR_DEPTH_121212,
    918		.max_hdmi_pixel_clock = 600000,
    919		.hdmi_ycbcr420_supported = true,
    920		.dp_ycbcr420_supported = true,
    921		.fec_supported = true,
    922		.flags.bits.IS_HBR2_CAPABLE = true,
    923		.flags.bits.IS_HBR3_CAPABLE = true,
    924		.flags.bits.IS_TPS3_CAPABLE = true,
    925		.flags.bits.IS_TPS4_CAPABLE = true
    926};
    927
    928static struct link_encoder *dcn30_link_encoder_create(
    929	const struct encoder_init_data *enc_init_data)
    930{
    931	struct dcn20_link_encoder *enc20 =
    932		kzalloc(sizeof(struct dcn20_link_encoder), GFP_KERNEL);
    933
    934	if (!enc20)
    935		return NULL;
    936
    937	dcn30_link_encoder_construct(enc20,
    938			enc_init_data,
    939			&link_enc_feature,
    940			&link_enc_regs[enc_init_data->transmitter],
    941			&link_enc_aux_regs[enc_init_data->channel - 1],
    942			&link_enc_hpd_regs[enc_init_data->hpd_source],
    943			&le_shift,
    944			&le_mask);
    945
    946	return &enc20->enc10.base;
    947}
    948
    949static struct panel_cntl *dcn30_panel_cntl_create(const struct panel_cntl_init_data *init_data)
    950{
    951	struct dce_panel_cntl *panel_cntl =
    952		kzalloc(sizeof(struct dce_panel_cntl), GFP_KERNEL);
    953
    954	if (!panel_cntl)
    955		return NULL;
    956
    957	dce_panel_cntl_construct(panel_cntl,
    958			init_data,
    959			&panel_cntl_regs[init_data->inst],
    960			&panel_cntl_shift,
    961			&panel_cntl_mask);
    962
    963	return &panel_cntl->base;
    964}
    965
    966static void read_dce_straps(
    967	struct dc_context *ctx,
    968	struct resource_straps *straps)
    969{
    970	generic_reg_get(ctx, mmDC_PINSTRAPS + BASE(mmDC_PINSTRAPS_BASE_IDX),
    971		FN(DC_PINSTRAPS, DC_PINSTRAPS_AUDIO), &straps->dc_pinstraps_audio);
    972
    973}
    974
    975static struct audio *dcn30_create_audio(
    976		struct dc_context *ctx, unsigned int inst)
    977{
    978	return dce_audio_create(ctx, inst,
    979			&audio_regs[inst], &audio_shift, &audio_mask);
    980}
    981
    982static struct vpg *dcn30_vpg_create(
    983	struct dc_context *ctx,
    984	uint32_t inst)
    985{
    986	struct dcn30_vpg *vpg3 = kzalloc(sizeof(struct dcn30_vpg), GFP_KERNEL);
    987
    988	if (!vpg3)
    989		return NULL;
    990
    991	vpg3_construct(vpg3, ctx, inst,
    992			&vpg_regs[inst],
    993			&vpg_shift,
    994			&vpg_mask);
    995
    996	return &vpg3->base;
    997}
    998
    999static struct afmt *dcn30_afmt_create(
   1000	struct dc_context *ctx,
   1001	uint32_t inst)
   1002{
   1003	struct dcn30_afmt *afmt3 = kzalloc(sizeof(struct dcn30_afmt), GFP_KERNEL);
   1004
   1005	if (!afmt3)
   1006		return NULL;
   1007
   1008	afmt3_construct(afmt3, ctx, inst,
   1009			&afmt_regs[inst],
   1010			&afmt_shift,
   1011			&afmt_mask);
   1012
   1013	return &afmt3->base;
   1014}
   1015
   1016static struct stream_encoder *dcn30_stream_encoder_create(enum engine_id eng_id,
   1017							  struct dc_context *ctx)
   1018{
   1019	struct dcn10_stream_encoder *enc1;
   1020	struct vpg *vpg;
   1021	struct afmt *afmt;
   1022	int vpg_inst;
   1023	int afmt_inst;
   1024
   1025	/* Mapping of VPG, AFMT, DME register blocks to DIO block instance */
   1026	if (eng_id <= ENGINE_ID_DIGF) {
   1027		vpg_inst = eng_id;
   1028		afmt_inst = eng_id;
   1029	} else
   1030		return NULL;
   1031
   1032	enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL);
   1033	vpg = dcn30_vpg_create(ctx, vpg_inst);
   1034	afmt = dcn30_afmt_create(ctx, afmt_inst);
   1035
   1036	if (!enc1 || !vpg || !afmt) {
   1037		kfree(enc1);
   1038		kfree(vpg);
   1039		kfree(afmt);
   1040		return NULL;
   1041	}
   1042
   1043	dcn30_dio_stream_encoder_construct(enc1, ctx, ctx->dc_bios,
   1044					eng_id, vpg, afmt,
   1045					&stream_enc_regs[eng_id],
   1046					&se_shift, &se_mask);
   1047
   1048	return &enc1->base;
   1049}
   1050
   1051static struct dce_hwseq *dcn30_hwseq_create(struct dc_context *ctx)
   1052{
   1053	struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL);
   1054
   1055	if (hws) {
   1056		hws->ctx = ctx;
   1057		hws->regs = &hwseq_reg;
   1058		hws->shifts = &hwseq_shift;
   1059		hws->masks = &hwseq_mask;
   1060	}
   1061	return hws;
   1062}
   1063static const struct resource_create_funcs res_create_funcs = {
   1064	.read_dce_straps = read_dce_straps,
   1065	.create_audio = dcn30_create_audio,
   1066	.create_stream_encoder = dcn30_stream_encoder_create,
   1067	.create_hwseq = dcn30_hwseq_create,
   1068};
   1069
   1070static const struct resource_create_funcs res_create_maximus_funcs = {
   1071	.read_dce_straps = NULL,
   1072	.create_audio = NULL,
   1073	.create_stream_encoder = NULL,
   1074	.create_hwseq = dcn30_hwseq_create,
   1075};
   1076
   1077static void dcn30_resource_destruct(struct dcn30_resource_pool *pool)
   1078{
   1079	unsigned int i;
   1080
   1081	for (i = 0; i < pool->base.stream_enc_count; i++) {
   1082		if (pool->base.stream_enc[i] != NULL) {
   1083			if (pool->base.stream_enc[i]->vpg != NULL) {
   1084				kfree(DCN30_VPG_FROM_VPG(pool->base.stream_enc[i]->vpg));
   1085				pool->base.stream_enc[i]->vpg = NULL;
   1086			}
   1087			if (pool->base.stream_enc[i]->afmt != NULL) {
   1088				kfree(DCN30_AFMT_FROM_AFMT(pool->base.stream_enc[i]->afmt));
   1089				pool->base.stream_enc[i]->afmt = NULL;
   1090			}
   1091			kfree(DCN10STRENC_FROM_STRENC(pool->base.stream_enc[i]));
   1092			pool->base.stream_enc[i] = NULL;
   1093		}
   1094	}
   1095
   1096	for (i = 0; i < pool->base.res_cap->num_dsc; i++) {
   1097		if (pool->base.dscs[i] != NULL)
   1098			dcn20_dsc_destroy(&pool->base.dscs[i]);
   1099	}
   1100
   1101	if (pool->base.mpc != NULL) {
   1102		kfree(TO_DCN20_MPC(pool->base.mpc));
   1103		pool->base.mpc = NULL;
   1104	}
   1105	if (pool->base.hubbub != NULL) {
   1106		kfree(pool->base.hubbub);
   1107		pool->base.hubbub = NULL;
   1108	}
   1109	for (i = 0; i < pool->base.pipe_count; i++) {
   1110		if (pool->base.dpps[i] != NULL)
   1111			dcn30_dpp_destroy(&pool->base.dpps[i]);
   1112
   1113		if (pool->base.ipps[i] != NULL)
   1114			pool->base.ipps[i]->funcs->ipp_destroy(&pool->base.ipps[i]);
   1115
   1116		if (pool->base.hubps[i] != NULL) {
   1117			kfree(TO_DCN20_HUBP(pool->base.hubps[i]));
   1118			pool->base.hubps[i] = NULL;
   1119		}
   1120
   1121		if (pool->base.irqs != NULL) {
   1122			dal_irq_service_destroy(&pool->base.irqs);
   1123		}
   1124	}
   1125
   1126	for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
   1127		if (pool->base.engines[i] != NULL)
   1128			dce110_engine_destroy(&pool->base.engines[i]);
   1129		if (pool->base.hw_i2cs[i] != NULL) {
   1130			kfree(pool->base.hw_i2cs[i]);
   1131			pool->base.hw_i2cs[i] = NULL;
   1132		}
   1133		if (pool->base.sw_i2cs[i] != NULL) {
   1134			kfree(pool->base.sw_i2cs[i]);
   1135			pool->base.sw_i2cs[i] = NULL;
   1136		}
   1137	}
   1138
   1139	for (i = 0; i < pool->base.res_cap->num_opp; i++) {
   1140		if (pool->base.opps[i] != NULL)
   1141			pool->base.opps[i]->funcs->opp_destroy(&pool->base.opps[i]);
   1142	}
   1143
   1144	for (i = 0; i < pool->base.res_cap->num_timing_generator; i++) {
   1145		if (pool->base.timing_generators[i] != NULL)	{
   1146			kfree(DCN10TG_FROM_TG(pool->base.timing_generators[i]));
   1147			pool->base.timing_generators[i] = NULL;
   1148		}
   1149	}
   1150
   1151	for (i = 0; i < pool->base.res_cap->num_dwb; i++) {
   1152		if (pool->base.dwbc[i] != NULL) {
   1153			kfree(TO_DCN30_DWBC(pool->base.dwbc[i]));
   1154			pool->base.dwbc[i] = NULL;
   1155		}
   1156		if (pool->base.mcif_wb[i] != NULL) {
   1157			kfree(TO_DCN30_MMHUBBUB(pool->base.mcif_wb[i]));
   1158			pool->base.mcif_wb[i] = NULL;
   1159		}
   1160	}
   1161
   1162	for (i = 0; i < pool->base.audio_count; i++) {
   1163		if (pool->base.audios[i])
   1164			dce_aud_destroy(&pool->base.audios[i]);
   1165	}
   1166
   1167	for (i = 0; i < pool->base.clk_src_count; i++) {
   1168		if (pool->base.clock_sources[i] != NULL) {
   1169			dcn20_clock_source_destroy(&pool->base.clock_sources[i]);
   1170			pool->base.clock_sources[i] = NULL;
   1171		}
   1172	}
   1173
   1174	for (i = 0; i < pool->base.res_cap->num_mpc_3dlut; i++) {
   1175		if (pool->base.mpc_lut[i] != NULL) {
   1176			dc_3dlut_func_release(pool->base.mpc_lut[i]);
   1177			pool->base.mpc_lut[i] = NULL;
   1178		}
   1179		if (pool->base.mpc_shaper[i] != NULL) {
   1180			dc_transfer_func_release(pool->base.mpc_shaper[i]);
   1181			pool->base.mpc_shaper[i] = NULL;
   1182		}
   1183	}
   1184
   1185	if (pool->base.dp_clock_source != NULL) {
   1186		dcn20_clock_source_destroy(&pool->base.dp_clock_source);
   1187		pool->base.dp_clock_source = NULL;
   1188	}
   1189
   1190	for (i = 0; i < pool->base.pipe_count; i++) {
   1191		if (pool->base.multiple_abms[i] != NULL)
   1192			dce_abm_destroy(&pool->base.multiple_abms[i]);
   1193	}
   1194
   1195	if (pool->base.psr != NULL)
   1196		dmub_psr_destroy(&pool->base.psr);
   1197
   1198	if (pool->base.dccg != NULL)
   1199		dcn_dccg_destroy(&pool->base.dccg);
   1200
   1201	if (pool->base.oem_device != NULL)
   1202		dal_ddc_service_destroy(&pool->base.oem_device);
   1203}
   1204
   1205static struct hubp *dcn30_hubp_create(
   1206	struct dc_context *ctx,
   1207	uint32_t inst)
   1208{
   1209	struct dcn20_hubp *hubp2 =
   1210		kzalloc(sizeof(struct dcn20_hubp), GFP_KERNEL);
   1211
   1212	if (!hubp2)
   1213		return NULL;
   1214
   1215	if (hubp3_construct(hubp2, ctx, inst,
   1216			&hubp_regs[inst], &hubp_shift, &hubp_mask))
   1217		return &hubp2->base;
   1218
   1219	BREAK_TO_DEBUGGER();
   1220	kfree(hubp2);
   1221	return NULL;
   1222}
   1223
   1224static bool dcn30_dwbc_create(struct dc_context *ctx, struct resource_pool *pool)
   1225{
   1226	int i;
   1227	uint32_t pipe_count = pool->res_cap->num_dwb;
   1228
   1229	for (i = 0; i < pipe_count; i++) {
   1230		struct dcn30_dwbc *dwbc30 = kzalloc(sizeof(struct dcn30_dwbc),
   1231						    GFP_KERNEL);
   1232
   1233		if (!dwbc30) {
   1234			dm_error("DC: failed to create dwbc30!\n");
   1235			return false;
   1236		}
   1237
   1238		dcn30_dwbc_construct(dwbc30, ctx,
   1239				&dwbc30_regs[i],
   1240				&dwbc30_shift,
   1241				&dwbc30_mask,
   1242				i);
   1243
   1244		pool->dwbc[i] = &dwbc30->base;
   1245	}
   1246	return true;
   1247}
   1248
   1249static bool dcn30_mmhubbub_create(struct dc_context *ctx, struct resource_pool *pool)
   1250{
   1251	int i;
   1252	uint32_t pipe_count = pool->res_cap->num_dwb;
   1253
   1254	for (i = 0; i < pipe_count; i++) {
   1255		struct dcn30_mmhubbub *mcif_wb30 = kzalloc(sizeof(struct dcn30_mmhubbub),
   1256						    GFP_KERNEL);
   1257
   1258		if (!mcif_wb30) {
   1259			dm_error("DC: failed to create mcif_wb30!\n");
   1260			return false;
   1261		}
   1262
   1263		dcn30_mmhubbub_construct(mcif_wb30, ctx,
   1264				&mcif_wb30_regs[i],
   1265				&mcif_wb30_shift,
   1266				&mcif_wb30_mask,
   1267				i);
   1268
   1269		pool->mcif_wb[i] = &mcif_wb30->base;
   1270	}
   1271	return true;
   1272}
   1273
   1274static struct display_stream_compressor *dcn30_dsc_create(
   1275	struct dc_context *ctx, uint32_t inst)
   1276{
   1277	struct dcn20_dsc *dsc =
   1278		kzalloc(sizeof(struct dcn20_dsc), GFP_KERNEL);
   1279
   1280	if (!dsc) {
   1281		BREAK_TO_DEBUGGER();
   1282		return NULL;
   1283	}
   1284
   1285	dsc2_construct(dsc, ctx, inst, &dsc_regs[inst], &dsc_shift, &dsc_mask);
   1286	return &dsc->base;
   1287}
   1288
   1289enum dc_status dcn30_add_stream_to_ctx(struct dc *dc, struct dc_state *new_ctx, struct dc_stream_state *dc_stream)
   1290{
   1291
   1292	return dcn20_add_stream_to_ctx(dc, new_ctx, dc_stream);
   1293}
   1294
   1295static void dcn30_destroy_resource_pool(struct resource_pool **pool)
   1296{
   1297	struct dcn30_resource_pool *dcn30_pool = TO_DCN30_RES_POOL(*pool);
   1298
   1299	dcn30_resource_destruct(dcn30_pool);
   1300	kfree(dcn30_pool);
   1301	*pool = NULL;
   1302}
   1303
   1304static struct clock_source *dcn30_clock_source_create(
   1305		struct dc_context *ctx,
   1306		struct dc_bios *bios,
   1307		enum clock_source_id id,
   1308		const struct dce110_clk_src_regs *regs,
   1309		bool dp_clk_src)
   1310{
   1311	struct dce110_clk_src *clk_src =
   1312		kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL);
   1313
   1314	if (!clk_src)
   1315		return NULL;
   1316
   1317	if (dcn3_clk_src_construct(clk_src, ctx, bios, id,
   1318			regs, &cs_shift, &cs_mask)) {
   1319		clk_src->base.dp_clk_src = dp_clk_src;
   1320		return &clk_src->base;
   1321	}
   1322
   1323	BREAK_TO_DEBUGGER();
   1324	return NULL;
   1325}
   1326
   1327int dcn30_populate_dml_pipes_from_context(
   1328	struct dc *dc, struct dc_state *context,
   1329	display_e2e_pipe_params_st *pipes,
   1330	bool fast_validate)
   1331{
   1332	int i, pipe_cnt;
   1333	struct resource_context *res_ctx = &context->res_ctx;
   1334
   1335	DC_FP_START();
   1336	dcn20_populate_dml_pipes_from_context(dc, context, pipes, fast_validate);
   1337	DC_FP_END();
   1338
   1339	for (i = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {
   1340		if (!res_ctx->pipe_ctx[i].stream)
   1341			continue;
   1342
   1343		pipes[pipe_cnt++].pipe.scale_ratio_depth.lb_depth =
   1344			dm_lb_16;
   1345	}
   1346
   1347	return pipe_cnt;
   1348}
   1349
   1350void dcn30_populate_dml_writeback_from_context(
   1351	struct dc *dc, struct resource_context *res_ctx, display_e2e_pipe_params_st *pipes)
   1352{
   1353	DC_FP_START();
   1354	dcn30_fpu_populate_dml_writeback_from_context(dc, res_ctx, pipes);
   1355	DC_FP_END();
   1356}
   1357
   1358unsigned int dcn30_calc_max_scaled_time(
   1359		unsigned int time_per_pixel,
   1360		enum mmhubbub_wbif_mode mode,
   1361		unsigned int urgent_watermark)
   1362{
   1363	unsigned int time_per_byte = 0;
   1364	unsigned int total_free_entry = 0xb40;
   1365	unsigned int buf_lh_capability;
   1366	unsigned int max_scaled_time;
   1367
   1368	if (mode == PACKED_444) /* packed mode 32 bpp */
   1369		time_per_byte = time_per_pixel/4;
   1370	else if (mode == PACKED_444_FP16) /* packed mode 64 bpp */
   1371		time_per_byte = time_per_pixel/8;
   1372
   1373	if (time_per_byte == 0)
   1374		time_per_byte = 1;
   1375
   1376	buf_lh_capability = (total_free_entry*time_per_byte*32) >> 6; /* time_per_byte is in u6.6*/
   1377	max_scaled_time   = buf_lh_capability - urgent_watermark;
   1378	return max_scaled_time;
   1379}
   1380
   1381void dcn30_set_mcif_arb_params(
   1382		struct dc *dc,
   1383		struct dc_state *context,
   1384		display_e2e_pipe_params_st *pipes,
   1385		int pipe_cnt)
   1386{
   1387	enum mmhubbub_wbif_mode wbif_mode;
   1388	struct display_mode_lib *dml = &context->bw_ctx.dml;
   1389	struct mcif_arb_params *wb_arb_params;
   1390	int i, j, dwb_pipe;
   1391
   1392	/* Writeback MCIF_WB arbitration parameters */
   1393	dwb_pipe = 0;
   1394	for (i = 0; i < dc->res_pool->pipe_count; i++) {
   1395
   1396		if (!context->res_ctx.pipe_ctx[i].stream)
   1397			continue;
   1398
   1399		for (j = 0; j < MAX_DWB_PIPES; j++) {
   1400			struct dc_writeback_info *writeback_info = &context->res_ctx.pipe_ctx[i].stream->writeback_info[j];
   1401
   1402			if (writeback_info->wb_enabled == false)
   1403				continue;
   1404
   1405			//wb_arb_params = &context->res_ctx.pipe_ctx[i].stream->writeback_info[j].mcif_arb_params;
   1406			wb_arb_params = &context->bw_ctx.bw.dcn.bw_writeback.mcif_wb_arb[dwb_pipe];
   1407
   1408			if (writeback_info->dwb_params.cnv_params.fc_out_format == DWB_OUT_FORMAT_64BPP_ARGB ||
   1409				writeback_info->dwb_params.cnv_params.fc_out_format == DWB_OUT_FORMAT_64BPP_RGBA)
   1410				wbif_mode = PACKED_444_FP16;
   1411			else
   1412				wbif_mode = PACKED_444;
   1413
   1414			DC_FP_START();
   1415			dcn30_fpu_set_mcif_arb_params(wb_arb_params, dml, pipes, pipe_cnt, j);
   1416			DC_FP_END();
   1417			wb_arb_params->time_per_pixel = (1000000 << 6) / context->res_ctx.pipe_ctx[i].stream->phy_pix_clk; /* time_per_pixel should be in u6.6 format */
   1418			wb_arb_params->slice_lines = 32;
   1419			wb_arb_params->arbitration_slice = 2; /* irrelevant since there is no YUV output */
   1420			wb_arb_params->max_scaled_time = dcn30_calc_max_scaled_time(wb_arb_params->time_per_pixel,
   1421					wbif_mode,
   1422					wb_arb_params->cli_watermark[0]); /* assume 4 watermark sets have the same value */
   1423
   1424			dwb_pipe++;
   1425
   1426			if (dwb_pipe >= MAX_DWB_PIPES)
   1427				return;
   1428		}
   1429		if (dwb_pipe >= MAX_DWB_PIPES)
   1430			return;
   1431	}
   1432
   1433}
   1434
   1435static struct dc_cap_funcs cap_funcs = {
   1436	.get_dcc_compression_cap = dcn20_get_dcc_compression_cap
   1437};
   1438
   1439bool dcn30_acquire_post_bldn_3dlut(
   1440		struct resource_context *res_ctx,
   1441		const struct resource_pool *pool,
   1442		int mpcc_id,
   1443		struct dc_3dlut **lut,
   1444		struct dc_transfer_func **shaper)
   1445{
   1446	int i;
   1447	bool ret = false;
   1448	union dc_3dlut_state *state;
   1449
   1450	ASSERT(*lut == NULL && *shaper == NULL);
   1451	*lut = NULL;
   1452	*shaper = NULL;
   1453
   1454	for (i = 0; i < pool->res_cap->num_mpc_3dlut; i++) {
   1455		if (!res_ctx->is_mpc_3dlut_acquired[i]) {
   1456			*lut = pool->mpc_lut[i];
   1457			*shaper = pool->mpc_shaper[i];
   1458			state = &pool->mpc_lut[i]->state;
   1459			res_ctx->is_mpc_3dlut_acquired[i] = true;
   1460			state->bits.rmu_idx_valid = 1;
   1461			state->bits.rmu_mux_num = i;
   1462			if (state->bits.rmu_mux_num == 0)
   1463				state->bits.mpc_rmu0_mux = mpcc_id;
   1464			else if (state->bits.rmu_mux_num == 1)
   1465				state->bits.mpc_rmu1_mux = mpcc_id;
   1466			else if (state->bits.rmu_mux_num == 2)
   1467				state->bits.mpc_rmu2_mux = mpcc_id;
   1468			ret = true;
   1469			break;
   1470			}
   1471		}
   1472	return ret;
   1473}
   1474
   1475bool dcn30_release_post_bldn_3dlut(
   1476		struct resource_context *res_ctx,
   1477		const struct resource_pool *pool,
   1478		struct dc_3dlut **lut,
   1479		struct dc_transfer_func **shaper)
   1480{
   1481	int i;
   1482	bool ret = false;
   1483
   1484	for (i = 0; i < pool->res_cap->num_mpc_3dlut; i++) {
   1485		if (pool->mpc_lut[i] == *lut && pool->mpc_shaper[i] == *shaper) {
   1486			res_ctx->is_mpc_3dlut_acquired[i] = false;
   1487			pool->mpc_lut[i]->state.raw = 0;
   1488			*lut = NULL;
   1489			*shaper = NULL;
   1490			ret = true;
   1491			break;
   1492		}
   1493	}
   1494	return ret;
   1495}
   1496
   1497static bool is_soc_bounding_box_valid(struct dc *dc)
   1498{
   1499	uint32_t hw_internal_rev = dc->ctx->asic_id.hw_internal_rev;
   1500
   1501	if (ASICREV_IS_SIENNA_CICHLID_P(hw_internal_rev))
   1502		return true;
   1503
   1504	return false;
   1505}
   1506
   1507static bool init_soc_bounding_box(struct dc *dc,
   1508				  struct dcn30_resource_pool *pool)
   1509{
   1510	struct _vcs_dpi_soc_bounding_box_st *loaded_bb = &dcn3_0_soc;
   1511	struct _vcs_dpi_ip_params_st *loaded_ip = &dcn3_0_ip;
   1512
   1513	DC_LOGGER_INIT(dc->ctx->logger);
   1514
   1515	if (!is_soc_bounding_box_valid(dc)) {
   1516		DC_LOG_ERROR("%s: not valid soc bounding box\n", __func__);
   1517		return false;
   1518	}
   1519
   1520	loaded_ip->max_num_otg = pool->base.res_cap->num_timing_generator;
   1521	loaded_ip->max_num_dpp = pool->base.pipe_count;
   1522	loaded_ip->clamp_min_dcfclk = dc->config.clamp_min_dcfclk;
   1523
   1524	DC_FP_START();
   1525	dcn20_patch_bounding_box(dc, loaded_bb);
   1526	DC_FP_END();
   1527
   1528	if (dc->ctx->dc_bios->funcs->get_soc_bb_info) {
   1529		struct bp_soc_bb_info bb_info = {0};
   1530
   1531		if (dc->ctx->dc_bios->funcs->get_soc_bb_info(dc->ctx->dc_bios, &bb_info) == BP_RESULT_OK) {
   1532			if (bb_info.dram_clock_change_latency_100ns > 0)
   1533				dcn3_0_soc.dram_clock_change_latency_us = bb_info.dram_clock_change_latency_100ns * 10;
   1534
   1535			if (bb_info.dram_sr_enter_exit_latency_100ns > 0)
   1536				dcn3_0_soc.sr_enter_plus_exit_time_us = bb_info.dram_sr_enter_exit_latency_100ns * 10;
   1537
   1538			if (bb_info.dram_sr_exit_latency_100ns > 0)
   1539				dcn3_0_soc.sr_exit_time_us = bb_info.dram_sr_exit_latency_100ns * 10;
   1540		}
   1541	}
   1542
   1543	return true;
   1544}
   1545
   1546static bool dcn30_split_stream_for_mpc_or_odm(
   1547		const struct dc *dc,
   1548		struct resource_context *res_ctx,
   1549		struct pipe_ctx *pri_pipe,
   1550		struct pipe_ctx *sec_pipe,
   1551		bool odm)
   1552{
   1553	int pipe_idx = sec_pipe->pipe_idx;
   1554	const struct resource_pool *pool = dc->res_pool;
   1555
   1556	*sec_pipe = *pri_pipe;
   1557
   1558	sec_pipe->pipe_idx = pipe_idx;
   1559	sec_pipe->plane_res.mi = pool->mis[pipe_idx];
   1560	sec_pipe->plane_res.hubp = pool->hubps[pipe_idx];
   1561	sec_pipe->plane_res.ipp = pool->ipps[pipe_idx];
   1562	sec_pipe->plane_res.xfm = pool->transforms[pipe_idx];
   1563	sec_pipe->plane_res.dpp = pool->dpps[pipe_idx];
   1564	sec_pipe->plane_res.mpcc_inst = pool->dpps[pipe_idx]->inst;
   1565	sec_pipe->stream_res.dsc = NULL;
   1566	if (odm) {
   1567		if (pri_pipe->next_odm_pipe) {
   1568			ASSERT(pri_pipe->next_odm_pipe != sec_pipe);
   1569			sec_pipe->next_odm_pipe = pri_pipe->next_odm_pipe;
   1570			sec_pipe->next_odm_pipe->prev_odm_pipe = sec_pipe;
   1571		}
   1572		if (pri_pipe->top_pipe && pri_pipe->top_pipe->next_odm_pipe) {
   1573			pri_pipe->top_pipe->next_odm_pipe->bottom_pipe = sec_pipe;
   1574			sec_pipe->top_pipe = pri_pipe->top_pipe->next_odm_pipe;
   1575		}
   1576		if (pri_pipe->bottom_pipe && pri_pipe->bottom_pipe->next_odm_pipe) {
   1577			pri_pipe->bottom_pipe->next_odm_pipe->top_pipe = sec_pipe;
   1578			sec_pipe->bottom_pipe = pri_pipe->bottom_pipe->next_odm_pipe;
   1579		}
   1580		pri_pipe->next_odm_pipe = sec_pipe;
   1581		sec_pipe->prev_odm_pipe = pri_pipe;
   1582
   1583		if (!sec_pipe->top_pipe)
   1584			sec_pipe->stream_res.opp = pool->opps[pipe_idx];
   1585		else
   1586			sec_pipe->stream_res.opp = sec_pipe->top_pipe->stream_res.opp;
   1587		if (sec_pipe->stream->timing.flags.DSC == 1) {
   1588			dcn20_acquire_dsc(dc, res_ctx, &sec_pipe->stream_res.dsc, pipe_idx);
   1589			ASSERT(sec_pipe->stream_res.dsc);
   1590			if (sec_pipe->stream_res.dsc == NULL)
   1591				return false;
   1592		}
   1593	} else {
   1594		if (pri_pipe->bottom_pipe) {
   1595			ASSERT(pri_pipe->bottom_pipe != sec_pipe);
   1596			sec_pipe->bottom_pipe = pri_pipe->bottom_pipe;
   1597			sec_pipe->bottom_pipe->top_pipe = sec_pipe;
   1598		}
   1599		pri_pipe->bottom_pipe = sec_pipe;
   1600		sec_pipe->top_pipe = pri_pipe;
   1601
   1602		ASSERT(pri_pipe->plane_state);
   1603	}
   1604
   1605	return true;
   1606}
   1607
   1608static struct pipe_ctx *dcn30_find_split_pipe(
   1609		struct dc *dc,
   1610		struct dc_state *context,
   1611		int old_index)
   1612{
   1613	struct pipe_ctx *pipe = NULL;
   1614	int i;
   1615
   1616	if (old_index >= 0 && context->res_ctx.pipe_ctx[old_index].stream == NULL) {
   1617		pipe = &context->res_ctx.pipe_ctx[old_index];
   1618		pipe->pipe_idx = old_index;
   1619	}
   1620
   1621	if (!pipe)
   1622		for (i = dc->res_pool->pipe_count - 1; i >= 0; i--) {
   1623			if (dc->current_state->res_ctx.pipe_ctx[i].top_pipe == NULL
   1624					&& dc->current_state->res_ctx.pipe_ctx[i].prev_odm_pipe == NULL) {
   1625				if (context->res_ctx.pipe_ctx[i].stream == NULL) {
   1626					pipe = &context->res_ctx.pipe_ctx[i];
   1627					pipe->pipe_idx = i;
   1628					break;
   1629				}
   1630			}
   1631		}
   1632
   1633	/*
   1634	 * May need to fix pipes getting tossed from 1 opp to another on flip
   1635	 * Add for debugging transient underflow during topology updates:
   1636	 * ASSERT(pipe);
   1637	 */
   1638	if (!pipe)
   1639		for (i = dc->res_pool->pipe_count - 1; i >= 0; i--) {
   1640			if (context->res_ctx.pipe_ctx[i].stream == NULL) {
   1641				pipe = &context->res_ctx.pipe_ctx[i];
   1642				pipe->pipe_idx = i;
   1643				break;
   1644			}
   1645		}
   1646
   1647	return pipe;
   1648}
   1649
   1650noinline bool dcn30_internal_validate_bw(
   1651		struct dc *dc,
   1652		struct dc_state *context,
   1653		display_e2e_pipe_params_st *pipes,
   1654		int *pipe_cnt_out,
   1655		int *vlevel_out,
   1656		bool fast_validate)
   1657{
   1658	bool out = false;
   1659	bool repopulate_pipes = false;
   1660	int split[MAX_PIPES] = { 0 };
   1661	bool merge[MAX_PIPES] = { false };
   1662	bool newly_split[MAX_PIPES] = { false };
   1663	int pipe_cnt, i, pipe_idx, vlevel;
   1664	struct vba_vars_st *vba = &context->bw_ctx.dml.vba;
   1665
   1666	ASSERT(pipes);
   1667	if (!pipes)
   1668		return false;
   1669
   1670	dc->res_pool->funcs->update_soc_for_wm_a(dc, context);
   1671	pipe_cnt = dc->res_pool->funcs->populate_dml_pipes(dc, context, pipes, fast_validate);
   1672
   1673	if (!pipe_cnt) {
   1674		out = true;
   1675		goto validate_out;
   1676	}
   1677
   1678	dml_log_pipe_params(&context->bw_ctx.dml, pipes, pipe_cnt);
   1679
   1680	if (!fast_validate) {
   1681		/*
   1682		 * DML favors voltage over p-state, but we're more interested in
   1683		 * supporting p-state over voltage. We can't support p-state in
   1684		 * prefetch mode > 0 so try capping the prefetch mode to start.
   1685		 */
   1686		context->bw_ctx.dml.soc.allow_dram_self_refresh_or_dram_clock_change_in_vblank =
   1687			dm_allow_self_refresh_and_mclk_switch;
   1688		vlevel = dml_get_voltage_level(&context->bw_ctx.dml, pipes, pipe_cnt);
   1689		/* This may adjust vlevel and maxMpcComb */
   1690		if (vlevel < context->bw_ctx.dml.soc.num_states)
   1691			vlevel = dcn20_validate_apply_pipe_split_flags(dc, context, vlevel, split, merge);
   1692	}
   1693	if (fast_validate || vlevel == context->bw_ctx.dml.soc.num_states ||
   1694			vba->DRAMClockChangeSupport[vlevel][vba->maxMpcComb] == dm_dram_clock_change_unsupported) {
   1695		/*
   1696		 * If mode is unsupported or there's still no p-state support then
   1697		 * fall back to favoring voltage.
   1698		 *
   1699		 * We don't actually support prefetch mode 2, so require that we
   1700		 * at least support prefetch mode 1.
   1701		 */
   1702		context->bw_ctx.dml.soc.allow_dram_self_refresh_or_dram_clock_change_in_vblank =
   1703			dm_allow_self_refresh;
   1704
   1705		vlevel = dml_get_voltage_level(&context->bw_ctx.dml, pipes, pipe_cnt);
   1706		if (vlevel < context->bw_ctx.dml.soc.num_states) {
   1707			memset(split, 0, sizeof(split));
   1708			memset(merge, 0, sizeof(merge));
   1709			vlevel = dcn20_validate_apply_pipe_split_flags(dc, context, vlevel, split, merge);
   1710		}
   1711	}
   1712
   1713	dml_log_mode_support_params(&context->bw_ctx.dml);
   1714
   1715	if (vlevel == context->bw_ctx.dml.soc.num_states)
   1716		goto validate_fail;
   1717
   1718	if (!dc->config.enable_windowed_mpo_odm) {
   1719		for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) {
   1720			struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
   1721			struct pipe_ctx *mpo_pipe = pipe->bottom_pipe;
   1722
   1723			if (!pipe->stream)
   1724				continue;
   1725
   1726			/* We only support full screen mpo with ODM */
   1727			if (vba->ODMCombineEnabled[vba->pipe_plane[pipe_idx]] != dm_odm_combine_mode_disabled
   1728					&& pipe->plane_state && mpo_pipe
   1729					&& memcmp(&mpo_pipe->plane_res.scl_data.recout,
   1730							&pipe->plane_res.scl_data.recout,
   1731							sizeof(struct rect)) != 0) {
   1732				ASSERT(mpo_pipe->plane_state != pipe->plane_state);
   1733				goto validate_fail;
   1734			}
   1735			pipe_idx++;
   1736		}
   1737	}
   1738
   1739	/* merge pipes if necessary */
   1740	for (i = 0; i < dc->res_pool->pipe_count; i++) {
   1741		struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
   1742
   1743		/*skip pipes that don't need merging*/
   1744		if (!merge[i])
   1745			continue;
   1746
   1747		/* if ODM merge we ignore mpc tree, mpo pipes will have their own flags */
   1748		if (pipe->prev_odm_pipe) {
   1749			/*split off odm pipe*/
   1750			pipe->prev_odm_pipe->next_odm_pipe = pipe->next_odm_pipe;
   1751			if (pipe->next_odm_pipe)
   1752				pipe->next_odm_pipe->prev_odm_pipe = pipe->prev_odm_pipe;
   1753
   1754			pipe->bottom_pipe = NULL;
   1755			pipe->next_odm_pipe = NULL;
   1756			pipe->plane_state = NULL;
   1757			pipe->stream = NULL;
   1758			pipe->top_pipe = NULL;
   1759			pipe->prev_odm_pipe = NULL;
   1760			if (pipe->stream_res.dsc)
   1761				dcn20_release_dsc(&context->res_ctx, dc->res_pool, &pipe->stream_res.dsc);
   1762			memset(&pipe->plane_res, 0, sizeof(pipe->plane_res));
   1763			memset(&pipe->stream_res, 0, sizeof(pipe->stream_res));
   1764			repopulate_pipes = true;
   1765		} else if (pipe->top_pipe && pipe->top_pipe->plane_state == pipe->plane_state) {
   1766			struct pipe_ctx *top_pipe = pipe->top_pipe;
   1767			struct pipe_ctx *bottom_pipe = pipe->bottom_pipe;
   1768
   1769			top_pipe->bottom_pipe = bottom_pipe;
   1770			if (bottom_pipe)
   1771				bottom_pipe->top_pipe = top_pipe;
   1772
   1773			pipe->top_pipe = NULL;
   1774			pipe->bottom_pipe = NULL;
   1775			pipe->plane_state = NULL;
   1776			pipe->stream = NULL;
   1777			memset(&pipe->plane_res, 0, sizeof(pipe->plane_res));
   1778			memset(&pipe->stream_res, 0, sizeof(pipe->stream_res));
   1779			repopulate_pipes = true;
   1780		} else
   1781			ASSERT(0); /* Should never try to merge master pipe */
   1782
   1783	}
   1784
   1785	for (i = 0, pipe_idx = -1; i < dc->res_pool->pipe_count; i++) {
   1786		struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
   1787		struct pipe_ctx *old_pipe = &dc->current_state->res_ctx.pipe_ctx[i];
   1788		struct pipe_ctx *hsplit_pipe = NULL;
   1789		bool odm;
   1790		int old_index = -1;
   1791
   1792		if (!pipe->stream || newly_split[i])
   1793			continue;
   1794
   1795		pipe_idx++;
   1796		odm = vba->ODMCombineEnabled[vba->pipe_plane[pipe_idx]] != dm_odm_combine_mode_disabled;
   1797
   1798		if (!pipe->plane_state && !odm)
   1799			continue;
   1800
   1801		if (split[i]) {
   1802			if (odm) {
   1803				if (split[i] == 4 && old_pipe->next_odm_pipe && old_pipe->next_odm_pipe->next_odm_pipe)
   1804					old_index = old_pipe->next_odm_pipe->next_odm_pipe->pipe_idx;
   1805				else if (old_pipe->next_odm_pipe)
   1806					old_index = old_pipe->next_odm_pipe->pipe_idx;
   1807			} else {
   1808				if (split[i] == 4 && old_pipe->bottom_pipe && old_pipe->bottom_pipe->bottom_pipe &&
   1809						old_pipe->bottom_pipe->bottom_pipe->plane_state == old_pipe->plane_state)
   1810					old_index = old_pipe->bottom_pipe->bottom_pipe->pipe_idx;
   1811				else if (old_pipe->bottom_pipe &&
   1812						old_pipe->bottom_pipe->plane_state == old_pipe->plane_state)
   1813					old_index = old_pipe->bottom_pipe->pipe_idx;
   1814			}
   1815			hsplit_pipe = dcn30_find_split_pipe(dc, context, old_index);
   1816			ASSERT(hsplit_pipe);
   1817			if (!hsplit_pipe)
   1818				goto validate_fail;
   1819
   1820			if (!dcn30_split_stream_for_mpc_or_odm(
   1821					dc, &context->res_ctx,
   1822					pipe, hsplit_pipe, odm))
   1823				goto validate_fail;
   1824
   1825			newly_split[hsplit_pipe->pipe_idx] = true;
   1826			repopulate_pipes = true;
   1827		}
   1828		if (split[i] == 4) {
   1829			struct pipe_ctx *pipe_4to1;
   1830
   1831			if (odm && old_pipe->next_odm_pipe)
   1832				old_index = old_pipe->next_odm_pipe->pipe_idx;
   1833			else if (!odm && old_pipe->bottom_pipe &&
   1834						old_pipe->bottom_pipe->plane_state == old_pipe->plane_state)
   1835				old_index = old_pipe->bottom_pipe->pipe_idx;
   1836			else
   1837				old_index = -1;
   1838			pipe_4to1 = dcn30_find_split_pipe(dc, context, old_index);
   1839			ASSERT(pipe_4to1);
   1840			if (!pipe_4to1)
   1841				goto validate_fail;
   1842			if (!dcn30_split_stream_for_mpc_or_odm(
   1843					dc, &context->res_ctx,
   1844					pipe, pipe_4to1, odm))
   1845				goto validate_fail;
   1846			newly_split[pipe_4to1->pipe_idx] = true;
   1847
   1848			if (odm && old_pipe->next_odm_pipe && old_pipe->next_odm_pipe->next_odm_pipe
   1849					&& old_pipe->next_odm_pipe->next_odm_pipe->next_odm_pipe)
   1850				old_index = old_pipe->next_odm_pipe->next_odm_pipe->next_odm_pipe->pipe_idx;
   1851			else if (!odm && old_pipe->bottom_pipe && old_pipe->bottom_pipe->bottom_pipe &&
   1852					old_pipe->bottom_pipe->bottom_pipe->bottom_pipe &&
   1853					old_pipe->bottom_pipe->bottom_pipe->bottom_pipe->plane_state == old_pipe->plane_state)
   1854				old_index = old_pipe->bottom_pipe->bottom_pipe->bottom_pipe->pipe_idx;
   1855			else
   1856				old_index = -1;
   1857			pipe_4to1 = dcn30_find_split_pipe(dc, context, old_index);
   1858			ASSERT(pipe_4to1);
   1859			if (!pipe_4to1)
   1860				goto validate_fail;
   1861			if (!dcn30_split_stream_for_mpc_or_odm(
   1862					dc, &context->res_ctx,
   1863					hsplit_pipe, pipe_4to1, odm))
   1864				goto validate_fail;
   1865			newly_split[pipe_4to1->pipe_idx] = true;
   1866		}
   1867		if (odm)
   1868			dcn20_build_mapped_resource(dc, context, pipe->stream);
   1869	}
   1870
   1871	for (i = 0; i < dc->res_pool->pipe_count; i++) {
   1872		struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
   1873
   1874		if (pipe->plane_state) {
   1875			if (!resource_build_scaling_params(pipe))
   1876				goto validate_fail;
   1877		}
   1878	}
   1879
   1880	/* Actual dsc count per stream dsc validation*/
   1881	if (!dcn20_validate_dsc(dc, context)) {
   1882		vba->ValidationStatus[vba->soc.num_states] = DML_FAIL_DSC_VALIDATION_FAILURE;
   1883		goto validate_fail;
   1884	}
   1885
   1886	if (repopulate_pipes)
   1887		pipe_cnt = dc->res_pool->funcs->populate_dml_pipes(dc, context, pipes, fast_validate);
   1888	*vlevel_out = vlevel;
   1889	*pipe_cnt_out = pipe_cnt;
   1890
   1891	out = true;
   1892	goto validate_out;
   1893
   1894validate_fail:
   1895	out = false;
   1896
   1897validate_out:
   1898	return out;
   1899}
   1900
   1901void dcn30_update_soc_for_wm_a(struct dc *dc, struct dc_state *context)
   1902{
   1903	DC_FP_START();
   1904	dcn30_fpu_update_soc_for_wm_a(dc, context);
   1905	DC_FP_END();
   1906}
   1907
   1908void dcn30_calculate_wm_and_dlg(
   1909		struct dc *dc, struct dc_state *context,
   1910		display_e2e_pipe_params_st *pipes,
   1911		int pipe_cnt,
   1912		int vlevel)
   1913{
   1914	DC_FP_START();
   1915	dcn30_fpu_calculate_wm_and_dlg(dc, context, pipes, pipe_cnt, vlevel);
   1916	DC_FP_END();
   1917}
   1918
   1919bool dcn30_validate_bandwidth(struct dc *dc,
   1920		struct dc_state *context,
   1921		bool fast_validate)
   1922{
   1923	bool out = false;
   1924
   1925	BW_VAL_TRACE_SETUP();
   1926
   1927	int vlevel = 0;
   1928	int pipe_cnt = 0;
   1929	display_e2e_pipe_params_st *pipes = kzalloc(dc->res_pool->pipe_count * sizeof(display_e2e_pipe_params_st), GFP_KERNEL);
   1930	DC_LOGGER_INIT(dc->ctx->logger);
   1931
   1932	BW_VAL_TRACE_COUNT();
   1933
   1934	DC_FP_START();
   1935	out = dcn30_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel, fast_validate);
   1936	DC_FP_END();
   1937
   1938	if (pipe_cnt == 0)
   1939		goto validate_out;
   1940
   1941	if (!out)
   1942		goto validate_fail;
   1943
   1944	BW_VAL_TRACE_END_VOLTAGE_LEVEL();
   1945
   1946	if (fast_validate) {
   1947		BW_VAL_TRACE_SKIP(fast);
   1948		goto validate_out;
   1949	}
   1950
   1951	DC_FP_START();
   1952	dc->res_pool->funcs->calculate_wm_and_dlg(dc, context, pipes, pipe_cnt, vlevel);
   1953	DC_FP_END();
   1954
   1955	BW_VAL_TRACE_END_WATERMARKS();
   1956
   1957	goto validate_out;
   1958
   1959validate_fail:
   1960	DC_LOG_WARNING("Mode Validation Warning: %s failed validation.\n",
   1961		dml_get_status_message(context->bw_ctx.dml.vba.ValidationStatus[context->bw_ctx.dml.vba.soc.num_states]));
   1962
   1963	BW_VAL_TRACE_SKIP(fail);
   1964	out = false;
   1965
   1966validate_out:
   1967	kfree(pipes);
   1968
   1969	BW_VAL_TRACE_FINISH();
   1970
   1971	return out;
   1972}
   1973
   1974void dcn30_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params)
   1975{
   1976	unsigned int i, j;
   1977	unsigned int num_states = 0;
   1978
   1979	unsigned int dcfclk_mhz[DC__VOLTAGE_STATES] = {0};
   1980	unsigned int dram_speed_mts[DC__VOLTAGE_STATES] = {0};
   1981	unsigned int optimal_uclk_for_dcfclk_sta_targets[DC__VOLTAGE_STATES] = {0};
   1982	unsigned int optimal_dcfclk_for_uclk[DC__VOLTAGE_STATES] = {0};
   1983
   1984	unsigned int dcfclk_sta_targets[DC__VOLTAGE_STATES] = {694, 875, 1000, 1200};
   1985	unsigned int num_dcfclk_sta_targets = 4;
   1986	unsigned int num_uclk_states;
   1987
   1988	struct dc_bounding_box_max_clk dcn30_bb_max_clk;
   1989
   1990	memset(&dcn30_bb_max_clk, 0, sizeof(dcn30_bb_max_clk));
   1991
   1992	if (dc->ctx->dc_bios->vram_info.num_chans)
   1993		dcn3_0_soc.num_chans = dc->ctx->dc_bios->vram_info.num_chans;
   1994
   1995	DC_FP_START();
   1996	dcn30_fpu_update_dram_channel_width_bytes(dc);
   1997	DC_FP_END();
   1998
   1999	if (bw_params->clk_table.entries[0].memclk_mhz) {
   2000
   2001		for (i = 0; i < MAX_NUM_DPM_LVL; i++) {
   2002			if (bw_params->clk_table.entries[i].dcfclk_mhz > dcn30_bb_max_clk.max_dcfclk_mhz)
   2003				dcn30_bb_max_clk.max_dcfclk_mhz = bw_params->clk_table.entries[i].dcfclk_mhz;
   2004			if (bw_params->clk_table.entries[i].dispclk_mhz > dcn30_bb_max_clk.max_dispclk_mhz)
   2005				dcn30_bb_max_clk.max_dispclk_mhz = bw_params->clk_table.entries[i].dispclk_mhz;
   2006			if (bw_params->clk_table.entries[i].dppclk_mhz > dcn30_bb_max_clk.max_dppclk_mhz)
   2007				dcn30_bb_max_clk.max_dppclk_mhz = bw_params->clk_table.entries[i].dppclk_mhz;
   2008			if (bw_params->clk_table.entries[i].phyclk_mhz > dcn30_bb_max_clk.max_phyclk_mhz)
   2009				dcn30_bb_max_clk.max_phyclk_mhz = bw_params->clk_table.entries[i].phyclk_mhz;
   2010		}
   2011
   2012		DC_FP_START();
   2013		dcn30_fpu_update_max_clk(&dcn30_bb_max_clk);
   2014		DC_FP_END();
   2015
   2016		if (dcn30_bb_max_clk.max_dcfclk_mhz > dcfclk_sta_targets[num_dcfclk_sta_targets-1]) {
   2017			// If max DCFCLK is greater than the max DCFCLK STA target, insert into the DCFCLK STA target array
   2018			dcfclk_sta_targets[num_dcfclk_sta_targets] = dcn30_bb_max_clk.max_dcfclk_mhz;
   2019			num_dcfclk_sta_targets++;
   2020		} else if (dcn30_bb_max_clk.max_dcfclk_mhz < dcfclk_sta_targets[num_dcfclk_sta_targets-1]) {
   2021			// If max DCFCLK is less than the max DCFCLK STA target, cap values and remove duplicates
   2022			for (i = 0; i < num_dcfclk_sta_targets; i++) {
   2023				if (dcfclk_sta_targets[i] > dcn30_bb_max_clk.max_dcfclk_mhz) {
   2024					dcfclk_sta_targets[i] = dcn30_bb_max_clk.max_dcfclk_mhz;
   2025					break;
   2026				}
   2027			}
   2028			// Update size of array since we "removed" duplicates
   2029			num_dcfclk_sta_targets = i + 1;
   2030		}
   2031
   2032		num_uclk_states = bw_params->clk_table.num_entries;
   2033
   2034		// Calculate optimal dcfclk for each uclk
   2035		for (i = 0; i < num_uclk_states; i++) {
   2036			DC_FP_START();
   2037			dcn30_fpu_get_optimal_dcfclk_fclk_for_uclk(bw_params->clk_table.entries[i].memclk_mhz * 16,
   2038					&optimal_dcfclk_for_uclk[i], NULL);
   2039			DC_FP_END();
   2040			if (optimal_dcfclk_for_uclk[i] < bw_params->clk_table.entries[0].dcfclk_mhz) {
   2041				optimal_dcfclk_for_uclk[i] = bw_params->clk_table.entries[0].dcfclk_mhz;
   2042			}
   2043		}
   2044
   2045		// Calculate optimal uclk for each dcfclk sta target
   2046		for (i = 0; i < num_dcfclk_sta_targets; i++) {
   2047			for (j = 0; j < num_uclk_states; j++) {
   2048				if (dcfclk_sta_targets[i] < optimal_dcfclk_for_uclk[j]) {
   2049					optimal_uclk_for_dcfclk_sta_targets[i] =
   2050							bw_params->clk_table.entries[j].memclk_mhz * 16;
   2051					break;
   2052				}
   2053			}
   2054		}
   2055
   2056		i = 0;
   2057		j = 0;
   2058		// create the final dcfclk and uclk table
   2059		while (i < num_dcfclk_sta_targets && j < num_uclk_states && num_states < DC__VOLTAGE_STATES) {
   2060			if (dcfclk_sta_targets[i] < optimal_dcfclk_for_uclk[j] && i < num_dcfclk_sta_targets) {
   2061				dcfclk_mhz[num_states] = dcfclk_sta_targets[i];
   2062				dram_speed_mts[num_states++] = optimal_uclk_for_dcfclk_sta_targets[i++];
   2063			} else {
   2064				if (j < num_uclk_states && optimal_dcfclk_for_uclk[j] <= dcn30_bb_max_clk.max_dcfclk_mhz) {
   2065					dcfclk_mhz[num_states] = optimal_dcfclk_for_uclk[j];
   2066					dram_speed_mts[num_states++] = bw_params->clk_table.entries[j++].memclk_mhz * 16;
   2067				} else {
   2068					j = num_uclk_states;
   2069				}
   2070			}
   2071		}
   2072
   2073		while (i < num_dcfclk_sta_targets && num_states < DC__VOLTAGE_STATES) {
   2074			dcfclk_mhz[num_states] = dcfclk_sta_targets[i];
   2075			dram_speed_mts[num_states++] = optimal_uclk_for_dcfclk_sta_targets[i++];
   2076		}
   2077
   2078		while (j < num_uclk_states && num_states < DC__VOLTAGE_STATES &&
   2079				optimal_dcfclk_for_uclk[j] <= dcn30_bb_max_clk.max_dcfclk_mhz) {
   2080			dcfclk_mhz[num_states] = optimal_dcfclk_for_uclk[j];
   2081			dram_speed_mts[num_states++] = bw_params->clk_table.entries[j++].memclk_mhz * 16;
   2082		}
   2083
   2084		dcn3_0_soc.num_states = num_states;
   2085		DC_FP_START();
   2086		dcn30_fpu_update_bw_bounding_box(dc, bw_params, &dcn30_bb_max_clk, dcfclk_mhz, dram_speed_mts);
   2087		DC_FP_END();
   2088	}
   2089}
   2090
   2091static const struct resource_funcs dcn30_res_pool_funcs = {
   2092	.destroy = dcn30_destroy_resource_pool,
   2093	.link_enc_create = dcn30_link_encoder_create,
   2094	.panel_cntl_create = dcn30_panel_cntl_create,
   2095	.validate_bandwidth = dcn30_validate_bandwidth,
   2096	.calculate_wm_and_dlg = dcn30_calculate_wm_and_dlg,
   2097	.update_soc_for_wm_a = dcn30_update_soc_for_wm_a,
   2098	.populate_dml_pipes = dcn30_populate_dml_pipes_from_context,
   2099	.acquire_idle_pipe_for_layer = dcn20_acquire_idle_pipe_for_layer,
   2100	.add_stream_to_ctx = dcn30_add_stream_to_ctx,
   2101	.add_dsc_to_stream_resource = dcn20_add_dsc_to_stream_resource,
   2102	.remove_stream_from_ctx = dcn20_remove_stream_from_ctx,
   2103	.populate_dml_writeback_from_context = dcn30_populate_dml_writeback_from_context,
   2104	.set_mcif_arb_params = dcn30_set_mcif_arb_params,
   2105	.find_first_free_match_stream_enc_for_link = dcn10_find_first_free_match_stream_enc_for_link,
   2106	.acquire_post_bldn_3dlut = dcn30_acquire_post_bldn_3dlut,
   2107	.release_post_bldn_3dlut = dcn30_release_post_bldn_3dlut,
   2108	.update_bw_bounding_box = dcn30_update_bw_bounding_box,
   2109	.patch_unknown_plane_state = dcn20_patch_unknown_plane_state,
   2110};
   2111
   2112#define CTX ctx
   2113
   2114#define REG(reg_name) \
   2115	(DCN_BASE.instance[0].segment[mm ## reg_name ## _BASE_IDX] + mm ## reg_name)
   2116
   2117static uint32_t read_pipe_fuses(struct dc_context *ctx)
   2118{
   2119	uint32_t value = REG_READ(CC_DC_PIPE_DIS);
   2120	/* Support for max 6 pipes */
   2121	value = value & 0x3f;
   2122	return value;
   2123}
   2124
   2125static bool dcn30_resource_construct(
   2126	uint8_t num_virtual_links,
   2127	struct dc *dc,
   2128	struct dcn30_resource_pool *pool)
   2129{
   2130	int i;
   2131	struct dc_context *ctx = dc->ctx;
   2132	struct irq_service_init_data init_data;
   2133	struct ddc_service_init_data ddc_init_data = {0};
   2134	uint32_t pipe_fuses = read_pipe_fuses(ctx);
   2135	uint32_t num_pipes = 0;
   2136
   2137	if (!(pipe_fuses == 0 || pipe_fuses == 0x3e)) {
   2138		BREAK_TO_DEBUGGER();
   2139		dm_error("DC: Unexpected fuse recipe for navi2x !\n");
   2140		/* fault to single pipe */
   2141		pipe_fuses = 0x3e;
   2142	}
   2143
   2144	DC_FP_START();
   2145
   2146	ctx->dc_bios->regs = &bios_regs;
   2147
   2148	pool->base.res_cap = &res_cap_dcn3;
   2149
   2150	pool->base.funcs = &dcn30_res_pool_funcs;
   2151
   2152	/*************************************************
   2153	 *  Resource + asic cap harcoding                *
   2154	 *************************************************/
   2155	pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE;
   2156	pool->base.pipe_count = pool->base.res_cap->num_timing_generator;
   2157	pool->base.mpcc_count = pool->base.res_cap->num_timing_generator;
   2158	dc->caps.max_downscale_ratio = 600;
   2159	dc->caps.i2c_speed_in_khz = 100;
   2160	dc->caps.i2c_speed_in_khz_hdcp = 100; /*1.4 w/a not applied by default*/
   2161	dc->caps.max_cursor_size = 256;
   2162	dc->caps.min_horizontal_blanking_period = 80;
   2163	dc->caps.dmdata_alloc_size = 2048;
   2164	dc->caps.mall_size_per_mem_channel = 8;
   2165	/* total size = mall per channel * num channels * 1024 * 1024 */
   2166	dc->caps.mall_size_total = dc->caps.mall_size_per_mem_channel * dc->ctx->dc_bios->vram_info.num_chans * 1048576;
   2167	dc->caps.cursor_cache_size = dc->caps.max_cursor_size * dc->caps.max_cursor_size * 8;
   2168
   2169	dc->caps.max_slave_planes = 2;
   2170	dc->caps.max_slave_yuv_planes = 2;
   2171	dc->caps.max_slave_rgb_planes = 2;
   2172	dc->caps.post_blend_color_processing = true;
   2173	dc->caps.force_dp_tps4_for_cp2520 = true;
   2174	dc->caps.extended_aux_timeout_support = true;
   2175	dc->caps.dmcub_support = true;
   2176
   2177	/* Color pipeline capabilities */
   2178	dc->caps.color.dpp.dcn_arch = 1;
   2179	dc->caps.color.dpp.input_lut_shared = 0;
   2180	dc->caps.color.dpp.icsc = 1;
   2181	dc->caps.color.dpp.dgam_ram = 0; // must use gamma_corr
   2182	dc->caps.color.dpp.dgam_rom_caps.srgb = 1;
   2183	dc->caps.color.dpp.dgam_rom_caps.bt2020 = 1;
   2184	dc->caps.color.dpp.dgam_rom_caps.gamma2_2 = 1;
   2185	dc->caps.color.dpp.dgam_rom_caps.pq = 1;
   2186	dc->caps.color.dpp.dgam_rom_caps.hlg = 1;
   2187	dc->caps.color.dpp.post_csc = 1;
   2188	dc->caps.color.dpp.gamma_corr = 1;
   2189	dc->caps.color.dpp.dgam_rom_for_yuv = 0;
   2190
   2191	dc->caps.color.dpp.hw_3d_lut = 1;
   2192	dc->caps.color.dpp.ogam_ram = 1;
   2193	// no OGAM ROM on DCN3
   2194	dc->caps.color.dpp.ogam_rom_caps.srgb = 0;
   2195	dc->caps.color.dpp.ogam_rom_caps.bt2020 = 0;
   2196	dc->caps.color.dpp.ogam_rom_caps.gamma2_2 = 0;
   2197	dc->caps.color.dpp.ogam_rom_caps.pq = 0;
   2198	dc->caps.color.dpp.ogam_rom_caps.hlg = 0;
   2199	dc->caps.color.dpp.ocsc = 0;
   2200
   2201	dc->caps.color.mpc.gamut_remap = 1;
   2202	dc->caps.color.mpc.num_3dluts = pool->base.res_cap->num_mpc_3dlut; //3
   2203	dc->caps.color.mpc.ogam_ram = 1;
   2204	dc->caps.color.mpc.ogam_rom_caps.srgb = 0;
   2205	dc->caps.color.mpc.ogam_rom_caps.bt2020 = 0;
   2206	dc->caps.color.mpc.ogam_rom_caps.gamma2_2 = 0;
   2207	dc->caps.color.mpc.ogam_rom_caps.pq = 0;
   2208	dc->caps.color.mpc.ogam_rom_caps.hlg = 0;
   2209	dc->caps.color.mpc.ocsc = 1;
   2210
   2211	dc->caps.hdmi_frl_pcon_support = true;
   2212
   2213	/* read VBIOS LTTPR caps */
   2214	{
   2215		if (ctx->dc_bios->funcs->get_lttpr_caps) {
   2216			enum bp_result bp_query_result;
   2217			uint8_t is_vbios_lttpr_enable = 0;
   2218
   2219			bp_query_result = ctx->dc_bios->funcs->get_lttpr_caps(ctx->dc_bios, &is_vbios_lttpr_enable);
   2220			dc->caps.vbios_lttpr_enable = (bp_query_result == BP_RESULT_OK) && !!is_vbios_lttpr_enable;
   2221		}
   2222
   2223		if (ctx->dc_bios->funcs->get_lttpr_interop) {
   2224			enum bp_result bp_query_result;
   2225			uint8_t is_vbios_interop_enabled = 0;
   2226
   2227			bp_query_result = ctx->dc_bios->funcs->get_lttpr_interop(ctx->dc_bios,
   2228					&is_vbios_interop_enabled);
   2229			dc->caps.vbios_lttpr_aware = (bp_query_result == BP_RESULT_OK) && !!is_vbios_interop_enabled;
   2230		}
   2231	}
   2232
   2233	if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV)
   2234		dc->debug = debug_defaults_drv;
   2235	else if (dc->ctx->dce_environment == DCE_ENV_FPGA_MAXIMUS) {
   2236		dc->debug = debug_defaults_diags;
   2237	} else
   2238		dc->debug = debug_defaults_diags;
   2239	// Init the vm_helper
   2240	if (dc->vm_helper)
   2241		vm_helper_init(dc->vm_helper, 16);
   2242
   2243	/*************************************************
   2244	 *  Create resources                             *
   2245	 *************************************************/
   2246
   2247	/* Clock Sources for Pixel Clock*/
   2248	pool->base.clock_sources[DCN30_CLK_SRC_PLL0] =
   2249			dcn30_clock_source_create(ctx, ctx->dc_bios,
   2250				CLOCK_SOURCE_COMBO_PHY_PLL0,
   2251				&clk_src_regs[0], false);
   2252	pool->base.clock_sources[DCN30_CLK_SRC_PLL1] =
   2253			dcn30_clock_source_create(ctx, ctx->dc_bios,
   2254				CLOCK_SOURCE_COMBO_PHY_PLL1,
   2255				&clk_src_regs[1], false);
   2256	pool->base.clock_sources[DCN30_CLK_SRC_PLL2] =
   2257			dcn30_clock_source_create(ctx, ctx->dc_bios,
   2258				CLOCK_SOURCE_COMBO_PHY_PLL2,
   2259				&clk_src_regs[2], false);
   2260	pool->base.clock_sources[DCN30_CLK_SRC_PLL3] =
   2261			dcn30_clock_source_create(ctx, ctx->dc_bios,
   2262				CLOCK_SOURCE_COMBO_PHY_PLL3,
   2263				&clk_src_regs[3], false);
   2264	pool->base.clock_sources[DCN30_CLK_SRC_PLL4] =
   2265			dcn30_clock_source_create(ctx, ctx->dc_bios,
   2266				CLOCK_SOURCE_COMBO_PHY_PLL4,
   2267				&clk_src_regs[4], false);
   2268	pool->base.clock_sources[DCN30_CLK_SRC_PLL5] =
   2269			dcn30_clock_source_create(ctx, ctx->dc_bios,
   2270				CLOCK_SOURCE_COMBO_PHY_PLL5,
   2271				&clk_src_regs[5], false);
   2272
   2273	pool->base.clk_src_count = DCN30_CLK_SRC_TOTAL;
   2274
   2275	/* todo: not reuse phy_pll registers */
   2276	pool->base.dp_clock_source =
   2277			dcn30_clock_source_create(ctx, ctx->dc_bios,
   2278				CLOCK_SOURCE_ID_DP_DTO,
   2279				&clk_src_regs[0], true);
   2280
   2281	for (i = 0; i < pool->base.clk_src_count; i++) {
   2282		if (pool->base.clock_sources[i] == NULL) {
   2283			dm_error("DC: failed to create clock sources!\n");
   2284			BREAK_TO_DEBUGGER();
   2285			goto create_fail;
   2286		}
   2287	}
   2288
   2289	/* DCCG */
   2290	pool->base.dccg = dccg30_create(ctx, &dccg_regs, &dccg_shift, &dccg_mask);
   2291	if (pool->base.dccg == NULL) {
   2292		dm_error("DC: failed to create dccg!\n");
   2293		BREAK_TO_DEBUGGER();
   2294		goto create_fail;
   2295	}
   2296
   2297	/* PP Lib and SMU interfaces */
   2298	init_soc_bounding_box(dc, pool);
   2299
   2300	num_pipes = dcn3_0_ip.max_num_dpp;
   2301
   2302	for (i = 0; i < dcn3_0_ip.max_num_dpp; i++)
   2303		if (pipe_fuses & 1 << i)
   2304			num_pipes--;
   2305
   2306	dcn3_0_ip.max_num_dpp = num_pipes;
   2307	dcn3_0_ip.max_num_otg = num_pipes;
   2308
   2309	dml_init_instance(&dc->dml, &dcn3_0_soc, &dcn3_0_ip, DML_PROJECT_DCN30);
   2310
   2311	/* IRQ */
   2312	init_data.ctx = dc->ctx;
   2313	pool->base.irqs = dal_irq_service_dcn30_create(&init_data);
   2314	if (!pool->base.irqs)
   2315		goto create_fail;
   2316
   2317	/* HUBBUB */
   2318	pool->base.hubbub = dcn30_hubbub_create(ctx);
   2319	if (pool->base.hubbub == NULL) {
   2320		BREAK_TO_DEBUGGER();
   2321		dm_error("DC: failed to create hubbub!\n");
   2322		goto create_fail;
   2323	}
   2324
   2325	/* HUBPs, DPPs, OPPs and TGs */
   2326	for (i = 0; i < pool->base.pipe_count; i++) {
   2327		pool->base.hubps[i] = dcn30_hubp_create(ctx, i);
   2328		if (pool->base.hubps[i] == NULL) {
   2329			BREAK_TO_DEBUGGER();
   2330			dm_error(
   2331				"DC: failed to create hubps!\n");
   2332			goto create_fail;
   2333		}
   2334
   2335		pool->base.dpps[i] = dcn30_dpp_create(ctx, i);
   2336		if (pool->base.dpps[i] == NULL) {
   2337			BREAK_TO_DEBUGGER();
   2338			dm_error(
   2339				"DC: failed to create dpps!\n");
   2340			goto create_fail;
   2341		}
   2342	}
   2343
   2344	for (i = 0; i < pool->base.res_cap->num_opp; i++) {
   2345		pool->base.opps[i] = dcn30_opp_create(ctx, i);
   2346		if (pool->base.opps[i] == NULL) {
   2347			BREAK_TO_DEBUGGER();
   2348			dm_error(
   2349				"DC: failed to create output pixel processor!\n");
   2350			goto create_fail;
   2351		}
   2352	}
   2353
   2354	for (i = 0; i < pool->base.res_cap->num_timing_generator; i++) {
   2355		pool->base.timing_generators[i] = dcn30_timing_generator_create(
   2356				ctx, i);
   2357		if (pool->base.timing_generators[i] == NULL) {
   2358			BREAK_TO_DEBUGGER();
   2359			dm_error("DC: failed to create tg!\n");
   2360			goto create_fail;
   2361		}
   2362	}
   2363	pool->base.timing_generator_count = i;
   2364	/* PSR */
   2365	pool->base.psr = dmub_psr_create(ctx);
   2366
   2367	if (pool->base.psr == NULL) {
   2368		dm_error("DC: failed to create PSR obj!\n");
   2369		BREAK_TO_DEBUGGER();
   2370		goto create_fail;
   2371	}
   2372
   2373	/* ABM */
   2374	for (i = 0; i < pool->base.res_cap->num_timing_generator; i++) {
   2375		pool->base.multiple_abms[i] = dmub_abm_create(ctx,
   2376				&abm_regs[i],
   2377				&abm_shift,
   2378				&abm_mask);
   2379		if (pool->base.multiple_abms[i] == NULL) {
   2380			dm_error("DC: failed to create abm for pipe %d!\n", i);
   2381			BREAK_TO_DEBUGGER();
   2382			goto create_fail;
   2383		}
   2384	}
   2385	/* MPC and DSC */
   2386	pool->base.mpc = dcn30_mpc_create(ctx, pool->base.mpcc_count, pool->base.res_cap->num_mpc_3dlut);
   2387	if (pool->base.mpc == NULL) {
   2388		BREAK_TO_DEBUGGER();
   2389		dm_error("DC: failed to create mpc!\n");
   2390		goto create_fail;
   2391	}
   2392
   2393	for (i = 0; i < pool->base.res_cap->num_dsc; i++) {
   2394		pool->base.dscs[i] = dcn30_dsc_create(ctx, i);
   2395		if (pool->base.dscs[i] == NULL) {
   2396			BREAK_TO_DEBUGGER();
   2397			dm_error("DC: failed to create display stream compressor %d!\n", i);
   2398			goto create_fail;
   2399		}
   2400	}
   2401
   2402	/* DWB and MMHUBBUB */
   2403	if (!dcn30_dwbc_create(ctx, &pool->base)) {
   2404		BREAK_TO_DEBUGGER();
   2405		dm_error("DC: failed to create dwbc!\n");
   2406		goto create_fail;
   2407	}
   2408
   2409	if (!dcn30_mmhubbub_create(ctx, &pool->base)) {
   2410		BREAK_TO_DEBUGGER();
   2411		dm_error("DC: failed to create mcif_wb!\n");
   2412		goto create_fail;
   2413	}
   2414
   2415	/* AUX and I2C */
   2416	for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
   2417		pool->base.engines[i] = dcn30_aux_engine_create(ctx, i);
   2418		if (pool->base.engines[i] == NULL) {
   2419			BREAK_TO_DEBUGGER();
   2420			dm_error(
   2421				"DC:failed to create aux engine!!\n");
   2422			goto create_fail;
   2423		}
   2424		pool->base.hw_i2cs[i] = dcn30_i2c_hw_create(ctx, i);
   2425		if (pool->base.hw_i2cs[i] == NULL) {
   2426			BREAK_TO_DEBUGGER();
   2427			dm_error(
   2428				"DC:failed to create hw i2c!!\n");
   2429			goto create_fail;
   2430		}
   2431		pool->base.sw_i2cs[i] = NULL;
   2432	}
   2433
   2434	/* Audio, Stream Encoders including DIG and virtual, MPC 3D LUTs */
   2435	if (!resource_construct(num_virtual_links, dc, &pool->base,
   2436			(!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment) ?
   2437			&res_create_funcs : &res_create_maximus_funcs)))
   2438		goto create_fail;
   2439
   2440	/* HW Sequencer and Plane caps */
   2441	dcn30_hw_sequencer_construct(dc);
   2442
   2443	dc->caps.max_planes =  pool->base.pipe_count;
   2444
   2445	for (i = 0; i < dc->caps.max_planes; ++i)
   2446		dc->caps.planes[i] = plane_cap;
   2447
   2448	dc->cap_funcs = cap_funcs;
   2449
   2450	if (dc->ctx->dc_bios->fw_info.oem_i2c_present) {
   2451		ddc_init_data.ctx = dc->ctx;
   2452		ddc_init_data.link = NULL;
   2453		ddc_init_data.id.id = dc->ctx->dc_bios->fw_info.oem_i2c_obj_id;
   2454		ddc_init_data.id.enum_id = 0;
   2455		ddc_init_data.id.type = OBJECT_TYPE_GENERIC;
   2456		pool->base.oem_device = dal_ddc_service_create(&ddc_init_data);
   2457	} else {
   2458		pool->base.oem_device = NULL;
   2459	}
   2460
   2461	DC_FP_END();
   2462
   2463	return true;
   2464
   2465create_fail:
   2466
   2467	DC_FP_END();
   2468	dcn30_resource_destruct(pool);
   2469
   2470	return false;
   2471}
   2472
   2473struct resource_pool *dcn30_create_resource_pool(
   2474		const struct dc_init_data *init_data,
   2475		struct dc *dc)
   2476{
   2477	struct dcn30_resource_pool *pool =
   2478		kzalloc(sizeof(struct dcn30_resource_pool), GFP_KERNEL);
   2479
   2480	if (!pool)
   2481		return NULL;
   2482
   2483	if (dcn30_resource_construct(init_data->num_virtual_links, dc, pool))
   2484		return &pool->base;
   2485
   2486	BREAK_TO_DEBUGGER();
   2487	kfree(pool);
   2488	return NULL;
   2489}