File Index
Files and directories
Sign in
FILE

dcn30_resource.c

File preview with syntax highlighting.

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