1 /* 2 * Copyright 2018 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 #include "dm_services.h" 27 #include "dc.h" 28 29 #include "dcn21_init.h" 30 31 #include "resource.h" 32 #include "include/irq_service_interface.h" 33 #include "dcn20/dcn20_resource.h" 34 35 #include "clk_mgr.h" 36 #include "dcn10/dcn10_hubp.h" 37 #include "dcn10/dcn10_ipp.h" 38 #include "dcn20/dcn20_hubbub.h" 39 #include "dcn20/dcn20_mpc.h" 40 #include "dcn20/dcn20_hubp.h" 41 #include "dcn21_hubp.h" 42 #include "irq/dcn21/irq_service_dcn21.h" 43 #include "dcn20/dcn20_dpp.h" 44 #include "dcn20/dcn20_optc.h" 45 #include "dcn21/dcn21_hwseq.h" 46 #include "dce110/dce110_hw_sequencer.h" 47 #include "dcn20/dcn20_opp.h" 48 #include "dcn20/dcn20_dsc.h" 49 #include "dcn21/dcn21_link_encoder.h" 50 #include "dcn20/dcn20_stream_encoder.h" 51 #include "dce/dce_clock_source.h" 52 #include "dce/dce_audio.h" 53 #include "dce/dce_hwseq.h" 54 #include "virtual/virtual_stream_encoder.h" 55 #include "dce110/dce110_resource.h" 56 #include "dml/display_mode_vba.h" 57 #include "dcn20/dcn20_dccg.h" 58 #include "dcn21_hubbub.h" 59 #include "dcn10/dcn10_resource.h" 60 61 #include "dcn20/dcn20_dwb.h" 62 #include "dcn20/dcn20_mmhubbub.h" 63 64 #include "renoir_ip_offset.h" 65 #include "dcn/dcn_2_1_0_offset.h" 66 #include "dcn/dcn_2_1_0_sh_mask.h" 67 68 #include "nbio/nbio_7_0_offset.h" 69 70 #include "mmhub/mmhub_2_0_0_offset.h" 71 #include "mmhub/mmhub_2_0_0_sh_mask.h" 72 73 #include "reg_helper.h" 74 #include "dce/dce_abm.h" 75 #include "dce/dce_dmcu.h" 76 #include "dce/dce_aux.h" 77 #include "dce/dce_i2c.h" 78 #include "dcn21_resource.h" 79 #include "vm_helper.h" 80 #include "dcn20/dcn20_vmid.h" 81 82 #define SOC_BOUNDING_BOX_VALID false 83 #define DC_LOGGER_INIT(logger) 84 85 86 struct _vcs_dpi_ip_params_st dcn2_1_ip = { 87 .odm_capable = 1, 88 .gpuvm_enable = 1, 89 .hostvm_enable = 1, 90 .gpuvm_max_page_table_levels = 1, 91 .hostvm_max_page_table_levels = 4, 92 .hostvm_cached_page_table_levels = 2, 93 .num_dsc = 3, 94 .rob_buffer_size_kbytes = 168, 95 .det_buffer_size_kbytes = 164, 96 .dpte_buffer_size_in_pte_reqs_luma = 44, 97 .dpte_buffer_size_in_pte_reqs_chroma = 42,//todo 98 .dpp_output_buffer_pixels = 2560, 99 .opp_output_buffer_lines = 1, 100 .pixel_chunk_size_kbytes = 8, 101 .pte_enable = 1, 102 .max_page_table_levels = 4, 103 .pte_chunk_size_kbytes = 2, 104 .meta_chunk_size_kbytes = 2, 105 .writeback_chunk_size_kbytes = 2, 106 .line_buffer_size_bits = 789504, 107 .is_line_buffer_bpp_fixed = 0, 108 .line_buffer_fixed_bpp = 0, 109 .dcc_supported = true, 110 .max_line_buffer_lines = 12, 111 .writeback_luma_buffer_size_kbytes = 12, 112 .writeback_chroma_buffer_size_kbytes = 8, 113 .writeback_chroma_line_buffer_width_pixels = 4, 114 .writeback_max_hscl_ratio = 1, 115 .writeback_max_vscl_ratio = 1, 116 .writeback_min_hscl_ratio = 1, 117 .writeback_min_vscl_ratio = 1, 118 .writeback_max_hscl_taps = 12, 119 .writeback_max_vscl_taps = 12, 120 .writeback_line_buffer_luma_buffer_size = 0, 121 .writeback_line_buffer_chroma_buffer_size = 14643, 122 .cursor_buffer_size = 8, 123 .cursor_chunk_size = 2, 124 .max_num_otg = 4, 125 .max_num_dpp = 4, 126 .max_num_wb = 1, 127 .max_dchub_pscl_bw_pix_per_clk = 4, 128 .max_pscl_lb_bw_pix_per_clk = 2, 129 .max_lb_vscl_bw_pix_per_clk = 4, 130 .max_vscl_hscl_bw_pix_per_clk = 4, 131 .max_hscl_ratio = 4, 132 .max_vscl_ratio = 4, 133 .hscl_mults = 4, 134 .vscl_mults = 4, 135 .max_hscl_taps = 8, 136 .max_vscl_taps = 8, 137 .dispclk_ramp_margin_percent = 1, 138 .underscan_factor = 1.10, 139 .min_vblank_lines = 32, // 140 .dppclk_delay_subtotal = 77, // 141 .dppclk_delay_scl_lb_only = 16, 142 .dppclk_delay_scl = 50, 143 .dppclk_delay_cnvc_formatter = 8, 144 .dppclk_delay_cnvc_cursor = 6, 145 .dispclk_delay_subtotal = 87, // 146 .dcfclk_cstate_latency = 10, // SRExitTime 147 .max_inter_dcn_tile_repeaters = 8, 148 149 .xfc_supported = false, 150 .xfc_fill_bw_overhead_percent = 10.0, 151 .xfc_fill_constant_bytes = 0, 152 .ptoi_supported = 0 153 }; 154 155 struct _vcs_dpi_soc_bounding_box_st dcn2_1_soc = { 156 .clock_limits = { 157 { 158 .state = 0, 159 .dcfclk_mhz = 304.0, 160 .fabricclk_mhz = 600.0, 161 .dispclk_mhz = 618.0, 162 .dppclk_mhz = 440.0, 163 .phyclk_mhz = 600.0, 164 .socclk_mhz = 278.0, 165 .dscclk_mhz = 205.67, 166 .dram_speed_mts = 1600.0, 167 }, 168 { 169 .state = 1, 170 .dcfclk_mhz = 304.0, 171 .fabricclk_mhz = 600.0, 172 .dispclk_mhz = 618.0, 173 .dppclk_mhz = 618.0, 174 .phyclk_mhz = 600.0, 175 .socclk_mhz = 278.0, 176 .dscclk_mhz = 205.67, 177 .dram_speed_mts = 1600.0, 178 }, 179 { 180 .state = 2, 181 .dcfclk_mhz = 608.0, 182 .fabricclk_mhz = 1066.0, 183 .dispclk_mhz = 888.0, 184 .dppclk_mhz = 888.0, 185 .phyclk_mhz = 810.0, 186 .socclk_mhz = 278.0, 187 .dscclk_mhz = 287.67, 188 .dram_speed_mts = 2133.0, 189 }, 190 { 191 .state = 3, 192 .dcfclk_mhz = 676.0, 193 .fabricclk_mhz = 1600.0, 194 .dispclk_mhz = 1015.0, 195 .dppclk_mhz = 1015.0, 196 .phyclk_mhz = 810.0, 197 .socclk_mhz = 715.0, 198 .dscclk_mhz = 318.334, 199 .dram_speed_mts = 4266.0, 200 }, 201 { 202 .state = 4, 203 .dcfclk_mhz = 810.0, 204 .fabricclk_mhz = 1600.0, 205 .dispclk_mhz = 1395.0, 206 .dppclk_mhz = 1285.0, 207 .phyclk_mhz = 1325.0, 208 .socclk_mhz = 953.0, 209 .dscclk_mhz = 489.0, 210 .dram_speed_mts = 4266.0, 211 }, 212 /*Extra state, no dispclk ramping*/ 213 { 214 .state = 5, 215 .dcfclk_mhz = 810.0, 216 .fabricclk_mhz = 1600.0, 217 .dispclk_mhz = 1395.0, 218 .dppclk_mhz = 1285.0, 219 .phyclk_mhz = 1325.0, 220 .socclk_mhz = 953.0, 221 .dscclk_mhz = 489.0, 222 .dram_speed_mts = 4266.0, 223 }, 224 225 }, 226 227 .sr_exit_time_us = 12.5, 228 .sr_enter_plus_exit_time_us = 17.0, 229 .urgent_latency_us = 4.0, 230 .urgent_latency_pixel_data_only_us = 4.0, 231 .urgent_latency_pixel_mixed_with_vm_data_us = 4.0, 232 .urgent_latency_vm_data_only_us = 4.0, 233 .urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096, 234 .urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096, 235 .urgent_out_of_order_return_per_channel_vm_only_bytes = 4096, 236 .pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 80.0, 237 .pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 75.0, 238 .pct_ideal_dram_sdp_bw_after_urgent_vm_only = 40.0, 239 .max_avg_sdp_bw_use_normal_percent = 60.0, 240 .max_avg_dram_bw_use_normal_percent = 100.0, 241 .writeback_latency_us = 12.0, 242 .max_request_size_bytes = 256, 243 .dram_channel_width_bytes = 4, 244 .fabric_datapath_to_dcn_data_return_bytes = 32, 245 .dcn_downspread_percent = 0.5, 246 .downspread_percent = 0.5, 247 .dram_page_open_time_ns = 50.0, 248 .dram_rw_turnaround_time_ns = 17.5, 249 .dram_return_buffer_per_channel_bytes = 8192, 250 .round_trip_ping_latency_dcfclk_cycles = 128, 251 .urgent_out_of_order_return_per_channel_bytes = 4096, 252 .channel_interleave_bytes = 256, 253 .num_banks = 8, 254 .num_chans = 4, 255 .vmm_page_size_bytes = 4096, 256 .dram_clock_change_latency_us = 23.84, 257 .return_bus_width_bytes = 64, 258 .dispclk_dppclk_vco_speed_mhz = 3550, 259 .xfc_bus_transport_time_us = 4, 260 .xfc_xbuf_latency_tolerance_us = 4, 261 .use_urgent_burst_bw = 1, 262 .num_states = 5 263 }; 264 265 #ifndef MAX 266 #define MAX(X, Y) ((X) > (Y) ? (X) : (Y)) 267 #endif 268 #ifndef MIN 269 #define MIN(X, Y) ((X) < (Y) ? (X) : (Y)) 270 #endif 271 272 /* begin ********************* 273 * macros to expend register list macro defined in HW object header file */ 274 275 /* DCN */ 276 /* TODO awful hack. fixup dcn20_dwb.h */ 277 #undef BASE_INNER 278 #define BASE_INNER(seg) DMU_BASE__INST0_SEG ## seg 279 280 #define BASE(seg) BASE_INNER(seg) 281 282 #define SR(reg_name)\ 283 .reg_name = BASE(mm ## reg_name ## _BASE_IDX) + \ 284 mm ## reg_name 285 286 #define SRI(reg_name, block, id)\ 287 .reg_name = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ 288 mm ## block ## id ## _ ## reg_name 289 290 #define SRIR(var_name, reg_name, block, id)\ 291 .var_name = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ 292 mm ## block ## id ## _ ## reg_name 293 294 #define SRII(reg_name, block, id)\ 295 .reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ 296 mm ## block ## id ## _ ## reg_name 297 298 #define DCCG_SRII(reg_name, block, id)\ 299 .block ## _ ## reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ 300 mm ## block ## id ## _ ## reg_name 301 302 /* NBIO */ 303 #define NBIO_BASE_INNER(seg) \ 304 NBIF0_BASE__INST0_SEG ## seg 305 306 #define NBIO_BASE(seg) \ 307 NBIO_BASE_INNER(seg) 308 309 #define NBIO_SR(reg_name)\ 310 .reg_name = NBIO_BASE(mm ## reg_name ## _BASE_IDX) + \ 311 mm ## reg_name 312 313 /* MMHUB */ 314 #define MMHUB_BASE_INNER(seg) \ 315 MMHUB_BASE__INST0_SEG ## seg 316 317 #define MMHUB_BASE(seg) \ 318 MMHUB_BASE_INNER(seg) 319 320 #define MMHUB_SR(reg_name)\ 321 .reg_name = MMHUB_BASE(mmMM ## reg_name ## _BASE_IDX) + \ 322 mmMM ## reg_name 323 324 #define clk_src_regs(index, pllid)\ 325 [index] = {\ 326 CS_COMMON_REG_LIST_DCN2_1(index, pllid),\ 327 } 328 329 static const struct dce110_clk_src_regs clk_src_regs[] = { 330 clk_src_regs(0, A), 331 clk_src_regs(1, B), 332 clk_src_regs(2, C), 333 clk_src_regs(3, D), 334 clk_src_regs(4, E), 335 }; 336 337 static const struct dce110_clk_src_shift cs_shift = { 338 CS_COMMON_MASK_SH_LIST_DCN2_0(__SHIFT) 339 }; 340 341 static const struct dce110_clk_src_mask cs_mask = { 342 CS_COMMON_MASK_SH_LIST_DCN2_0(_MASK) 343 }; 344 345 static const struct bios_registers bios_regs = { 346 NBIO_SR(BIOS_SCRATCH_3), 347 NBIO_SR(BIOS_SCRATCH_6) 348 }; 349 350 static const struct dce_dmcu_registers dmcu_regs = { 351 DMCU_DCN20_REG_LIST() 352 }; 353 354 static const struct dce_dmcu_shift dmcu_shift = { 355 DMCU_MASK_SH_LIST_DCN10(__SHIFT) 356 }; 357 358 static const struct dce_dmcu_mask dmcu_mask = { 359 DMCU_MASK_SH_LIST_DCN10(_MASK) 360 }; 361 362 static const struct dce_abm_registers abm_regs = { 363 ABM_DCN20_REG_LIST() 364 }; 365 366 static const struct dce_abm_shift abm_shift = { 367 ABM_MASK_SH_LIST_DCN20(__SHIFT) 368 }; 369 370 static const struct dce_abm_mask abm_mask = { 371 ABM_MASK_SH_LIST_DCN20(_MASK) 372 }; 373 374 #define audio_regs(id)\ 375 [id] = {\ 376 AUD_COMMON_REG_LIST(id)\ 377 } 378 379 static const struct dce_audio_registers audio_regs[] = { 380 audio_regs(0), 381 audio_regs(1), 382 audio_regs(2), 383 audio_regs(3), 384 audio_regs(4), 385 audio_regs(5), 386 }; 387 388 #define DCE120_AUD_COMMON_MASK_SH_LIST(mask_sh)\ 389 SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_INDEX, AZALIA_ENDPOINT_REG_INDEX, mask_sh),\ 390 SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_DATA, AZALIA_ENDPOINT_REG_DATA, mask_sh),\ 391 AUD_COMMON_MASK_SH_LIST_BASE(mask_sh) 392 393 static const struct dce_audio_shift audio_shift = { 394 DCE120_AUD_COMMON_MASK_SH_LIST(__SHIFT) 395 }; 396 397 static const struct dce_audio_mask audio_mask = { 398 DCE120_AUD_COMMON_MASK_SH_LIST(_MASK) 399 }; 400 401 static const struct dccg_registers dccg_regs = { 402 DCCG_COMMON_REG_LIST_DCN_BASE() 403 }; 404 405 static const struct dccg_shift dccg_shift = { 406 DCCG_MASK_SH_LIST_DCN2(__SHIFT) 407 }; 408 409 static const struct dccg_mask dccg_mask = { 410 DCCG_MASK_SH_LIST_DCN2(_MASK) 411 }; 412 413 #define opp_regs(id)\ 414 [id] = {\ 415 OPP_REG_LIST_DCN20(id),\ 416 } 417 418 static const struct dcn20_opp_registers opp_regs[] = { 419 opp_regs(0), 420 opp_regs(1), 421 opp_regs(2), 422 opp_regs(3), 423 opp_regs(4), 424 opp_regs(5), 425 }; 426 427 static const struct dcn20_opp_shift opp_shift = { 428 OPP_MASK_SH_LIST_DCN20(__SHIFT) 429 }; 430 431 static const struct dcn20_opp_mask opp_mask = { 432 OPP_MASK_SH_LIST_DCN20(_MASK) 433 }; 434 435 #define tg_regs(id)\ 436 [id] = {TG_COMMON_REG_LIST_DCN2_0(id)} 437 438 static const struct dcn_optc_registers tg_regs[] = { 439 tg_regs(0), 440 tg_regs(1), 441 tg_regs(2), 442 tg_regs(3) 443 }; 444 445 static const struct dcn_optc_shift tg_shift = { 446 TG_COMMON_MASK_SH_LIST_DCN2_0(__SHIFT) 447 }; 448 449 static const struct dcn_optc_mask tg_mask = { 450 TG_COMMON_MASK_SH_LIST_DCN2_0(_MASK) 451 }; 452 453 static const struct dcn20_mpc_registers mpc_regs = { 454 MPC_REG_LIST_DCN2_0(0), 455 MPC_REG_LIST_DCN2_0(1), 456 MPC_REG_LIST_DCN2_0(2), 457 MPC_REG_LIST_DCN2_0(3), 458 MPC_REG_LIST_DCN2_0(4), 459 MPC_REG_LIST_DCN2_0(5), 460 MPC_OUT_MUX_REG_LIST_DCN2_0(0), 461 MPC_OUT_MUX_REG_LIST_DCN2_0(1), 462 MPC_OUT_MUX_REG_LIST_DCN2_0(2), 463 MPC_OUT_MUX_REG_LIST_DCN2_0(3) 464 }; 465 466 static const struct dcn20_mpc_shift mpc_shift = { 467 MPC_COMMON_MASK_SH_LIST_DCN2_0(__SHIFT) 468 }; 469 470 static const struct dcn20_mpc_mask mpc_mask = { 471 MPC_COMMON_MASK_SH_LIST_DCN2_0(_MASK) 472 }; 473 474 #define hubp_regs(id)\ 475 [id] = {\ 476 HUBP_REG_LIST_DCN21(id)\ 477 } 478 479 static const struct dcn_hubp2_registers hubp_regs[] = { 480 hubp_regs(0), 481 hubp_regs(1), 482 hubp_regs(2), 483 hubp_regs(3) 484 }; 485 486 static const struct dcn_hubp2_shift hubp_shift = { 487 HUBP_MASK_SH_LIST_DCN21(__SHIFT) 488 }; 489 490 static const struct dcn_hubp2_mask hubp_mask = { 491 HUBP_MASK_SH_LIST_DCN21(_MASK) 492 }; 493 494 static const struct dcn_hubbub_registers hubbub_reg = { 495 HUBBUB_REG_LIST_DCN21() 496 }; 497 498 static const struct dcn_hubbub_shift hubbub_shift = { 499 HUBBUB_MASK_SH_LIST_DCN21(__SHIFT) 500 }; 501 502 static const struct dcn_hubbub_mask hubbub_mask = { 503 HUBBUB_MASK_SH_LIST_DCN21(_MASK) 504 }; 505 506 507 #define vmid_regs(id)\ 508 [id] = {\ 509 DCN20_VMID_REG_LIST(id)\ 510 } 511 512 static const struct dcn_vmid_registers vmid_regs[] = { 513 vmid_regs(0), 514 vmid_regs(1), 515 vmid_regs(2), 516 vmid_regs(3), 517 vmid_regs(4), 518 vmid_regs(5), 519 vmid_regs(6), 520 vmid_regs(7), 521 vmid_regs(8), 522 vmid_regs(9), 523 vmid_regs(10), 524 vmid_regs(11), 525 vmid_regs(12), 526 vmid_regs(13), 527 vmid_regs(14), 528 vmid_regs(15) 529 }; 530 531 static const struct dcn20_vmid_shift vmid_shifts = { 532 DCN20_VMID_MASK_SH_LIST(__SHIFT) 533 }; 534 535 static const struct dcn20_vmid_mask vmid_masks = { 536 DCN20_VMID_MASK_SH_LIST(_MASK) 537 }; 538 539 #define dsc_regsDCN20(id)\ 540 [id] = {\ 541 DSC_REG_LIST_DCN20(id)\ 542 } 543 544 static const struct dcn20_dsc_registers dsc_regs[] = { 545 dsc_regsDCN20(0), 546 dsc_regsDCN20(1), 547 dsc_regsDCN20(2), 548 dsc_regsDCN20(3), 549 dsc_regsDCN20(4), 550 dsc_regsDCN20(5) 551 }; 552 553 static const struct dcn20_dsc_shift dsc_shift = { 554 DSC_REG_LIST_SH_MASK_DCN20(__SHIFT) 555 }; 556 557 static const struct dcn20_dsc_mask dsc_mask = { 558 DSC_REG_LIST_SH_MASK_DCN20(_MASK) 559 }; 560 561 #define ipp_regs(id)\ 562 [id] = {\ 563 IPP_REG_LIST_DCN20(id),\ 564 } 565 566 static const struct dcn10_ipp_registers ipp_regs[] = { 567 ipp_regs(0), 568 ipp_regs(1), 569 ipp_regs(2), 570 ipp_regs(3), 571 }; 572 573 static const struct dcn10_ipp_shift ipp_shift = { 574 IPP_MASK_SH_LIST_DCN20(__SHIFT) 575 }; 576 577 static const struct dcn10_ipp_mask ipp_mask = { 578 IPP_MASK_SH_LIST_DCN20(_MASK), 579 }; 580 581 #define opp_regs(id)\ 582 [id] = {\ 583 OPP_REG_LIST_DCN20(id),\ 584 } 585 586 587 #define aux_engine_regs(id)\ 588 [id] = {\ 589 AUX_COMMON_REG_LIST0(id), \ 590 .AUXN_IMPCAL = 0, \ 591 .AUXP_IMPCAL = 0, \ 592 .AUX_RESET_MASK = DP_AUX0_AUX_CONTROL__AUX_RESET_MASK, \ 593 } 594 595 static const struct dce110_aux_registers aux_engine_regs[] = { 596 aux_engine_regs(0), 597 aux_engine_regs(1), 598 aux_engine_regs(2), 599 aux_engine_regs(3), 600 aux_engine_regs(4), 601 }; 602 603 #define tf_regs(id)\ 604 [id] = {\ 605 TF_REG_LIST_DCN20(id),\ 606 } 607 608 static const struct dcn2_dpp_registers tf_regs[] = { 609 tf_regs(0), 610 tf_regs(1), 611 tf_regs(2), 612 tf_regs(3), 613 }; 614 615 static const struct dcn2_dpp_shift tf_shift = { 616 TF_REG_LIST_SH_MASK_DCN20(__SHIFT) 617 }; 618 619 static const struct dcn2_dpp_mask tf_mask = { 620 TF_REG_LIST_SH_MASK_DCN20(_MASK) 621 }; 622 623 #define stream_enc_regs(id)\ 624 [id] = {\ 625 SE_DCN2_REG_LIST(id)\ 626 } 627 628 static const struct dcn10_stream_enc_registers stream_enc_regs[] = { 629 stream_enc_regs(0), 630 stream_enc_regs(1), 631 stream_enc_regs(2), 632 stream_enc_regs(3), 633 stream_enc_regs(4), 634 }; 635 636 static const struct dce110_aux_registers_shift aux_shift = { 637 DCN_AUX_MASK_SH_LIST(__SHIFT) 638 }; 639 640 static const struct dce110_aux_registers_mask aux_mask = { 641 DCN_AUX_MASK_SH_LIST(_MASK) 642 }; 643 644 static const struct dcn10_stream_encoder_shift se_shift = { 645 SE_COMMON_MASK_SH_LIST_DCN20(__SHIFT) 646 }; 647 648 static const struct dcn10_stream_encoder_mask se_mask = { 649 SE_COMMON_MASK_SH_LIST_DCN20(_MASK) 650 }; 651 652 static void dcn21_pp_smu_destroy(struct pp_smu_funcs **pp_smu); 653 654 static int dcn21_populate_dml_pipes_from_context( 655 struct dc *dc, struct dc_state *context, display_e2e_pipe_params_st *pipes); 656 657 static struct input_pixel_processor *dcn21_ipp_create( 658 struct dc_context *ctx, uint32_t inst) 659 { 660 struct dcn10_ipp *ipp = 661 kzalloc(sizeof(struct dcn10_ipp), GFP_KERNEL); 662 663 if (!ipp) { 664 BREAK_TO_DEBUGGER(); 665 return NULL; 666 } 667 668 dcn20_ipp_construct(ipp, ctx, inst, 669 &ipp_regs[inst], &ipp_shift, &ipp_mask); 670 return &ipp->base; 671 } 672 673 static struct dpp *dcn21_dpp_create( 674 struct dc_context *ctx, 675 uint32_t inst) 676 { 677 struct dcn20_dpp *dpp = 678 kzalloc(sizeof(struct dcn20_dpp), GFP_KERNEL); 679 680 if (!dpp) 681 return NULL; 682 683 if (dpp2_construct(dpp, ctx, inst, 684 &tf_regs[inst], &tf_shift, &tf_mask)) 685 return &dpp->base; 686 687 BREAK_TO_DEBUGGER(); 688 kfree(dpp); 689 return NULL; 690 } 691 692 static struct dce_aux *dcn21_aux_engine_create( 693 struct dc_context *ctx, 694 uint32_t inst) 695 { 696 struct aux_engine_dce110 *aux_engine = 697 kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL); 698 699 if (!aux_engine) 700 return NULL; 701 702 dce110_aux_engine_construct(aux_engine, ctx, inst, 703 SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD, 704 &aux_engine_regs[inst], 705 &aux_mask, 706 &aux_shift, 707 ctx->dc->caps.extended_aux_timeout_support); 708 709 return &aux_engine->base; 710 } 711 712 #define i2c_inst_regs(id) { I2C_HW_ENGINE_COMMON_REG_LIST(id) } 713 714 static const struct dce_i2c_registers i2c_hw_regs[] = { 715 i2c_inst_regs(1), 716 i2c_inst_regs(2), 717 i2c_inst_regs(3), 718 i2c_inst_regs(4), 719 i2c_inst_regs(5), 720 }; 721 722 static const struct dce_i2c_shift i2c_shifts = { 723 I2C_COMMON_MASK_SH_LIST_DCN2(__SHIFT) 724 }; 725 726 static const struct dce_i2c_mask i2c_masks = { 727 I2C_COMMON_MASK_SH_LIST_DCN2(_MASK) 728 }; 729 730 struct dce_i2c_hw *dcn21_i2c_hw_create( 731 struct dc_context *ctx, 732 uint32_t inst) 733 { 734 struct dce_i2c_hw *dce_i2c_hw = 735 kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL); 736 737 if (!dce_i2c_hw) 738 return NULL; 739 740 dcn2_i2c_hw_construct(dce_i2c_hw, ctx, inst, 741 &i2c_hw_regs[inst], &i2c_shifts, &i2c_masks); 742 743 return dce_i2c_hw; 744 } 745 746 static const struct resource_caps res_cap_rn = { 747 .num_timing_generator = 4, 748 .num_opp = 4, 749 .num_video_plane = 4, 750 .num_audio = 4, // 4 audio endpoints. 4 audio streams 751 .num_stream_encoder = 5, 752 .num_pll = 5, // maybe 3 because the last two used for USB-c 753 .num_dwb = 1, 754 .num_ddc = 5, 755 .num_vmid = 1, 756 .num_dsc = 3, 757 }; 758 759 #ifdef DIAGS_BUILD 760 static const struct resource_caps res_cap_rn_FPGA_4pipe = { 761 .num_timing_generator = 4, 762 .num_opp = 4, 763 .num_video_plane = 4, 764 .num_audio = 7, 765 .num_stream_encoder = 4, 766 .num_pll = 4, 767 .num_dwb = 1, 768 .num_ddc = 4, 769 .num_dsc = 0, 770 }; 771 772 static const struct resource_caps res_cap_rn_FPGA_2pipe_dsc = { 773 .num_timing_generator = 2, 774 .num_opp = 2, 775 .num_video_plane = 2, 776 .num_audio = 7, 777 .num_stream_encoder = 2, 778 .num_pll = 4, 779 .num_dwb = 1, 780 .num_ddc = 4, 781 .num_dsc = 2, 782 }; 783 #endif 784 785 static const struct dc_plane_cap plane_cap = { 786 .type = DC_PLANE_TYPE_DCN_UNIVERSAL, 787 .blends_with_above = true, 788 .blends_with_below = true, 789 .per_pixel_alpha = true, 790 791 .pixel_format_support = { 792 .argb8888 = true, 793 .nv12 = true, 794 .fp16 = true 795 }, 796 797 .max_upscale_factor = { 798 .argb8888 = 16000, 799 .nv12 = 16000, 800 .fp16 = 16000 801 }, 802 803 .max_downscale_factor = { 804 .argb8888 = 250, 805 .nv12 = 250, 806 .fp16 = 250 807 } 808 }; 809 810 static const struct dc_debug_options debug_defaults_drv = { 811 .disable_dmcu = true, 812 .force_abm_enable = false, 813 .timing_trace = false, 814 .clock_trace = true, 815 .disable_pplib_clock_request = true, 816 .pipe_split_policy = MPC_SPLIT_AVOID_MULT_DISP, 817 .force_single_disp_pipe_split = false, 818 .disable_dcc = DCC_ENABLE, 819 .vsr_support = true, 820 .performance_trace = false, 821 .max_downscale_src_width = 3840, 822 .disable_pplib_wm_range = false, 823 .scl_reset_length10 = true, 824 .sanity_checks = true, 825 .disable_48mhz_pwrdwn = false, 826 .nv12_iflip_vm_wa = true 827 }; 828 829 static const struct dc_debug_options debug_defaults_diags = { 830 .disable_dmcu = true, 831 .force_abm_enable = false, 832 .timing_trace = true, 833 .clock_trace = true, 834 .disable_dpp_power_gate = true, 835 .disable_hubp_power_gate = true, 836 .disable_clock_gate = true, 837 .disable_pplib_clock_request = true, 838 .disable_pplib_wm_range = true, 839 .disable_stutter = true, 840 .disable_48mhz_pwrdwn = true, 841 }; 842 843 enum dcn20_clk_src_array_id { 844 DCN20_CLK_SRC_PLL0, 845 DCN20_CLK_SRC_PLL1, 846 DCN20_CLK_SRC_TOTAL_DCN21 847 }; 848 849 static void dcn21_resource_destruct(struct dcn21_resource_pool *pool) 850 { 851 unsigned int i; 852 853 for (i = 0; i < pool->base.stream_enc_count; i++) { 854 if (pool->base.stream_enc[i] != NULL) { 855 kfree(DCN10STRENC_FROM_STRENC(pool->base.stream_enc[i])); 856 pool->base.stream_enc[i] = NULL; 857 } 858 } 859 860 for (i = 0; i < pool->base.res_cap->num_dsc; i++) { 861 if (pool->base.dscs[i] != NULL) 862 dcn20_dsc_destroy(&pool->base.dscs[i]); 863 } 864 865 if (pool->base.mpc != NULL) { 866 kfree(TO_DCN20_MPC(pool->base.mpc)); 867 pool->base.mpc = NULL; 868 } 869 if (pool->base.hubbub != NULL) { 870 kfree(pool->base.hubbub); 871 pool->base.hubbub = NULL; 872 } 873 for (i = 0; i < pool->base.pipe_count; i++) { 874 if (pool->base.dpps[i] != NULL) 875 dcn20_dpp_destroy(&pool->base.dpps[i]); 876 877 if (pool->base.ipps[i] != NULL) 878 pool->base.ipps[i]->funcs->ipp_destroy(&pool->base.ipps[i]); 879 880 if (pool->base.hubps[i] != NULL) { 881 kfree(TO_DCN20_HUBP(pool->base.hubps[i])); 882 pool->base.hubps[i] = NULL; 883 } 884 885 if (pool->base.irqs != NULL) { 886 dal_irq_service_destroy(&pool->base.irqs); 887 } 888 } 889 890 for (i = 0; i < pool->base.res_cap->num_ddc; i++) { 891 if (pool->base.engines[i] != NULL) 892 dce110_engine_destroy(&pool->base.engines[i]); 893 if (pool->base.hw_i2cs[i] != NULL) { 894 kfree(pool->base.hw_i2cs[i]); 895 pool->base.hw_i2cs[i] = NULL; 896 } 897 if (pool->base.sw_i2cs[i] != NULL) { 898 kfree(pool->base.sw_i2cs[i]); 899 pool->base.sw_i2cs[i] = NULL; 900 } 901 } 902 903 for (i = 0; i < pool->base.res_cap->num_opp; i++) { 904 if (pool->base.opps[i] != NULL) 905 pool->base.opps[i]->funcs->opp_destroy(&pool->base.opps[i]); 906 } 907 908 for (i = 0; i < pool->base.res_cap->num_timing_generator; i++) { 909 if (pool->base.timing_generators[i] != NULL) { 910 kfree(DCN10TG_FROM_TG(pool->base.timing_generators[i])); 911 pool->base.timing_generators[i] = NULL; 912 } 913 } 914 915 for (i = 0; i < pool->base.res_cap->num_dwb; i++) { 916 if (pool->base.dwbc[i] != NULL) { 917 kfree(TO_DCN20_DWBC(pool->base.dwbc[i])); 918 pool->base.dwbc[i] = NULL; 919 } 920 if (pool->base.mcif_wb[i] != NULL) { 921 kfree(TO_DCN20_MMHUBBUB(pool->base.mcif_wb[i])); 922 pool->base.mcif_wb[i] = NULL; 923 } 924 } 925 926 for (i = 0; i < pool->base.audio_count; i++) { 927 if (pool->base.audios[i]) 928 dce_aud_destroy(&pool->base.audios[i]); 929 } 930 931 for (i = 0; i < pool->base.clk_src_count; i++) { 932 if (pool->base.clock_sources[i] != NULL) { 933 dcn20_clock_source_destroy(&pool->base.clock_sources[i]); 934 pool->base.clock_sources[i] = NULL; 935 } 936 } 937 938 if (pool->base.dp_clock_source != NULL) { 939 dcn20_clock_source_destroy(&pool->base.dp_clock_source); 940 pool->base.dp_clock_source = NULL; 941 } 942 943 944 if (pool->base.abm != NULL) 945 dce_abm_destroy(&pool->base.abm); 946 947 if (pool->base.dmcu != NULL) 948 dce_dmcu_destroy(&pool->base.dmcu); 949 950 if (pool->base.dccg != NULL) 951 dcn_dccg_destroy(&pool->base.dccg); 952 953 if (pool->base.pp_smu != NULL) 954 dcn21_pp_smu_destroy(&pool->base.pp_smu); 955 } 956 957 958 static void calculate_wm_set_for_vlevel( 959 int vlevel, 960 struct wm_range_table_entry *table_entry, 961 struct dcn_watermarks *wm_set, 962 struct display_mode_lib *dml, 963 display_e2e_pipe_params_st *pipes, 964 int pipe_cnt) 965 { 966 double dram_clock_change_latency_cached = dml->soc.dram_clock_change_latency_us; 967 968 ASSERT(vlevel < dml->soc.num_states); 969 /* only pipe 0 is read for voltage and dcf/soc clocks */ 970 pipes[0].clks_cfg.voltage = vlevel; 971 pipes[0].clks_cfg.dcfclk_mhz = dml->soc.clock_limits[vlevel].dcfclk_mhz; 972 pipes[0].clks_cfg.socclk_mhz = dml->soc.clock_limits[vlevel].socclk_mhz; 973 974 dml->soc.dram_clock_change_latency_us = table_entry->pstate_latency_us; 975 976 wm_set->urgent_ns = get_wm_urgent(dml, pipes, pipe_cnt) * 1000; 977 wm_set->cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(dml, pipes, pipe_cnt) * 1000; 978 wm_set->cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(dml, pipes, pipe_cnt) * 1000; 979 wm_set->cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(dml, pipes, pipe_cnt) * 1000; 980 wm_set->pte_meta_urgent_ns = get_wm_memory_trip(dml, pipes, pipe_cnt) * 1000; 981 wm_set->frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(dml, pipes, pipe_cnt) * 1000; 982 wm_set->frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(dml, pipes, pipe_cnt) * 1000; 983 wm_set->urgent_latency_ns = get_urgent_latency(dml, pipes, pipe_cnt) * 1000; 984 dml->soc.dram_clock_change_latency_us = dram_clock_change_latency_cached; 985 986 } 987 988 static void patch_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_st *bb) 989 { 990 kernel_fpu_begin(); 991 if (dc->bb_overrides.sr_exit_time_ns) { 992 bb->sr_exit_time_us = dc->bb_overrides.sr_exit_time_ns / 1000.0; 993 } 994 995 if (dc->bb_overrides.sr_enter_plus_exit_time_ns) { 996 bb->sr_enter_plus_exit_time_us = 997 dc->bb_overrides.sr_enter_plus_exit_time_ns / 1000.0; 998 } 999 1000 if (dc->bb_overrides.urgent_latency_ns) { 1001 bb->urgent_latency_us = dc->bb_overrides.urgent_latency_ns / 1000.0; 1002 } 1003 1004 if (dc->bb_overrides.dram_clock_change_latency_ns) { 1005 bb->dram_clock_change_latency_us = 1006 dc->bb_overrides.dram_clock_change_latency_ns / 1000.0; 1007 } 1008 kernel_fpu_end(); 1009 } 1010 1011 void dcn21_calculate_wm( 1012 struct dc *dc, struct dc_state *context, 1013 display_e2e_pipe_params_st *pipes, 1014 int *out_pipe_cnt, 1015 int *pipe_split_from, 1016 int vlevel_req) 1017 { 1018 int pipe_cnt, i, pipe_idx; 1019 int vlevel, vlevel_max; 1020 struct wm_range_table_entry *table_entry; 1021 struct clk_bw_params *bw_params = dc->clk_mgr->bw_params; 1022 1023 ASSERT(bw_params); 1024 1025 patch_bounding_box(dc, &context->bw_ctx.dml.soc); 1026 1027 for (i = 0, pipe_idx = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) { 1028 if (!context->res_ctx.pipe_ctx[i].stream) 1029 continue; 1030 1031 pipes[pipe_cnt].clks_cfg.refclk_mhz = dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000.0; 1032 pipes[pipe_cnt].clks_cfg.dispclk_mhz = context->bw_ctx.dml.vba.RequiredDISPCLK[vlevel_req][context->bw_ctx.dml.vba.maxMpcComb]; 1033 1034 if (pipe_split_from[i] < 0) { 1035 pipes[pipe_cnt].clks_cfg.dppclk_mhz = 1036 context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel_req][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx]; 1037 if (context->bw_ctx.dml.vba.BlendingAndTiming[pipe_idx] == pipe_idx) 1038 pipes[pipe_cnt].pipe.dest.odm_combine = 1039 context->bw_ctx.dml.vba.ODMCombineEnablePerState[vlevel_req][pipe_idx]; 1040 else 1041 pipes[pipe_cnt].pipe.dest.odm_combine = 0; 1042 pipe_idx++; 1043 } else { 1044 pipes[pipe_cnt].clks_cfg.dppclk_mhz = 1045 context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel_req][context->bw_ctx.dml.vba.maxMpcComb][pipe_split_from[i]]; 1046 if (context->bw_ctx.dml.vba.BlendingAndTiming[pipe_split_from[i]] == pipe_split_from[i]) 1047 pipes[pipe_cnt].pipe.dest.odm_combine = 1048 context->bw_ctx.dml.vba.ODMCombineEnablePerState[vlevel_req][pipe_split_from[i]]; 1049 else 1050 pipes[pipe_cnt].pipe.dest.odm_combine = 0; 1051 } 1052 pipe_cnt++; 1053 } 1054 1055 if (pipe_cnt != pipe_idx) { 1056 if (dc->res_pool->funcs->populate_dml_pipes) 1057 pipe_cnt = dc->res_pool->funcs->populate_dml_pipes(dc, 1058 context, pipes); 1059 else 1060 pipe_cnt = dcn21_populate_dml_pipes_from_context(dc, 1061 context, pipes); 1062 } 1063 1064 *out_pipe_cnt = pipe_cnt; 1065 1066 vlevel_max = bw_params->clk_table.num_entries - 1; 1067 1068 1069 /* WM Set D */ 1070 table_entry = &bw_params->wm_table.entries[WM_D]; 1071 if (table_entry->wm_type == WM_TYPE_RETRAINING) 1072 vlevel = 0; 1073 else 1074 vlevel = vlevel_max; 1075 calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.d, 1076 &context->bw_ctx.dml, pipes, pipe_cnt); 1077 /* WM Set C */ 1078 table_entry = &bw_params->wm_table.entries[WM_C]; 1079 vlevel = MIN(MAX(vlevel_req, 2), vlevel_max); 1080 calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.c, 1081 &context->bw_ctx.dml, pipes, pipe_cnt); 1082 /* WM Set B */ 1083 table_entry = &bw_params->wm_table.entries[WM_B]; 1084 vlevel = MIN(MAX(vlevel_req, 1), vlevel_max); 1085 calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.b, 1086 &context->bw_ctx.dml, pipes, pipe_cnt); 1087 1088 /* WM Set A */ 1089 table_entry = &bw_params->wm_table.entries[WM_A]; 1090 vlevel = MIN(vlevel_req, vlevel_max); 1091 calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.a, 1092 &context->bw_ctx.dml, pipes, pipe_cnt); 1093 } 1094 1095 1096 bool dcn21_validate_bandwidth(struct dc *dc, struct dc_state *context, 1097 bool fast_validate) 1098 { 1099 bool out = false; 1100 1101 BW_VAL_TRACE_SETUP(); 1102 1103 int vlevel = 0; 1104 int pipe_split_from[MAX_PIPES]; 1105 int pipe_cnt = 0; 1106 display_e2e_pipe_params_st *pipes = kzalloc(dc->res_pool->pipe_count * sizeof(display_e2e_pipe_params_st), GFP_KERNEL); 1107 DC_LOGGER_INIT(dc->ctx->logger); 1108 1109 BW_VAL_TRACE_COUNT(); 1110 1111 out = dcn20_fast_validate_bw(dc, context, pipes, &pipe_cnt, pipe_split_from, &vlevel); 1112 1113 if (pipe_cnt == 0) 1114 goto validate_out; 1115 1116 if (!out) 1117 goto validate_fail; 1118 1119 BW_VAL_TRACE_END_VOLTAGE_LEVEL(); 1120 1121 if (fast_validate) { 1122 BW_VAL_TRACE_SKIP(fast); 1123 goto validate_out; 1124 } 1125 1126 dcn21_calculate_wm(dc, context, pipes, &pipe_cnt, pipe_split_from, vlevel); 1127 dcn20_calculate_dlg_params(dc, context, pipes, pipe_cnt, vlevel); 1128 1129 BW_VAL_TRACE_END_WATERMARKS(); 1130 1131 goto validate_out; 1132 1133 validate_fail: 1134 DC_LOG_WARNING("Mode Validation Warning: %s failed validation.\n", 1135 dml_get_status_message(context->bw_ctx.dml.vba.ValidationStatus[context->bw_ctx.dml.vba.soc.num_states])); 1136 1137 BW_VAL_TRACE_SKIP(fail); 1138 out = false; 1139 1140 validate_out: 1141 kfree(pipes); 1142 1143 BW_VAL_TRACE_FINISH(); 1144 1145 return out; 1146 } 1147 static void dcn21_destroy_resource_pool(struct resource_pool **pool) 1148 { 1149 struct dcn21_resource_pool *dcn21_pool = TO_DCN21_RES_POOL(*pool); 1150 1151 dcn21_resource_destruct(dcn21_pool); 1152 kfree(dcn21_pool); 1153 *pool = NULL; 1154 } 1155 1156 static struct clock_source *dcn21_clock_source_create( 1157 struct dc_context *ctx, 1158 struct dc_bios *bios, 1159 enum clock_source_id id, 1160 const struct dce110_clk_src_regs *regs, 1161 bool dp_clk_src) 1162 { 1163 struct dce110_clk_src *clk_src = 1164 kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL); 1165 1166 if (!clk_src) 1167 return NULL; 1168 1169 if (dcn20_clk_src_construct(clk_src, ctx, bios, id, 1170 regs, &cs_shift, &cs_mask)) { 1171 clk_src->base.dp_clk_src = dp_clk_src; 1172 return &clk_src->base; 1173 } 1174 1175 BREAK_TO_DEBUGGER(); 1176 return NULL; 1177 } 1178 1179 static struct hubp *dcn21_hubp_create( 1180 struct dc_context *ctx, 1181 uint32_t inst) 1182 { 1183 struct dcn21_hubp *hubp21 = 1184 kzalloc(sizeof(struct dcn21_hubp), GFP_KERNEL); 1185 1186 if (!hubp21) 1187 return NULL; 1188 1189 if (hubp21_construct(hubp21, ctx, inst, 1190 &hubp_regs[inst], &hubp_shift, &hubp_mask)) 1191 return &hubp21->base; 1192 1193 BREAK_TO_DEBUGGER(); 1194 kfree(hubp21); 1195 return NULL; 1196 } 1197 1198 static struct hubbub *dcn21_hubbub_create(struct dc_context *ctx) 1199 { 1200 int i; 1201 1202 struct dcn20_hubbub *hubbub = kzalloc(sizeof(struct dcn20_hubbub), 1203 GFP_KERNEL); 1204 1205 if (!hubbub) 1206 return NULL; 1207 1208 hubbub21_construct(hubbub, ctx, 1209 &hubbub_reg, 1210 &hubbub_shift, 1211 &hubbub_mask); 1212 1213 for (i = 0; i < res_cap_rn.num_vmid; i++) { 1214 struct dcn20_vmid *vmid = &hubbub->vmid[i]; 1215 1216 vmid->ctx = ctx; 1217 1218 vmid->regs = &vmid_regs[i]; 1219 vmid->shifts = &vmid_shifts; 1220 vmid->masks = &vmid_masks; 1221 } 1222 1223 return &hubbub->base; 1224 } 1225 1226 struct output_pixel_processor *dcn21_opp_create( 1227 struct dc_context *ctx, uint32_t inst) 1228 { 1229 struct dcn20_opp *opp = 1230 kzalloc(sizeof(struct dcn20_opp), GFP_KERNEL); 1231 1232 if (!opp) { 1233 BREAK_TO_DEBUGGER(); 1234 return NULL; 1235 } 1236 1237 dcn20_opp_construct(opp, ctx, inst, 1238 &opp_regs[inst], &opp_shift, &opp_mask); 1239 return &opp->base; 1240 } 1241 1242 struct timing_generator *dcn21_timing_generator_create( 1243 struct dc_context *ctx, 1244 uint32_t instance) 1245 { 1246 struct optc *tgn10 = 1247 kzalloc(sizeof(struct optc), GFP_KERNEL); 1248 1249 if (!tgn10) 1250 return NULL; 1251 1252 tgn10->base.inst = instance; 1253 tgn10->base.ctx = ctx; 1254 1255 tgn10->tg_regs = &tg_regs[instance]; 1256 tgn10->tg_shift = &tg_shift; 1257 tgn10->tg_mask = &tg_mask; 1258 1259 dcn20_timing_generator_init(tgn10); 1260 1261 return &tgn10->base; 1262 } 1263 1264 struct mpc *dcn21_mpc_create(struct dc_context *ctx) 1265 { 1266 struct dcn20_mpc *mpc20 = kzalloc(sizeof(struct dcn20_mpc), 1267 GFP_KERNEL); 1268 1269 if (!mpc20) 1270 return NULL; 1271 1272 dcn20_mpc_construct(mpc20, ctx, 1273 &mpc_regs, 1274 &mpc_shift, 1275 &mpc_mask, 1276 6); 1277 1278 return &mpc20->base; 1279 } 1280 1281 static void read_dce_straps( 1282 struct dc_context *ctx, 1283 struct resource_straps *straps) 1284 { 1285 generic_reg_get(ctx, mmDC_PINSTRAPS + BASE(mmDC_PINSTRAPS_BASE_IDX), 1286 FN(DC_PINSTRAPS, DC_PINSTRAPS_AUDIO), &straps->dc_pinstraps_audio); 1287 1288 } 1289 1290 1291 struct display_stream_compressor *dcn21_dsc_create( 1292 struct dc_context *ctx, uint32_t inst) 1293 { 1294 struct dcn20_dsc *dsc = 1295 kzalloc(sizeof(struct dcn20_dsc), GFP_KERNEL); 1296 1297 if (!dsc) { 1298 BREAK_TO_DEBUGGER(); 1299 return NULL; 1300 } 1301 1302 dsc2_construct(dsc, ctx, inst, &dsc_regs[inst], &dsc_shift, &dsc_mask); 1303 return &dsc->base; 1304 } 1305 1306 static void update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params) 1307 { 1308 /* 1309 TODO: Fix this function to calcualte correct values. 1310 There are known issues with this function currently 1311 that will need to be investigated. Use hardcoded known good values for now. 1312 1313 1314 struct dcn21_resource_pool *pool = TO_DCN21_RES_POOL(dc->res_pool); 1315 struct clk_limit_table *clk_table = &bw_params->clk_table; 1316 int i; 1317 1318 dcn2_1_ip.max_num_otg = pool->base.res_cap->num_timing_generator; 1319 dcn2_1_ip.max_num_dpp = pool->base.pipe_count; 1320 dcn2_1_soc.num_chans = bw_params->num_channels; 1321 1322 for (i = 0; i < clk_table->num_entries; i++) { 1323 1324 dcn2_1_soc.clock_limits[i].state = i; 1325 dcn2_1_soc.clock_limits[i].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz; 1326 dcn2_1_soc.clock_limits[i].fabricclk_mhz = clk_table->entries[i].fclk_mhz; 1327 dcn2_1_soc.clock_limits[i].socclk_mhz = clk_table->entries[i].socclk_mhz; 1328 dcn2_1_soc.clock_limits[i].dram_speed_mts = clk_table->entries[i].memclk_mhz * 16 / 1000; 1329 } 1330 dcn2_1_soc.clock_limits[i] = dcn2_1_soc.clock_limits[i - i]; 1331 dcn2_1_soc.num_states = i; 1332 */ 1333 } 1334 1335 /* Temporary Place holder until we can get them from fuse */ 1336 static struct dpm_clocks dummy_clocks = { 1337 .DcfClocks = { 1338 {.Freq = 400, .Vol = 1}, 1339 {.Freq = 483, .Vol = 1}, 1340 {.Freq = 602, .Vol = 1}, 1341 {.Freq = 738, .Vol = 1} }, 1342 .SocClocks = { 1343 {.Freq = 300, .Vol = 1}, 1344 {.Freq = 400, .Vol = 1}, 1345 {.Freq = 400, .Vol = 1}, 1346 {.Freq = 400, .Vol = 1} }, 1347 .FClocks = { 1348 {.Freq = 400, .Vol = 1}, 1349 {.Freq = 800, .Vol = 1}, 1350 {.Freq = 1067, .Vol = 1}, 1351 {.Freq = 1600, .Vol = 1} }, 1352 .MemClocks = { 1353 {.Freq = 800, .Vol = 1}, 1354 {.Freq = 1600, .Vol = 1}, 1355 {.Freq = 1067, .Vol = 1}, 1356 {.Freq = 1600, .Vol = 1} }, 1357 1358 }; 1359 1360 static enum pp_smu_status dummy_set_wm_ranges(struct pp_smu *pp, 1361 struct pp_smu_wm_range_sets *ranges) 1362 { 1363 return PP_SMU_RESULT_OK; 1364 } 1365 1366 static enum pp_smu_status dummy_get_dpm_clock_table(struct pp_smu *pp, 1367 struct dpm_clocks *clock_table) 1368 { 1369 *clock_table = dummy_clocks; 1370 return PP_SMU_RESULT_OK; 1371 } 1372 1373 static struct pp_smu_funcs *dcn21_pp_smu_create(struct dc_context *ctx) 1374 { 1375 struct pp_smu_funcs *pp_smu = kzalloc(sizeof(*pp_smu), GFP_KERNEL); 1376 1377 if (!pp_smu) 1378 return pp_smu; 1379 1380 if (IS_FPGA_MAXIMUS_DC(ctx->dce_environment) || IS_DIAG_DC(ctx->dce_environment)) { 1381 pp_smu->ctx.ver = PP_SMU_VER_RN; 1382 pp_smu->rn_funcs.get_dpm_clock_table = dummy_get_dpm_clock_table; 1383 pp_smu->rn_funcs.set_wm_ranges = dummy_set_wm_ranges; 1384 } else { 1385 1386 dm_pp_get_funcs(ctx, pp_smu); 1387 1388 if (pp_smu->ctx.ver != PP_SMU_VER_RN) 1389 pp_smu = memset(pp_smu, 0, sizeof(struct pp_smu_funcs)); 1390 } 1391 1392 return pp_smu; 1393 } 1394 1395 static void dcn21_pp_smu_destroy(struct pp_smu_funcs **pp_smu) 1396 { 1397 if (pp_smu && *pp_smu) { 1398 kfree(*pp_smu); 1399 *pp_smu = NULL; 1400 } 1401 } 1402 1403 static struct audio *dcn21_create_audio( 1404 struct dc_context *ctx, unsigned int inst) 1405 { 1406 return dce_audio_create(ctx, inst, 1407 &audio_regs[inst], &audio_shift, &audio_mask); 1408 } 1409 1410 static struct dc_cap_funcs cap_funcs = { 1411 .get_dcc_compression_cap = dcn20_get_dcc_compression_cap 1412 }; 1413 1414 struct stream_encoder *dcn21_stream_encoder_create( 1415 enum engine_id eng_id, 1416 struct dc_context *ctx) 1417 { 1418 struct dcn10_stream_encoder *enc1 = 1419 kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL); 1420 1421 if (!enc1) 1422 return NULL; 1423 1424 dcn20_stream_encoder_construct(enc1, ctx, ctx->dc_bios, eng_id, 1425 &stream_enc_regs[eng_id], 1426 &se_shift, &se_mask); 1427 1428 return &enc1->base; 1429 } 1430 1431 static const struct dce_hwseq_registers hwseq_reg = { 1432 HWSEQ_DCN21_REG_LIST() 1433 }; 1434 1435 static const struct dce_hwseq_shift hwseq_shift = { 1436 HWSEQ_DCN21_MASK_SH_LIST(__SHIFT) 1437 }; 1438 1439 static const struct dce_hwseq_mask hwseq_mask = { 1440 HWSEQ_DCN21_MASK_SH_LIST(_MASK) 1441 }; 1442 1443 static struct dce_hwseq *dcn21_hwseq_create( 1444 struct dc_context *ctx) 1445 { 1446 struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL); 1447 1448 if (hws) { 1449 hws->ctx = ctx; 1450 hws->regs = &hwseq_reg; 1451 hws->shifts = &hwseq_shift; 1452 hws->masks = &hwseq_mask; 1453 hws->wa.DEGVIDCN21 = true; 1454 } 1455 return hws; 1456 } 1457 1458 static const struct resource_create_funcs res_create_funcs = { 1459 .read_dce_straps = read_dce_straps, 1460 .create_audio = dcn21_create_audio, 1461 .create_stream_encoder = dcn21_stream_encoder_create, 1462 .create_hwseq = dcn21_hwseq_create, 1463 }; 1464 1465 static const struct resource_create_funcs res_create_maximus_funcs = { 1466 .read_dce_straps = NULL, 1467 .create_audio = NULL, 1468 .create_stream_encoder = NULL, 1469 .create_hwseq = dcn21_hwseq_create, 1470 }; 1471 1472 static const struct encoder_feature_support link_enc_feature = { 1473 .max_hdmi_deep_color = COLOR_DEPTH_121212, 1474 .max_hdmi_pixel_clock = 600000, 1475 .hdmi_ycbcr420_supported = true, 1476 .dp_ycbcr420_supported = true, 1477 .flags.bits.IS_HBR2_CAPABLE = true, 1478 .flags.bits.IS_HBR3_CAPABLE = true, 1479 .flags.bits.IS_TPS3_CAPABLE = true, 1480 .flags.bits.IS_TPS4_CAPABLE = true 1481 }; 1482 1483 1484 #define link_regs(id, phyid)\ 1485 [id] = {\ 1486 LE_DCN10_REG_LIST(id), \ 1487 UNIPHY_DCN2_REG_LIST(phyid), \ 1488 SRI(DP_DPHY_INTERNAL_CTRL, DP, id) \ 1489 } 1490 1491 static const struct dcn10_link_enc_registers link_enc_regs[] = { 1492 link_regs(0, A), 1493 link_regs(1, B), 1494 link_regs(2, C), 1495 link_regs(3, D), 1496 link_regs(4, E), 1497 }; 1498 1499 #define aux_regs(id)\ 1500 [id] = {\ 1501 DCN2_AUX_REG_LIST(id)\ 1502 } 1503 1504 static const struct dcn10_link_enc_aux_registers link_enc_aux_regs[] = { 1505 aux_regs(0), 1506 aux_regs(1), 1507 aux_regs(2), 1508 aux_regs(3), 1509 aux_regs(4) 1510 }; 1511 1512 #define hpd_regs(id)\ 1513 [id] = {\ 1514 HPD_REG_LIST(id)\ 1515 } 1516 1517 static const struct dcn10_link_enc_hpd_registers link_enc_hpd_regs[] = { 1518 hpd_regs(0), 1519 hpd_regs(1), 1520 hpd_regs(2), 1521 hpd_regs(3), 1522 hpd_regs(4) 1523 }; 1524 1525 static const struct dcn10_link_enc_shift le_shift = { 1526 LINK_ENCODER_MASK_SH_LIST_DCN20(__SHIFT) 1527 }; 1528 1529 static const struct dcn10_link_enc_mask le_mask = { 1530 LINK_ENCODER_MASK_SH_LIST_DCN20(_MASK) 1531 }; 1532 1533 static int map_transmitter_id_to_phy_instance( 1534 enum transmitter transmitter) 1535 { 1536 switch (transmitter) { 1537 case TRANSMITTER_UNIPHY_A: 1538 return 0; 1539 break; 1540 case TRANSMITTER_UNIPHY_B: 1541 return 1; 1542 break; 1543 case TRANSMITTER_UNIPHY_C: 1544 return 2; 1545 break; 1546 case TRANSMITTER_UNIPHY_D: 1547 return 3; 1548 break; 1549 case TRANSMITTER_UNIPHY_E: 1550 return 4; 1551 break; 1552 default: 1553 ASSERT(0); 1554 return 0; 1555 } 1556 } 1557 1558 static struct link_encoder *dcn21_link_encoder_create( 1559 const struct encoder_init_data *enc_init_data) 1560 { 1561 struct dcn21_link_encoder *enc21 = 1562 kzalloc(sizeof(struct dcn21_link_encoder), GFP_KERNEL); 1563 int link_regs_id; 1564 1565 if (!enc21) 1566 return NULL; 1567 1568 link_regs_id = 1569 map_transmitter_id_to_phy_instance(enc_init_data->transmitter); 1570 1571 dcn21_link_encoder_construct(enc21, 1572 enc_init_data, 1573 &link_enc_feature, 1574 &link_enc_regs[link_regs_id], 1575 &link_enc_aux_regs[enc_init_data->channel - 1], 1576 &link_enc_hpd_regs[enc_init_data->hpd_source], 1577 &le_shift, 1578 &le_mask); 1579 1580 return &enc21->enc10.base; 1581 } 1582 #define CTX ctx 1583 1584 #define REG(reg_name) \ 1585 (DCN_BASE.instance[0].segment[mm ## reg_name ## _BASE_IDX] + mm ## reg_name) 1586 1587 static uint32_t read_pipe_fuses(struct dc_context *ctx) 1588 { 1589 uint32_t value = REG_READ(CC_DC_PIPE_DIS); 1590 /* RV1 support max 4 pipes */ 1591 value = value & 0xf; 1592 return value; 1593 } 1594 1595 static int dcn21_populate_dml_pipes_from_context( 1596 struct dc *dc, struct dc_state *context, display_e2e_pipe_params_st *pipes) 1597 { 1598 uint32_t pipe_cnt = dcn20_populate_dml_pipes_from_context(dc, context, pipes); 1599 int i; 1600 struct resource_context *res_ctx = &context->res_ctx; 1601 1602 for (i = 0; i < dc->res_pool->pipe_count; i++) { 1603 1604 if (!res_ctx->pipe_ctx[i].stream) 1605 continue; 1606 1607 pipes[i].pipe.src.hostvm = 1; 1608 pipes[i].pipe.src.gpuvm = 1; 1609 } 1610 1611 return pipe_cnt; 1612 } 1613 1614 static struct resource_funcs dcn21_res_pool_funcs = { 1615 .destroy = dcn21_destroy_resource_pool, 1616 .link_enc_create = dcn21_link_encoder_create, 1617 .validate_bandwidth = dcn21_validate_bandwidth, 1618 .populate_dml_pipes = dcn21_populate_dml_pipes_from_context, 1619 .add_stream_to_ctx = dcn20_add_stream_to_ctx, 1620 .remove_stream_from_ctx = dcn20_remove_stream_from_ctx, 1621 .acquire_idle_pipe_for_layer = dcn20_acquire_idle_pipe_for_layer, 1622 .populate_dml_writeback_from_context = dcn20_populate_dml_writeback_from_context, 1623 .get_default_swizzle_mode = dcn20_get_default_swizzle_mode, 1624 .set_mcif_arb_params = dcn20_set_mcif_arb_params, 1625 .find_first_free_match_stream_enc_for_link = dcn10_find_first_free_match_stream_enc_for_link, 1626 .update_bw_bounding_box = update_bw_bounding_box 1627 }; 1628 1629 static bool dcn21_resource_construct( 1630 uint8_t num_virtual_links, 1631 struct dc *dc, 1632 struct dcn21_resource_pool *pool) 1633 { 1634 int i, j; 1635 struct dc_context *ctx = dc->ctx; 1636 struct irq_service_init_data init_data; 1637 uint32_t pipe_fuses = read_pipe_fuses(ctx); 1638 uint32_t num_pipes; 1639 1640 ctx->dc_bios->regs = &bios_regs; 1641 1642 pool->base.res_cap = &res_cap_rn; 1643 #ifdef DIAGS_BUILD 1644 if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) 1645 //pool->base.res_cap = &res_cap_nv10_FPGA_2pipe_dsc; 1646 pool->base.res_cap = &res_cap_rn_FPGA_4pipe; 1647 #endif 1648 1649 pool->base.funcs = &dcn21_res_pool_funcs; 1650 1651 /************************************************* 1652 * Resource + asic cap harcoding * 1653 *************************************************/ 1654 pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE; 1655 1656 /* max pipe num for ASIC before check pipe fuses */ 1657 pool->base.pipe_count = pool->base.res_cap->num_timing_generator; 1658 1659 dc->caps.max_downscale_ratio = 200; 1660 dc->caps.i2c_speed_in_khz = 100; 1661 dc->caps.max_cursor_size = 256; 1662 dc->caps.dmdata_alloc_size = 2048; 1663 dc->caps.hw_3d_lut = true; 1664 1665 dc->caps.max_slave_planes = 1; 1666 dc->caps.post_blend_color_processing = true; 1667 dc->caps.force_dp_tps4_for_cp2520 = true; 1668 dc->caps.extended_aux_timeout_support = true; 1669 dc->caps.dmcub_support = true; 1670 1671 if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV) 1672 dc->debug = debug_defaults_drv; 1673 else if (dc->ctx->dce_environment == DCE_ENV_FPGA_MAXIMUS) { 1674 pool->base.pipe_count = 4; 1675 dc->debug = debug_defaults_diags; 1676 } else 1677 dc->debug = debug_defaults_diags; 1678 1679 // Init the vm_helper 1680 if (dc->vm_helper) 1681 vm_helper_init(dc->vm_helper, 16); 1682 1683 /************************************************* 1684 * Create resources * 1685 *************************************************/ 1686 1687 pool->base.clock_sources[DCN20_CLK_SRC_PLL0] = 1688 dcn21_clock_source_create(ctx, ctx->dc_bios, 1689 CLOCK_SOURCE_COMBO_PHY_PLL0, 1690 &clk_src_regs[0], false); 1691 pool->base.clock_sources[DCN20_CLK_SRC_PLL1] = 1692 dcn21_clock_source_create(ctx, ctx->dc_bios, 1693 CLOCK_SOURCE_COMBO_PHY_PLL1, 1694 &clk_src_regs[1], false); 1695 1696 pool->base.clk_src_count = DCN20_CLK_SRC_TOTAL_DCN21; 1697 1698 /* todo: not reuse phy_pll registers */ 1699 pool->base.dp_clock_source = 1700 dcn21_clock_source_create(ctx, ctx->dc_bios, 1701 CLOCK_SOURCE_ID_DP_DTO, 1702 &clk_src_regs[0], true); 1703 1704 for (i = 0; i < pool->base.clk_src_count; i++) { 1705 if (pool->base.clock_sources[i] == NULL) { 1706 dm_error("DC: failed to create clock sources!\n"); 1707 BREAK_TO_DEBUGGER(); 1708 goto create_fail; 1709 } 1710 } 1711 1712 pool->base.dccg = dccg2_create(ctx, &dccg_regs, &dccg_shift, &dccg_mask); 1713 if (pool->base.dccg == NULL) { 1714 dm_error("DC: failed to create dccg!\n"); 1715 BREAK_TO_DEBUGGER(); 1716 goto create_fail; 1717 } 1718 1719 pool->base.dmcu = dcn21_dmcu_create(ctx, 1720 &dmcu_regs, 1721 &dmcu_shift, 1722 &dmcu_mask); 1723 if (pool->base.dmcu == NULL) { 1724 dm_error("DC: failed to create dmcu!\n"); 1725 BREAK_TO_DEBUGGER(); 1726 goto create_fail; 1727 } 1728 1729 pool->base.abm = dce_abm_create(ctx, 1730 &abm_regs, 1731 &abm_shift, 1732 &abm_mask); 1733 if (pool->base.abm == NULL) { 1734 dm_error("DC: failed to create abm!\n"); 1735 BREAK_TO_DEBUGGER(); 1736 goto create_fail; 1737 } 1738 1739 pool->base.pp_smu = dcn21_pp_smu_create(ctx); 1740 1741 num_pipes = dcn2_1_ip.max_num_dpp; 1742 1743 for (i = 0; i < dcn2_1_ip.max_num_dpp; i++) 1744 if (pipe_fuses & 1 << i) 1745 num_pipes--; 1746 dcn2_1_ip.max_num_dpp = num_pipes; 1747 dcn2_1_ip.max_num_otg = num_pipes; 1748 1749 dml_init_instance(&dc->dml, &dcn2_1_soc, &dcn2_1_ip, DML_PROJECT_DCN21); 1750 1751 init_data.ctx = dc->ctx; 1752 pool->base.irqs = dal_irq_service_dcn21_create(&init_data); 1753 if (!pool->base.irqs) 1754 goto create_fail; 1755 1756 j = 0; 1757 /* mem input -> ipp -> dpp -> opp -> TG */ 1758 for (i = 0; i < pool->base.pipe_count; i++) { 1759 /* if pipe is disabled, skip instance of HW pipe, 1760 * i.e, skip ASIC register instance 1761 */ 1762 if ((pipe_fuses & (1 << i)) != 0) 1763 continue; 1764 1765 pool->base.hubps[i] = dcn21_hubp_create(ctx, i); 1766 if (pool->base.hubps[i] == NULL) { 1767 BREAK_TO_DEBUGGER(); 1768 dm_error( 1769 "DC: failed to create memory input!\n"); 1770 goto create_fail; 1771 } 1772 1773 pool->base.ipps[i] = dcn21_ipp_create(ctx, i); 1774 if (pool->base.ipps[i] == NULL) { 1775 BREAK_TO_DEBUGGER(); 1776 dm_error( 1777 "DC: failed to create input pixel processor!\n"); 1778 goto create_fail; 1779 } 1780 1781 pool->base.dpps[i] = dcn21_dpp_create(ctx, i); 1782 if (pool->base.dpps[i] == NULL) { 1783 BREAK_TO_DEBUGGER(); 1784 dm_error( 1785 "DC: failed to create dpps!\n"); 1786 goto create_fail; 1787 } 1788 1789 pool->base.opps[i] = dcn21_opp_create(ctx, i); 1790 if (pool->base.opps[i] == NULL) { 1791 BREAK_TO_DEBUGGER(); 1792 dm_error( 1793 "DC: failed to create output pixel processor!\n"); 1794 goto create_fail; 1795 } 1796 1797 pool->base.timing_generators[i] = dcn21_timing_generator_create( 1798 ctx, i); 1799 if (pool->base.timing_generators[i] == NULL) { 1800 BREAK_TO_DEBUGGER(); 1801 dm_error("DC: failed to create tg!\n"); 1802 goto create_fail; 1803 } 1804 j++; 1805 } 1806 1807 for (i = 0; i < pool->base.res_cap->num_ddc; i++) { 1808 pool->base.engines[i] = dcn21_aux_engine_create(ctx, i); 1809 if (pool->base.engines[i] == NULL) { 1810 BREAK_TO_DEBUGGER(); 1811 dm_error( 1812 "DC:failed to create aux engine!!\n"); 1813 goto create_fail; 1814 } 1815 pool->base.hw_i2cs[i] = dcn21_i2c_hw_create(ctx, i); 1816 if (pool->base.hw_i2cs[i] == NULL) { 1817 BREAK_TO_DEBUGGER(); 1818 dm_error( 1819 "DC:failed to create hw i2c!!\n"); 1820 goto create_fail; 1821 } 1822 pool->base.sw_i2cs[i] = NULL; 1823 } 1824 1825 pool->base.timing_generator_count = j; 1826 pool->base.pipe_count = j; 1827 pool->base.mpcc_count = j; 1828 1829 pool->base.mpc = dcn21_mpc_create(ctx); 1830 if (pool->base.mpc == NULL) { 1831 BREAK_TO_DEBUGGER(); 1832 dm_error("DC: failed to create mpc!\n"); 1833 goto create_fail; 1834 } 1835 1836 pool->base.hubbub = dcn21_hubbub_create(ctx); 1837 if (pool->base.hubbub == NULL) { 1838 BREAK_TO_DEBUGGER(); 1839 dm_error("DC: failed to create hubbub!\n"); 1840 goto create_fail; 1841 } 1842 1843 for (i = 0; i < pool->base.res_cap->num_dsc; i++) { 1844 pool->base.dscs[i] = dcn21_dsc_create(ctx, i); 1845 if (pool->base.dscs[i] == NULL) { 1846 BREAK_TO_DEBUGGER(); 1847 dm_error("DC: failed to create display stream compressor %d!\n", i); 1848 goto create_fail; 1849 } 1850 } 1851 1852 if (!dcn20_dwbc_create(ctx, &pool->base)) { 1853 BREAK_TO_DEBUGGER(); 1854 dm_error("DC: failed to create dwbc!\n"); 1855 goto create_fail; 1856 } 1857 if (!dcn20_mmhubbub_create(ctx, &pool->base)) { 1858 BREAK_TO_DEBUGGER(); 1859 dm_error("DC: failed to create mcif_wb!\n"); 1860 goto create_fail; 1861 } 1862 1863 if (!resource_construct(num_virtual_links, dc, &pool->base, 1864 (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment) ? 1865 &res_create_funcs : &res_create_maximus_funcs))) 1866 goto create_fail; 1867 1868 dcn21_hw_sequencer_construct(dc); 1869 1870 dc->caps.max_planes = pool->base.pipe_count; 1871 1872 for (i = 0; i < dc->caps.max_planes; ++i) 1873 dc->caps.planes[i] = plane_cap; 1874 1875 dc->cap_funcs = cap_funcs; 1876 1877 return true; 1878 1879 create_fail: 1880 1881 dcn21_resource_destruct(pool); 1882 1883 return false; 1884 } 1885 1886 struct resource_pool *dcn21_create_resource_pool( 1887 const struct dc_init_data *init_data, 1888 struct dc *dc) 1889 { 1890 struct dcn21_resource_pool *pool = 1891 kzalloc(sizeof(struct dcn21_resource_pool), GFP_KERNEL); 1892 1893 if (!pool) 1894 return NULL; 1895 1896 if (dcn21_resource_construct(init_data->num_virtual_links, dc, pool)) 1897 return &pool->base; 1898 1899 BREAK_TO_DEBUGGER(); 1900 kfree(pool); 1901 return NULL; 1902 } 1903