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 dml->soc.sr_exit_time_us = table_entry->sr_exit_time_us; 976 dml->soc.sr_enter_plus_exit_time_us = table_entry->sr_enter_plus_exit_time_us; 977 978 wm_set->urgent_ns = get_wm_urgent(dml, pipes, pipe_cnt) * 1000; 979 wm_set->cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(dml, pipes, pipe_cnt) * 1000; 980 wm_set->cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(dml, pipes, pipe_cnt) * 1000; 981 wm_set->cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(dml, pipes, pipe_cnt) * 1000; 982 wm_set->pte_meta_urgent_ns = get_wm_memory_trip(dml, pipes, pipe_cnt) * 1000; 983 wm_set->frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(dml, pipes, pipe_cnt) * 1000; 984 wm_set->frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(dml, pipes, pipe_cnt) * 1000; 985 wm_set->urgent_latency_ns = get_urgent_latency(dml, pipes, pipe_cnt) * 1000; 986 dml->soc.dram_clock_change_latency_us = dram_clock_change_latency_cached; 987 988 } 989 990 static void patch_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_st *bb) 991 { 992 int i; 993 994 kernel_fpu_begin(); 995 if (dc->bb_overrides.sr_exit_time_ns) { 996 for (i = 0; i < WM_SET_COUNT; i++) { 997 dc->clk_mgr->bw_params->wm_table.entries[i].sr_exit_time_us = 998 dc->bb_overrides.sr_exit_time_ns / 1000.0; 999 } 1000 } 1001 1002 if (dc->bb_overrides.sr_enter_plus_exit_time_ns) { 1003 for (i = 0; i < WM_SET_COUNT; i++) { 1004 dc->clk_mgr->bw_params->wm_table.entries[i].sr_enter_plus_exit_time_us = 1005 dc->bb_overrides.sr_enter_plus_exit_time_ns / 1000.0; 1006 } 1007 } 1008 1009 if (dc->bb_overrides.urgent_latency_ns) { 1010 bb->urgent_latency_us = dc->bb_overrides.urgent_latency_ns / 1000.0; 1011 } 1012 1013 if (dc->bb_overrides.dram_clock_change_latency_ns) { 1014 bb->dram_clock_change_latency_us = 1015 dc->bb_overrides.dram_clock_change_latency_ns / 1000.0; 1016 } 1017 kernel_fpu_end(); 1018 } 1019 1020 void dcn21_calculate_wm( 1021 struct dc *dc, struct dc_state *context, 1022 display_e2e_pipe_params_st *pipes, 1023 int *out_pipe_cnt, 1024 int *pipe_split_from, 1025 int vlevel_req) 1026 { 1027 int pipe_cnt, i, pipe_idx; 1028 int vlevel, vlevel_max; 1029 struct wm_range_table_entry *table_entry; 1030 struct clk_bw_params *bw_params = dc->clk_mgr->bw_params; 1031 1032 ASSERT(bw_params); 1033 1034 patch_bounding_box(dc, &context->bw_ctx.dml.soc); 1035 1036 for (i = 0, pipe_idx = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) { 1037 if (!context->res_ctx.pipe_ctx[i].stream) 1038 continue; 1039 1040 pipes[pipe_cnt].clks_cfg.refclk_mhz = dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000.0; 1041 pipes[pipe_cnt].clks_cfg.dispclk_mhz = context->bw_ctx.dml.vba.RequiredDISPCLK[vlevel_req][context->bw_ctx.dml.vba.maxMpcComb]; 1042 1043 if (pipe_split_from[i] < 0) { 1044 pipes[pipe_cnt].clks_cfg.dppclk_mhz = 1045 context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel_req][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx]; 1046 if (context->bw_ctx.dml.vba.BlendingAndTiming[pipe_idx] == pipe_idx) 1047 pipes[pipe_cnt].pipe.dest.odm_combine = 1048 context->bw_ctx.dml.vba.ODMCombineEnablePerState[vlevel_req][pipe_idx]; 1049 else 1050 pipes[pipe_cnt].pipe.dest.odm_combine = 0; 1051 pipe_idx++; 1052 } else { 1053 pipes[pipe_cnt].clks_cfg.dppclk_mhz = 1054 context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel_req][context->bw_ctx.dml.vba.maxMpcComb][pipe_split_from[i]]; 1055 if (context->bw_ctx.dml.vba.BlendingAndTiming[pipe_split_from[i]] == pipe_split_from[i]) 1056 pipes[pipe_cnt].pipe.dest.odm_combine = 1057 context->bw_ctx.dml.vba.ODMCombineEnablePerState[vlevel_req][pipe_split_from[i]]; 1058 else 1059 pipes[pipe_cnt].pipe.dest.odm_combine = 0; 1060 } 1061 pipe_cnt++; 1062 } 1063 1064 if (pipe_cnt != pipe_idx) { 1065 if (dc->res_pool->funcs->populate_dml_pipes) 1066 pipe_cnt = dc->res_pool->funcs->populate_dml_pipes(dc, 1067 context, pipes); 1068 else 1069 pipe_cnt = dcn21_populate_dml_pipes_from_context(dc, 1070 context, pipes); 1071 } 1072 1073 *out_pipe_cnt = pipe_cnt; 1074 1075 vlevel_max = bw_params->clk_table.num_entries - 1; 1076 1077 1078 /* WM Set D */ 1079 table_entry = &bw_params->wm_table.entries[WM_D]; 1080 if (table_entry->wm_type == WM_TYPE_RETRAINING) 1081 vlevel = 0; 1082 else 1083 vlevel = vlevel_max; 1084 calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.d, 1085 &context->bw_ctx.dml, pipes, pipe_cnt); 1086 /* WM Set C */ 1087 table_entry = &bw_params->wm_table.entries[WM_C]; 1088 vlevel = MIN(MAX(vlevel_req, 2), vlevel_max); 1089 calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.c, 1090 &context->bw_ctx.dml, pipes, pipe_cnt); 1091 /* WM Set B */ 1092 table_entry = &bw_params->wm_table.entries[WM_B]; 1093 vlevel = MIN(MAX(vlevel_req, 1), vlevel_max); 1094 calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.b, 1095 &context->bw_ctx.dml, pipes, pipe_cnt); 1096 1097 /* WM Set A */ 1098 table_entry = &bw_params->wm_table.entries[WM_A]; 1099 vlevel = MIN(vlevel_req, vlevel_max); 1100 calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.a, 1101 &context->bw_ctx.dml, pipes, pipe_cnt); 1102 } 1103 1104 1105 bool dcn21_validate_bandwidth(struct dc *dc, struct dc_state *context, 1106 bool fast_validate) 1107 { 1108 bool out = false; 1109 1110 BW_VAL_TRACE_SETUP(); 1111 1112 int vlevel = 0; 1113 int pipe_split_from[MAX_PIPES]; 1114 int pipe_cnt = 0; 1115 display_e2e_pipe_params_st *pipes = kzalloc(dc->res_pool->pipe_count * sizeof(display_e2e_pipe_params_st), GFP_KERNEL); 1116 DC_LOGGER_INIT(dc->ctx->logger); 1117 1118 BW_VAL_TRACE_COUNT(); 1119 1120 out = dcn20_fast_validate_bw(dc, context, pipes, &pipe_cnt, pipe_split_from, &vlevel); 1121 1122 if (pipe_cnt == 0) 1123 goto validate_out; 1124 1125 if (!out) 1126 goto validate_fail; 1127 1128 BW_VAL_TRACE_END_VOLTAGE_LEVEL(); 1129 1130 if (fast_validate) { 1131 BW_VAL_TRACE_SKIP(fast); 1132 goto validate_out; 1133 } 1134 1135 dcn21_calculate_wm(dc, context, pipes, &pipe_cnt, pipe_split_from, vlevel); 1136 dcn20_calculate_dlg_params(dc, context, pipes, pipe_cnt, vlevel); 1137 1138 BW_VAL_TRACE_END_WATERMARKS(); 1139 1140 goto validate_out; 1141 1142 validate_fail: 1143 DC_LOG_WARNING("Mode Validation Warning: %s failed validation.\n", 1144 dml_get_status_message(context->bw_ctx.dml.vba.ValidationStatus[context->bw_ctx.dml.vba.soc.num_states])); 1145 1146 BW_VAL_TRACE_SKIP(fail); 1147 out = false; 1148 1149 validate_out: 1150 kfree(pipes); 1151 1152 BW_VAL_TRACE_FINISH(); 1153 1154 return out; 1155 } 1156 static void dcn21_destroy_resource_pool(struct resource_pool **pool) 1157 { 1158 struct dcn21_resource_pool *dcn21_pool = TO_DCN21_RES_POOL(*pool); 1159 1160 dcn21_resource_destruct(dcn21_pool); 1161 kfree(dcn21_pool); 1162 *pool = NULL; 1163 } 1164 1165 static struct clock_source *dcn21_clock_source_create( 1166 struct dc_context *ctx, 1167 struct dc_bios *bios, 1168 enum clock_source_id id, 1169 const struct dce110_clk_src_regs *regs, 1170 bool dp_clk_src) 1171 { 1172 struct dce110_clk_src *clk_src = 1173 kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL); 1174 1175 if (!clk_src) 1176 return NULL; 1177 1178 if (dcn20_clk_src_construct(clk_src, ctx, bios, id, 1179 regs, &cs_shift, &cs_mask)) { 1180 clk_src->base.dp_clk_src = dp_clk_src; 1181 return &clk_src->base; 1182 } 1183 1184 BREAK_TO_DEBUGGER(); 1185 return NULL; 1186 } 1187 1188 static struct hubp *dcn21_hubp_create( 1189 struct dc_context *ctx, 1190 uint32_t inst) 1191 { 1192 struct dcn21_hubp *hubp21 = 1193 kzalloc(sizeof(struct dcn21_hubp), GFP_KERNEL); 1194 1195 if (!hubp21) 1196 return NULL; 1197 1198 if (hubp21_construct(hubp21, ctx, inst, 1199 &hubp_regs[inst], &hubp_shift, &hubp_mask)) 1200 return &hubp21->base; 1201 1202 BREAK_TO_DEBUGGER(); 1203 kfree(hubp21); 1204 return NULL; 1205 } 1206 1207 static struct hubbub *dcn21_hubbub_create(struct dc_context *ctx) 1208 { 1209 int i; 1210 1211 struct dcn20_hubbub *hubbub = kzalloc(sizeof(struct dcn20_hubbub), 1212 GFP_KERNEL); 1213 1214 if (!hubbub) 1215 return NULL; 1216 1217 hubbub21_construct(hubbub, ctx, 1218 &hubbub_reg, 1219 &hubbub_shift, 1220 &hubbub_mask); 1221 1222 for (i = 0; i < res_cap_rn.num_vmid; i++) { 1223 struct dcn20_vmid *vmid = &hubbub->vmid[i]; 1224 1225 vmid->ctx = ctx; 1226 1227 vmid->regs = &vmid_regs[i]; 1228 vmid->shifts = &vmid_shifts; 1229 vmid->masks = &vmid_masks; 1230 } 1231 1232 return &hubbub->base; 1233 } 1234 1235 struct output_pixel_processor *dcn21_opp_create( 1236 struct dc_context *ctx, uint32_t inst) 1237 { 1238 struct dcn20_opp *opp = 1239 kzalloc(sizeof(struct dcn20_opp), GFP_KERNEL); 1240 1241 if (!opp) { 1242 BREAK_TO_DEBUGGER(); 1243 return NULL; 1244 } 1245 1246 dcn20_opp_construct(opp, ctx, inst, 1247 &opp_regs[inst], &opp_shift, &opp_mask); 1248 return &opp->base; 1249 } 1250 1251 struct timing_generator *dcn21_timing_generator_create( 1252 struct dc_context *ctx, 1253 uint32_t instance) 1254 { 1255 struct optc *tgn10 = 1256 kzalloc(sizeof(struct optc), GFP_KERNEL); 1257 1258 if (!tgn10) 1259 return NULL; 1260 1261 tgn10->base.inst = instance; 1262 tgn10->base.ctx = ctx; 1263 1264 tgn10->tg_regs = &tg_regs[instance]; 1265 tgn10->tg_shift = &tg_shift; 1266 tgn10->tg_mask = &tg_mask; 1267 1268 dcn20_timing_generator_init(tgn10); 1269 1270 return &tgn10->base; 1271 } 1272 1273 struct mpc *dcn21_mpc_create(struct dc_context *ctx) 1274 { 1275 struct dcn20_mpc *mpc20 = kzalloc(sizeof(struct dcn20_mpc), 1276 GFP_KERNEL); 1277 1278 if (!mpc20) 1279 return NULL; 1280 1281 dcn20_mpc_construct(mpc20, ctx, 1282 &mpc_regs, 1283 &mpc_shift, 1284 &mpc_mask, 1285 6); 1286 1287 return &mpc20->base; 1288 } 1289 1290 static void read_dce_straps( 1291 struct dc_context *ctx, 1292 struct resource_straps *straps) 1293 { 1294 generic_reg_get(ctx, mmDC_PINSTRAPS + BASE(mmDC_PINSTRAPS_BASE_IDX), 1295 FN(DC_PINSTRAPS, DC_PINSTRAPS_AUDIO), &straps->dc_pinstraps_audio); 1296 1297 } 1298 1299 1300 struct display_stream_compressor *dcn21_dsc_create( 1301 struct dc_context *ctx, uint32_t inst) 1302 { 1303 struct dcn20_dsc *dsc = 1304 kzalloc(sizeof(struct dcn20_dsc), GFP_KERNEL); 1305 1306 if (!dsc) { 1307 BREAK_TO_DEBUGGER(); 1308 return NULL; 1309 } 1310 1311 dsc2_construct(dsc, ctx, inst, &dsc_regs[inst], &dsc_shift, &dsc_mask); 1312 return &dsc->base; 1313 } 1314 1315 static void update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params) 1316 { 1317 /* 1318 TODO: Fix this function to calcualte correct values. 1319 There are known issues with this function currently 1320 that will need to be investigated. Use hardcoded known good values for now. 1321 1322 1323 struct dcn21_resource_pool *pool = TO_DCN21_RES_POOL(dc->res_pool); 1324 struct clk_limit_table *clk_table = &bw_params->clk_table; 1325 int i; 1326 1327 dcn2_1_ip.max_num_otg = pool->base.res_cap->num_timing_generator; 1328 dcn2_1_ip.max_num_dpp = pool->base.pipe_count; 1329 dcn2_1_soc.num_chans = bw_params->num_channels; 1330 1331 for (i = 0; i < clk_table->num_entries; i++) { 1332 1333 dcn2_1_soc.clock_limits[i].state = i; 1334 dcn2_1_soc.clock_limits[i].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz; 1335 dcn2_1_soc.clock_limits[i].fabricclk_mhz = clk_table->entries[i].fclk_mhz; 1336 dcn2_1_soc.clock_limits[i].socclk_mhz = clk_table->entries[i].socclk_mhz; 1337 dcn2_1_soc.clock_limits[i].dram_speed_mts = clk_table->entries[i].memclk_mhz * 16 / 1000; 1338 } 1339 dcn2_1_soc.clock_limits[i] = dcn2_1_soc.clock_limits[i - i]; 1340 dcn2_1_soc.num_states = i; 1341 */ 1342 } 1343 1344 /* Temporary Place holder until we can get them from fuse */ 1345 static struct dpm_clocks dummy_clocks = { 1346 .DcfClocks = { 1347 {.Freq = 400, .Vol = 1}, 1348 {.Freq = 483, .Vol = 1}, 1349 {.Freq = 602, .Vol = 1}, 1350 {.Freq = 738, .Vol = 1} }, 1351 .SocClocks = { 1352 {.Freq = 300, .Vol = 1}, 1353 {.Freq = 400, .Vol = 1}, 1354 {.Freq = 400, .Vol = 1}, 1355 {.Freq = 400, .Vol = 1} }, 1356 .FClocks = { 1357 {.Freq = 400, .Vol = 1}, 1358 {.Freq = 800, .Vol = 1}, 1359 {.Freq = 1067, .Vol = 1}, 1360 {.Freq = 1600, .Vol = 1} }, 1361 .MemClocks = { 1362 {.Freq = 800, .Vol = 1}, 1363 {.Freq = 1600, .Vol = 1}, 1364 {.Freq = 1067, .Vol = 1}, 1365 {.Freq = 1600, .Vol = 1} }, 1366 1367 }; 1368 1369 static enum pp_smu_status dummy_set_wm_ranges(struct pp_smu *pp, 1370 struct pp_smu_wm_range_sets *ranges) 1371 { 1372 return PP_SMU_RESULT_OK; 1373 } 1374 1375 static enum pp_smu_status dummy_get_dpm_clock_table(struct pp_smu *pp, 1376 struct dpm_clocks *clock_table) 1377 { 1378 *clock_table = dummy_clocks; 1379 return PP_SMU_RESULT_OK; 1380 } 1381 1382 static struct pp_smu_funcs *dcn21_pp_smu_create(struct dc_context *ctx) 1383 { 1384 struct pp_smu_funcs *pp_smu = kzalloc(sizeof(*pp_smu), GFP_KERNEL); 1385 1386 if (!pp_smu) 1387 return pp_smu; 1388 1389 if (IS_FPGA_MAXIMUS_DC(ctx->dce_environment) || IS_DIAG_DC(ctx->dce_environment)) { 1390 pp_smu->ctx.ver = PP_SMU_VER_RN; 1391 pp_smu->rn_funcs.get_dpm_clock_table = dummy_get_dpm_clock_table; 1392 pp_smu->rn_funcs.set_wm_ranges = dummy_set_wm_ranges; 1393 } else { 1394 1395 dm_pp_get_funcs(ctx, pp_smu); 1396 1397 if (pp_smu->ctx.ver != PP_SMU_VER_RN) 1398 pp_smu = memset(pp_smu, 0, sizeof(struct pp_smu_funcs)); 1399 } 1400 1401 return pp_smu; 1402 } 1403 1404 static void dcn21_pp_smu_destroy(struct pp_smu_funcs **pp_smu) 1405 { 1406 if (pp_smu && *pp_smu) { 1407 kfree(*pp_smu); 1408 *pp_smu = NULL; 1409 } 1410 } 1411 1412 static struct audio *dcn21_create_audio( 1413 struct dc_context *ctx, unsigned int inst) 1414 { 1415 return dce_audio_create(ctx, inst, 1416 &audio_regs[inst], &audio_shift, &audio_mask); 1417 } 1418 1419 static struct dc_cap_funcs cap_funcs = { 1420 .get_dcc_compression_cap = dcn20_get_dcc_compression_cap 1421 }; 1422 1423 struct stream_encoder *dcn21_stream_encoder_create( 1424 enum engine_id eng_id, 1425 struct dc_context *ctx) 1426 { 1427 struct dcn10_stream_encoder *enc1 = 1428 kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL); 1429 1430 if (!enc1) 1431 return NULL; 1432 1433 dcn20_stream_encoder_construct(enc1, ctx, ctx->dc_bios, eng_id, 1434 &stream_enc_regs[eng_id], 1435 &se_shift, &se_mask); 1436 1437 return &enc1->base; 1438 } 1439 1440 static const struct dce_hwseq_registers hwseq_reg = { 1441 HWSEQ_DCN21_REG_LIST() 1442 }; 1443 1444 static const struct dce_hwseq_shift hwseq_shift = { 1445 HWSEQ_DCN21_MASK_SH_LIST(__SHIFT) 1446 }; 1447 1448 static const struct dce_hwseq_mask hwseq_mask = { 1449 HWSEQ_DCN21_MASK_SH_LIST(_MASK) 1450 }; 1451 1452 static struct dce_hwseq *dcn21_hwseq_create( 1453 struct dc_context *ctx) 1454 { 1455 struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL); 1456 1457 if (hws) { 1458 hws->ctx = ctx; 1459 hws->regs = &hwseq_reg; 1460 hws->shifts = &hwseq_shift; 1461 hws->masks = &hwseq_mask; 1462 hws->wa.DEGVIDCN21 = true; 1463 } 1464 return hws; 1465 } 1466 1467 static const struct resource_create_funcs res_create_funcs = { 1468 .read_dce_straps = read_dce_straps, 1469 .create_audio = dcn21_create_audio, 1470 .create_stream_encoder = dcn21_stream_encoder_create, 1471 .create_hwseq = dcn21_hwseq_create, 1472 }; 1473 1474 static const struct resource_create_funcs res_create_maximus_funcs = { 1475 .read_dce_straps = NULL, 1476 .create_audio = NULL, 1477 .create_stream_encoder = NULL, 1478 .create_hwseq = dcn21_hwseq_create, 1479 }; 1480 1481 static const struct encoder_feature_support link_enc_feature = { 1482 .max_hdmi_deep_color = COLOR_DEPTH_121212, 1483 .max_hdmi_pixel_clock = 600000, 1484 .hdmi_ycbcr420_supported = true, 1485 .dp_ycbcr420_supported = true, 1486 .flags.bits.IS_HBR2_CAPABLE = true, 1487 .flags.bits.IS_HBR3_CAPABLE = true, 1488 .flags.bits.IS_TPS3_CAPABLE = true, 1489 .flags.bits.IS_TPS4_CAPABLE = true 1490 }; 1491 1492 1493 #define link_regs(id, phyid)\ 1494 [id] = {\ 1495 LE_DCN10_REG_LIST(id), \ 1496 UNIPHY_DCN2_REG_LIST(phyid), \ 1497 SRI(DP_DPHY_INTERNAL_CTRL, DP, id) \ 1498 } 1499 1500 static const struct dcn10_link_enc_registers link_enc_regs[] = { 1501 link_regs(0, A), 1502 link_regs(1, B), 1503 link_regs(2, C), 1504 link_regs(3, D), 1505 link_regs(4, E), 1506 }; 1507 1508 #define aux_regs(id)\ 1509 [id] = {\ 1510 DCN2_AUX_REG_LIST(id)\ 1511 } 1512 1513 static const struct dcn10_link_enc_aux_registers link_enc_aux_regs[] = { 1514 aux_regs(0), 1515 aux_regs(1), 1516 aux_regs(2), 1517 aux_regs(3), 1518 aux_regs(4) 1519 }; 1520 1521 #define hpd_regs(id)\ 1522 [id] = {\ 1523 HPD_REG_LIST(id)\ 1524 } 1525 1526 static const struct dcn10_link_enc_hpd_registers link_enc_hpd_regs[] = { 1527 hpd_regs(0), 1528 hpd_regs(1), 1529 hpd_regs(2), 1530 hpd_regs(3), 1531 hpd_regs(4) 1532 }; 1533 1534 static const struct dcn10_link_enc_shift le_shift = { 1535 LINK_ENCODER_MASK_SH_LIST_DCN20(__SHIFT) 1536 }; 1537 1538 static const struct dcn10_link_enc_mask le_mask = { 1539 LINK_ENCODER_MASK_SH_LIST_DCN20(_MASK) 1540 }; 1541 1542 static int map_transmitter_id_to_phy_instance( 1543 enum transmitter transmitter) 1544 { 1545 switch (transmitter) { 1546 case TRANSMITTER_UNIPHY_A: 1547 return 0; 1548 break; 1549 case TRANSMITTER_UNIPHY_B: 1550 return 1; 1551 break; 1552 case TRANSMITTER_UNIPHY_C: 1553 return 2; 1554 break; 1555 case TRANSMITTER_UNIPHY_D: 1556 return 3; 1557 break; 1558 case TRANSMITTER_UNIPHY_E: 1559 return 4; 1560 break; 1561 default: 1562 ASSERT(0); 1563 return 0; 1564 } 1565 } 1566 1567 static struct link_encoder *dcn21_link_encoder_create( 1568 const struct encoder_init_data *enc_init_data) 1569 { 1570 struct dcn21_link_encoder *enc21 = 1571 kzalloc(sizeof(struct dcn21_link_encoder), GFP_KERNEL); 1572 int link_regs_id; 1573 1574 if (!enc21) 1575 return NULL; 1576 1577 link_regs_id = 1578 map_transmitter_id_to_phy_instance(enc_init_data->transmitter); 1579 1580 dcn21_link_encoder_construct(enc21, 1581 enc_init_data, 1582 &link_enc_feature, 1583 &link_enc_regs[link_regs_id], 1584 &link_enc_aux_regs[enc_init_data->channel - 1], 1585 &link_enc_hpd_regs[enc_init_data->hpd_source], 1586 &le_shift, 1587 &le_mask); 1588 1589 return &enc21->enc10.base; 1590 } 1591 #define CTX ctx 1592 1593 #define REG(reg_name) \ 1594 (DCN_BASE.instance[0].segment[mm ## reg_name ## _BASE_IDX] + mm ## reg_name) 1595 1596 static uint32_t read_pipe_fuses(struct dc_context *ctx) 1597 { 1598 uint32_t value = REG_READ(CC_DC_PIPE_DIS); 1599 /* RV1 support max 4 pipes */ 1600 value = value & 0xf; 1601 return value; 1602 } 1603 1604 static int dcn21_populate_dml_pipes_from_context( 1605 struct dc *dc, struct dc_state *context, display_e2e_pipe_params_st *pipes) 1606 { 1607 uint32_t pipe_cnt = dcn20_populate_dml_pipes_from_context(dc, context, pipes); 1608 int i; 1609 struct resource_context *res_ctx = &context->res_ctx; 1610 1611 for (i = 0; i < dc->res_pool->pipe_count; i++) { 1612 1613 if (!res_ctx->pipe_ctx[i].stream) 1614 continue; 1615 1616 pipes[i].pipe.src.hostvm = 1; 1617 pipes[i].pipe.src.gpuvm = 1; 1618 } 1619 1620 return pipe_cnt; 1621 } 1622 1623 static struct resource_funcs dcn21_res_pool_funcs = { 1624 .destroy = dcn21_destroy_resource_pool, 1625 .link_enc_create = dcn21_link_encoder_create, 1626 .validate_bandwidth = dcn21_validate_bandwidth, 1627 .populate_dml_pipes = dcn21_populate_dml_pipes_from_context, 1628 .add_stream_to_ctx = dcn20_add_stream_to_ctx, 1629 .remove_stream_from_ctx = dcn20_remove_stream_from_ctx, 1630 .acquire_idle_pipe_for_layer = dcn20_acquire_idle_pipe_for_layer, 1631 .populate_dml_writeback_from_context = dcn20_populate_dml_writeback_from_context, 1632 .get_default_swizzle_mode = dcn20_get_default_swizzle_mode, 1633 .set_mcif_arb_params = dcn20_set_mcif_arb_params, 1634 .find_first_free_match_stream_enc_for_link = dcn10_find_first_free_match_stream_enc_for_link, 1635 .update_bw_bounding_box = update_bw_bounding_box 1636 }; 1637 1638 static bool dcn21_resource_construct( 1639 uint8_t num_virtual_links, 1640 struct dc *dc, 1641 struct dcn21_resource_pool *pool) 1642 { 1643 int i, j; 1644 struct dc_context *ctx = dc->ctx; 1645 struct irq_service_init_data init_data; 1646 uint32_t pipe_fuses = read_pipe_fuses(ctx); 1647 uint32_t num_pipes; 1648 1649 ctx->dc_bios->regs = &bios_regs; 1650 1651 pool->base.res_cap = &res_cap_rn; 1652 #ifdef DIAGS_BUILD 1653 if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) 1654 //pool->base.res_cap = &res_cap_nv10_FPGA_2pipe_dsc; 1655 pool->base.res_cap = &res_cap_rn_FPGA_4pipe; 1656 #endif 1657 1658 pool->base.funcs = &dcn21_res_pool_funcs; 1659 1660 /************************************************* 1661 * Resource + asic cap harcoding * 1662 *************************************************/ 1663 pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE; 1664 1665 /* max pipe num for ASIC before check pipe fuses */ 1666 pool->base.pipe_count = pool->base.res_cap->num_timing_generator; 1667 1668 dc->caps.max_downscale_ratio = 200; 1669 dc->caps.i2c_speed_in_khz = 100; 1670 dc->caps.max_cursor_size = 256; 1671 dc->caps.dmdata_alloc_size = 2048; 1672 dc->caps.hw_3d_lut = true; 1673 1674 dc->caps.max_slave_planes = 1; 1675 dc->caps.post_blend_color_processing = true; 1676 dc->caps.force_dp_tps4_for_cp2520 = true; 1677 dc->caps.extended_aux_timeout_support = true; 1678 dc->caps.dmcub_support = true; 1679 1680 if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV) 1681 dc->debug = debug_defaults_drv; 1682 else if (dc->ctx->dce_environment == DCE_ENV_FPGA_MAXIMUS) { 1683 pool->base.pipe_count = 4; 1684 dc->debug = debug_defaults_diags; 1685 } else 1686 dc->debug = debug_defaults_diags; 1687 1688 // Init the vm_helper 1689 if (dc->vm_helper) 1690 vm_helper_init(dc->vm_helper, 16); 1691 1692 /************************************************* 1693 * Create resources * 1694 *************************************************/ 1695 1696 pool->base.clock_sources[DCN20_CLK_SRC_PLL0] = 1697 dcn21_clock_source_create(ctx, ctx->dc_bios, 1698 CLOCK_SOURCE_COMBO_PHY_PLL0, 1699 &clk_src_regs[0], false); 1700 pool->base.clock_sources[DCN20_CLK_SRC_PLL1] = 1701 dcn21_clock_source_create(ctx, ctx->dc_bios, 1702 CLOCK_SOURCE_COMBO_PHY_PLL1, 1703 &clk_src_regs[1], false); 1704 1705 pool->base.clk_src_count = DCN20_CLK_SRC_TOTAL_DCN21; 1706 1707 /* todo: not reuse phy_pll registers */ 1708 pool->base.dp_clock_source = 1709 dcn21_clock_source_create(ctx, ctx->dc_bios, 1710 CLOCK_SOURCE_ID_DP_DTO, 1711 &clk_src_regs[0], true); 1712 1713 for (i = 0; i < pool->base.clk_src_count; i++) { 1714 if (pool->base.clock_sources[i] == NULL) { 1715 dm_error("DC: failed to create clock sources!\n"); 1716 BREAK_TO_DEBUGGER(); 1717 goto create_fail; 1718 } 1719 } 1720 1721 pool->base.dccg = dccg2_create(ctx, &dccg_regs, &dccg_shift, &dccg_mask); 1722 if (pool->base.dccg == NULL) { 1723 dm_error("DC: failed to create dccg!\n"); 1724 BREAK_TO_DEBUGGER(); 1725 goto create_fail; 1726 } 1727 1728 pool->base.dmcu = dcn21_dmcu_create(ctx, 1729 &dmcu_regs, 1730 &dmcu_shift, 1731 &dmcu_mask); 1732 if (pool->base.dmcu == NULL) { 1733 dm_error("DC: failed to create dmcu!\n"); 1734 BREAK_TO_DEBUGGER(); 1735 goto create_fail; 1736 } 1737 1738 pool->base.abm = dce_abm_create(ctx, 1739 &abm_regs, 1740 &abm_shift, 1741 &abm_mask); 1742 if (pool->base.abm == NULL) { 1743 dm_error("DC: failed to create abm!\n"); 1744 BREAK_TO_DEBUGGER(); 1745 goto create_fail; 1746 } 1747 1748 pool->base.pp_smu = dcn21_pp_smu_create(ctx); 1749 1750 num_pipes = dcn2_1_ip.max_num_dpp; 1751 1752 for (i = 0; i < dcn2_1_ip.max_num_dpp; i++) 1753 if (pipe_fuses & 1 << i) 1754 num_pipes--; 1755 dcn2_1_ip.max_num_dpp = num_pipes; 1756 dcn2_1_ip.max_num_otg = num_pipes; 1757 1758 dml_init_instance(&dc->dml, &dcn2_1_soc, &dcn2_1_ip, DML_PROJECT_DCN21); 1759 1760 init_data.ctx = dc->ctx; 1761 pool->base.irqs = dal_irq_service_dcn21_create(&init_data); 1762 if (!pool->base.irqs) 1763 goto create_fail; 1764 1765 j = 0; 1766 /* mem input -> ipp -> dpp -> opp -> TG */ 1767 for (i = 0; i < pool->base.pipe_count; i++) { 1768 /* if pipe is disabled, skip instance of HW pipe, 1769 * i.e, skip ASIC register instance 1770 */ 1771 if ((pipe_fuses & (1 << i)) != 0) 1772 continue; 1773 1774 pool->base.hubps[i] = dcn21_hubp_create(ctx, i); 1775 if (pool->base.hubps[i] == NULL) { 1776 BREAK_TO_DEBUGGER(); 1777 dm_error( 1778 "DC: failed to create memory input!\n"); 1779 goto create_fail; 1780 } 1781 1782 pool->base.ipps[i] = dcn21_ipp_create(ctx, i); 1783 if (pool->base.ipps[i] == NULL) { 1784 BREAK_TO_DEBUGGER(); 1785 dm_error( 1786 "DC: failed to create input pixel processor!\n"); 1787 goto create_fail; 1788 } 1789 1790 pool->base.dpps[i] = dcn21_dpp_create(ctx, i); 1791 if (pool->base.dpps[i] == NULL) { 1792 BREAK_TO_DEBUGGER(); 1793 dm_error( 1794 "DC: failed to create dpps!\n"); 1795 goto create_fail; 1796 } 1797 1798 pool->base.opps[i] = dcn21_opp_create(ctx, i); 1799 if (pool->base.opps[i] == NULL) { 1800 BREAK_TO_DEBUGGER(); 1801 dm_error( 1802 "DC: failed to create output pixel processor!\n"); 1803 goto create_fail; 1804 } 1805 1806 pool->base.timing_generators[i] = dcn21_timing_generator_create( 1807 ctx, i); 1808 if (pool->base.timing_generators[i] == NULL) { 1809 BREAK_TO_DEBUGGER(); 1810 dm_error("DC: failed to create tg!\n"); 1811 goto create_fail; 1812 } 1813 j++; 1814 } 1815 1816 for (i = 0; i < pool->base.res_cap->num_ddc; i++) { 1817 pool->base.engines[i] = dcn21_aux_engine_create(ctx, i); 1818 if (pool->base.engines[i] == NULL) { 1819 BREAK_TO_DEBUGGER(); 1820 dm_error( 1821 "DC:failed to create aux engine!!\n"); 1822 goto create_fail; 1823 } 1824 pool->base.hw_i2cs[i] = dcn21_i2c_hw_create(ctx, i); 1825 if (pool->base.hw_i2cs[i] == NULL) { 1826 BREAK_TO_DEBUGGER(); 1827 dm_error( 1828 "DC:failed to create hw i2c!!\n"); 1829 goto create_fail; 1830 } 1831 pool->base.sw_i2cs[i] = NULL; 1832 } 1833 1834 pool->base.timing_generator_count = j; 1835 pool->base.pipe_count = j; 1836 pool->base.mpcc_count = j; 1837 1838 pool->base.mpc = dcn21_mpc_create(ctx); 1839 if (pool->base.mpc == NULL) { 1840 BREAK_TO_DEBUGGER(); 1841 dm_error("DC: failed to create mpc!\n"); 1842 goto create_fail; 1843 } 1844 1845 pool->base.hubbub = dcn21_hubbub_create(ctx); 1846 if (pool->base.hubbub == NULL) { 1847 BREAK_TO_DEBUGGER(); 1848 dm_error("DC: failed to create hubbub!\n"); 1849 goto create_fail; 1850 } 1851 1852 for (i = 0; i < pool->base.res_cap->num_dsc; i++) { 1853 pool->base.dscs[i] = dcn21_dsc_create(ctx, i); 1854 if (pool->base.dscs[i] == NULL) { 1855 BREAK_TO_DEBUGGER(); 1856 dm_error("DC: failed to create display stream compressor %d!\n", i); 1857 goto create_fail; 1858 } 1859 } 1860 1861 if (!dcn20_dwbc_create(ctx, &pool->base)) { 1862 BREAK_TO_DEBUGGER(); 1863 dm_error("DC: failed to create dwbc!\n"); 1864 goto create_fail; 1865 } 1866 if (!dcn20_mmhubbub_create(ctx, &pool->base)) { 1867 BREAK_TO_DEBUGGER(); 1868 dm_error("DC: failed to create mcif_wb!\n"); 1869 goto create_fail; 1870 } 1871 1872 if (!resource_construct(num_virtual_links, dc, &pool->base, 1873 (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment) ? 1874 &res_create_funcs : &res_create_maximus_funcs))) 1875 goto create_fail; 1876 1877 dcn21_hw_sequencer_construct(dc); 1878 1879 dc->caps.max_planes = pool->base.pipe_count; 1880 1881 for (i = 0; i < dc->caps.max_planes; ++i) 1882 dc->caps.planes[i] = plane_cap; 1883 1884 dc->cap_funcs = cap_funcs; 1885 1886 return true; 1887 1888 create_fail: 1889 1890 dcn21_resource_destruct(pool); 1891 1892 return false; 1893 } 1894 1895 struct resource_pool *dcn21_create_resource_pool( 1896 const struct dc_init_data *init_data, 1897 struct dc *dc) 1898 { 1899 struct dcn21_resource_pool *pool = 1900 kzalloc(sizeof(struct dcn21_resource_pool), GFP_KERNEL); 1901 1902 if (!pool) 1903 return NULL; 1904 1905 if (dcn21_resource_construct(init_data->num_virtual_links, dc, pool)) 1906 return &pool->base; 1907 1908 BREAK_TO_DEBUGGER(); 1909 kfree(pool); 1910 return NULL; 1911 } 1912