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