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}