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_DCE110_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 void dce100_opp_destroy(struct output_pixel_processor **opp) 637 { 638 struct dce110_opp *dce110_opp; 639 640 if (!opp || !*opp) 641 return; 642 643 dce110_opp = FROM_DCE11_OPP(*opp); 644 645 dm_free(dce110_opp->regamma.coeff128_dx); 646 dm_free(dce110_opp->regamma.coeff128_oem); 647 dm_free(dce110_opp->regamma.coeff128); 648 dm_free(dce110_opp->regamma.axis_x_1025); 649 dm_free(dce110_opp->regamma.axis_x_256); 650 dm_free(dce110_opp->regamma.coordinates_x); 651 dm_free(dce110_opp->regamma.rgb_regamma); 652 dm_free(dce110_opp->regamma.rgb_resulted); 653 dm_free(dce110_opp->regamma.rgb_oem); 654 dm_free(dce110_opp->regamma.rgb_user); 655 dm_free(dce110_opp); 656 657 *opp = NULL; 658 } 659 660 struct clock_source *dce100_clock_source_create( 661 struct dc_context *ctx, 662 struct dc_bios *bios, 663 enum clock_source_id id, 664 const struct dce110_clk_src_regs *regs, 665 bool dp_clk_src) 666 { 667 struct dce110_clk_src *clk_src = 668 dm_alloc(sizeof(struct dce110_clk_src)); 669 670 if (!clk_src) 671 return NULL; 672 673 if (dce110_clk_src_construct(clk_src, ctx, bios, id, 674 regs, &cs_shift, &cs_mask)) { 675 clk_src->base.dp_clk_src = dp_clk_src; 676 return &clk_src->base; 677 } 678 679 BREAK_TO_DEBUGGER(); 680 return NULL; 681 } 682 683 void dce100_clock_source_destroy(struct clock_source **clk_src) 684 { 685 dm_free(TO_DCE110_CLK_SRC(*clk_src)); 686 *clk_src = NULL; 687 } 688 689 static void destruct(struct dce110_resource_pool *pool) 690 { 691 unsigned int i; 692 693 for (i = 0; i < pool->base.pipe_count; i++) { 694 if (pool->base.opps[i] != NULL) 695 dce100_opp_destroy(&pool->base.opps[i]); 696 697 if (pool->base.transforms[i] != NULL) 698 dce100_transform_destroy(&pool->base.transforms[i]); 699 700 if (pool->base.ipps[i] != NULL) 701 dce110_ipp_destroy(&pool->base.ipps[i]); 702 703 if (pool->base.mis[i] != NULL) { 704 dm_free(TO_DCE110_MEM_INPUT(pool->base.mis[i])); 705 pool->base.mis[i] = NULL; 706 } 707 708 if (pool->base.timing_generators[i] != NULL) { 709 dm_free(DCE110TG_FROM_TG(pool->base.timing_generators[i])); 710 pool->base.timing_generators[i] = NULL; 711 } 712 } 713 714 for (i = 0; i < pool->base.stream_enc_count; i++) { 715 if (pool->base.stream_enc[i] != NULL) 716 dm_free(DCE110STRENC_FROM_STRENC(pool->base.stream_enc[i])); 717 } 718 719 for (i = 0; i < pool->base.clk_src_count; i++) { 720 if (pool->base.clock_sources[i] != NULL) 721 dce100_clock_source_destroy(&pool->base.clock_sources[i]); 722 } 723 724 if (pool->base.dp_clock_source != NULL) 725 dce100_clock_source_destroy(&pool->base.dp_clock_source); 726 727 for (i = 0; i < pool->base.audio_count; i++) { 728 if (pool->base.audios[i] != NULL) 729 dce_aud_destroy(&pool->base.audios[i]); 730 } 731 732 if (pool->base.display_clock != NULL) 733 dce_disp_clk_destroy(&pool->base.display_clock); 734 735 if (pool->base.irqs != NULL) 736 dal_irq_service_destroy(&pool->base.irqs); 737 } 738 739 static enum dc_status validate_mapped_resource( 740 const struct core_dc *dc, 741 struct validate_context *context) 742 { 743 enum dc_status status = DC_OK; 744 uint8_t i, j; 745 746 for (i = 0; i < context->stream_count; i++) { 747 struct core_stream *stream = context->streams[i]; 748 struct core_link *link = stream->sink->link; 749 750 if (resource_is_stream_unchanged(dc->current_context, stream)) 751 continue; 752 753 for (j = 0; j < MAX_PIPES; j++) { 754 struct pipe_ctx *pipe_ctx = 755 &context->res_ctx.pipe_ctx[j]; 756 757 if (context->res_ctx.pipe_ctx[j].stream != stream) 758 continue; 759 760 if (!pipe_ctx->tg->funcs->validate_timing( 761 pipe_ctx->tg, &stream->public.timing)) 762 return DC_FAIL_CONTROLLER_VALIDATE; 763 764 status = dce110_resource_build_pipe_hw_param(pipe_ctx); 765 766 if (status != DC_OK) 767 return status; 768 769 if (!link->link_enc->funcs->validate_output_with_stream( 770 link->link_enc, 771 pipe_ctx)) 772 return DC_FAIL_ENC_VALIDATE; 773 774 /* TODO: validate audio ASIC caps, encoder */ 775 status = dc_link_validate_mode_timing(stream, 776 link, 777 &stream->public.timing); 778 779 if (status != DC_OK) 780 return status; 781 782 resource_build_info_frame(pipe_ctx); 783 784 /* do not need to validate non root pipes */ 785 break; 786 } 787 } 788 789 return DC_OK; 790 } 791 792 enum dc_status dce100_validate_bandwidth( 793 const struct core_dc *dc, 794 struct validate_context *context) 795 { 796 /* TODO implement when needed but for now hardcode max value*/ 797 context->bw_results.dispclk_khz = 681000; 798 799 return DC_OK; 800 } 801 802 static bool dce100_validate_surface_sets( 803 const struct dc_validation_set set[], 804 int set_count) 805 { 806 int i; 807 808 for (i = 0; i < set_count; i++) { 809 if (set[i].surface_count == 0) 810 continue; 811 812 if (set[i].surface_count > 1) 813 return false; 814 815 if (set[i].surfaces[0]->clip_rect.width 816 != set[i].stream->src.width 817 || set[i].surfaces[0]->clip_rect.height 818 != set[i].stream->src.height) 819 return false; 820 if (set[i].surfaces[0]->format 821 >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) 822 return false; 823 } 824 825 return true; 826 } 827 828 enum dc_status dce100_validate_with_context( 829 const struct core_dc *dc, 830 const struct dc_validation_set set[], 831 int set_count, 832 struct validate_context *context) 833 { 834 struct dc_context *dc_ctx = dc->ctx; 835 enum dc_status result = DC_ERROR_UNEXPECTED; 836 int i; 837 838 if (!dce100_validate_surface_sets(set, set_count)) 839 return DC_FAIL_SURFACE_VALIDATE; 840 841 context->res_ctx.pool = dc->res_pool; 842 843 for (i = 0; i < set_count; i++) { 844 context->streams[i] = DC_STREAM_TO_CORE(set[i].stream); 845 dc_stream_retain(&context->streams[i]->public); 846 context->stream_count++; 847 } 848 849 result = resource_map_pool_resources(dc, context); 850 851 if (result == DC_OK) 852 result = resource_map_clock_resources(dc, context); 853 854 if (!resource_validate_attach_surfaces( 855 set, set_count, dc->current_context, context)) { 856 DC_ERROR("Failed to attach surface to stream!\n"); 857 return DC_FAIL_ATTACH_SURFACES; 858 } 859 860 if (result == DC_OK) 861 result = validate_mapped_resource(dc, context); 862 863 if (result == DC_OK) 864 result = resource_build_scaling_params_for_context(dc, context); 865 866 if (result == DC_OK) 867 result = dce100_validate_bandwidth(dc, context); 868 869 return result; 870 } 871 872 enum dc_status dce100_validate_guaranteed( 873 const struct core_dc *dc, 874 const struct dc_stream *dc_stream, 875 struct validate_context *context) 876 { 877 enum dc_status result = DC_ERROR_UNEXPECTED; 878 879 context->res_ctx.pool = dc->res_pool; 880 881 context->streams[0] = DC_STREAM_TO_CORE(dc_stream); 882 dc_stream_retain(&context->streams[0]->public); 883 context->stream_count++; 884 885 result = resource_map_pool_resources(dc, context); 886 887 if (result == DC_OK) 888 result = resource_map_clock_resources(dc, context); 889 890 if (result == DC_OK) 891 result = validate_mapped_resource(dc, context); 892 893 if (result == DC_OK) { 894 validate_guaranteed_copy_streams( 895 context, dc->public.caps.max_streams); 896 result = resource_build_scaling_params_for_context(dc, context); 897 } 898 899 if (result == DC_OK) 900 result = dce100_validate_bandwidth(dc, context); 901 902 return result; 903 } 904 905 static void dce100_destroy_resource_pool(struct resource_pool **pool) 906 { 907 struct dce110_resource_pool *dce110_pool = TO_DCE110_RES_POOL(*pool); 908 909 destruct(dce110_pool); 910 dm_free(dce110_pool); 911 *pool = NULL; 912 } 913 914 static const struct resource_funcs dce100_res_pool_funcs = { 915 .destroy = dce100_destroy_resource_pool, 916 .link_enc_create = dce100_link_encoder_create, 917 .validate_with_context = dce100_validate_with_context, 918 .validate_guaranteed = dce100_validate_guaranteed, 919 .validate_bandwidth = dce100_validate_bandwidth 920 }; 921 922 static bool construct( 923 uint8_t num_virtual_links, 924 struct core_dc *dc, 925 struct dce110_resource_pool *pool) 926 { 927 unsigned int i; 928 struct dc_context *ctx = dc->ctx; 929 struct firmware_info info; 930 struct dc_bios *bp; 931 struct dm_pp_static_clock_info static_clk_info = {0}; 932 933 ctx->dc_bios->regs = &bios_regs; 934 935 pool->base.res_cap = &res_cap; 936 pool->base.funcs = &dce100_res_pool_funcs; 937 pool->base.underlay_pipe_index = -1; 938 939 bp = ctx->dc_bios; 940 941 if ((bp->funcs->get_firmware_info(bp, &info) == BP_RESULT_OK) && 942 info.external_clock_source_frequency_for_dp != 0) { 943 pool->base.dp_clock_source = 944 dce100_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_EXTERNAL, NULL, true); 945 946 pool->base.clock_sources[0] = 947 dce100_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL0, &clk_src_regs[0], false); 948 pool->base.clock_sources[1] = 949 dce100_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[1], false); 950 pool->base.clock_sources[2] = 951 dce100_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL2, &clk_src_regs[2], false); 952 pool->base.clk_src_count = 3; 953 954 } else { 955 pool->base.dp_clock_source = 956 dce100_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL0, &clk_src_regs[0], true); 957 958 pool->base.clock_sources[0] = 959 dce100_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[1], false); 960 pool->base.clock_sources[1] = 961 dce100_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL2, &clk_src_regs[2], false); 962 pool->base.clk_src_count = 2; 963 } 964 965 if (pool->base.dp_clock_source == NULL) { 966 dm_error("DC: failed to create dp clock source!\n"); 967 BREAK_TO_DEBUGGER(); 968 goto res_create_fail; 969 } 970 971 for (i = 0; i < pool->base.clk_src_count; i++) { 972 if (pool->base.clock_sources[i] == NULL) { 973 dm_error("DC: failed to create clock sources!\n"); 974 BREAK_TO_DEBUGGER(); 975 goto res_create_fail; 976 } 977 } 978 979 pool->base.display_clock = dce_disp_clk_create(ctx, 980 &disp_clk_regs, 981 &disp_clk_shift, 982 &disp_clk_mask); 983 if (pool->base.display_clock == NULL) { 984 dm_error("DC: failed to create display clock!\n"); 985 BREAK_TO_DEBUGGER(); 986 goto res_create_fail; 987 } 988 989 990 /* get static clock information for PPLIB or firmware, save 991 * max_clock_state 992 */ 993 if (dm_pp_get_static_clocks(ctx, &static_clk_info)) 994 pool->base.display_clock->max_clks_state = 995 static_clk_info.max_clocks_state; 996 { 997 struct irq_service_init_data init_data; 998 init_data.ctx = dc->ctx; 999 pool->base.irqs = dal_irq_service_dce110_create(&init_data); 1000 if (!pool->base.irqs) 1001 goto res_create_fail; 1002 } 1003 1004 /************************************************* 1005 * Resource + asic cap harcoding * 1006 *************************************************/ 1007 pool->base.underlay_pipe_index = -1; 1008 pool->base.pipe_count = res_cap.num_timing_generator; 1009 dc->public.caps.max_downscale_ratio = 200; 1010 dc->public.caps.i2c_speed_in_khz = 40; 1011 1012 for (i = 0; i < pool->base.pipe_count; i++) { 1013 pool->base.timing_generators[i] = 1014 dce100_timing_generator_create( 1015 ctx, 1016 i, 1017 &dce100_tg_offsets[i]); 1018 if (pool->base.timing_generators[i] == NULL) { 1019 BREAK_TO_DEBUGGER(); 1020 dm_error("DC: failed to create tg!\n"); 1021 goto res_create_fail; 1022 } 1023 1024 pool->base.mis[i] = dce100_mem_input_create(ctx, i, 1025 &dce100_mi_reg_offsets[i]); 1026 if (pool->base.mis[i] == NULL) { 1027 BREAK_TO_DEBUGGER(); 1028 dm_error( 1029 "DC: failed to create memory input!\n"); 1030 goto res_create_fail; 1031 } 1032 1033 pool->base.ipps[i] = dce100_ipp_create(ctx, i, 1034 &dce100_ipp_reg_offsets[i]); 1035 if (pool->base.ipps[i] == NULL) { 1036 BREAK_TO_DEBUGGER(); 1037 dm_error( 1038 "DC: failed to create input pixel processor!\n"); 1039 goto res_create_fail; 1040 } 1041 1042 pool->base.transforms[i] = dce100_transform_create(ctx, i); 1043 if (pool->base.transforms[i] == NULL) { 1044 BREAK_TO_DEBUGGER(); 1045 dm_error( 1046 "DC: failed to create transform!\n"); 1047 goto res_create_fail; 1048 } 1049 1050 pool->base.opps[i] = dce100_opp_create(ctx, i); 1051 if (pool->base.opps[i] == NULL) { 1052 BREAK_TO_DEBUGGER(); 1053 dm_error( 1054 "DC: failed to create output pixel processor!\n"); 1055 goto res_create_fail; 1056 } 1057 } 1058 1059 if (!resource_construct(num_virtual_links, dc, &pool->base, 1060 &res_create_funcs)) 1061 goto res_create_fail; 1062 1063 /* Create hardware sequencer */ 1064 if (!dce100_hw_sequencer_construct(dc)) 1065 goto res_create_fail; 1066 1067 return true; 1068 1069 res_create_fail: 1070 destruct(pool); 1071 1072 return false; 1073 } 1074 1075 struct resource_pool *dce100_create_resource_pool( 1076 uint8_t num_virtual_links, 1077 struct core_dc *dc) 1078 { 1079 struct dce110_resource_pool *pool = 1080 dm_alloc(sizeof(struct dce110_resource_pool)); 1081 1082 if (!pool) 1083 return NULL; 1084 1085 if (construct(num_virtual_links, dc, pool)) 1086 return &pool->base; 1087 1088 BREAK_TO_DEBUGGER(); 1089 return NULL; 1090 } 1091 1092