1 /* 2 * Copyright 2012-15 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 28 #include "link_encoder.h" 29 #include "stream_encoder.h" 30 31 #include "resource.h" 32 #include "include/irq_service_interface.h" 33 #include "dce110/dce110_resource.h" 34 #include "dce110/dce110_timing_generator.h" 35 36 #include "irq/dce110/irq_service_dce110.h" 37 38 #include "dce/dce_mem_input.h" 39 #include "dce/dce_transform.h" 40 #include "dce/dce_link_encoder.h" 41 #include "dce/dce_stream_encoder.h" 42 #include "dce/dce_audio.h" 43 #include "dce/dce_opp.h" 44 #include "dce/dce_ipp.h" 45 #include "dce/dce_clocks.h" 46 #include "dce/dce_clock_source.h" 47 48 #include "dce/dce_hwseq.h" 49 #include "dce112/dce112_hw_sequencer.h" 50 #include "dce/dce_abm.h" 51 #include "dce/dce_dmcu.h" 52 #include "dce/dce_aux.h" 53 54 #include "reg_helper.h" 55 56 #include "dce/dce_11_2_d.h" 57 #include "dce/dce_11_2_sh_mask.h" 58 59 #include "dce100/dce100_resource.h" 60 61 #include "dce112_resource.h" 62 63 #define DC_LOGGER \ 64 dc->ctx->logger 65 66 #ifndef mmDP_DPHY_INTERNAL_CTRL 67 #define mmDP_DPHY_INTERNAL_CTRL 0x4aa7 68 #define mmDP0_DP_DPHY_INTERNAL_CTRL 0x4aa7 69 #define mmDP1_DP_DPHY_INTERNAL_CTRL 0x4ba7 70 #define mmDP2_DP_DPHY_INTERNAL_CTRL 0x4ca7 71 #define mmDP3_DP_DPHY_INTERNAL_CTRL 0x4da7 72 #define mmDP4_DP_DPHY_INTERNAL_CTRL 0x4ea7 73 #define mmDP5_DP_DPHY_INTERNAL_CTRL 0x4fa7 74 #define mmDP6_DP_DPHY_INTERNAL_CTRL 0x54a7 75 #define mmDP7_DP_DPHY_INTERNAL_CTRL 0x56a7 76 #define mmDP8_DP_DPHY_INTERNAL_CTRL 0x57a7 77 #endif 78 79 #ifndef mmBIOS_SCRATCH_2 80 #define mmBIOS_SCRATCH_2 0x05CB 81 #define mmBIOS_SCRATCH_6 0x05CF 82 #endif 83 84 #ifndef mmDP_DPHY_BS_SR_SWAP_CNTL 85 #define mmDP_DPHY_BS_SR_SWAP_CNTL 0x4ADC 86 #define mmDP0_DP_DPHY_BS_SR_SWAP_CNTL 0x4ADC 87 #define mmDP1_DP_DPHY_BS_SR_SWAP_CNTL 0x4BDC 88 #define mmDP2_DP_DPHY_BS_SR_SWAP_CNTL 0x4CDC 89 #define mmDP3_DP_DPHY_BS_SR_SWAP_CNTL 0x4DDC 90 #define mmDP4_DP_DPHY_BS_SR_SWAP_CNTL 0x4EDC 91 #define mmDP5_DP_DPHY_BS_SR_SWAP_CNTL 0x4FDC 92 #define mmDP6_DP_DPHY_BS_SR_SWAP_CNTL 0x54DC 93 #endif 94 95 #ifndef mmDP_DPHY_FAST_TRAINING 96 #define mmDP_DPHY_FAST_TRAINING 0x4ABC 97 #define mmDP0_DP_DPHY_FAST_TRAINING 0x4ABC 98 #define mmDP1_DP_DPHY_FAST_TRAINING 0x4BBC 99 #define mmDP2_DP_DPHY_FAST_TRAINING 0x4CBC 100 #define mmDP3_DP_DPHY_FAST_TRAINING 0x4DBC 101 #define mmDP4_DP_DPHY_FAST_TRAINING 0x4EBC 102 #define mmDP5_DP_DPHY_FAST_TRAINING 0x4FBC 103 #define mmDP6_DP_DPHY_FAST_TRAINING 0x54BC 104 #endif 105 106 enum dce112_clk_src_array_id { 107 DCE112_CLK_SRC_PLL0, 108 DCE112_CLK_SRC_PLL1, 109 DCE112_CLK_SRC_PLL2, 110 DCE112_CLK_SRC_PLL3, 111 DCE112_CLK_SRC_PLL4, 112 DCE112_CLK_SRC_PLL5, 113 114 DCE112_CLK_SRC_TOTAL 115 }; 116 117 static const struct dce110_timing_generator_offsets dce112_tg_offsets[] = { 118 { 119 .crtc = (mmCRTC0_CRTC_CONTROL - mmCRTC_CONTROL), 120 .dcp = (mmDCP0_GRPH_CONTROL - mmGRPH_CONTROL), 121 }, 122 { 123 .crtc = (mmCRTC1_CRTC_CONTROL - mmCRTC_CONTROL), 124 .dcp = (mmDCP1_GRPH_CONTROL - mmGRPH_CONTROL), 125 }, 126 { 127 .crtc = (mmCRTC2_CRTC_CONTROL - mmCRTC_CONTROL), 128 .dcp = (mmDCP2_GRPH_CONTROL - mmGRPH_CONTROL), 129 }, 130 { 131 .crtc = (mmCRTC3_CRTC_CONTROL - mmCRTC_CONTROL), 132 .dcp = (mmDCP3_GRPH_CONTROL - mmGRPH_CONTROL), 133 }, 134 { 135 .crtc = (mmCRTC4_CRTC_CONTROL - mmCRTC_CONTROL), 136 .dcp = (mmDCP4_GRPH_CONTROL - mmGRPH_CONTROL), 137 }, 138 { 139 .crtc = (mmCRTC5_CRTC_CONTROL - mmCRTC_CONTROL), 140 .dcp = (mmDCP5_GRPH_CONTROL - mmGRPH_CONTROL), 141 } 142 }; 143 144 /* set register offset */ 145 #define SR(reg_name)\ 146 .reg_name = mm ## reg_name 147 148 /* set register offset with instance */ 149 #define SRI(reg_name, block, id)\ 150 .reg_name = mm ## block ## id ## _ ## reg_name 151 152 153 static const struct dccg_registers disp_clk_regs = { 154 CLK_COMMON_REG_LIST_DCE_BASE() 155 }; 156 157 static const struct dccg_shift disp_clk_shift = { 158 CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT) 159 }; 160 161 static const struct dccg_mask disp_clk_mask = { 162 CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK) 163 }; 164 165 static const struct dce_dmcu_registers dmcu_regs = { 166 DMCU_DCE110_COMMON_REG_LIST() 167 }; 168 169 static const struct dce_dmcu_shift dmcu_shift = { 170 DMCU_MASK_SH_LIST_DCE110(__SHIFT) 171 }; 172 173 static const struct dce_dmcu_mask dmcu_mask = { 174 DMCU_MASK_SH_LIST_DCE110(_MASK) 175 }; 176 177 static const struct dce_abm_registers abm_regs = { 178 ABM_DCE110_COMMON_REG_LIST() 179 }; 180 181 static const struct dce_abm_shift abm_shift = { 182 ABM_MASK_SH_LIST_DCE110(__SHIFT) 183 }; 184 185 static const struct dce_abm_mask abm_mask = { 186 ABM_MASK_SH_LIST_DCE110(_MASK) 187 }; 188 189 #define ipp_regs(id)\ 190 [id] = {\ 191 IPP_DCE110_REG_LIST_DCE_BASE(id)\ 192 } 193 194 static const struct dce_ipp_registers ipp_regs[] = { 195 ipp_regs(0), 196 ipp_regs(1), 197 ipp_regs(2), 198 ipp_regs(3), 199 ipp_regs(4), 200 ipp_regs(5) 201 }; 202 203 static const struct dce_ipp_shift ipp_shift = { 204 IPP_DCE100_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT) 205 }; 206 207 static const struct dce_ipp_mask ipp_mask = { 208 IPP_DCE100_MASK_SH_LIST_DCE_COMMON_BASE(_MASK) 209 }; 210 211 #define transform_regs(id)\ 212 [id] = {\ 213 XFM_COMMON_REG_LIST_DCE110(id)\ 214 } 215 216 static const struct dce_transform_registers xfm_regs[] = { 217 transform_regs(0), 218 transform_regs(1), 219 transform_regs(2), 220 transform_regs(3), 221 transform_regs(4), 222 transform_regs(5) 223 }; 224 225 static const struct dce_transform_shift xfm_shift = { 226 XFM_COMMON_MASK_SH_LIST_DCE110(__SHIFT) 227 }; 228 229 static const struct dce_transform_mask xfm_mask = { 230 XFM_COMMON_MASK_SH_LIST_DCE110(_MASK) 231 }; 232 233 #define aux_regs(id)\ 234 [id] = {\ 235 AUX_REG_LIST(id)\ 236 } 237 238 static const struct dce110_link_enc_aux_registers link_enc_aux_regs[] = { 239 aux_regs(0), 240 aux_regs(1), 241 aux_regs(2), 242 aux_regs(3), 243 aux_regs(4), 244 aux_regs(5) 245 }; 246 247 #define hpd_regs(id)\ 248 [id] = {\ 249 HPD_REG_LIST(id)\ 250 } 251 252 static const struct dce110_link_enc_hpd_registers link_enc_hpd_regs[] = { 253 hpd_regs(0), 254 hpd_regs(1), 255 hpd_regs(2), 256 hpd_regs(3), 257 hpd_regs(4), 258 hpd_regs(5) 259 }; 260 261 #define link_regs(id)\ 262 [id] = {\ 263 LE_DCE110_REG_LIST(id)\ 264 } 265 266 static const struct dce110_link_enc_registers link_enc_regs[] = { 267 link_regs(0), 268 link_regs(1), 269 link_regs(2), 270 link_regs(3), 271 link_regs(4), 272 link_regs(5), 273 link_regs(6), 274 }; 275 276 #define stream_enc_regs(id)\ 277 [id] = {\ 278 SE_COMMON_REG_LIST(id),\ 279 .TMDS_CNTL = 0,\ 280 } 281 282 static const struct dce110_stream_enc_registers stream_enc_regs[] = { 283 stream_enc_regs(0), 284 stream_enc_regs(1), 285 stream_enc_regs(2), 286 stream_enc_regs(3), 287 stream_enc_regs(4), 288 stream_enc_regs(5) 289 }; 290 291 static const struct dce_stream_encoder_shift se_shift = { 292 SE_COMMON_MASK_SH_LIST_DCE112(__SHIFT) 293 }; 294 295 static const struct dce_stream_encoder_mask se_mask = { 296 SE_COMMON_MASK_SH_LIST_DCE112(_MASK) 297 }; 298 299 #define opp_regs(id)\ 300 [id] = {\ 301 OPP_DCE_112_REG_LIST(id),\ 302 } 303 304 static const struct dce_opp_registers opp_regs[] = { 305 opp_regs(0), 306 opp_regs(1), 307 opp_regs(2), 308 opp_regs(3), 309 opp_regs(4), 310 opp_regs(5) 311 }; 312 313 static const struct dce_opp_shift opp_shift = { 314 OPP_COMMON_MASK_SH_LIST_DCE_112(__SHIFT) 315 }; 316 317 static const struct dce_opp_mask opp_mask = { 318 OPP_COMMON_MASK_SH_LIST_DCE_112(_MASK) 319 }; 320 321 #define aux_engine_regs(id)\ 322 [id] = {\ 323 AUX_COMMON_REG_LIST(id), \ 324 .AUX_RESET_MASK = 0 \ 325 } 326 327 static const struct dce110_aux_registers aux_engine_regs[] = { 328 aux_engine_regs(0), 329 aux_engine_regs(1), 330 aux_engine_regs(2), 331 aux_engine_regs(3), 332 aux_engine_regs(4), 333 aux_engine_regs(5) 334 }; 335 336 #define audio_regs(id)\ 337 [id] = {\ 338 AUD_COMMON_REG_LIST(id)\ 339 } 340 341 static const struct dce_audio_registers audio_regs[] = { 342 audio_regs(0), 343 audio_regs(1), 344 audio_regs(2), 345 audio_regs(3), 346 audio_regs(4), 347 audio_regs(5) 348 }; 349 350 static const struct dce_audio_shift audio_shift = { 351 AUD_COMMON_MASK_SH_LIST(__SHIFT) 352 }; 353 354 static const struct dce_aduio_mask audio_mask = { 355 AUD_COMMON_MASK_SH_LIST(_MASK) 356 }; 357 358 #define clk_src_regs(index, id)\ 359 [index] = {\ 360 CS_COMMON_REG_LIST_DCE_112(id),\ 361 } 362 363 static const struct dce110_clk_src_regs clk_src_regs[] = { 364 clk_src_regs(0, A), 365 clk_src_regs(1, B), 366 clk_src_regs(2, C), 367 clk_src_regs(3, D), 368 clk_src_regs(4, E), 369 clk_src_regs(5, F) 370 }; 371 372 static const struct dce110_clk_src_shift cs_shift = { 373 CS_COMMON_MASK_SH_LIST_DCE_112(__SHIFT) 374 }; 375 376 static const struct dce110_clk_src_mask cs_mask = { 377 CS_COMMON_MASK_SH_LIST_DCE_112(_MASK) 378 }; 379 380 static const struct bios_registers bios_regs = { 381 .BIOS_SCRATCH_6 = mmBIOS_SCRATCH_6 382 }; 383 384 static const struct resource_caps polaris_10_resource_cap = { 385 .num_timing_generator = 6, 386 .num_audio = 6, 387 .num_stream_encoder = 6, 388 .num_pll = 8, /* why 8? 6 combo PHY PLL + 2 regular PLLs? */ 389 }; 390 391 static const struct resource_caps polaris_11_resource_cap = { 392 .num_timing_generator = 5, 393 .num_audio = 5, 394 .num_stream_encoder = 5, 395 .num_pll = 8, /* why 8? 6 combo PHY PLL + 2 regular PLLs? */ 396 }; 397 398 #define CTX ctx 399 #define REG(reg) mm ## reg 400 401 #ifndef mmCC_DC_HDMI_STRAPS 402 #define mmCC_DC_HDMI_STRAPS 0x4819 403 #define CC_DC_HDMI_STRAPS__HDMI_DISABLE_MASK 0x40 404 #define CC_DC_HDMI_STRAPS__HDMI_DISABLE__SHIFT 0x6 405 #define CC_DC_HDMI_STRAPS__AUDIO_STREAM_NUMBER_MASK 0x700 406 #define CC_DC_HDMI_STRAPS__AUDIO_STREAM_NUMBER__SHIFT 0x8 407 #endif 408 409 static void read_dce_straps( 410 struct dc_context *ctx, 411 struct resource_straps *straps) 412 { 413 REG_GET_2(CC_DC_HDMI_STRAPS, 414 HDMI_DISABLE, &straps->hdmi_disable, 415 AUDIO_STREAM_NUMBER, &straps->audio_stream_number); 416 417 REG_GET(DC_PINSTRAPS, DC_PINSTRAPS_AUDIO, &straps->dc_pinstraps_audio); 418 } 419 420 static struct audio *create_audio( 421 struct dc_context *ctx, unsigned int inst) 422 { 423 return dce_audio_create(ctx, inst, 424 &audio_regs[inst], &audio_shift, &audio_mask); 425 } 426 427 428 static struct timing_generator *dce112_timing_generator_create( 429 struct dc_context *ctx, 430 uint32_t instance, 431 const struct dce110_timing_generator_offsets *offsets) 432 { 433 struct dce110_timing_generator *tg110 = 434 kzalloc(sizeof(struct dce110_timing_generator), GFP_KERNEL); 435 436 if (!tg110) 437 return NULL; 438 439 dce110_timing_generator_construct(tg110, ctx, instance, offsets); 440 return &tg110->base; 441 } 442 443 static struct stream_encoder *dce112_stream_encoder_create( 444 enum engine_id eng_id, 445 struct dc_context *ctx) 446 { 447 struct dce110_stream_encoder *enc110 = 448 kzalloc(sizeof(struct dce110_stream_encoder), GFP_KERNEL); 449 450 if (!enc110) 451 return NULL; 452 453 dce110_stream_encoder_construct(enc110, ctx, ctx->dc_bios, eng_id, 454 &stream_enc_regs[eng_id], 455 &se_shift, &se_mask); 456 return &enc110->base; 457 } 458 459 #define SRII(reg_name, block, id)\ 460 .reg_name[id] = mm ## block ## id ## _ ## reg_name 461 462 static const struct dce_hwseq_registers hwseq_reg = { 463 HWSEQ_DCE112_REG_LIST() 464 }; 465 466 static const struct dce_hwseq_shift hwseq_shift = { 467 HWSEQ_DCE112_MASK_SH_LIST(__SHIFT) 468 }; 469 470 static const struct dce_hwseq_mask hwseq_mask = { 471 HWSEQ_DCE112_MASK_SH_LIST(_MASK) 472 }; 473 474 static struct dce_hwseq *dce112_hwseq_create( 475 struct dc_context *ctx) 476 { 477 struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL); 478 479 if (hws) { 480 hws->ctx = ctx; 481 hws->regs = &hwseq_reg; 482 hws->shifts = &hwseq_shift; 483 hws->masks = &hwseq_mask; 484 } 485 return hws; 486 } 487 488 static const struct resource_create_funcs res_create_funcs = { 489 .read_dce_straps = read_dce_straps, 490 .create_audio = create_audio, 491 .create_stream_encoder = dce112_stream_encoder_create, 492 .create_hwseq = dce112_hwseq_create, 493 }; 494 495 #define mi_inst_regs(id) { MI_DCE11_2_REG_LIST(id) } 496 static const struct dce_mem_input_registers mi_regs[] = { 497 mi_inst_regs(0), 498 mi_inst_regs(1), 499 mi_inst_regs(2), 500 mi_inst_regs(3), 501 mi_inst_regs(4), 502 mi_inst_regs(5), 503 }; 504 505 static const struct dce_mem_input_shift mi_shifts = { 506 MI_DCE11_2_MASK_SH_LIST(__SHIFT) 507 }; 508 509 static const struct dce_mem_input_mask mi_masks = { 510 MI_DCE11_2_MASK_SH_LIST(_MASK) 511 }; 512 513 static struct mem_input *dce112_mem_input_create( 514 struct dc_context *ctx, 515 uint32_t inst) 516 { 517 struct dce_mem_input *dce_mi = kzalloc(sizeof(struct dce_mem_input), 518 GFP_KERNEL); 519 520 if (!dce_mi) { 521 BREAK_TO_DEBUGGER(); 522 return NULL; 523 } 524 525 dce112_mem_input_construct(dce_mi, ctx, inst, &mi_regs[inst], &mi_shifts, &mi_masks); 526 return &dce_mi->base; 527 } 528 529 static void dce112_transform_destroy(struct transform **xfm) 530 { 531 kfree(TO_DCE_TRANSFORM(*xfm)); 532 *xfm = NULL; 533 } 534 535 static struct transform *dce112_transform_create( 536 struct dc_context *ctx, 537 uint32_t inst) 538 { 539 struct dce_transform *transform = 540 kzalloc(sizeof(struct dce_transform), GFP_KERNEL); 541 542 if (!transform) 543 return NULL; 544 545 dce_transform_construct(transform, ctx, inst, 546 &xfm_regs[inst], &xfm_shift, &xfm_mask); 547 transform->lb_memory_size = 0x1404; /*5124*/ 548 return &transform->base; 549 } 550 551 static const struct encoder_feature_support link_enc_feature = { 552 .max_hdmi_deep_color = COLOR_DEPTH_121212, 553 .max_hdmi_pixel_clock = 600000, 554 .ycbcr420_supported = true, 555 .flags.bits.IS_HBR2_CAPABLE = true, 556 .flags.bits.IS_HBR3_CAPABLE = true, 557 .flags.bits.IS_TPS3_CAPABLE = true, 558 .flags.bits.IS_TPS4_CAPABLE = true, 559 .flags.bits.IS_YCBCR_CAPABLE = true 560 }; 561 562 static 563 struct link_encoder *dce112_link_encoder_create( 564 const struct encoder_init_data *enc_init_data) 565 { 566 struct dce110_link_encoder *enc110 = 567 kzalloc(sizeof(struct dce110_link_encoder), GFP_KERNEL); 568 569 if (!enc110) 570 return NULL; 571 572 dce110_link_encoder_construct(enc110, 573 enc_init_data, 574 &link_enc_feature, 575 &link_enc_regs[enc_init_data->transmitter], 576 &link_enc_aux_regs[enc_init_data->channel - 1], 577 &link_enc_hpd_regs[enc_init_data->hpd_source]); 578 return &enc110->base; 579 } 580 581 static struct input_pixel_processor *dce112_ipp_create( 582 struct dc_context *ctx, uint32_t inst) 583 { 584 struct dce_ipp *ipp = kzalloc(sizeof(struct dce_ipp), GFP_KERNEL); 585 586 if (!ipp) { 587 BREAK_TO_DEBUGGER(); 588 return NULL; 589 } 590 591 dce_ipp_construct(ipp, ctx, inst, 592 &ipp_regs[inst], &ipp_shift, &ipp_mask); 593 return &ipp->base; 594 } 595 596 static 597 struct output_pixel_processor *dce112_opp_create( 598 struct dc_context *ctx, 599 uint32_t inst) 600 { 601 struct dce110_opp *opp = 602 kzalloc(sizeof(struct dce110_opp), GFP_KERNEL); 603 604 if (!opp) 605 return NULL; 606 607 dce110_opp_construct(opp, 608 ctx, inst, &opp_regs[inst], &opp_shift, &opp_mask); 609 return &opp->base; 610 } 611 612 static 613 struct aux_engine *dce112_aux_engine_create( 614 struct dc_context *ctx, 615 uint32_t inst) 616 { 617 struct aux_engine_dce110 *aux_engine = 618 kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL); 619 620 if (!aux_engine) 621 return NULL; 622 623 dce110_aux_engine_construct(aux_engine, ctx, inst, 624 SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD, 625 &aux_engine_regs[inst]); 626 627 return &aux_engine->base; 628 } 629 630 static 631 struct clock_source *dce112_clock_source_create( 632 struct dc_context *ctx, 633 struct dc_bios *bios, 634 enum clock_source_id id, 635 const struct dce110_clk_src_regs *regs, 636 bool dp_clk_src) 637 { 638 struct dce110_clk_src *clk_src = 639 kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL); 640 641 if (!clk_src) 642 return NULL; 643 644 if (dce110_clk_src_construct(clk_src, ctx, bios, id, 645 regs, &cs_shift, &cs_mask)) { 646 clk_src->base.dp_clk_src = dp_clk_src; 647 return &clk_src->base; 648 } 649 650 BREAK_TO_DEBUGGER(); 651 return NULL; 652 } 653 654 static 655 void dce112_clock_source_destroy(struct clock_source **clk_src) 656 { 657 kfree(TO_DCE110_CLK_SRC(*clk_src)); 658 *clk_src = NULL; 659 } 660 661 static void destruct(struct dce110_resource_pool *pool) 662 { 663 unsigned int i; 664 665 for (i = 0; i < pool->base.pipe_count; i++) { 666 if (pool->base.opps[i] != NULL) 667 dce110_opp_destroy(&pool->base.opps[i]); 668 669 if (pool->base.engines[i] != NULL) 670 dce110_engine_destroy(&pool->base.engines[i]); 671 672 if (pool->base.transforms[i] != NULL) 673 dce112_transform_destroy(&pool->base.transforms[i]); 674 675 if (pool->base.ipps[i] != NULL) 676 dce_ipp_destroy(&pool->base.ipps[i]); 677 678 if (pool->base.mis[i] != NULL) { 679 kfree(TO_DCE_MEM_INPUT(pool->base.mis[i])); 680 pool->base.mis[i] = NULL; 681 } 682 683 if (pool->base.timing_generators[i] != NULL) { 684 kfree(DCE110TG_FROM_TG(pool->base.timing_generators[i])); 685 pool->base.timing_generators[i] = NULL; 686 } 687 688 } 689 690 for (i = 0; i < pool->base.stream_enc_count; i++) { 691 if (pool->base.stream_enc[i] != NULL) 692 kfree(DCE110STRENC_FROM_STRENC(pool->base.stream_enc[i])); 693 } 694 695 for (i = 0; i < pool->base.clk_src_count; i++) { 696 if (pool->base.clock_sources[i] != NULL) { 697 dce112_clock_source_destroy(&pool->base.clock_sources[i]); 698 } 699 } 700 701 if (pool->base.dp_clock_source != NULL) 702 dce112_clock_source_destroy(&pool->base.dp_clock_source); 703 704 for (i = 0; i < pool->base.audio_count; i++) { 705 if (pool->base.audios[i] != NULL) { 706 dce_aud_destroy(&pool->base.audios[i]); 707 } 708 } 709 710 if (pool->base.abm != NULL) 711 dce_abm_destroy(&pool->base.abm); 712 713 if (pool->base.dmcu != NULL) 714 dce_dmcu_destroy(&pool->base.dmcu); 715 716 if (pool->base.dccg != NULL) 717 dce_dccg_destroy(&pool->base.dccg); 718 719 if (pool->base.irqs != NULL) { 720 dal_irq_service_destroy(&pool->base.irqs); 721 } 722 } 723 724 static struct clock_source *find_matching_pll( 725 struct resource_context *res_ctx, 726 const struct resource_pool *pool, 727 const struct dc_stream_state *const stream) 728 { 729 switch (stream->sink->link->link_enc->transmitter) { 730 case TRANSMITTER_UNIPHY_A: 731 return pool->clock_sources[DCE112_CLK_SRC_PLL0]; 732 case TRANSMITTER_UNIPHY_B: 733 return pool->clock_sources[DCE112_CLK_SRC_PLL1]; 734 case TRANSMITTER_UNIPHY_C: 735 return pool->clock_sources[DCE112_CLK_SRC_PLL2]; 736 case TRANSMITTER_UNIPHY_D: 737 return pool->clock_sources[DCE112_CLK_SRC_PLL3]; 738 case TRANSMITTER_UNIPHY_E: 739 return pool->clock_sources[DCE112_CLK_SRC_PLL4]; 740 case TRANSMITTER_UNIPHY_F: 741 return pool->clock_sources[DCE112_CLK_SRC_PLL5]; 742 default: 743 return NULL; 744 }; 745 746 return 0; 747 } 748 749 static enum dc_status build_mapped_resource( 750 const struct dc *dc, 751 struct dc_state *context, 752 struct dc_stream_state *stream) 753 { 754 struct pipe_ctx *pipe_ctx = resource_get_head_pipe_for_stream(&context->res_ctx, stream); 755 756 if (!pipe_ctx) 757 return DC_ERROR_UNEXPECTED; 758 759 dce110_resource_build_pipe_hw_param(pipe_ctx); 760 761 resource_build_info_frame(pipe_ctx); 762 763 return DC_OK; 764 } 765 766 bool dce112_validate_bandwidth( 767 struct dc *dc, 768 struct dc_state *context) 769 { 770 bool result = false; 771 772 DC_LOG_BANDWIDTH_CALCS( 773 "%s: start", 774 __func__); 775 776 if (bw_calcs( 777 dc->ctx, 778 dc->bw_dceip, 779 dc->bw_vbios, 780 context->res_ctx.pipe_ctx, 781 dc->res_pool->pipe_count, 782 &context->bw.dce)) 783 result = true; 784 785 if (!result) 786 DC_LOG_BANDWIDTH_VALIDATION( 787 "%s: Bandwidth validation failed!", 788 __func__); 789 790 if (memcmp(&dc->current_state->bw.dce, 791 &context->bw.dce, sizeof(context->bw.dce))) { 792 793 DC_LOG_BANDWIDTH_CALCS( 794 "%s: finish,\n" 795 "nbpMark_b: %d nbpMark_a: %d urgentMark_b: %d urgentMark_a: %d\n" 796 "stutMark_b: %d stutMark_a: %d\n" 797 "nbpMark_b: %d nbpMark_a: %d urgentMark_b: %d urgentMark_a: %d\n" 798 "stutMark_b: %d stutMark_a: %d\n" 799 "nbpMark_b: %d nbpMark_a: %d urgentMark_b: %d urgentMark_a: %d\n" 800 "stutMark_b: %d stutMark_a: %d stutter_mode_enable: %d\n" 801 "cstate: %d pstate: %d nbpstate: %d sync: %d dispclk: %d\n" 802 "sclk: %d sclk_sleep: %d yclk: %d blackout_recovery_time_us: %d\n" 803 , 804 __func__, 805 context->bw.dce.nbp_state_change_wm_ns[0].b_mark, 806 context->bw.dce.nbp_state_change_wm_ns[0].a_mark, 807 context->bw.dce.urgent_wm_ns[0].b_mark, 808 context->bw.dce.urgent_wm_ns[0].a_mark, 809 context->bw.dce.stutter_exit_wm_ns[0].b_mark, 810 context->bw.dce.stutter_exit_wm_ns[0].a_mark, 811 context->bw.dce.nbp_state_change_wm_ns[1].b_mark, 812 context->bw.dce.nbp_state_change_wm_ns[1].a_mark, 813 context->bw.dce.urgent_wm_ns[1].b_mark, 814 context->bw.dce.urgent_wm_ns[1].a_mark, 815 context->bw.dce.stutter_exit_wm_ns[1].b_mark, 816 context->bw.dce.stutter_exit_wm_ns[1].a_mark, 817 context->bw.dce.nbp_state_change_wm_ns[2].b_mark, 818 context->bw.dce.nbp_state_change_wm_ns[2].a_mark, 819 context->bw.dce.urgent_wm_ns[2].b_mark, 820 context->bw.dce.urgent_wm_ns[2].a_mark, 821 context->bw.dce.stutter_exit_wm_ns[2].b_mark, 822 context->bw.dce.stutter_exit_wm_ns[2].a_mark, 823 context->bw.dce.stutter_mode_enable, 824 context->bw.dce.cpuc_state_change_enable, 825 context->bw.dce.cpup_state_change_enable, 826 context->bw.dce.nbp_state_change_enable, 827 context->bw.dce.all_displays_in_sync, 828 context->bw.dce.dispclk_khz, 829 context->bw.dce.sclk_khz, 830 context->bw.dce.sclk_deep_sleep_khz, 831 context->bw.dce.yclk_khz, 832 context->bw.dce.blackout_recovery_time_us); 833 } 834 return result; 835 } 836 837 enum dc_status resource_map_phy_clock_resources( 838 const struct dc *dc, 839 struct dc_state *context, 840 struct dc_stream_state *stream) 841 { 842 843 /* acquire new resources */ 844 struct pipe_ctx *pipe_ctx = resource_get_head_pipe_for_stream( 845 &context->res_ctx, stream); 846 847 if (!pipe_ctx) 848 return DC_ERROR_UNEXPECTED; 849 850 if (dc_is_dp_signal(pipe_ctx->stream->signal) 851 || pipe_ctx->stream->signal == SIGNAL_TYPE_VIRTUAL) 852 pipe_ctx->clock_source = 853 dc->res_pool->dp_clock_source; 854 else 855 pipe_ctx->clock_source = find_matching_pll( 856 &context->res_ctx, dc->res_pool, 857 stream); 858 859 if (pipe_ctx->clock_source == NULL) 860 return DC_NO_CLOCK_SOURCE_RESOURCE; 861 862 resource_reference_clock_source( 863 &context->res_ctx, 864 dc->res_pool, 865 pipe_ctx->clock_source); 866 867 return DC_OK; 868 } 869 870 static bool dce112_validate_surface_sets( 871 struct dc_state *context) 872 { 873 int i; 874 875 for (i = 0; i < context->stream_count; i++) { 876 if (context->stream_status[i].plane_count == 0) 877 continue; 878 879 if (context->stream_status[i].plane_count > 1) 880 return false; 881 882 if (context->stream_status[i].plane_states[0]->format 883 >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) 884 return false; 885 } 886 887 return true; 888 } 889 890 enum dc_status dce112_add_stream_to_ctx( 891 struct dc *dc, 892 struct dc_state *new_ctx, 893 struct dc_stream_state *dc_stream) 894 { 895 enum dc_status result = DC_ERROR_UNEXPECTED; 896 897 result = resource_map_pool_resources(dc, new_ctx, dc_stream); 898 899 if (result == DC_OK) 900 result = resource_map_phy_clock_resources(dc, new_ctx, dc_stream); 901 902 903 if (result == DC_OK) 904 result = build_mapped_resource(dc, new_ctx, dc_stream); 905 906 return result; 907 } 908 909 static 910 enum dc_status dce112_validate_global( 911 struct dc *dc, 912 struct dc_state *context) 913 { 914 if (!dce112_validate_surface_sets(context)) 915 return DC_FAIL_SURFACE_VALIDATE; 916 917 return DC_OK; 918 } 919 920 static void dce112_destroy_resource_pool(struct resource_pool **pool) 921 { 922 struct dce110_resource_pool *dce110_pool = TO_DCE110_RES_POOL(*pool); 923 924 destruct(dce110_pool); 925 kfree(dce110_pool); 926 *pool = NULL; 927 } 928 929 static const struct resource_funcs dce112_res_pool_funcs = { 930 .destroy = dce112_destroy_resource_pool, 931 .link_enc_create = dce112_link_encoder_create, 932 .validate_bandwidth = dce112_validate_bandwidth, 933 .validate_plane = dce100_validate_plane, 934 .add_stream_to_ctx = dce112_add_stream_to_ctx, 935 .validate_global = dce112_validate_global 936 }; 937 938 static void bw_calcs_data_update_from_pplib(struct dc *dc) 939 { 940 struct dm_pp_clock_levels_with_latency eng_clks = {0}; 941 struct dm_pp_clock_levels_with_latency mem_clks = {0}; 942 struct dm_pp_wm_sets_with_clock_ranges clk_ranges = {0}; 943 struct dm_pp_clock_levels clks = {0}; 944 945 /*do system clock TODO PPLIB: after PPLIB implement, 946 * then remove old way 947 */ 948 if (!dm_pp_get_clock_levels_by_type_with_latency( 949 dc->ctx, 950 DM_PP_CLOCK_TYPE_ENGINE_CLK, 951 &eng_clks)) { 952 953 /* This is only for temporary */ 954 dm_pp_get_clock_levels_by_type( 955 dc->ctx, 956 DM_PP_CLOCK_TYPE_ENGINE_CLK, 957 &clks); 958 /* convert all the clock fro kHz to fix point mHz */ 959 dc->bw_vbios->high_sclk = bw_frc_to_fixed( 960 clks.clocks_in_khz[clks.num_levels-1], 1000); 961 dc->bw_vbios->mid1_sclk = bw_frc_to_fixed( 962 clks.clocks_in_khz[clks.num_levels/8], 1000); 963 dc->bw_vbios->mid2_sclk = bw_frc_to_fixed( 964 clks.clocks_in_khz[clks.num_levels*2/8], 1000); 965 dc->bw_vbios->mid3_sclk = bw_frc_to_fixed( 966 clks.clocks_in_khz[clks.num_levels*3/8], 1000); 967 dc->bw_vbios->mid4_sclk = bw_frc_to_fixed( 968 clks.clocks_in_khz[clks.num_levels*4/8], 1000); 969 dc->bw_vbios->mid5_sclk = bw_frc_to_fixed( 970 clks.clocks_in_khz[clks.num_levels*5/8], 1000); 971 dc->bw_vbios->mid6_sclk = bw_frc_to_fixed( 972 clks.clocks_in_khz[clks.num_levels*6/8], 1000); 973 dc->bw_vbios->low_sclk = bw_frc_to_fixed( 974 clks.clocks_in_khz[0], 1000); 975 976 /*do memory clock*/ 977 dm_pp_get_clock_levels_by_type( 978 dc->ctx, 979 DM_PP_CLOCK_TYPE_MEMORY_CLK, 980 &clks); 981 982 dc->bw_vbios->low_yclk = bw_frc_to_fixed( 983 clks.clocks_in_khz[0] * MEMORY_TYPE_MULTIPLIER, 1000); 984 dc->bw_vbios->mid_yclk = bw_frc_to_fixed( 985 clks.clocks_in_khz[clks.num_levels>>1] * MEMORY_TYPE_MULTIPLIER, 986 1000); 987 dc->bw_vbios->high_yclk = bw_frc_to_fixed( 988 clks.clocks_in_khz[clks.num_levels-1] * MEMORY_TYPE_MULTIPLIER, 989 1000); 990 991 return; 992 } 993 994 /* convert all the clock fro kHz to fix point mHz TODO: wloop data */ 995 dc->bw_vbios->high_sclk = bw_frc_to_fixed( 996 eng_clks.data[eng_clks.num_levels-1].clocks_in_khz, 1000); 997 dc->bw_vbios->mid1_sclk = bw_frc_to_fixed( 998 eng_clks.data[eng_clks.num_levels/8].clocks_in_khz, 1000); 999 dc->bw_vbios->mid2_sclk = bw_frc_to_fixed( 1000 eng_clks.data[eng_clks.num_levels*2/8].clocks_in_khz, 1000); 1001 dc->bw_vbios->mid3_sclk = bw_frc_to_fixed( 1002 eng_clks.data[eng_clks.num_levels*3/8].clocks_in_khz, 1000); 1003 dc->bw_vbios->mid4_sclk = bw_frc_to_fixed( 1004 eng_clks.data[eng_clks.num_levels*4/8].clocks_in_khz, 1000); 1005 dc->bw_vbios->mid5_sclk = bw_frc_to_fixed( 1006 eng_clks.data[eng_clks.num_levels*5/8].clocks_in_khz, 1000); 1007 dc->bw_vbios->mid6_sclk = bw_frc_to_fixed( 1008 eng_clks.data[eng_clks.num_levels*6/8].clocks_in_khz, 1000); 1009 dc->bw_vbios->low_sclk = bw_frc_to_fixed( 1010 eng_clks.data[0].clocks_in_khz, 1000); 1011 1012 /*do memory clock*/ 1013 dm_pp_get_clock_levels_by_type_with_latency( 1014 dc->ctx, 1015 DM_PP_CLOCK_TYPE_MEMORY_CLK, 1016 &mem_clks); 1017 1018 /* we don't need to call PPLIB for validation clock since they 1019 * also give us the highest sclk and highest mclk (UMA clock). 1020 * ALSO always convert UMA clock (from PPLIB) to YCLK (HW formula): 1021 * YCLK = UMACLK*m_memoryTypeMultiplier 1022 */ 1023 dc->bw_vbios->low_yclk = bw_frc_to_fixed( 1024 mem_clks.data[0].clocks_in_khz * MEMORY_TYPE_MULTIPLIER, 1000); 1025 dc->bw_vbios->mid_yclk = bw_frc_to_fixed( 1026 mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz * MEMORY_TYPE_MULTIPLIER, 1027 1000); 1028 dc->bw_vbios->high_yclk = bw_frc_to_fixed( 1029 mem_clks.data[mem_clks.num_levels-1].clocks_in_khz * MEMORY_TYPE_MULTIPLIER, 1030 1000); 1031 1032 /* Now notify PPLib/SMU about which Watermarks sets they should select 1033 * depending on DPM state they are in. And update BW MGR GFX Engine and 1034 * Memory clock member variables for Watermarks calculations for each 1035 * Watermark Set 1036 */ 1037 clk_ranges.num_wm_sets = 4; 1038 clk_ranges.wm_clk_ranges[0].wm_set_id = WM_SET_A; 1039 clk_ranges.wm_clk_ranges[0].wm_min_eng_clk_in_khz = 1040 eng_clks.data[0].clocks_in_khz; 1041 clk_ranges.wm_clk_ranges[0].wm_max_eng_clk_in_khz = 1042 eng_clks.data[eng_clks.num_levels*3/8].clocks_in_khz - 1; 1043 clk_ranges.wm_clk_ranges[0].wm_min_mem_clk_in_khz = 1044 mem_clks.data[0].clocks_in_khz; 1045 clk_ranges.wm_clk_ranges[0].wm_max_mem_clk_in_khz = 1046 mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz - 1; 1047 1048 clk_ranges.wm_clk_ranges[1].wm_set_id = WM_SET_B; 1049 clk_ranges.wm_clk_ranges[1].wm_min_eng_clk_in_khz = 1050 eng_clks.data[eng_clks.num_levels*3/8].clocks_in_khz; 1051 /* 5 GHz instead of data[7].clockInKHz to cover Overdrive */ 1052 clk_ranges.wm_clk_ranges[1].wm_max_eng_clk_in_khz = 5000000; 1053 clk_ranges.wm_clk_ranges[1].wm_min_mem_clk_in_khz = 1054 mem_clks.data[0].clocks_in_khz; 1055 clk_ranges.wm_clk_ranges[1].wm_max_mem_clk_in_khz = 1056 mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz - 1; 1057 1058 clk_ranges.wm_clk_ranges[2].wm_set_id = WM_SET_C; 1059 clk_ranges.wm_clk_ranges[2].wm_min_eng_clk_in_khz = 1060 eng_clks.data[0].clocks_in_khz; 1061 clk_ranges.wm_clk_ranges[2].wm_max_eng_clk_in_khz = 1062 eng_clks.data[eng_clks.num_levels*3/8].clocks_in_khz - 1; 1063 clk_ranges.wm_clk_ranges[2].wm_min_mem_clk_in_khz = 1064 mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz; 1065 /* 5 GHz instead of data[2].clockInKHz to cover Overdrive */ 1066 clk_ranges.wm_clk_ranges[2].wm_max_mem_clk_in_khz = 5000000; 1067 1068 clk_ranges.wm_clk_ranges[3].wm_set_id = WM_SET_D; 1069 clk_ranges.wm_clk_ranges[3].wm_min_eng_clk_in_khz = 1070 eng_clks.data[eng_clks.num_levels*3/8].clocks_in_khz; 1071 /* 5 GHz instead of data[7].clockInKHz to cover Overdrive */ 1072 clk_ranges.wm_clk_ranges[3].wm_max_eng_clk_in_khz = 5000000; 1073 clk_ranges.wm_clk_ranges[3].wm_min_mem_clk_in_khz = 1074 mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz; 1075 /* 5 GHz instead of data[2].clockInKHz to cover Overdrive */ 1076 clk_ranges.wm_clk_ranges[3].wm_max_mem_clk_in_khz = 5000000; 1077 1078 /* Notify PP Lib/SMU which Watermarks to use for which clock ranges */ 1079 dm_pp_notify_wm_clock_changes(dc->ctx, &clk_ranges); 1080 } 1081 1082 static 1083 const struct resource_caps *dce112_resource_cap( 1084 struct hw_asic_id *asic_id) 1085 { 1086 if (ASIC_REV_IS_POLARIS11_M(asic_id->hw_internal_rev) || 1087 ASIC_REV_IS_POLARIS12_V(asic_id->hw_internal_rev)) 1088 return &polaris_11_resource_cap; 1089 else 1090 return &polaris_10_resource_cap; 1091 } 1092 1093 static bool construct( 1094 uint8_t num_virtual_links, 1095 struct dc *dc, 1096 struct dce110_resource_pool *pool) 1097 { 1098 unsigned int i; 1099 struct dc_context *ctx = dc->ctx; 1100 struct dm_pp_static_clock_info static_clk_info = {0}; 1101 1102 ctx->dc_bios->regs = &bios_regs; 1103 1104 pool->base.res_cap = dce112_resource_cap(&ctx->asic_id); 1105 pool->base.funcs = &dce112_res_pool_funcs; 1106 1107 /************************************************* 1108 * Resource + asic cap harcoding * 1109 *************************************************/ 1110 pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE; 1111 pool->base.pipe_count = pool->base.res_cap->num_timing_generator; 1112 pool->base.timing_generator_count = pool->base.res_cap->num_timing_generator; 1113 dc->caps.max_downscale_ratio = 200; 1114 dc->caps.i2c_speed_in_khz = 100; 1115 dc->caps.max_cursor_size = 128; 1116 dc->caps.dual_link_dvi = true; 1117 1118 1119 /************************************************* 1120 * Create resources * 1121 *************************************************/ 1122 1123 pool->base.clock_sources[DCE112_CLK_SRC_PLL0] = 1124 dce112_clock_source_create( 1125 ctx, ctx->dc_bios, 1126 CLOCK_SOURCE_COMBO_PHY_PLL0, 1127 &clk_src_regs[0], false); 1128 pool->base.clock_sources[DCE112_CLK_SRC_PLL1] = 1129 dce112_clock_source_create( 1130 ctx, ctx->dc_bios, 1131 CLOCK_SOURCE_COMBO_PHY_PLL1, 1132 &clk_src_regs[1], false); 1133 pool->base.clock_sources[DCE112_CLK_SRC_PLL2] = 1134 dce112_clock_source_create( 1135 ctx, ctx->dc_bios, 1136 CLOCK_SOURCE_COMBO_PHY_PLL2, 1137 &clk_src_regs[2], false); 1138 pool->base.clock_sources[DCE112_CLK_SRC_PLL3] = 1139 dce112_clock_source_create( 1140 ctx, ctx->dc_bios, 1141 CLOCK_SOURCE_COMBO_PHY_PLL3, 1142 &clk_src_regs[3], false); 1143 pool->base.clock_sources[DCE112_CLK_SRC_PLL4] = 1144 dce112_clock_source_create( 1145 ctx, ctx->dc_bios, 1146 CLOCK_SOURCE_COMBO_PHY_PLL4, 1147 &clk_src_regs[4], false); 1148 pool->base.clock_sources[DCE112_CLK_SRC_PLL5] = 1149 dce112_clock_source_create( 1150 ctx, ctx->dc_bios, 1151 CLOCK_SOURCE_COMBO_PHY_PLL5, 1152 &clk_src_regs[5], false); 1153 pool->base.clk_src_count = DCE112_CLK_SRC_TOTAL; 1154 1155 pool->base.dp_clock_source = dce112_clock_source_create( 1156 ctx, ctx->dc_bios, 1157 CLOCK_SOURCE_ID_DP_DTO, &clk_src_regs[0], true); 1158 1159 1160 for (i = 0; i < pool->base.clk_src_count; i++) { 1161 if (pool->base.clock_sources[i] == NULL) { 1162 dm_error("DC: failed to create clock sources!\n"); 1163 BREAK_TO_DEBUGGER(); 1164 goto res_create_fail; 1165 } 1166 } 1167 1168 pool->base.dccg = dce112_dccg_create(ctx, 1169 &disp_clk_regs, 1170 &disp_clk_shift, 1171 &disp_clk_mask); 1172 if (pool->base.dccg == NULL) { 1173 dm_error("DC: failed to create display clock!\n"); 1174 BREAK_TO_DEBUGGER(); 1175 goto res_create_fail; 1176 } 1177 1178 pool->base.dmcu = dce_dmcu_create(ctx, 1179 &dmcu_regs, 1180 &dmcu_shift, 1181 &dmcu_mask); 1182 if (pool->base.dmcu == NULL) { 1183 dm_error("DC: failed to create dmcu!\n"); 1184 BREAK_TO_DEBUGGER(); 1185 goto res_create_fail; 1186 } 1187 1188 pool->base.abm = dce_abm_create(ctx, 1189 &abm_regs, 1190 &abm_shift, 1191 &abm_mask); 1192 if (pool->base.abm == NULL) { 1193 dm_error("DC: failed to create abm!\n"); 1194 BREAK_TO_DEBUGGER(); 1195 goto res_create_fail; 1196 } 1197 1198 /* get static clock information for PPLIB or firmware, save 1199 * max_clock_state 1200 */ 1201 if (dm_pp_get_static_clocks(ctx, &static_clk_info)) 1202 pool->base.dccg->max_clks_state = 1203 static_clk_info.max_clocks_state; 1204 1205 { 1206 struct irq_service_init_data init_data; 1207 init_data.ctx = dc->ctx; 1208 pool->base.irqs = dal_irq_service_dce110_create(&init_data); 1209 if (!pool->base.irqs) 1210 goto res_create_fail; 1211 } 1212 1213 for (i = 0; i < pool->base.pipe_count; i++) { 1214 pool->base.timing_generators[i] = 1215 dce112_timing_generator_create( 1216 ctx, 1217 i, 1218 &dce112_tg_offsets[i]); 1219 if (pool->base.timing_generators[i] == NULL) { 1220 BREAK_TO_DEBUGGER(); 1221 dm_error("DC: failed to create tg!\n"); 1222 goto res_create_fail; 1223 } 1224 1225 pool->base.mis[i] = dce112_mem_input_create(ctx, i); 1226 if (pool->base.mis[i] == NULL) { 1227 BREAK_TO_DEBUGGER(); 1228 dm_error( 1229 "DC: failed to create memory input!\n"); 1230 goto res_create_fail; 1231 } 1232 1233 pool->base.ipps[i] = dce112_ipp_create(ctx, i); 1234 if (pool->base.ipps[i] == NULL) { 1235 BREAK_TO_DEBUGGER(); 1236 dm_error( 1237 "DC:failed to create input pixel processor!\n"); 1238 goto res_create_fail; 1239 } 1240 1241 pool->base.transforms[i] = dce112_transform_create(ctx, i); 1242 if (pool->base.transforms[i] == NULL) { 1243 BREAK_TO_DEBUGGER(); 1244 dm_error( 1245 "DC: failed to create transform!\n"); 1246 goto res_create_fail; 1247 } 1248 1249 pool->base.opps[i] = dce112_opp_create( 1250 ctx, 1251 i); 1252 if (pool->base.opps[i] == NULL) { 1253 BREAK_TO_DEBUGGER(); 1254 dm_error( 1255 "DC:failed to create output pixel processor!\n"); 1256 goto res_create_fail; 1257 } 1258 pool->base.engines[i] = dce112_aux_engine_create(ctx, i); 1259 if (pool->base.engines[i] == NULL) { 1260 BREAK_TO_DEBUGGER(); 1261 dm_error( 1262 "DC:failed to create aux engine!!\n"); 1263 goto res_create_fail; 1264 } 1265 } 1266 1267 if (!resource_construct(num_virtual_links, dc, &pool->base, 1268 &res_create_funcs)) 1269 goto res_create_fail; 1270 1271 dc->caps.max_planes = pool->base.pipe_count; 1272 1273 /* Create hardware sequencer */ 1274 dce112_hw_sequencer_construct(dc); 1275 1276 bw_calcs_init(dc->bw_dceip, dc->bw_vbios, dc->ctx->asic_id); 1277 1278 bw_calcs_data_update_from_pplib(dc); 1279 1280 return true; 1281 1282 res_create_fail: 1283 destruct(pool); 1284 return false; 1285 } 1286 1287 struct resource_pool *dce112_create_resource_pool( 1288 uint8_t num_virtual_links, 1289 struct dc *dc) 1290 { 1291 struct dce110_resource_pool *pool = 1292 kzalloc(sizeof(struct dce110_resource_pool), GFP_KERNEL); 1293 1294 if (!pool) 1295 return NULL; 1296 1297 if (construct(num_virtual_links, dc, pool)) 1298 return &pool->base; 1299 1300 kfree(pool); 1301 BREAK_TO_DEBUGGER(); 1302 return NULL; 1303 } 1304