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 "dce/dce_8_0_d.h" 27 #include "dce/dce_8_0_sh_mask.h" 28 29 #include "dm_services.h" 30 31 #include "link_encoder.h" 32 #include "stream_encoder.h" 33 34 #include "resource.h" 35 #include "include/irq_service_interface.h" 36 #include "irq/dce80/irq_service_dce80.h" 37 #include "dce110/dce110_timing_generator.h" 38 #include "dce110/dce110_resource.h" 39 #include "dce80/dce80_timing_generator.h" 40 #include "dce/dce_clk_mgr.h" 41 #include "dce/dce_mem_input.h" 42 #include "dce/dce_link_encoder.h" 43 #include "dce/dce_stream_encoder.h" 44 #include "dce/dce_mem_input.h" 45 #include "dce/dce_ipp.h" 46 #include "dce/dce_transform.h" 47 #include "dce/dce_opp.h" 48 #include "dce/dce_clock_source.h" 49 #include "dce/dce_audio.h" 50 #include "dce/dce_hwseq.h" 51 #include "dce80/dce80_hw_sequencer.h" 52 #include "dce100/dce100_resource.h" 53 54 #include "reg_helper.h" 55 56 #include "dce/dce_dmcu.h" 57 #include "dce/dce_aux.h" 58 #include "dce/dce_abm.h" 59 #include "dce/dce_i2c.h" 60 /* TODO remove this include */ 61 62 #ifndef mmMC_HUB_RDREQ_DMIF_LIMIT 63 #include "gmc/gmc_7_1_d.h" 64 #include "gmc/gmc_7_1_sh_mask.h" 65 #endif 66 67 #ifndef mmDP_DPHY_INTERNAL_CTRL 68 #define mmDP_DPHY_INTERNAL_CTRL 0x1CDE 69 #define mmDP0_DP_DPHY_INTERNAL_CTRL 0x1CDE 70 #define mmDP1_DP_DPHY_INTERNAL_CTRL 0x1FDE 71 #define mmDP2_DP_DPHY_INTERNAL_CTRL 0x42DE 72 #define mmDP3_DP_DPHY_INTERNAL_CTRL 0x45DE 73 #define mmDP4_DP_DPHY_INTERNAL_CTRL 0x48DE 74 #define mmDP5_DP_DPHY_INTERNAL_CTRL 0x4BDE 75 #define mmDP6_DP_DPHY_INTERNAL_CTRL 0x4EDE 76 #endif 77 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_FAST_TRAINING 85 #define mmDP_DPHY_FAST_TRAINING 0x1CCE 86 #define mmDP0_DP_DPHY_FAST_TRAINING 0x1CCE 87 #define mmDP1_DP_DPHY_FAST_TRAINING 0x1FCE 88 #define mmDP2_DP_DPHY_FAST_TRAINING 0x42CE 89 #define mmDP3_DP_DPHY_FAST_TRAINING 0x45CE 90 #define mmDP4_DP_DPHY_FAST_TRAINING 0x48CE 91 #define mmDP5_DP_DPHY_FAST_TRAINING 0x4BCE 92 #define mmDP6_DP_DPHY_FAST_TRAINING 0x4ECE 93 #endif 94 95 96 #ifndef mmHPD_DC_HPD_CONTROL 97 #define mmHPD_DC_HPD_CONTROL 0x189A 98 #define mmHPD0_DC_HPD_CONTROL 0x189A 99 #define mmHPD1_DC_HPD_CONTROL 0x18A2 100 #define mmHPD2_DC_HPD_CONTROL 0x18AA 101 #define mmHPD3_DC_HPD_CONTROL 0x18B2 102 #define mmHPD4_DC_HPD_CONTROL 0x18BA 103 #define mmHPD5_DC_HPD_CONTROL 0x18C2 104 #endif 105 106 #define DCE11_DIG_FE_CNTL 0x4a00 107 #define DCE11_DIG_BE_CNTL 0x4a47 108 #define DCE11_DP_SEC 0x4ac3 109 110 static const struct dce110_timing_generator_offsets dce80_tg_offsets[] = { 111 { 112 .crtc = (mmCRTC0_CRTC_CONTROL - mmCRTC_CONTROL), 113 .dcp = (mmGRPH_CONTROL - mmGRPH_CONTROL), 114 .dmif = (mmDMIF_PG0_DPG_WATERMARK_MASK_CONTROL 115 - mmDPG_WATERMARK_MASK_CONTROL), 116 }, 117 { 118 .crtc = (mmCRTC1_CRTC_CONTROL - mmCRTC_CONTROL), 119 .dcp = (mmDCP1_GRPH_CONTROL - mmGRPH_CONTROL), 120 .dmif = (mmDMIF_PG1_DPG_WATERMARK_MASK_CONTROL 121 - mmDPG_WATERMARK_MASK_CONTROL), 122 }, 123 { 124 .crtc = (mmCRTC2_CRTC_CONTROL - mmCRTC_CONTROL), 125 .dcp = (mmDCP2_GRPH_CONTROL - mmGRPH_CONTROL), 126 .dmif = (mmDMIF_PG2_DPG_WATERMARK_MASK_CONTROL 127 - mmDPG_WATERMARK_MASK_CONTROL), 128 }, 129 { 130 .crtc = (mmCRTC3_CRTC_CONTROL - mmCRTC_CONTROL), 131 .dcp = (mmDCP3_GRPH_CONTROL - mmGRPH_CONTROL), 132 .dmif = (mmDMIF_PG3_DPG_WATERMARK_MASK_CONTROL 133 - mmDPG_WATERMARK_MASK_CONTROL), 134 }, 135 { 136 .crtc = (mmCRTC4_CRTC_CONTROL - mmCRTC_CONTROL), 137 .dcp = (mmDCP4_GRPH_CONTROL - mmGRPH_CONTROL), 138 .dmif = (mmDMIF_PG4_DPG_WATERMARK_MASK_CONTROL 139 - mmDPG_WATERMARK_MASK_CONTROL), 140 }, 141 { 142 .crtc = (mmCRTC5_CRTC_CONTROL - mmCRTC_CONTROL), 143 .dcp = (mmDCP5_GRPH_CONTROL - mmGRPH_CONTROL), 144 .dmif = (mmDMIF_PG5_DPG_WATERMARK_MASK_CONTROL 145 - mmDPG_WATERMARK_MASK_CONTROL), 146 } 147 }; 148 149 /* set register offset */ 150 #define SR(reg_name)\ 151 .reg_name = mm ## reg_name 152 153 /* set register offset with instance */ 154 #define SRI(reg_name, block, id)\ 155 .reg_name = mm ## block ## id ## _ ## reg_name 156 157 158 static const struct clk_mgr_registers disp_clk_regs = { 159 CLK_COMMON_REG_LIST_DCE_BASE() 160 }; 161 162 static const struct clk_mgr_shift disp_clk_shift = { 163 CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT) 164 }; 165 166 static const struct clk_mgr_mask disp_clk_mask = { 167 CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK) 168 }; 169 170 #define ipp_regs(id)\ 171 [id] = {\ 172 IPP_COMMON_REG_LIST_DCE_BASE(id)\ 173 } 174 175 static const struct dce_ipp_registers ipp_regs[] = { 176 ipp_regs(0), 177 ipp_regs(1), 178 ipp_regs(2), 179 ipp_regs(3), 180 ipp_regs(4), 181 ipp_regs(5) 182 }; 183 184 static const struct dce_ipp_shift ipp_shift = { 185 IPP_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT) 186 }; 187 188 static const struct dce_ipp_mask ipp_mask = { 189 IPP_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK) 190 }; 191 192 #define transform_regs(id)\ 193 [id] = {\ 194 XFM_COMMON_REG_LIST_DCE80(id)\ 195 } 196 197 static const struct dce_transform_registers xfm_regs[] = { 198 transform_regs(0), 199 transform_regs(1), 200 transform_regs(2), 201 transform_regs(3), 202 transform_regs(4), 203 transform_regs(5) 204 }; 205 206 static const struct dce_transform_shift xfm_shift = { 207 XFM_COMMON_MASK_SH_LIST_DCE80(__SHIFT) 208 }; 209 210 static const struct dce_transform_mask xfm_mask = { 211 XFM_COMMON_MASK_SH_LIST_DCE80(_MASK) 212 }; 213 214 #define aux_regs(id)\ 215 [id] = {\ 216 AUX_REG_LIST(id)\ 217 } 218 219 static const struct dce110_link_enc_aux_registers link_enc_aux_regs[] = { 220 aux_regs(0), 221 aux_regs(1), 222 aux_regs(2), 223 aux_regs(3), 224 aux_regs(4), 225 aux_regs(5) 226 }; 227 228 #define hpd_regs(id)\ 229 [id] = {\ 230 HPD_REG_LIST(id)\ 231 } 232 233 static const struct dce110_link_enc_hpd_registers link_enc_hpd_regs[] = { 234 hpd_regs(0), 235 hpd_regs(1), 236 hpd_regs(2), 237 hpd_regs(3), 238 hpd_regs(4), 239 hpd_regs(5) 240 }; 241 242 #define link_regs(id)\ 243 [id] = {\ 244 LE_DCE80_REG_LIST(id)\ 245 } 246 247 static const struct dce110_link_enc_registers link_enc_regs[] = { 248 link_regs(0), 249 link_regs(1), 250 link_regs(2), 251 link_regs(3), 252 link_regs(4), 253 link_regs(5), 254 link_regs(6), 255 }; 256 257 #define stream_enc_regs(id)\ 258 [id] = {\ 259 SE_COMMON_REG_LIST_DCE_BASE(id),\ 260 .AFMT_CNTL = 0,\ 261 } 262 263 static const struct dce110_stream_enc_registers stream_enc_regs[] = { 264 stream_enc_regs(0), 265 stream_enc_regs(1), 266 stream_enc_regs(2), 267 stream_enc_regs(3), 268 stream_enc_regs(4), 269 stream_enc_regs(5), 270 stream_enc_regs(6) 271 }; 272 273 static const struct dce_stream_encoder_shift se_shift = { 274 SE_COMMON_MASK_SH_LIST_DCE80_100(__SHIFT) 275 }; 276 277 static const struct dce_stream_encoder_mask se_mask = { 278 SE_COMMON_MASK_SH_LIST_DCE80_100(_MASK) 279 }; 280 281 #define opp_regs(id)\ 282 [id] = {\ 283 OPP_DCE_80_REG_LIST(id),\ 284 } 285 286 static const struct dce_opp_registers opp_regs[] = { 287 opp_regs(0), 288 opp_regs(1), 289 opp_regs(2), 290 opp_regs(3), 291 opp_regs(4), 292 opp_regs(5) 293 }; 294 295 static const struct dce_opp_shift opp_shift = { 296 OPP_COMMON_MASK_SH_LIST_DCE_80(__SHIFT) 297 }; 298 299 static const struct dce_opp_mask opp_mask = { 300 OPP_COMMON_MASK_SH_LIST_DCE_80(_MASK) 301 }; 302 303 #define aux_engine_regs(id)\ 304 [id] = {\ 305 AUX_COMMON_REG_LIST(id), \ 306 .AUX_RESET_MASK = 0 \ 307 } 308 309 static const struct dce110_aux_registers aux_engine_regs[] = { 310 aux_engine_regs(0), 311 aux_engine_regs(1), 312 aux_engine_regs(2), 313 aux_engine_regs(3), 314 aux_engine_regs(4), 315 aux_engine_regs(5) 316 }; 317 318 #define audio_regs(id)\ 319 [id] = {\ 320 AUD_COMMON_REG_LIST(id)\ 321 } 322 323 static const struct dce_audio_registers audio_regs[] = { 324 audio_regs(0), 325 audio_regs(1), 326 audio_regs(2), 327 audio_regs(3), 328 audio_regs(4), 329 audio_regs(5), 330 audio_regs(6), 331 }; 332 333 static const struct dce_audio_shift audio_shift = { 334 AUD_COMMON_MASK_SH_LIST(__SHIFT) 335 }; 336 337 static const struct dce_aduio_mask audio_mask = { 338 AUD_COMMON_MASK_SH_LIST(_MASK) 339 }; 340 341 #define clk_src_regs(id)\ 342 [id] = {\ 343 CS_COMMON_REG_LIST_DCE_80(id),\ 344 } 345 346 347 static const struct dce110_clk_src_regs clk_src_regs[] = { 348 clk_src_regs(0), 349 clk_src_regs(1), 350 clk_src_regs(2) 351 }; 352 353 static const struct dce110_clk_src_shift cs_shift = { 354 CS_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT) 355 }; 356 357 static const struct dce110_clk_src_mask cs_mask = { 358 CS_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK) 359 }; 360 361 static const struct bios_registers bios_regs = { 362 .BIOS_SCRATCH_6 = mmBIOS_SCRATCH_6 363 }; 364 365 static const struct resource_caps res_cap = { 366 .num_timing_generator = 6, 367 .num_audio = 6, 368 .num_stream_encoder = 6, 369 .num_pll = 3, 370 .num_ddc = 6, 371 }; 372 373 static const struct resource_caps res_cap_81 = { 374 .num_timing_generator = 4, 375 .num_audio = 7, 376 .num_stream_encoder = 7, 377 .num_pll = 3, 378 .num_ddc = 6, 379 }; 380 381 static const struct resource_caps res_cap_83 = { 382 .num_timing_generator = 2, 383 .num_audio = 6, 384 .num_stream_encoder = 6, 385 .num_pll = 2, 386 .num_ddc = 2, 387 }; 388 389 static const struct dce_dmcu_registers dmcu_regs = { 390 DMCU_DCE80_REG_LIST() 391 }; 392 393 static const struct dce_dmcu_shift dmcu_shift = { 394 DMCU_MASK_SH_LIST_DCE80(__SHIFT) 395 }; 396 397 static const struct dce_dmcu_mask dmcu_mask = { 398 DMCU_MASK_SH_LIST_DCE80(_MASK) 399 }; 400 static const struct dce_abm_registers abm_regs = { 401 ABM_DCE110_COMMON_REG_LIST() 402 }; 403 404 static const struct dce_abm_shift abm_shift = { 405 ABM_MASK_SH_LIST_DCE110(__SHIFT) 406 }; 407 408 static const struct dce_abm_mask abm_mask = { 409 ABM_MASK_SH_LIST_DCE110(_MASK) 410 }; 411 412 #define CTX ctx 413 #define REG(reg) mm ## reg 414 415 #ifndef mmCC_DC_HDMI_STRAPS 416 #define mmCC_DC_HDMI_STRAPS 0x1918 417 #define CC_DC_HDMI_STRAPS__HDMI_DISABLE_MASK 0x40 418 #define CC_DC_HDMI_STRAPS__HDMI_DISABLE__SHIFT 0x6 419 #define CC_DC_HDMI_STRAPS__AUDIO_STREAM_NUMBER_MASK 0x700 420 #define CC_DC_HDMI_STRAPS__AUDIO_STREAM_NUMBER__SHIFT 0x8 421 #endif 422 423 static void read_dce_straps( 424 struct dc_context *ctx, 425 struct resource_straps *straps) 426 { 427 REG_GET_2(CC_DC_HDMI_STRAPS, 428 HDMI_DISABLE, &straps->hdmi_disable, 429 AUDIO_STREAM_NUMBER, &straps->audio_stream_number); 430 431 REG_GET(DC_PINSTRAPS, DC_PINSTRAPS_AUDIO, &straps->dc_pinstraps_audio); 432 } 433 434 static struct audio *create_audio( 435 struct dc_context *ctx, unsigned int inst) 436 { 437 return dce_audio_create(ctx, inst, 438 &audio_regs[inst], &audio_shift, &audio_mask); 439 } 440 441 static struct timing_generator *dce80_timing_generator_create( 442 struct dc_context *ctx, 443 uint32_t instance, 444 const struct dce110_timing_generator_offsets *offsets) 445 { 446 struct dce110_timing_generator *tg110 = 447 kzalloc(sizeof(struct dce110_timing_generator), GFP_KERNEL); 448 449 if (!tg110) 450 return NULL; 451 452 dce80_timing_generator_construct(tg110, ctx, instance, offsets); 453 return &tg110->base; 454 } 455 456 static struct output_pixel_processor *dce80_opp_create( 457 struct dc_context *ctx, 458 uint32_t inst) 459 { 460 struct dce110_opp *opp = 461 kzalloc(sizeof(struct dce110_opp), GFP_KERNEL); 462 463 if (!opp) 464 return NULL; 465 466 dce110_opp_construct(opp, 467 ctx, inst, &opp_regs[inst], &opp_shift, &opp_mask); 468 return &opp->base; 469 } 470 471 struct aux_engine *dce80_aux_engine_create( 472 struct dc_context *ctx, 473 uint32_t inst) 474 { 475 struct aux_engine_dce110 *aux_engine = 476 kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL); 477 478 if (!aux_engine) 479 return NULL; 480 481 dce110_aux_engine_construct(aux_engine, ctx, inst, 482 SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD, 483 &aux_engine_regs[inst]); 484 485 return &aux_engine->base; 486 } 487 #define i2c_inst_regs(id) { I2C_HW_ENGINE_COMMON_REG_LIST(id) } 488 489 static const struct dce_i2c_registers i2c_hw_regs[] = { 490 i2c_inst_regs(1), 491 i2c_inst_regs(2), 492 i2c_inst_regs(3), 493 i2c_inst_regs(4), 494 i2c_inst_regs(5), 495 i2c_inst_regs(6), 496 }; 497 498 static const struct dce_i2c_shift i2c_shifts = { 499 I2C_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT) 500 }; 501 502 static const struct dce_i2c_mask i2c_masks = { 503 I2C_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK) 504 }; 505 506 struct dce_i2c_hw *dce80_i2c_hw_create( 507 struct dc_context *ctx, 508 uint32_t inst) 509 { 510 struct dce_i2c_hw *dce_i2c_hw = 511 kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL); 512 513 if (!dce_i2c_hw) 514 return NULL; 515 516 dce_i2c_hw_construct(dce_i2c_hw, ctx, inst, 517 &i2c_hw_regs[inst], &i2c_shifts, &i2c_masks); 518 519 return dce_i2c_hw; 520 } 521 522 struct dce_i2c_sw *dce80_i2c_sw_create( 523 struct dc_context *ctx) 524 { 525 struct dce_i2c_sw *dce_i2c_sw = 526 kzalloc(sizeof(struct dce_i2c_sw), GFP_KERNEL); 527 528 if (!dce_i2c_sw) 529 return NULL; 530 531 dce_i2c_sw_construct(dce_i2c_sw, ctx); 532 533 return dce_i2c_sw; 534 } 535 static struct stream_encoder *dce80_stream_encoder_create( 536 enum engine_id eng_id, 537 struct dc_context *ctx) 538 { 539 struct dce110_stream_encoder *enc110 = 540 kzalloc(sizeof(struct dce110_stream_encoder), GFP_KERNEL); 541 542 if (!enc110) 543 return NULL; 544 545 dce110_stream_encoder_construct(enc110, ctx, ctx->dc_bios, eng_id, 546 &stream_enc_regs[eng_id], 547 &se_shift, &se_mask); 548 return &enc110->base; 549 } 550 551 #define SRII(reg_name, block, id)\ 552 .reg_name[id] = mm ## block ## id ## _ ## reg_name 553 554 static const struct dce_hwseq_registers hwseq_reg = { 555 HWSEQ_DCE8_REG_LIST() 556 }; 557 558 static const struct dce_hwseq_shift hwseq_shift = { 559 HWSEQ_DCE8_MASK_SH_LIST(__SHIFT) 560 }; 561 562 static const struct dce_hwseq_mask hwseq_mask = { 563 HWSEQ_DCE8_MASK_SH_LIST(_MASK) 564 }; 565 566 static struct dce_hwseq *dce80_hwseq_create( 567 struct dc_context *ctx) 568 { 569 struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL); 570 571 if (hws) { 572 hws->ctx = ctx; 573 hws->regs = &hwseq_reg; 574 hws->shifts = &hwseq_shift; 575 hws->masks = &hwseq_mask; 576 } 577 return hws; 578 } 579 580 static const struct resource_create_funcs res_create_funcs = { 581 .read_dce_straps = read_dce_straps, 582 .create_audio = create_audio, 583 .create_stream_encoder = dce80_stream_encoder_create, 584 .create_hwseq = dce80_hwseq_create, 585 }; 586 587 #define mi_inst_regs(id) { \ 588 MI_DCE8_REG_LIST(id), \ 589 .MC_HUB_RDREQ_DMIF_LIMIT = mmMC_HUB_RDREQ_DMIF_LIMIT \ 590 } 591 static const struct dce_mem_input_registers mi_regs[] = { 592 mi_inst_regs(0), 593 mi_inst_regs(1), 594 mi_inst_regs(2), 595 mi_inst_regs(3), 596 mi_inst_regs(4), 597 mi_inst_regs(5), 598 }; 599 600 static const struct dce_mem_input_shift mi_shifts = { 601 MI_DCE8_MASK_SH_LIST(__SHIFT), 602 .ENABLE = MC_HUB_RDREQ_DMIF_LIMIT__ENABLE__SHIFT 603 }; 604 605 static const struct dce_mem_input_mask mi_masks = { 606 MI_DCE8_MASK_SH_LIST(_MASK), 607 .ENABLE = MC_HUB_RDREQ_DMIF_LIMIT__ENABLE_MASK 608 }; 609 610 static struct mem_input *dce80_mem_input_create( 611 struct dc_context *ctx, 612 uint32_t inst) 613 { 614 struct dce_mem_input *dce_mi = kzalloc(sizeof(struct dce_mem_input), 615 GFP_KERNEL); 616 617 if (!dce_mi) { 618 BREAK_TO_DEBUGGER(); 619 return NULL; 620 } 621 622 dce_mem_input_construct(dce_mi, ctx, inst, &mi_regs[inst], &mi_shifts, &mi_masks); 623 dce_mi->wa.single_head_rdreq_dmif_limit = 2; 624 return &dce_mi->base; 625 } 626 627 static void dce80_transform_destroy(struct transform **xfm) 628 { 629 kfree(TO_DCE_TRANSFORM(*xfm)); 630 *xfm = NULL; 631 } 632 633 static struct transform *dce80_transform_create( 634 struct dc_context *ctx, 635 uint32_t inst) 636 { 637 struct dce_transform *transform = 638 kzalloc(sizeof(struct dce_transform), GFP_KERNEL); 639 640 if (!transform) 641 return NULL; 642 643 dce_transform_construct(transform, ctx, inst, 644 &xfm_regs[inst], &xfm_shift, &xfm_mask); 645 transform->prescaler_on = false; 646 return &transform->base; 647 } 648 649 static const struct encoder_feature_support link_enc_feature = { 650 .max_hdmi_deep_color = COLOR_DEPTH_121212, 651 .max_hdmi_pixel_clock = 297000, 652 .flags.bits.IS_HBR2_CAPABLE = true, 653 .flags.bits.IS_TPS3_CAPABLE = true 654 }; 655 656 struct link_encoder *dce80_link_encoder_create( 657 const struct encoder_init_data *enc_init_data) 658 { 659 struct dce110_link_encoder *enc110 = 660 kzalloc(sizeof(struct dce110_link_encoder), GFP_KERNEL); 661 662 if (!enc110) 663 return NULL; 664 665 dce110_link_encoder_construct(enc110, 666 enc_init_data, 667 &link_enc_feature, 668 &link_enc_regs[enc_init_data->transmitter], 669 &link_enc_aux_regs[enc_init_data->channel - 1], 670 &link_enc_hpd_regs[enc_init_data->hpd_source]); 671 return &enc110->base; 672 } 673 674 struct clock_source *dce80_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 kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL); 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 dce80_clock_source_destroy(struct clock_source **clk_src) 698 { 699 kfree(TO_DCE110_CLK_SRC(*clk_src)); 700 *clk_src = NULL; 701 } 702 703 static struct input_pixel_processor *dce80_ipp_create( 704 struct dc_context *ctx, uint32_t inst) 705 { 706 struct dce_ipp *ipp = kzalloc(sizeof(struct dce_ipp), GFP_KERNEL); 707 708 if (!ipp) { 709 BREAK_TO_DEBUGGER(); 710 return NULL; 711 } 712 713 dce_ipp_construct(ipp, ctx, inst, 714 &ipp_regs[inst], &ipp_shift, &ipp_mask); 715 return &ipp->base; 716 } 717 718 static void destruct(struct dce110_resource_pool *pool) 719 { 720 unsigned int i; 721 722 for (i = 0; i < pool->base.pipe_count; i++) { 723 if (pool->base.opps[i] != NULL) 724 dce110_opp_destroy(&pool->base.opps[i]); 725 726 if (pool->base.transforms[i] != NULL) 727 dce80_transform_destroy(&pool->base.transforms[i]); 728 729 if (pool->base.ipps[i] != NULL) 730 dce_ipp_destroy(&pool->base.ipps[i]); 731 732 if (pool->base.mis[i] != NULL) { 733 kfree(TO_DCE_MEM_INPUT(pool->base.mis[i])); 734 pool->base.mis[i] = NULL; 735 } 736 737 if (pool->base.timing_generators[i] != NULL) { 738 kfree(DCE110TG_FROM_TG(pool->base.timing_generators[i])); 739 pool->base.timing_generators[i] = NULL; 740 } 741 } 742 743 for (i = 0; i < pool->base.res_cap->num_ddc; i++) { 744 if (pool->base.engines[i] != NULL) 745 dce110_engine_destroy(&pool->base.engines[i]); 746 if (pool->base.hw_i2cs[i] != NULL) { 747 kfree(pool->base.hw_i2cs[i]); 748 pool->base.hw_i2cs[i] = NULL; 749 } 750 if (pool->base.sw_i2cs[i] != NULL) { 751 kfree(pool->base.sw_i2cs[i]); 752 pool->base.sw_i2cs[i] = NULL; 753 } 754 } 755 756 for (i = 0; i < pool->base.stream_enc_count; i++) { 757 if (pool->base.stream_enc[i] != NULL) 758 kfree(DCE110STRENC_FROM_STRENC(pool->base.stream_enc[i])); 759 } 760 761 for (i = 0; i < pool->base.clk_src_count; i++) { 762 if (pool->base.clock_sources[i] != NULL) { 763 dce80_clock_source_destroy(&pool->base.clock_sources[i]); 764 } 765 } 766 767 if (pool->base.abm != NULL) 768 dce_abm_destroy(&pool->base.abm); 769 770 if (pool->base.dmcu != NULL) 771 dce_dmcu_destroy(&pool->base.dmcu); 772 773 if (pool->base.dp_clock_source != NULL) 774 dce80_clock_source_destroy(&pool->base.dp_clock_source); 775 776 for (i = 0; i < pool->base.audio_count; i++) { 777 if (pool->base.audios[i] != NULL) { 778 dce_aud_destroy(&pool->base.audios[i]); 779 } 780 } 781 782 if (pool->base.clk_mgr != NULL) 783 dce_clk_mgr_destroy(&pool->base.clk_mgr); 784 785 if (pool->base.irqs != NULL) { 786 dal_irq_service_destroy(&pool->base.irqs); 787 } 788 } 789 790 bool dce80_validate_bandwidth( 791 struct dc *dc, 792 struct dc_state *context) 793 { 794 /* TODO implement when needed but for now hardcode max value*/ 795 context->bw.dce.dispclk_khz = 681000; 796 context->bw.dce.yclk_khz = 250000 * MEMORY_TYPE_MULTIPLIER_CZ; 797 798 return true; 799 } 800 801 static bool dce80_validate_surface_sets( 802 struct dc_state *context) 803 { 804 int i; 805 806 for (i = 0; i < context->stream_count; i++) { 807 if (context->stream_status[i].plane_count == 0) 808 continue; 809 810 if (context->stream_status[i].plane_count > 1) 811 return false; 812 813 if (context->stream_status[i].plane_states[0]->format 814 >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) 815 return false; 816 } 817 818 return true; 819 } 820 821 enum dc_status dce80_validate_global( 822 struct dc *dc, 823 struct dc_state *context) 824 { 825 if (!dce80_validate_surface_sets(context)) 826 return DC_FAIL_SURFACE_VALIDATE; 827 828 return DC_OK; 829 } 830 831 static void dce80_destroy_resource_pool(struct resource_pool **pool) 832 { 833 struct dce110_resource_pool *dce110_pool = TO_DCE110_RES_POOL(*pool); 834 835 destruct(dce110_pool); 836 kfree(dce110_pool); 837 *pool = NULL; 838 } 839 840 static const struct resource_funcs dce80_res_pool_funcs = { 841 .destroy = dce80_destroy_resource_pool, 842 .link_enc_create = dce80_link_encoder_create, 843 .validate_bandwidth = dce80_validate_bandwidth, 844 .validate_plane = dce100_validate_plane, 845 .add_stream_to_ctx = dce100_add_stream_to_ctx, 846 .validate_global = dce80_validate_global 847 }; 848 849 static bool dce80_construct( 850 uint8_t num_virtual_links, 851 struct dc *dc, 852 struct dce110_resource_pool *pool) 853 { 854 unsigned int i; 855 struct dc_context *ctx = dc->ctx; 856 struct dc_firmware_info info; 857 struct dc_bios *bp; 858 859 ctx->dc_bios->regs = &bios_regs; 860 861 pool->base.res_cap = &res_cap; 862 pool->base.funcs = &dce80_res_pool_funcs; 863 864 865 /************************************************* 866 * Resource + asic cap harcoding * 867 *************************************************/ 868 pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE; 869 pool->base.pipe_count = res_cap.num_timing_generator; 870 pool->base.timing_generator_count = res_cap.num_timing_generator; 871 dc->caps.max_downscale_ratio = 200; 872 dc->caps.i2c_speed_in_khz = 40; 873 dc->caps.max_cursor_size = 128; 874 dc->caps.dual_link_dvi = true; 875 876 /************************************************* 877 * Create resources * 878 *************************************************/ 879 880 bp = ctx->dc_bios; 881 882 if ((bp->funcs->get_firmware_info(bp, &info) == BP_RESULT_OK) && 883 info.external_clock_source_frequency_for_dp != 0) { 884 pool->base.dp_clock_source = 885 dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_EXTERNAL, NULL, true); 886 887 pool->base.clock_sources[0] = 888 dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL0, &clk_src_regs[0], false); 889 pool->base.clock_sources[1] = 890 dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[1], false); 891 pool->base.clock_sources[2] = 892 dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL2, &clk_src_regs[2], false); 893 pool->base.clk_src_count = 3; 894 895 } else { 896 pool->base.dp_clock_source = 897 dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL0, &clk_src_regs[0], true); 898 899 pool->base.clock_sources[0] = 900 dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[1], false); 901 pool->base.clock_sources[1] = 902 dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL2, &clk_src_regs[2], false); 903 pool->base.clk_src_count = 2; 904 } 905 906 if (pool->base.dp_clock_source == NULL) { 907 dm_error("DC: failed to create dp clock source!\n"); 908 BREAK_TO_DEBUGGER(); 909 goto res_create_fail; 910 } 911 912 for (i = 0; i < pool->base.clk_src_count; i++) { 913 if (pool->base.clock_sources[i] == NULL) { 914 dm_error("DC: failed to create clock sources!\n"); 915 BREAK_TO_DEBUGGER(); 916 goto res_create_fail; 917 } 918 } 919 920 pool->base.clk_mgr = dce_clk_mgr_create(ctx, 921 &disp_clk_regs, 922 &disp_clk_shift, 923 &disp_clk_mask); 924 if (pool->base.clk_mgr == NULL) { 925 dm_error("DC: failed to create display clock!\n"); 926 BREAK_TO_DEBUGGER(); 927 goto res_create_fail; 928 } 929 930 pool->base.dmcu = dce_dmcu_create(ctx, 931 &dmcu_regs, 932 &dmcu_shift, 933 &dmcu_mask); 934 if (pool->base.dmcu == NULL) { 935 dm_error("DC: failed to create dmcu!\n"); 936 BREAK_TO_DEBUGGER(); 937 goto res_create_fail; 938 } 939 940 pool->base.abm = dce_abm_create(ctx, 941 &abm_regs, 942 &abm_shift, 943 &abm_mask); 944 if (pool->base.abm == NULL) { 945 dm_error("DC: failed to create abm!\n"); 946 BREAK_TO_DEBUGGER(); 947 goto res_create_fail; 948 } 949 950 { 951 struct irq_service_init_data init_data; 952 init_data.ctx = dc->ctx; 953 pool->base.irqs = dal_irq_service_dce80_create(&init_data); 954 if (!pool->base.irqs) 955 goto res_create_fail; 956 } 957 958 for (i = 0; i < pool->base.pipe_count; i++) { 959 pool->base.timing_generators[i] = dce80_timing_generator_create( 960 ctx, i, &dce80_tg_offsets[i]); 961 if (pool->base.timing_generators[i] == NULL) { 962 BREAK_TO_DEBUGGER(); 963 dm_error("DC: failed to create tg!\n"); 964 goto res_create_fail; 965 } 966 967 pool->base.mis[i] = dce80_mem_input_create(ctx, i); 968 if (pool->base.mis[i] == NULL) { 969 BREAK_TO_DEBUGGER(); 970 dm_error("DC: failed to create memory input!\n"); 971 goto res_create_fail; 972 } 973 974 pool->base.ipps[i] = dce80_ipp_create(ctx, i); 975 if (pool->base.ipps[i] == NULL) { 976 BREAK_TO_DEBUGGER(); 977 dm_error("DC: failed to create input pixel processor!\n"); 978 goto res_create_fail; 979 } 980 981 pool->base.transforms[i] = dce80_transform_create(ctx, i); 982 if (pool->base.transforms[i] == NULL) { 983 BREAK_TO_DEBUGGER(); 984 dm_error("DC: failed to create transform!\n"); 985 goto res_create_fail; 986 } 987 988 pool->base.opps[i] = dce80_opp_create(ctx, i); 989 if (pool->base.opps[i] == NULL) { 990 BREAK_TO_DEBUGGER(); 991 dm_error("DC: failed to create output pixel processor!\n"); 992 goto res_create_fail; 993 } 994 } 995 996 for (i = 0; i < pool->base.res_cap->num_ddc; i++) { 997 pool->base.engines[i] = dce80_aux_engine_create(ctx, i); 998 if (pool->base.engines[i] == NULL) { 999 BREAK_TO_DEBUGGER(); 1000 dm_error( 1001 "DC:failed to create aux engine!!\n"); 1002 goto res_create_fail; 1003 } 1004 pool->base.hw_i2cs[i] = dce80_i2c_hw_create(ctx, i); 1005 if (pool->base.hw_i2cs[i] == NULL) { 1006 BREAK_TO_DEBUGGER(); 1007 dm_error( 1008 "DC:failed to create i2c engine!!\n"); 1009 goto res_create_fail; 1010 } 1011 pool->base.sw_i2cs[i] = dce80_i2c_sw_create(ctx); 1012 if (pool->base.sw_i2cs[i] == NULL) { 1013 BREAK_TO_DEBUGGER(); 1014 dm_error( 1015 "DC:failed to create sw i2c!!\n"); 1016 goto res_create_fail; 1017 } 1018 } 1019 1020 dc->caps.max_planes = pool->base.pipe_count; 1021 dc->caps.disable_dp_clk_share = true; 1022 1023 if (!resource_construct(num_virtual_links, dc, &pool->base, 1024 &res_create_funcs)) 1025 goto res_create_fail; 1026 1027 /* Create hardware sequencer */ 1028 dce80_hw_sequencer_construct(dc); 1029 1030 return true; 1031 1032 res_create_fail: 1033 destruct(pool); 1034 return false; 1035 } 1036 1037 struct resource_pool *dce80_create_resource_pool( 1038 uint8_t num_virtual_links, 1039 struct dc *dc) 1040 { 1041 struct dce110_resource_pool *pool = 1042 kzalloc(sizeof(struct dce110_resource_pool), GFP_KERNEL); 1043 1044 if (!pool) 1045 return NULL; 1046 1047 if (dce80_construct(num_virtual_links, dc, pool)) 1048 return &pool->base; 1049 1050 BREAK_TO_DEBUGGER(); 1051 return NULL; 1052 } 1053 1054 static bool dce81_construct( 1055 uint8_t num_virtual_links, 1056 struct dc *dc, 1057 struct dce110_resource_pool *pool) 1058 { 1059 unsigned int i; 1060 struct dc_context *ctx = dc->ctx; 1061 struct dc_firmware_info info; 1062 struct dc_bios *bp; 1063 1064 ctx->dc_bios->regs = &bios_regs; 1065 1066 pool->base.res_cap = &res_cap_81; 1067 pool->base.funcs = &dce80_res_pool_funcs; 1068 1069 1070 /************************************************* 1071 * Resource + asic cap harcoding * 1072 *************************************************/ 1073 pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE; 1074 pool->base.pipe_count = res_cap_81.num_timing_generator; 1075 pool->base.timing_generator_count = res_cap_81.num_timing_generator; 1076 dc->caps.max_downscale_ratio = 200; 1077 dc->caps.i2c_speed_in_khz = 40; 1078 dc->caps.max_cursor_size = 128; 1079 dc->caps.is_apu = true; 1080 1081 /************************************************* 1082 * Create resources * 1083 *************************************************/ 1084 1085 bp = ctx->dc_bios; 1086 1087 if ((bp->funcs->get_firmware_info(bp, &info) == BP_RESULT_OK) && 1088 info.external_clock_source_frequency_for_dp != 0) { 1089 pool->base.dp_clock_source = 1090 dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_EXTERNAL, NULL, true); 1091 1092 pool->base.clock_sources[0] = 1093 dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL0, &clk_src_regs[0], false); 1094 pool->base.clock_sources[1] = 1095 dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[1], false); 1096 pool->base.clock_sources[2] = 1097 dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL2, &clk_src_regs[2], false); 1098 pool->base.clk_src_count = 3; 1099 1100 } else { 1101 pool->base.dp_clock_source = 1102 dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL0, &clk_src_regs[0], true); 1103 1104 pool->base.clock_sources[0] = 1105 dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[1], false); 1106 pool->base.clock_sources[1] = 1107 dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL2, &clk_src_regs[2], false); 1108 pool->base.clk_src_count = 2; 1109 } 1110 1111 if (pool->base.dp_clock_source == NULL) { 1112 dm_error("DC: failed to create dp clock source!\n"); 1113 BREAK_TO_DEBUGGER(); 1114 goto res_create_fail; 1115 } 1116 1117 for (i = 0; i < pool->base.clk_src_count; i++) { 1118 if (pool->base.clock_sources[i] == NULL) { 1119 dm_error("DC: failed to create clock sources!\n"); 1120 BREAK_TO_DEBUGGER(); 1121 goto res_create_fail; 1122 } 1123 } 1124 1125 pool->base.clk_mgr = dce_clk_mgr_create(ctx, 1126 &disp_clk_regs, 1127 &disp_clk_shift, 1128 &disp_clk_mask); 1129 if (pool->base.clk_mgr == NULL) { 1130 dm_error("DC: failed to create display clock!\n"); 1131 BREAK_TO_DEBUGGER(); 1132 goto res_create_fail; 1133 } 1134 1135 pool->base.dmcu = dce_dmcu_create(ctx, 1136 &dmcu_regs, 1137 &dmcu_shift, 1138 &dmcu_mask); 1139 if (pool->base.dmcu == NULL) { 1140 dm_error("DC: failed to create dmcu!\n"); 1141 BREAK_TO_DEBUGGER(); 1142 goto res_create_fail; 1143 } 1144 1145 pool->base.abm = dce_abm_create(ctx, 1146 &abm_regs, 1147 &abm_shift, 1148 &abm_mask); 1149 if (pool->base.abm == NULL) { 1150 dm_error("DC: failed to create abm!\n"); 1151 BREAK_TO_DEBUGGER(); 1152 goto res_create_fail; 1153 } 1154 1155 { 1156 struct irq_service_init_data init_data; 1157 init_data.ctx = dc->ctx; 1158 pool->base.irqs = dal_irq_service_dce80_create(&init_data); 1159 if (!pool->base.irqs) 1160 goto res_create_fail; 1161 } 1162 1163 for (i = 0; i < pool->base.pipe_count; i++) { 1164 pool->base.timing_generators[i] = dce80_timing_generator_create( 1165 ctx, i, &dce80_tg_offsets[i]); 1166 if (pool->base.timing_generators[i] == NULL) { 1167 BREAK_TO_DEBUGGER(); 1168 dm_error("DC: failed to create tg!\n"); 1169 goto res_create_fail; 1170 } 1171 1172 pool->base.mis[i] = dce80_mem_input_create(ctx, i); 1173 if (pool->base.mis[i] == NULL) { 1174 BREAK_TO_DEBUGGER(); 1175 dm_error("DC: failed to create memory input!\n"); 1176 goto res_create_fail; 1177 } 1178 1179 pool->base.ipps[i] = dce80_ipp_create(ctx, i); 1180 if (pool->base.ipps[i] == NULL) { 1181 BREAK_TO_DEBUGGER(); 1182 dm_error("DC: failed to create input pixel processor!\n"); 1183 goto res_create_fail; 1184 } 1185 1186 pool->base.transforms[i] = dce80_transform_create(ctx, i); 1187 if (pool->base.transforms[i] == NULL) { 1188 BREAK_TO_DEBUGGER(); 1189 dm_error("DC: failed to create transform!\n"); 1190 goto res_create_fail; 1191 } 1192 1193 pool->base.opps[i] = dce80_opp_create(ctx, i); 1194 if (pool->base.opps[i] == NULL) { 1195 BREAK_TO_DEBUGGER(); 1196 dm_error("DC: failed to create output pixel processor!\n"); 1197 goto res_create_fail; 1198 } 1199 } 1200 1201 for (i = 0; i < pool->base.res_cap->num_ddc; i++) { 1202 pool->base.engines[i] = dce80_aux_engine_create(ctx, i); 1203 if (pool->base.engines[i] == NULL) { 1204 BREAK_TO_DEBUGGER(); 1205 dm_error( 1206 "DC:failed to create aux engine!!\n"); 1207 goto res_create_fail; 1208 } 1209 pool->base.hw_i2cs[i] = dce80_i2c_hw_create(ctx, i); 1210 if (pool->base.hw_i2cs[i] == NULL) { 1211 BREAK_TO_DEBUGGER(); 1212 dm_error( 1213 "DC:failed to create i2c engine!!\n"); 1214 goto res_create_fail; 1215 } 1216 pool->base.sw_i2cs[i] = dce80_i2c_sw_create(ctx); 1217 if (pool->base.sw_i2cs[i] == NULL) { 1218 BREAK_TO_DEBUGGER(); 1219 dm_error( 1220 "DC:failed to create sw i2c!!\n"); 1221 goto res_create_fail; 1222 } 1223 } 1224 1225 dc->caps.max_planes = pool->base.pipe_count; 1226 dc->caps.disable_dp_clk_share = true; 1227 1228 if (!resource_construct(num_virtual_links, dc, &pool->base, 1229 &res_create_funcs)) 1230 goto res_create_fail; 1231 1232 /* Create hardware sequencer */ 1233 dce80_hw_sequencer_construct(dc); 1234 1235 return true; 1236 1237 res_create_fail: 1238 destruct(pool); 1239 return false; 1240 } 1241 1242 struct resource_pool *dce81_create_resource_pool( 1243 uint8_t num_virtual_links, 1244 struct dc *dc) 1245 { 1246 struct dce110_resource_pool *pool = 1247 kzalloc(sizeof(struct dce110_resource_pool), GFP_KERNEL); 1248 1249 if (!pool) 1250 return NULL; 1251 1252 if (dce81_construct(num_virtual_links, dc, pool)) 1253 return &pool->base; 1254 1255 BREAK_TO_DEBUGGER(); 1256 return NULL; 1257 } 1258 1259 static bool dce83_construct( 1260 uint8_t num_virtual_links, 1261 struct dc *dc, 1262 struct dce110_resource_pool *pool) 1263 { 1264 unsigned int i; 1265 struct dc_context *ctx = dc->ctx; 1266 struct dc_firmware_info info; 1267 struct dc_bios *bp; 1268 1269 ctx->dc_bios->regs = &bios_regs; 1270 1271 pool->base.res_cap = &res_cap_83; 1272 pool->base.funcs = &dce80_res_pool_funcs; 1273 1274 1275 /************************************************* 1276 * Resource + asic cap harcoding * 1277 *************************************************/ 1278 pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE; 1279 pool->base.pipe_count = res_cap_83.num_timing_generator; 1280 pool->base.timing_generator_count = res_cap_83.num_timing_generator; 1281 dc->caps.max_downscale_ratio = 200; 1282 dc->caps.i2c_speed_in_khz = 40; 1283 dc->caps.max_cursor_size = 128; 1284 dc->caps.is_apu = true; 1285 1286 /************************************************* 1287 * Create resources * 1288 *************************************************/ 1289 1290 bp = ctx->dc_bios; 1291 1292 if ((bp->funcs->get_firmware_info(bp, &info) == BP_RESULT_OK) && 1293 info.external_clock_source_frequency_for_dp != 0) { 1294 pool->base.dp_clock_source = 1295 dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_EXTERNAL, NULL, true); 1296 1297 pool->base.clock_sources[0] = 1298 dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[0], false); 1299 pool->base.clock_sources[1] = 1300 dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL2, &clk_src_regs[1], false); 1301 pool->base.clk_src_count = 2; 1302 1303 } else { 1304 pool->base.dp_clock_source = 1305 dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[0], true); 1306 1307 pool->base.clock_sources[0] = 1308 dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL2, &clk_src_regs[1], false); 1309 pool->base.clk_src_count = 1; 1310 } 1311 1312 if (pool->base.dp_clock_source == NULL) { 1313 dm_error("DC: failed to create dp clock source!\n"); 1314 BREAK_TO_DEBUGGER(); 1315 goto res_create_fail; 1316 } 1317 1318 for (i = 0; i < pool->base.clk_src_count; i++) { 1319 if (pool->base.clock_sources[i] == NULL) { 1320 dm_error("DC: failed to create clock sources!\n"); 1321 BREAK_TO_DEBUGGER(); 1322 goto res_create_fail; 1323 } 1324 } 1325 1326 pool->base.clk_mgr = dce_clk_mgr_create(ctx, 1327 &disp_clk_regs, 1328 &disp_clk_shift, 1329 &disp_clk_mask); 1330 if (pool->base.clk_mgr == NULL) { 1331 dm_error("DC: failed to create display clock!\n"); 1332 BREAK_TO_DEBUGGER(); 1333 goto res_create_fail; 1334 } 1335 1336 pool->base.dmcu = dce_dmcu_create(ctx, 1337 &dmcu_regs, 1338 &dmcu_shift, 1339 &dmcu_mask); 1340 if (pool->base.dmcu == NULL) { 1341 dm_error("DC: failed to create dmcu!\n"); 1342 BREAK_TO_DEBUGGER(); 1343 goto res_create_fail; 1344 } 1345 1346 pool->base.abm = dce_abm_create(ctx, 1347 &abm_regs, 1348 &abm_shift, 1349 &abm_mask); 1350 if (pool->base.abm == NULL) { 1351 dm_error("DC: failed to create abm!\n"); 1352 BREAK_TO_DEBUGGER(); 1353 goto res_create_fail; 1354 } 1355 1356 { 1357 struct irq_service_init_data init_data; 1358 init_data.ctx = dc->ctx; 1359 pool->base.irqs = dal_irq_service_dce80_create(&init_data); 1360 if (!pool->base.irqs) 1361 goto res_create_fail; 1362 } 1363 1364 for (i = 0; i < pool->base.pipe_count; i++) { 1365 pool->base.timing_generators[i] = dce80_timing_generator_create( 1366 ctx, i, &dce80_tg_offsets[i]); 1367 if (pool->base.timing_generators[i] == NULL) { 1368 BREAK_TO_DEBUGGER(); 1369 dm_error("DC: failed to create tg!\n"); 1370 goto res_create_fail; 1371 } 1372 1373 pool->base.mis[i] = dce80_mem_input_create(ctx, i); 1374 if (pool->base.mis[i] == NULL) { 1375 BREAK_TO_DEBUGGER(); 1376 dm_error("DC: failed to create memory input!\n"); 1377 goto res_create_fail; 1378 } 1379 1380 pool->base.ipps[i] = dce80_ipp_create(ctx, i); 1381 if (pool->base.ipps[i] == NULL) { 1382 BREAK_TO_DEBUGGER(); 1383 dm_error("DC: failed to create input pixel processor!\n"); 1384 goto res_create_fail; 1385 } 1386 1387 pool->base.transforms[i] = dce80_transform_create(ctx, i); 1388 if (pool->base.transforms[i] == NULL) { 1389 BREAK_TO_DEBUGGER(); 1390 dm_error("DC: failed to create transform!\n"); 1391 goto res_create_fail; 1392 } 1393 1394 pool->base.opps[i] = dce80_opp_create(ctx, i); 1395 if (pool->base.opps[i] == NULL) { 1396 BREAK_TO_DEBUGGER(); 1397 dm_error("DC: failed to create output pixel processor!\n"); 1398 goto res_create_fail; 1399 } 1400 } 1401 1402 for (i = 0; i < pool->base.res_cap->num_ddc; i++) { 1403 pool->base.engines[i] = dce80_aux_engine_create(ctx, i); 1404 if (pool->base.engines[i] == NULL) { 1405 BREAK_TO_DEBUGGER(); 1406 dm_error( 1407 "DC:failed to create aux engine!!\n"); 1408 goto res_create_fail; 1409 } 1410 pool->base.hw_i2cs[i] = dce80_i2c_hw_create(ctx, i); 1411 if (pool->base.hw_i2cs[i] == NULL) { 1412 BREAK_TO_DEBUGGER(); 1413 dm_error( 1414 "DC:failed to create i2c engine!!\n"); 1415 goto res_create_fail; 1416 } 1417 pool->base.sw_i2cs[i] = dce80_i2c_sw_create(ctx); 1418 if (pool->base.sw_i2cs[i] == NULL) { 1419 BREAK_TO_DEBUGGER(); 1420 dm_error( 1421 "DC:failed to create sw i2c!!\n"); 1422 goto res_create_fail; 1423 } 1424 } 1425 1426 dc->caps.max_planes = pool->base.pipe_count; 1427 dc->caps.disable_dp_clk_share = true; 1428 1429 if (!resource_construct(num_virtual_links, dc, &pool->base, 1430 &res_create_funcs)) 1431 goto res_create_fail; 1432 1433 /* Create hardware sequencer */ 1434 dce80_hw_sequencer_construct(dc); 1435 1436 return true; 1437 1438 res_create_fail: 1439 destruct(pool); 1440 return false; 1441 } 1442 1443 struct resource_pool *dce83_create_resource_pool( 1444 uint8_t num_virtual_links, 1445 struct dc *dc) 1446 { 1447 struct dce110_resource_pool *pool = 1448 kzalloc(sizeof(struct dce110_resource_pool), GFP_KERNEL); 1449 1450 if (!pool) 1451 return NULL; 1452 1453 if (dce83_construct(num_virtual_links, dc, pool)) 1454 return &pool->base; 1455 1456 BREAK_TO_DEBUGGER(); 1457 return NULL; 1458 } 1459