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 #include "dm_services.h" 26 27 #include "link_encoder.h" 28 #include "stream_encoder.h" 29 30 #include "resource.h" 31 #include "include/irq_service_interface.h" 32 #include "../virtual/virtual_stream_encoder.h" 33 #include "dce110/dce110_resource.h" 34 #include "dce110/dce110_timing_generator.h" 35 #include "irq/dce110/irq_service_dce110.h" 36 #include "dce/dce_link_encoder.h" 37 #include "dce/dce_stream_encoder.h" 38 #include "dce110/dce110_mem_input.h" 39 #include "dce110/dce110_mem_input_v.h" 40 #include "dce110/dce110_ipp.h" 41 #include "dce/dce_transform.h" 42 #include "dce/dce_opp.h" 43 #include "dce/dce_clocks.h" 44 #include "dce/dce_clock_source.h" 45 #include "dce/dce_audio.h" 46 #include "dce/dce_hwseq.h" 47 #include "dce100/dce100_hw_sequencer.h" 48 49 #include "reg_helper.h" 50 51 #include "dce/dce_10_0_d.h" 52 #include "dce/dce_10_0_sh_mask.h" 53 54 #ifndef mmMC_HUB_RDREQ_DMIF_LIMIT 55 #include "gmc/gmc_8_2_d.h" 56 #include "gmc/gmc_8_2_sh_mask.h" 57 #endif 58 59 #ifndef mmDP_DPHY_INTERNAL_CTRL 60 #define mmDP_DPHY_INTERNAL_CTRL 0x4aa7 61 #define mmDP0_DP_DPHY_INTERNAL_CTRL 0x4aa7 62 #define mmDP1_DP_DPHY_INTERNAL_CTRL 0x4ba7 63 #define mmDP2_DP_DPHY_INTERNAL_CTRL 0x4ca7 64 #define mmDP3_DP_DPHY_INTERNAL_CTRL 0x4da7 65 #define mmDP4_DP_DPHY_INTERNAL_CTRL 0x4ea7 66 #define mmDP5_DP_DPHY_INTERNAL_CTRL 0x4fa7 67 #define mmDP6_DP_DPHY_INTERNAL_CTRL 0x54a7 68 #define mmDP7_DP_DPHY_INTERNAL_CTRL 0x56a7 69 #define mmDP8_DP_DPHY_INTERNAL_CTRL 0x57a7 70 #endif 71 72 #ifndef mmBIOS_SCRATCH_2 73 #define mmBIOS_SCRATCH_2 0x05CB 74 #define mmBIOS_SCRATCH_6 0x05CF 75 #endif 76 77 #ifndef mmDP_DPHY_BS_SR_SWAP_CNTL 78 #define mmDP_DPHY_BS_SR_SWAP_CNTL 0x4ADC 79 #define mmDP0_DP_DPHY_BS_SR_SWAP_CNTL 0x4ADC 80 #define mmDP1_DP_DPHY_BS_SR_SWAP_CNTL 0x4BDC 81 #define mmDP2_DP_DPHY_BS_SR_SWAP_CNTL 0x4CDC 82 #define mmDP3_DP_DPHY_BS_SR_SWAP_CNTL 0x4DDC 83 #define mmDP4_DP_DPHY_BS_SR_SWAP_CNTL 0x4EDC 84 #define mmDP5_DP_DPHY_BS_SR_SWAP_CNTL 0x4FDC 85 #define mmDP6_DP_DPHY_BS_SR_SWAP_CNTL 0x54DC 86 #endif 87 88 #ifndef mmDP_DPHY_FAST_TRAINING 89 #define mmDP_DPHY_FAST_TRAINING 0x4ABC 90 #define mmDP0_DP_DPHY_FAST_TRAINING 0x4ABC 91 #define mmDP1_DP_DPHY_FAST_TRAINING 0x4BBC 92 #define mmDP2_DP_DPHY_FAST_TRAINING 0x4CBC 93 #define mmDP3_DP_DPHY_FAST_TRAINING 0x4DBC 94 #define mmDP4_DP_DPHY_FAST_TRAINING 0x4EBC 95 #define mmDP5_DP_DPHY_FAST_TRAINING 0x4FBC 96 #define mmDP6_DP_DPHY_FAST_TRAINING 0x54BC 97 #endif 98 99 static const struct dce110_timing_generator_offsets dce100_tg_offsets[] = { 100 { 101 .crtc = (mmCRTC0_CRTC_CONTROL - mmCRTC_CONTROL), 102 .dcp = (mmDCP0_GRPH_CONTROL - mmGRPH_CONTROL), 103 }, 104 { 105 .crtc = (mmCRTC1_CRTC_CONTROL - mmCRTC_CONTROL), 106 .dcp = (mmDCP1_GRPH_CONTROL - mmGRPH_CONTROL), 107 }, 108 { 109 .crtc = (mmCRTC2_CRTC_CONTROL - mmCRTC_CONTROL), 110 .dcp = (mmDCP2_GRPH_CONTROL - mmGRPH_CONTROL), 111 }, 112 { 113 .crtc = (mmCRTC3_CRTC_CONTROL - mmCRTC_CONTROL), 114 .dcp = (mmDCP3_GRPH_CONTROL - mmGRPH_CONTROL), 115 }, 116 { 117 .crtc = (mmCRTC4_CRTC_CONTROL - mmCRTC_CONTROL), 118 .dcp = (mmDCP4_GRPH_CONTROL - mmGRPH_CONTROL), 119 }, 120 { 121 .crtc = (mmCRTC5_CRTC_CONTROL - mmCRTC_CONTROL), 122 .dcp = (mmDCP5_GRPH_CONTROL - mmGRPH_CONTROL), 123 } 124 }; 125 126 static const struct dce110_mem_input_reg_offsets dce100_mi_reg_offsets[] = { 127 { 128 .dcp = (mmDCP0_GRPH_CONTROL - mmGRPH_CONTROL), 129 .dmif = (mmDMIF_PG0_DPG_WATERMARK_MASK_CONTROL 130 - mmDPG_WATERMARK_MASK_CONTROL), 131 .pipe = (mmPIPE0_DMIF_BUFFER_CONTROL 132 - mmPIPE0_DMIF_BUFFER_CONTROL), 133 }, 134 { 135 .dcp = (mmDCP1_GRPH_CONTROL - mmGRPH_CONTROL), 136 .dmif = (mmDMIF_PG1_DPG_WATERMARK_MASK_CONTROL 137 - mmDPG_WATERMARK_MASK_CONTROL), 138 .pipe = (mmPIPE1_DMIF_BUFFER_CONTROL 139 - mmPIPE0_DMIF_BUFFER_CONTROL), 140 }, 141 { 142 .dcp = (mmDCP2_GRPH_CONTROL - mmGRPH_CONTROL), 143 .dmif = (mmDMIF_PG2_DPG_WATERMARK_MASK_CONTROL 144 - mmDPG_WATERMARK_MASK_CONTROL), 145 .pipe = (mmPIPE2_DMIF_BUFFER_CONTROL 146 - mmPIPE0_DMIF_BUFFER_CONTROL), 147 }, 148 { 149 .dcp = (mmDCP3_GRPH_CONTROL - mmGRPH_CONTROL), 150 .dmif = (mmDMIF_PG3_DPG_WATERMARK_MASK_CONTROL 151 - mmDPG_WATERMARK_MASK_CONTROL), 152 .pipe = (mmPIPE3_DMIF_BUFFER_CONTROL 153 - mmPIPE0_DMIF_BUFFER_CONTROL), 154 }, 155 { 156 .dcp = (mmDCP4_GRPH_CONTROL - mmGRPH_CONTROL), 157 .dmif = (mmDMIF_PG4_DPG_WATERMARK_MASK_CONTROL 158 - mmDPG_WATERMARK_MASK_CONTROL), 159 .pipe = (mmPIPE4_DMIF_BUFFER_CONTROL 160 - mmPIPE0_DMIF_BUFFER_CONTROL), 161 }, 162 { 163 .dcp = (mmDCP5_GRPH_CONTROL - mmGRPH_CONTROL), 164 .dmif = (mmDMIF_PG5_DPG_WATERMARK_MASK_CONTROL 165 - mmDPG_WATERMARK_MASK_CONTROL), 166 .pipe = (mmPIPE5_DMIF_BUFFER_CONTROL 167 - mmPIPE0_DMIF_BUFFER_CONTROL), 168 } 169 }; 170 171 172 static const struct dce110_ipp_reg_offsets dce100_ipp_reg_offsets[] = { 173 { 174 .dcp_offset = (mmDCP0_CUR_CONTROL - mmCUR_CONTROL), 175 }, 176 { 177 .dcp_offset = (mmDCP1_CUR_CONTROL - mmCUR_CONTROL), 178 }, 179 { 180 .dcp_offset = (mmDCP2_CUR_CONTROL - mmCUR_CONTROL), 181 }, 182 { 183 .dcp_offset = (mmDCP3_CUR_CONTROL - mmCUR_CONTROL), 184 }, 185 { 186 .dcp_offset = (mmDCP4_CUR_CONTROL - mmCUR_CONTROL), 187 }, 188 { 189 .dcp_offset = (mmDCP5_CUR_CONTROL - mmCUR_CONTROL), 190 } 191 }; 192 193 194 195 /* set register offset */ 196 #define SR(reg_name)\ 197 .reg_name = mm ## reg_name 198 199 /* set register offset with instance */ 200 #define SRI(reg_name, block, id)\ 201 .reg_name = mm ## block ## id ## _ ## reg_name 202 203 204 static const struct dce_disp_clk_registers disp_clk_regs = { 205 CLK_COMMON_REG_LIST_DCE_BASE() 206 }; 207 208 static const struct dce_disp_clk_shift disp_clk_shift = { 209 CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT) 210 }; 211 212 static const struct dce_disp_clk_mask disp_clk_mask = { 213 CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK) 214 }; 215 216 #define transform_regs(id)\ 217 [id] = {\ 218 XFM_COMMON_REG_LIST_DCE100(id)\ 219 } 220 221 static const struct dce_transform_registers xfm_regs[] = { 222 transform_regs(0), 223 transform_regs(1), 224 transform_regs(2), 225 transform_regs(3), 226 transform_regs(4), 227 transform_regs(5) 228 }; 229 230 static const struct dce_transform_shift xfm_shift = { 231 XFM_COMMON_MASK_SH_LIST_DCE110(__SHIFT) 232 }; 233 234 static const struct dce_transform_mask xfm_mask = { 235 XFM_COMMON_MASK_SH_LIST_DCE110(_MASK) 236 }; 237 238 #define aux_regs(id)\ 239 [id] = {\ 240 AUX_REG_LIST(id)\ 241 } 242 243 static const struct dce110_link_enc_aux_registers link_enc_aux_regs[] = { 244 aux_regs(0), 245 aux_regs(1), 246 aux_regs(2), 247 aux_regs(3), 248 aux_regs(4), 249 aux_regs(5) 250 }; 251 252 #define hpd_regs(id)\ 253 [id] = {\ 254 HPD_REG_LIST(id)\ 255 } 256 257 static const struct dce110_link_enc_hpd_registers link_enc_hpd_regs[] = { 258 hpd_regs(0), 259 hpd_regs(1), 260 hpd_regs(2), 261 hpd_regs(3), 262 hpd_regs(4), 263 hpd_regs(5) 264 }; 265 266 #define link_regs(id)\ 267 [id] = {\ 268 LE_DCE100_REG_LIST(id)\ 269 } 270 271 static const struct dce110_link_enc_registers link_enc_regs[] = { 272 link_regs(0), 273 link_regs(1), 274 link_regs(2), 275 link_regs(3), 276 link_regs(4), 277 link_regs(5), 278 link_regs(6), 279 }; 280 281 #define stream_enc_regs(id)\ 282 [id] = {\ 283 SE_COMMON_REG_LIST_DCE_BASE(id),\ 284 .AFMT_CNTL = 0,\ 285 } 286 287 static const struct dce110_stream_enc_registers stream_enc_regs[] = { 288 stream_enc_regs(0), 289 stream_enc_regs(1), 290 stream_enc_regs(2), 291 stream_enc_regs(3), 292 stream_enc_regs(4), 293 stream_enc_regs(5), 294 stream_enc_regs(6) 295 }; 296 297 static const struct dce_stream_encoder_shift se_shift = { 298 SE_COMMON_MASK_SH_LIST_DCE80_100(__SHIFT) 299 }; 300 301 static const struct dce_stream_encoder_mask se_mask = { 302 SE_COMMON_MASK_SH_LIST_DCE80_100(_MASK) 303 }; 304 305 #define opp_regs(id)\ 306 [id] = {\ 307 OPP_DCE_100_REG_LIST(id),\ 308 } 309 310 static const struct dce_opp_registers opp_regs[] = { 311 opp_regs(0), 312 opp_regs(1), 313 opp_regs(2), 314 opp_regs(3), 315 opp_regs(4), 316 opp_regs(5) 317 }; 318 319 static const struct dce_opp_shift opp_shift = { 320 OPP_COMMON_MASK_SH_LIST_DCE_100(__SHIFT) 321 }; 322 323 static const struct dce_opp_mask opp_mask = { 324 OPP_COMMON_MASK_SH_LIST_DCE_100(_MASK) 325 }; 326 327 328 #define audio_regs(id)\ 329 [id] = {\ 330 AUD_COMMON_REG_LIST(id)\ 331 } 332 333 static const struct dce_audio_registers audio_regs[] = { 334 audio_regs(0), 335 audio_regs(1), 336 audio_regs(2), 337 audio_regs(3), 338 audio_regs(4), 339 audio_regs(5), 340 audio_regs(6), 341 }; 342 343 static const struct dce_audio_shift audio_shift = { 344 AUD_COMMON_MASK_SH_LIST(__SHIFT) 345 }; 346 347 static const struct dce_aduio_mask audio_mask = { 348 AUD_COMMON_MASK_SH_LIST(_MASK) 349 }; 350 351 #define clk_src_regs(id)\ 352 [id] = {\ 353 CS_COMMON_REG_LIST_DCE_100_110(id),\ 354 } 355 356 static const struct dce110_clk_src_regs clk_src_regs[] = { 357 clk_src_regs(0), 358 clk_src_regs(1), 359 clk_src_regs(2) 360 }; 361 362 static const struct dce110_clk_src_shift cs_shift = { 363 CS_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT) 364 }; 365 366 static const struct dce110_clk_src_mask cs_mask = { 367 CS_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK) 368 }; 369 370 371 372 #define DCFE_MEM_PWR_CTRL_REG_BASE 0x1b03 373 374 static const struct bios_registers bios_regs = { 375 .BIOS_SCRATCH_6 = mmBIOS_SCRATCH_6 376 }; 377 378 static const struct resource_caps res_cap = { 379 .num_timing_generator = 6, 380 .num_audio = 6, 381 .num_stream_encoder = 6, 382 .num_pll = 3 383 }; 384 385 #define CTX ctx 386 #define REG(reg) mm ## reg 387 388 #ifndef mmCC_DC_HDMI_STRAPS 389 #define mmCC_DC_HDMI_STRAPS 0x1918 390 #define CC_DC_HDMI_STRAPS__HDMI_DISABLE_MASK 0x40 391 #define CC_DC_HDMI_STRAPS__HDMI_DISABLE__SHIFT 0x6 392 #define CC_DC_HDMI_STRAPS__AUDIO_STREAM_NUMBER_MASK 0x700 393 #define CC_DC_HDMI_STRAPS__AUDIO_STREAM_NUMBER__SHIFT 0x8 394 #endif 395 396 static void read_dce_straps( 397 struct dc_context *ctx, 398 struct resource_straps *straps) 399 { 400 REG_GET_2(CC_DC_HDMI_STRAPS, 401 HDMI_DISABLE, &straps->hdmi_disable, 402 AUDIO_STREAM_NUMBER, &straps->audio_stream_number); 403 404 REG_GET(DC_PINSTRAPS, DC_PINSTRAPS_AUDIO, &straps->dc_pinstraps_audio); 405 } 406 407 static struct audio *create_audio( 408 struct dc_context *ctx, unsigned int inst) 409 { 410 return dce_audio_create(ctx, inst, 411 &audio_regs[inst], &audio_shift, &audio_mask); 412 } 413 414 static struct timing_generator *dce100_timing_generator_create( 415 struct dc_context *ctx, 416 uint32_t instance, 417 const struct dce110_timing_generator_offsets *offsets) 418 { 419 struct dce110_timing_generator *tg110 = 420 dm_alloc(sizeof(struct dce110_timing_generator)); 421 422 if (!tg110) 423 return NULL; 424 425 if (dce110_timing_generator_construct(tg110, ctx, instance, 426 offsets)) 427 return &tg110->base; 428 429 BREAK_TO_DEBUGGER(); 430 dm_free(tg110); 431 return NULL; 432 } 433 434 static struct stream_encoder *dce100_stream_encoder_create( 435 enum engine_id eng_id, 436 struct dc_context *ctx) 437 { 438 struct dce110_stream_encoder *enc110 = 439 dm_alloc(sizeof(struct dce110_stream_encoder)); 440 441 if (!enc110) 442 return NULL; 443 444 if (dce110_stream_encoder_construct( 445 enc110, ctx, ctx->dc_bios, eng_id, 446 &stream_enc_regs[eng_id], &se_shift, &se_mask)) 447 return &enc110->base; 448 449 BREAK_TO_DEBUGGER(); 450 dm_free(enc110); 451 return NULL; 452 } 453 454 #define SRII(reg_name, block, id)\ 455 .reg_name[id] = mm ## block ## id ## _ ## reg_name 456 457 static const struct dce_hwseq_registers hwseq_reg = { 458 HWSEQ_DCE10_REG_LIST() 459 }; 460 461 static const struct dce_hwseq_shift hwseq_shift = { 462 HWSEQ_DCE10_MASK_SH_LIST(__SHIFT) 463 }; 464 465 static const struct dce_hwseq_mask hwseq_mask = { 466 HWSEQ_DCE10_MASK_SH_LIST(_MASK) 467 }; 468 469 static struct dce_hwseq *dce100_hwseq_create( 470 struct dc_context *ctx) 471 { 472 struct dce_hwseq *hws = dm_alloc(sizeof(struct dce_hwseq)); 473 474 if (hws) { 475 hws->ctx = ctx; 476 hws->regs = &hwseq_reg; 477 hws->shifts = &hwseq_shift; 478 hws->masks = &hwseq_mask; 479 } 480 return hws; 481 } 482 483 static const struct resource_create_funcs res_create_funcs = { 484 .read_dce_straps = read_dce_straps, 485 .create_audio = create_audio, 486 .create_stream_encoder = dce100_stream_encoder_create, 487 .create_hwseq = dce100_hwseq_create, 488 }; 489 490 #define mi_inst_regs(id) { \ 491 MI_DCE8_REG_LIST(id), \ 492 .MC_HUB_RDREQ_DMIF_LIMIT = mmMC_HUB_RDREQ_DMIF_LIMIT \ 493 } 494 static const struct dce_mem_input_registers mi_regs[] = { 495 mi_inst_regs(0), 496 mi_inst_regs(1), 497 mi_inst_regs(2), 498 mi_inst_regs(3), 499 mi_inst_regs(4), 500 mi_inst_regs(5), 501 }; 502 503 static const struct dce_mem_input_shift mi_shifts = { 504 MI_DCE8_MASK_SH_LIST(__SHIFT), 505 .ENABLE = MC_HUB_RDREQ_DMIF_LIMIT__ENABLE__SHIFT 506 }; 507 508 static const struct dce_mem_input_mask mi_masks = { 509 MI_DCE8_MASK_SH_LIST(_MASK), 510 .ENABLE = MC_HUB_RDREQ_DMIF_LIMIT__ENABLE_MASK 511 }; 512 513 static struct mem_input *dce100_mem_input_create( 514 struct dc_context *ctx, 515 uint32_t inst, 516 const struct dce110_mem_input_reg_offsets *offset) 517 { 518 struct dce110_mem_input *mem_input110 = 519 dm_alloc(sizeof(struct dce110_mem_input)); 520 521 if (!mem_input110) 522 return NULL; 523 524 if (dce110_mem_input_construct(mem_input110, ctx, inst, offset)) { 525 struct mem_input *mi = &mem_input110->base; 526 527 mi->regs = &mi_regs[inst]; 528 mi->shifts = &mi_shifts; 529 mi->masks = &mi_masks; 530 mi->wa.single_head_rdreq_dmif_limit = 2; 531 return mi; 532 } 533 534 BREAK_TO_DEBUGGER(); 535 dm_free(mem_input110); 536 return NULL; 537 } 538 539 static void dce100_transform_destroy(struct transform **xfm) 540 { 541 dm_free(TO_DCE_TRANSFORM(*xfm)); 542 *xfm = NULL; 543 } 544 545 static struct transform *dce100_transform_create( 546 struct dc_context *ctx, 547 uint32_t inst) 548 { 549 struct dce_transform *transform = 550 dm_alloc(sizeof(struct dce_transform)); 551 552 if (!transform) 553 return NULL; 554 555 if (dce_transform_construct(transform, ctx, inst, 556 &xfm_regs[inst], &xfm_shift, &xfm_mask)) { 557 return &transform->base; 558 } 559 560 BREAK_TO_DEBUGGER(); 561 dm_free(transform); 562 return NULL; 563 } 564 565 static struct input_pixel_processor *dce100_ipp_create( 566 struct dc_context *ctx, 567 uint32_t inst, 568 const struct dce110_ipp_reg_offsets *offsets) 569 { 570 struct dce110_ipp *ipp = 571 dm_alloc(sizeof(struct dce110_ipp)); 572 573 if (!ipp) 574 return NULL; 575 576 if (dce110_ipp_construct(ipp, ctx, inst, offsets)) 577 return &ipp->base; 578 579 BREAK_TO_DEBUGGER(); 580 dm_free(ipp); 581 return NULL; 582 } 583 584 static const struct encoder_feature_support link_enc_feature = { 585 .max_hdmi_deep_color = COLOR_DEPTH_121212, 586 .max_hdmi_pixel_clock = 300000, 587 .flags.bits.IS_HBR2_CAPABLE = true, 588 .flags.bits.IS_TPS3_CAPABLE = true, 589 .flags.bits.IS_YCBCR_CAPABLE = true 590 }; 591 592 struct link_encoder *dce100_link_encoder_create( 593 const struct encoder_init_data *enc_init_data) 594 { 595 struct dce110_link_encoder *enc110 = 596 dm_alloc(sizeof(struct dce110_link_encoder)); 597 598 if (!enc110) 599 return NULL; 600 601 if (dce110_link_encoder_construct( 602 enc110, 603 enc_init_data, 604 &link_enc_feature, 605 &link_enc_regs[enc_init_data->transmitter], 606 &link_enc_aux_regs[enc_init_data->channel - 1], 607 &link_enc_hpd_regs[enc_init_data->hpd_source])) { 608 609 return &enc110->base; 610 } 611 612 BREAK_TO_DEBUGGER(); 613 dm_free(enc110); 614 return NULL; 615 } 616 617 struct output_pixel_processor *dce100_opp_create( 618 struct dc_context *ctx, 619 uint32_t inst) 620 { 621 struct dce110_opp *opp = 622 dm_alloc(sizeof(struct dce110_opp)); 623 624 if (!opp) 625 return NULL; 626 627 if (dce110_opp_construct(opp, 628 ctx, inst, &opp_regs[inst], &opp_shift, &opp_mask)) 629 return &opp->base; 630 631 BREAK_TO_DEBUGGER(); 632 dm_free(opp); 633 return NULL; 634 } 635 636 struct clock_source *dce100_clock_source_create( 637 struct dc_context *ctx, 638 struct dc_bios *bios, 639 enum clock_source_id id, 640 const struct dce110_clk_src_regs *regs, 641 bool dp_clk_src) 642 { 643 struct dce110_clk_src *clk_src = 644 dm_alloc(sizeof(struct dce110_clk_src)); 645 646 if (!clk_src) 647 return NULL; 648 649 if (dce110_clk_src_construct(clk_src, ctx, bios, id, 650 regs, &cs_shift, &cs_mask)) { 651 clk_src->base.dp_clk_src = dp_clk_src; 652 return &clk_src->base; 653 } 654 655 BREAK_TO_DEBUGGER(); 656 return NULL; 657 } 658 659 void dce100_clock_source_destroy(struct clock_source **clk_src) 660 { 661 dm_free(TO_DCE110_CLK_SRC(*clk_src)); 662 *clk_src = NULL; 663 } 664 665 static void destruct(struct dce110_resource_pool *pool) 666 { 667 unsigned int i; 668 669 for (i = 0; i < pool->base.pipe_count; i++) { 670 if (pool->base.opps[i] != NULL) 671 dce110_opp_destroy(&pool->base.opps[i]); 672 673 if (pool->base.transforms[i] != NULL) 674 dce100_transform_destroy(&pool->base.transforms[i]); 675 676 if (pool->base.ipps[i] != NULL) 677 dce110_ipp_destroy(&pool->base.ipps[i]); 678 679 if (pool->base.mis[i] != NULL) { 680 dm_free(TO_DCE110_MEM_INPUT(pool->base.mis[i])); 681 pool->base.mis[i] = NULL; 682 } 683 684 if (pool->base.timing_generators[i] != NULL) { 685 dm_free(DCE110TG_FROM_TG(pool->base.timing_generators[i])); 686 pool->base.timing_generators[i] = NULL; 687 } 688 } 689 690 for (i = 0; i < pool->base.stream_enc_count; i++) { 691 if (pool->base.stream_enc[i] != NULL) 692 dm_free(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 dce100_clock_source_destroy(&pool->base.clock_sources[i]); 698 } 699 700 if (pool->base.dp_clock_source != NULL) 701 dce100_clock_source_destroy(&pool->base.dp_clock_source); 702 703 for (i = 0; i < pool->base.audio_count; i++) { 704 if (pool->base.audios[i] != NULL) 705 dce_aud_destroy(&pool->base.audios[i]); 706 } 707 708 if (pool->base.display_clock != NULL) 709 dce_disp_clk_destroy(&pool->base.display_clock); 710 711 if (pool->base.irqs != NULL) 712 dal_irq_service_destroy(&pool->base.irqs); 713 } 714 715 static enum dc_status validate_mapped_resource( 716 const struct core_dc *dc, 717 struct validate_context *context) 718 { 719 enum dc_status status = DC_OK; 720 uint8_t i, j; 721 722 for (i = 0; i < context->stream_count; i++) { 723 struct core_stream *stream = context->streams[i]; 724 struct core_link *link = stream->sink->link; 725 726 if (resource_is_stream_unchanged(dc->current_context, stream)) 727 continue; 728 729 for (j = 0; j < MAX_PIPES; j++) { 730 struct pipe_ctx *pipe_ctx = 731 &context->res_ctx.pipe_ctx[j]; 732 733 if (context->res_ctx.pipe_ctx[j].stream != stream) 734 continue; 735 736 if (!pipe_ctx->tg->funcs->validate_timing( 737 pipe_ctx->tg, &stream->public.timing)) 738 return DC_FAIL_CONTROLLER_VALIDATE; 739 740 status = dce110_resource_build_pipe_hw_param(pipe_ctx); 741 742 if (status != DC_OK) 743 return status; 744 745 if (!link->link_enc->funcs->validate_output_with_stream( 746 link->link_enc, 747 pipe_ctx)) 748 return DC_FAIL_ENC_VALIDATE; 749 750 /* TODO: validate audio ASIC caps, encoder */ 751 status = dc_link_validate_mode_timing(stream, 752 link, 753 &stream->public.timing); 754 755 if (status != DC_OK) 756 return status; 757 758 resource_build_info_frame(pipe_ctx); 759 760 /* do not need to validate non root pipes */ 761 break; 762 } 763 } 764 765 return DC_OK; 766 } 767 768 bool dce100_validate_bandwidth( 769 const struct core_dc *dc, 770 struct validate_context *context) 771 { 772 /* TODO implement when needed but for now hardcode max value*/ 773 context->dispclk_khz = 681000; 774 775 return true; 776 } 777 778 static bool dce100_validate_surface_sets( 779 const struct dc_validation_set set[], 780 int set_count) 781 { 782 int i; 783 784 for (i = 0; i < set_count; i++) { 785 if (set[i].surface_count == 0) 786 continue; 787 788 if (set[i].surface_count > 1) 789 return false; 790 791 if (set[i].surfaces[0]->clip_rect.width 792 < set[i].stream->src.width 793 || set[i].surfaces[0]->clip_rect.height 794 < set[i].stream->src.height) 795 return false; 796 if (set[i].surfaces[0]->format 797 >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) 798 return false; 799 } 800 801 return true; 802 } 803 804 enum dc_status dce100_validate_with_context( 805 const struct core_dc *dc, 806 const struct dc_validation_set set[], 807 int set_count, 808 struct validate_context *context) 809 { 810 struct dc_context *dc_ctx = dc->ctx; 811 enum dc_status result = DC_ERROR_UNEXPECTED; 812 int i; 813 814 if (!dce100_validate_surface_sets(set, set_count)) 815 return DC_FAIL_SURFACE_VALIDATE; 816 817 context->res_ctx.pool = dc->res_pool; 818 819 for (i = 0; i < set_count; i++) { 820 context->streams[i] = DC_STREAM_TO_CORE(set[i].stream); 821 dc_stream_retain(&context->streams[i]->public); 822 context->stream_count++; 823 } 824 825 result = resource_map_pool_resources(dc, context); 826 827 if (result == DC_OK) 828 result = resource_map_clock_resources(dc, context); 829 830 if (!resource_validate_attach_surfaces( 831 set, set_count, dc->current_context, context)) { 832 DC_ERROR("Failed to attach surface to stream!\n"); 833 return DC_FAIL_ATTACH_SURFACES; 834 } 835 836 if (result == DC_OK) 837 result = validate_mapped_resource(dc, context); 838 839 if (result == DC_OK) 840 result = resource_build_scaling_params_for_context(dc, context); 841 842 if (result == DC_OK) 843 if (!dce100_validate_bandwidth(dc, context)) 844 result = DC_FAIL_BANDWIDTH_VALIDATE; 845 846 return result; 847 } 848 849 enum dc_status dce100_validate_guaranteed( 850 const struct core_dc *dc, 851 const struct dc_stream *dc_stream, 852 struct validate_context *context) 853 { 854 enum dc_status result = DC_ERROR_UNEXPECTED; 855 856 context->res_ctx.pool = dc->res_pool; 857 858 context->streams[0] = DC_STREAM_TO_CORE(dc_stream); 859 dc_stream_retain(&context->streams[0]->public); 860 context->stream_count++; 861 862 result = resource_map_pool_resources(dc, context); 863 864 if (result == DC_OK) 865 result = resource_map_clock_resources(dc, context); 866 867 if (result == DC_OK) 868 result = validate_mapped_resource(dc, context); 869 870 if (result == DC_OK) { 871 validate_guaranteed_copy_streams( 872 context, dc->public.caps.max_streams); 873 result = resource_build_scaling_params_for_context(dc, context); 874 } 875 876 if (result == DC_OK) 877 if (!dce100_validate_bandwidth(dc, context)) 878 result = DC_FAIL_BANDWIDTH_VALIDATE; 879 880 return result; 881 } 882 883 static void dce100_destroy_resource_pool(struct resource_pool **pool) 884 { 885 struct dce110_resource_pool *dce110_pool = TO_DCE110_RES_POOL(*pool); 886 887 destruct(dce110_pool); 888 dm_free(dce110_pool); 889 *pool = NULL; 890 } 891 892 static const struct resource_funcs dce100_res_pool_funcs = { 893 .destroy = dce100_destroy_resource_pool, 894 .link_enc_create = dce100_link_encoder_create, 895 .validate_with_context = dce100_validate_with_context, 896 .validate_guaranteed = dce100_validate_guaranteed, 897 .validate_bandwidth = dce100_validate_bandwidth 898 }; 899 900 static bool construct( 901 uint8_t num_virtual_links, 902 struct core_dc *dc, 903 struct dce110_resource_pool *pool) 904 { 905 unsigned int i; 906 struct dc_context *ctx = dc->ctx; 907 struct firmware_info info; 908 struct dc_bios *bp; 909 struct dm_pp_static_clock_info static_clk_info = {0}; 910 911 ctx->dc_bios->regs = &bios_regs; 912 913 pool->base.res_cap = &res_cap; 914 pool->base.funcs = &dce100_res_pool_funcs; 915 pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE; 916 917 bp = ctx->dc_bios; 918 919 if ((bp->funcs->get_firmware_info(bp, &info) == BP_RESULT_OK) && 920 info.external_clock_source_frequency_for_dp != 0) { 921 pool->base.dp_clock_source = 922 dce100_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_EXTERNAL, NULL, true); 923 924 pool->base.clock_sources[0] = 925 dce100_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL0, &clk_src_regs[0], false); 926 pool->base.clock_sources[1] = 927 dce100_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[1], false); 928 pool->base.clock_sources[2] = 929 dce100_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL2, &clk_src_regs[2], false); 930 pool->base.clk_src_count = 3; 931 932 } else { 933 pool->base.dp_clock_source = 934 dce100_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL0, &clk_src_regs[0], true); 935 936 pool->base.clock_sources[0] = 937 dce100_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[1], false); 938 pool->base.clock_sources[1] = 939 dce100_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL2, &clk_src_regs[2], false); 940 pool->base.clk_src_count = 2; 941 } 942 943 if (pool->base.dp_clock_source == NULL) { 944 dm_error("DC: failed to create dp clock source!\n"); 945 BREAK_TO_DEBUGGER(); 946 goto res_create_fail; 947 } 948 949 for (i = 0; i < pool->base.clk_src_count; i++) { 950 if (pool->base.clock_sources[i] == NULL) { 951 dm_error("DC: failed to create clock sources!\n"); 952 BREAK_TO_DEBUGGER(); 953 goto res_create_fail; 954 } 955 } 956 957 pool->base.display_clock = dce_disp_clk_create(ctx, 958 &disp_clk_regs, 959 &disp_clk_shift, 960 &disp_clk_mask); 961 if (pool->base.display_clock == NULL) { 962 dm_error("DC: failed to create display clock!\n"); 963 BREAK_TO_DEBUGGER(); 964 goto res_create_fail; 965 } 966 967 968 /* get static clock information for PPLIB or firmware, save 969 * max_clock_state 970 */ 971 if (dm_pp_get_static_clocks(ctx, &static_clk_info)) 972 pool->base.display_clock->max_clks_state = 973 static_clk_info.max_clocks_state; 974 { 975 struct irq_service_init_data init_data; 976 init_data.ctx = dc->ctx; 977 pool->base.irqs = dal_irq_service_dce110_create(&init_data); 978 if (!pool->base.irqs) 979 goto res_create_fail; 980 } 981 982 /************************************************* 983 * Resource + asic cap harcoding * 984 *************************************************/ 985 pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE; 986 pool->base.pipe_count = res_cap.num_timing_generator; 987 dc->public.caps.max_downscale_ratio = 200; 988 dc->public.caps.i2c_speed_in_khz = 40; 989 dc->public.caps.max_cursor_size = 128; 990 991 for (i = 0; i < pool->base.pipe_count; i++) { 992 pool->base.timing_generators[i] = 993 dce100_timing_generator_create( 994 ctx, 995 i, 996 &dce100_tg_offsets[i]); 997 if (pool->base.timing_generators[i] == NULL) { 998 BREAK_TO_DEBUGGER(); 999 dm_error("DC: failed to create tg!\n"); 1000 goto res_create_fail; 1001 } 1002 1003 pool->base.mis[i] = dce100_mem_input_create(ctx, i, 1004 &dce100_mi_reg_offsets[i]); 1005 if (pool->base.mis[i] == NULL) { 1006 BREAK_TO_DEBUGGER(); 1007 dm_error( 1008 "DC: failed to create memory input!\n"); 1009 goto res_create_fail; 1010 } 1011 1012 pool->base.ipps[i] = dce100_ipp_create(ctx, i, 1013 &dce100_ipp_reg_offsets[i]); 1014 if (pool->base.ipps[i] == NULL) { 1015 BREAK_TO_DEBUGGER(); 1016 dm_error( 1017 "DC: failed to create input pixel processor!\n"); 1018 goto res_create_fail; 1019 } 1020 1021 pool->base.transforms[i] = dce100_transform_create(ctx, i); 1022 if (pool->base.transforms[i] == NULL) { 1023 BREAK_TO_DEBUGGER(); 1024 dm_error( 1025 "DC: failed to create transform!\n"); 1026 goto res_create_fail; 1027 } 1028 1029 pool->base.opps[i] = dce100_opp_create(ctx, i); 1030 if (pool->base.opps[i] == NULL) { 1031 BREAK_TO_DEBUGGER(); 1032 dm_error( 1033 "DC: failed to create output pixel processor!\n"); 1034 goto res_create_fail; 1035 } 1036 } 1037 1038 if (!resource_construct(num_virtual_links, dc, &pool->base, 1039 &res_create_funcs)) 1040 goto res_create_fail; 1041 1042 /* Create hardware sequencer */ 1043 if (!dce100_hw_sequencer_construct(dc)) 1044 goto res_create_fail; 1045 1046 return true; 1047 1048 res_create_fail: 1049 destruct(pool); 1050 1051 return false; 1052 } 1053 1054 struct resource_pool *dce100_create_resource_pool( 1055 uint8_t num_virtual_links, 1056 struct core_dc *dc) 1057 { 1058 struct dce110_resource_pool *pool = 1059 dm_alloc(sizeof(struct dce110_resource_pool)); 1060 1061 if (!pool) 1062 return NULL; 1063 1064 if (construct(num_virtual_links, dc, pool)) 1065 return &pool->base; 1066 1067 BREAK_TO_DEBUGGER(); 1068 return NULL; 1069 } 1070 1071