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