1 /* 2 * Copyright 2012-15 Advanced Micro Devices, Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 * OTHER DEALINGS IN THE SOFTWARE. 21 * 22 * Authors: AMD 23 * 24 */ 25 26 #include "dm_services.h" 27 28 #include "ObjectID.h" 29 #include "atomfirmware.h" 30 #include "atomfirmwareid.h" 31 32 #include "include/bios_parser_interface.h" 33 34 #include "command_table2.h" 35 #include "command_table_helper2.h" 36 #include "bios_parser_helper.h" 37 #include "bios_parser_types_internal2.h" 38 39 #define GET_INDEX_INTO_MASTER_TABLE(MasterOrData, FieldName)\ 40 (((char *)(&((\ 41 struct atom_master_list_of_##MasterOrData##_functions_v2_1 *)0)\ 42 ->FieldName)-(char *)0)/sizeof(uint16_t)) 43 44 #define EXEC_BIOS_CMD_TABLE(fname, params)\ 45 (cgs_atom_exec_cmd_table(bp->base.ctx->cgs_device, \ 46 GET_INDEX_INTO_MASTER_TABLE(command, fname), \ 47 ¶ms) == 0) 48 49 #define BIOS_CMD_TABLE_REVISION(fname, frev, crev)\ 50 cgs_atom_get_cmd_table_revs(bp->base.ctx->cgs_device, \ 51 GET_INDEX_INTO_MASTER_TABLE(command, fname), &frev, &crev) 52 53 #define BIOS_CMD_TABLE_PARA_REVISION(fname)\ 54 bios_cmd_table_para_revision(bp->base.ctx->cgs_device, \ 55 GET_INDEX_INTO_MASTER_TABLE(command, fname)) 56 57 static void init_dig_encoder_control(struct bios_parser *bp); 58 static void init_transmitter_control(struct bios_parser *bp); 59 static void init_set_pixel_clock(struct bios_parser *bp); 60 61 static void init_set_crtc_timing(struct bios_parser *bp); 62 63 static void init_select_crtc_source(struct bios_parser *bp); 64 static void init_enable_crtc(struct bios_parser *bp); 65 66 static void init_external_encoder_control(struct bios_parser *bp); 67 static void init_enable_disp_power_gating(struct bios_parser *bp); 68 static void init_set_dce_clock(struct bios_parser *bp); 69 static void init_get_smu_clock_info(struct bios_parser *bp); 70 71 void dal_firmware_parser_init_cmd_tbl(struct bios_parser *bp) 72 { 73 init_dig_encoder_control(bp); 74 init_transmitter_control(bp); 75 init_set_pixel_clock(bp); 76 77 init_set_crtc_timing(bp); 78 79 init_select_crtc_source(bp); 80 init_enable_crtc(bp); 81 82 init_external_encoder_control(bp); 83 init_enable_disp_power_gating(bp); 84 init_set_dce_clock(bp); 85 init_get_smu_clock_info(bp); 86 } 87 88 static uint32_t bios_cmd_table_para_revision(void *cgs_device, 89 uint32_t index) 90 { 91 uint8_t frev, crev; 92 93 if (cgs_atom_get_cmd_table_revs(cgs_device, 94 index, 95 &frev, &crev) != 0) 96 return 0; 97 return crev; 98 } 99 100 /****************************************************************************** 101 ****************************************************************************** 102 ** 103 ** D I G E N C O D E R C O N T R O L 104 ** 105 ****************************************************************************** 106 *****************************************************************************/ 107 108 static enum bp_result encoder_control_digx_v1_5( 109 struct bios_parser *bp, 110 struct bp_encoder_control *cntl); 111 112 static void init_dig_encoder_control(struct bios_parser *bp) 113 { 114 uint32_t version = 115 BIOS_CMD_TABLE_PARA_REVISION(digxencodercontrol); 116 117 switch (version) { 118 case 5: 119 bp->cmd_tbl.dig_encoder_control = encoder_control_digx_v1_5; 120 break; 121 default: 122 bp->cmd_tbl.dig_encoder_control = NULL; 123 break; 124 } 125 } 126 127 static enum bp_result encoder_control_digx_v1_5( 128 struct bios_parser *bp, 129 struct bp_encoder_control *cntl) 130 { 131 enum bp_result result = BP_RESULT_FAILURE; 132 struct dig_encoder_stream_setup_parameters_v1_5 params = {0}; 133 134 params.digid = (uint8_t)(cntl->engine_id); 135 params.action = bp->cmd_helper->encoder_action_to_atom(cntl->action); 136 137 params.pclk_10khz = cntl->pixel_clock / 10; 138 params.digmode = 139 (uint8_t)(bp->cmd_helper->encoder_mode_bp_to_atom( 140 cntl->signal, 141 cntl->enable_dp_audio)); 142 params.lanenum = (uint8_t)(cntl->lanes_number); 143 144 switch (cntl->color_depth) { 145 case COLOR_DEPTH_888: 146 params.bitpercolor = PANEL_8BIT_PER_COLOR; 147 break; 148 case COLOR_DEPTH_101010: 149 params.bitpercolor = PANEL_10BIT_PER_COLOR; 150 break; 151 case COLOR_DEPTH_121212: 152 params.bitpercolor = PANEL_12BIT_PER_COLOR; 153 break; 154 case COLOR_DEPTH_161616: 155 params.bitpercolor = PANEL_16BIT_PER_COLOR; 156 break; 157 default: 158 break; 159 } 160 161 if (cntl->signal == SIGNAL_TYPE_HDMI_TYPE_A) 162 switch (cntl->color_depth) { 163 case COLOR_DEPTH_101010: 164 params.pclk_10khz = 165 (params.pclk_10khz * 30) / 24; 166 break; 167 case COLOR_DEPTH_121212: 168 params.pclk_10khz = 169 (params.pclk_10khz * 36) / 24; 170 break; 171 case COLOR_DEPTH_161616: 172 params.pclk_10khz = 173 (params.pclk_10khz * 48) / 24; 174 break; 175 default: 176 break; 177 } 178 179 if (EXEC_BIOS_CMD_TABLE(digxencodercontrol, params)) 180 result = BP_RESULT_OK; 181 182 return result; 183 } 184 185 /***************************************************************************** 186 ****************************************************************************** 187 ** 188 ** TRANSMITTER CONTROL 189 ** 190 ****************************************************************************** 191 *****************************************************************************/ 192 193 static enum bp_result transmitter_control_v1_6( 194 struct bios_parser *bp, 195 struct bp_transmitter_control *cntl); 196 197 static void init_transmitter_control(struct bios_parser *bp) 198 { 199 uint8_t frev; 200 uint8_t crev; 201 202 if (BIOS_CMD_TABLE_REVISION(dig1transmittercontrol, frev, crev) != 0) 203 BREAK_TO_DEBUGGER(); 204 switch (crev) { 205 case 6: 206 bp->cmd_tbl.transmitter_control = transmitter_control_v1_6; 207 break; 208 default: 209 bp->cmd_tbl.transmitter_control = NULL; 210 break; 211 } 212 } 213 214 static enum bp_result transmitter_control_v1_6( 215 struct bios_parser *bp, 216 struct bp_transmitter_control *cntl) 217 { 218 enum bp_result result = BP_RESULT_FAILURE; 219 const struct command_table_helper *cmd = bp->cmd_helper; 220 struct dig_transmitter_control_ps_allocation_v1_6 ps = { { 0 } }; 221 222 ps.param.phyid = cmd->phy_id_to_atom(cntl->transmitter); 223 ps.param.action = (uint8_t)cntl->action; 224 225 if (cntl->action == TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS) 226 ps.param.mode_laneset.dplaneset = (uint8_t)cntl->lane_settings; 227 else 228 ps.param.mode_laneset.digmode = 229 cmd->signal_type_to_atom_dig_mode(cntl->signal); 230 231 ps.param.lanenum = (uint8_t)cntl->lanes_number; 232 ps.param.hpdsel = cmd->hpd_sel_to_atom(cntl->hpd_sel); 233 ps.param.digfe_sel = cmd->dig_encoder_sel_to_atom(cntl->engine_id); 234 ps.param.connobj_id = (uint8_t)cntl->connector_obj_id.id; 235 ps.param.symclk_10khz = cntl->pixel_clock/10; 236 237 238 if (cntl->action == TRANSMITTER_CONTROL_ENABLE || 239 cntl->action == TRANSMITTER_CONTROL_ACTIAVATE || 240 cntl->action == TRANSMITTER_CONTROL_DEACTIVATE) { 241 dm_logger_write(bp->base.ctx->logger, LOG_BIOS,\ 242 "%s:ps.param.symclk_10khz = %d\n",\ 243 __func__, ps.param.symclk_10khz); 244 } 245 246 247 /*color_depth not used any more, driver has deep color factor in the Phyclk*/ 248 if (EXEC_BIOS_CMD_TABLE(dig1transmittercontrol, ps)) 249 result = BP_RESULT_OK; 250 return result; 251 } 252 253 /****************************************************************************** 254 ****************************************************************************** 255 ** 256 ** SET PIXEL CLOCK 257 ** 258 ****************************************************************************** 259 *****************************************************************************/ 260 261 static enum bp_result set_pixel_clock_v7( 262 struct bios_parser *bp, 263 struct bp_pixel_clock_parameters *bp_params); 264 265 static void init_set_pixel_clock(struct bios_parser *bp) 266 { 267 switch (BIOS_CMD_TABLE_PARA_REVISION(setpixelclock)) { 268 case 7: 269 bp->cmd_tbl.set_pixel_clock = set_pixel_clock_v7; 270 break; 271 default: 272 bp->cmd_tbl.set_pixel_clock = NULL; 273 break; 274 } 275 } 276 277 278 279 static enum bp_result set_pixel_clock_v7( 280 struct bios_parser *bp, 281 struct bp_pixel_clock_parameters *bp_params) 282 { 283 enum bp_result result = BP_RESULT_FAILURE; 284 struct set_pixel_clock_parameter_v1_7 clk; 285 uint8_t controller_id; 286 uint32_t pll_id; 287 288 memset(&clk, 0, sizeof(clk)); 289 290 if (bp->cmd_helper->clock_source_id_to_atom(bp_params->pll_id, &pll_id) 291 && bp->cmd_helper->controller_id_to_atom(bp_params-> 292 controller_id, &controller_id)) { 293 /* Note: VBIOS still wants to use ucCRTC name which is now 294 * 1 byte in ULONG 295 *typedef struct _CRTC_PIXEL_CLOCK_FREQ 296 *{ 297 * target the pixel clock to drive the CRTC timing. 298 * ULONG ulPixelClock:24; 299 * 0 means disable PPLL/DCPLL. Expanded to 24 bits comparing to 300 * previous version. 301 * ATOM_CRTC1~6, indicate the CRTC controller to 302 * ULONG ucCRTC:8; 303 * drive the pixel clock. not used for DCPLL case. 304 *}CRTC_PIXEL_CLOCK_FREQ; 305 *union 306 *{ 307 * pixel clock and CRTC id frequency 308 * CRTC_PIXEL_CLOCK_FREQ ulCrtcPclkFreq; 309 * ULONG ulDispEngClkFreq; dispclk frequency 310 *}; 311 */ 312 clk.crtc_id = controller_id; 313 clk.pll_id = (uint8_t) pll_id; 314 clk.encoderobjid = 315 bp->cmd_helper->encoder_id_to_atom( 316 dal_graphics_object_id_get_encoder_id( 317 bp_params->encoder_object_id)); 318 319 clk.encoder_mode = (uint8_t) bp-> 320 cmd_helper->encoder_mode_bp_to_atom( 321 bp_params->signal_type, false); 322 323 /* We need to convert from KHz units into 10KHz units */ 324 clk.pixclk_100hz = cpu_to_le32(bp_params->target_pixel_clock * 325 10); 326 327 clk.deep_color_ratio = 328 (uint8_t) bp->cmd_helper-> 329 transmitter_color_depth_to_atom( 330 bp_params->color_depth); 331 dm_logger_write(bp->base.ctx->logger, LOG_BIOS,\ 332 "%s:program display clock = %d"\ 333 "colorDepth = %d\n", __func__,\ 334 bp_params->target_pixel_clock, bp_params->color_depth); 335 336 if (bp_params->flags.FORCE_PROGRAMMING_OF_PLL) 337 clk.miscinfo |= PIXEL_CLOCK_V7_MISC_FORCE_PROG_PPLL; 338 339 if (bp_params->flags.PROGRAM_PHY_PLL_ONLY) 340 clk.miscinfo |= PIXEL_CLOCK_V7_MISC_PROG_PHYPLL; 341 342 if (bp_params->flags.SUPPORT_YUV_420) 343 clk.miscinfo |= PIXEL_CLOCK_V7_MISC_YUV420_MODE; 344 345 if (bp_params->flags.SET_XTALIN_REF_SRC) 346 clk.miscinfo |= PIXEL_CLOCK_V7_MISC_REF_DIV_SRC_XTALIN; 347 348 if (bp_params->flags.SET_GENLOCK_REF_DIV_SRC) 349 clk.miscinfo |= PIXEL_CLOCK_V7_MISC_REF_DIV_SRC_GENLK; 350 351 if (bp_params->signal_type == SIGNAL_TYPE_DVI_DUAL_LINK) 352 clk.miscinfo |= PIXEL_CLOCK_V7_MISC_DVI_DUALLINK_EN; 353 354 if (EXEC_BIOS_CMD_TABLE(setpixelclock, clk)) 355 result = BP_RESULT_OK; 356 } 357 return result; 358 } 359 360 /****************************************************************************** 361 ****************************************************************************** 362 ** 363 ** SET CRTC TIMING 364 ** 365 ****************************************************************************** 366 *****************************************************************************/ 367 368 static enum bp_result set_crtc_using_dtd_timing_v3( 369 struct bios_parser *bp, 370 struct bp_hw_crtc_timing_parameters *bp_params); 371 372 static void init_set_crtc_timing(struct bios_parser *bp) 373 { 374 uint32_t dtd_version = 375 BIOS_CMD_TABLE_PARA_REVISION(setcrtc_usingdtdtiming); 376 377 switch (dtd_version) { 378 case 3: 379 bp->cmd_tbl.set_crtc_timing = 380 set_crtc_using_dtd_timing_v3; 381 break; 382 default: 383 bp->cmd_tbl.set_crtc_timing = NULL; 384 break; 385 } 386 } 387 388 static enum bp_result set_crtc_using_dtd_timing_v3( 389 struct bios_parser *bp, 390 struct bp_hw_crtc_timing_parameters *bp_params) 391 { 392 enum bp_result result = BP_RESULT_FAILURE; 393 struct set_crtc_using_dtd_timing_parameters params = {0}; 394 uint8_t atom_controller_id; 395 396 if (bp->cmd_helper->controller_id_to_atom( 397 bp_params->controller_id, &atom_controller_id)) 398 params.crtc_id = atom_controller_id; 399 400 /* bios usH_Size wants h addressable size */ 401 params.h_size = cpu_to_le16((uint16_t)bp_params->h_addressable); 402 /* bios usH_Blanking_Time wants borders included in blanking */ 403 params.h_blanking_time = 404 cpu_to_le16((uint16_t)(bp_params->h_total - 405 bp_params->h_addressable)); 406 /* bios usV_Size wants v addressable size */ 407 params.v_size = cpu_to_le16((uint16_t)bp_params->v_addressable); 408 /* bios usV_Blanking_Time wants borders included in blanking */ 409 params.v_blanking_time = 410 cpu_to_le16((uint16_t)(bp_params->v_total - 411 bp_params->v_addressable)); 412 /* bios usHSyncOffset is the offset from the end of h addressable, 413 * our horizontalSyncStart is the offset from the beginning 414 * of h addressable 415 */ 416 params.h_syncoffset = 417 cpu_to_le16((uint16_t)(bp_params->h_sync_start - 418 bp_params->h_addressable)); 419 params.h_syncwidth = cpu_to_le16((uint16_t)bp_params->h_sync_width); 420 /* bios usHSyncOffset is the offset from the end of v addressable, 421 * our verticalSyncStart is the offset from the beginning of 422 * v addressable 423 */ 424 params.v_syncoffset = 425 cpu_to_le16((uint16_t)(bp_params->v_sync_start - 426 bp_params->v_addressable)); 427 params.v_syncwidth = cpu_to_le16((uint16_t)bp_params->v_sync_width); 428 429 /* we assume that overscan from original timing does not get bigger 430 * than 255 431 * we will program all the borders in the Set CRTC Overscan call below 432 */ 433 434 if (bp_params->flags.HSYNC_POSITIVE_POLARITY == 0) 435 params.modemiscinfo = 436 cpu_to_le16(le16_to_cpu(params.modemiscinfo) | 437 ATOM_HSYNC_POLARITY); 438 439 if (bp_params->flags.VSYNC_POSITIVE_POLARITY == 0) 440 params.modemiscinfo = 441 cpu_to_le16(le16_to_cpu(params.modemiscinfo) | 442 ATOM_VSYNC_POLARITY); 443 444 if (bp_params->flags.INTERLACE) { 445 params.modemiscinfo = 446 cpu_to_le16(le16_to_cpu(params.modemiscinfo) | 447 ATOM_INTERLACE); 448 449 /* original DAL code has this condition to apply this 450 * for non-TV/CV only 451 * due to complex MV testing for possible impact 452 * if ( pACParameters->signal != SignalType_YPbPr && 453 * pACParameters->signal != SignalType_Composite && 454 * pACParameters->signal != SignalType_SVideo) 455 */ 456 { 457 /* HW will deduct 0.5 line from 2nd feild. 458 * i.e. for 1080i, it is 2 lines for 1st field, 459 * 2.5 lines for the 2nd feild. we need input as 5 460 * instead of 4. 461 * but it is 4 either from Edid data (spec CEA 861) 462 * or CEA timing table. 463 */ 464 params.v_syncoffset = 465 cpu_to_le16(le16_to_cpu(params.v_syncoffset) + 466 1); 467 468 } 469 } 470 471 if (bp_params->flags.HORZ_COUNT_BY_TWO) 472 params.modemiscinfo = 473 cpu_to_le16(le16_to_cpu(params.modemiscinfo) | 474 0x100); /* ATOM_DOUBLE_CLOCK_MODE */ 475 476 if (EXEC_BIOS_CMD_TABLE(setcrtc_usingdtdtiming, params)) 477 result = BP_RESULT_OK; 478 479 return result; 480 } 481 482 /****************************************************************************** 483 ****************************************************************************** 484 ** 485 ** SELECT CRTC SOURCE 486 ** 487 ****************************************************************************** 488 *****************************************************************************/ 489 490 491 static enum bp_result select_crtc_source_v3( 492 struct bios_parser *bp, 493 struct bp_crtc_source_select *bp_params); 494 495 static void init_select_crtc_source(struct bios_parser *bp) 496 { 497 switch (BIOS_CMD_TABLE_PARA_REVISION(selectcrtc_source)) { 498 case 3: 499 bp->cmd_tbl.select_crtc_source = select_crtc_source_v3; 500 break; 501 default: 502 bp->cmd_tbl.select_crtc_source = NULL; 503 break; 504 } 505 } 506 507 508 static enum bp_result select_crtc_source_v3( 509 struct bios_parser *bp, 510 struct bp_crtc_source_select *bp_params) 511 { 512 bool result = BP_RESULT_FAILURE; 513 struct select_crtc_source_parameters_v2_3 params; 514 uint8_t atom_controller_id; 515 uint32_t atom_engine_id; 516 enum signal_type s = bp_params->signal; 517 518 memset(¶ms, 0, sizeof(params)); 519 520 if (bp->cmd_helper->controller_id_to_atom(bp_params->controller_id, 521 &atom_controller_id)) 522 params.crtc_id = atom_controller_id; 523 else 524 return result; 525 526 if (bp->cmd_helper->engine_bp_to_atom(bp_params->engine_id, 527 &atom_engine_id)) 528 params.encoder_id = (uint8_t)atom_engine_id; 529 else 530 return result; 531 532 if (s == SIGNAL_TYPE_EDP || 533 (s == SIGNAL_TYPE_DISPLAY_PORT && bp_params->sink_signal == 534 SIGNAL_TYPE_LVDS)) 535 s = SIGNAL_TYPE_LVDS; 536 537 params.encode_mode = 538 bp->cmd_helper->encoder_mode_bp_to_atom( 539 s, bp_params->enable_dp_audio); 540 /* Needed for VBIOS Random Spatial Dithering feature */ 541 params.dst_bpc = (uint8_t)(bp_params->display_output_bit_depth); 542 543 if (EXEC_BIOS_CMD_TABLE(selectcrtc_source, params)) 544 result = BP_RESULT_OK; 545 546 return result; 547 } 548 549 /****************************************************************************** 550 ****************************************************************************** 551 ** 552 ** ENABLE CRTC 553 ** 554 ****************************************************************************** 555 *****************************************************************************/ 556 557 static enum bp_result enable_crtc_v1( 558 struct bios_parser *bp, 559 enum controller_id controller_id, 560 bool enable); 561 562 static void init_enable_crtc(struct bios_parser *bp) 563 { 564 switch (BIOS_CMD_TABLE_PARA_REVISION(enablecrtc)) { 565 case 1: 566 bp->cmd_tbl.enable_crtc = enable_crtc_v1; 567 break; 568 default: 569 bp->cmd_tbl.enable_crtc = NULL; 570 break; 571 } 572 } 573 574 static enum bp_result enable_crtc_v1( 575 struct bios_parser *bp, 576 enum controller_id controller_id, 577 bool enable) 578 { 579 bool result = BP_RESULT_FAILURE; 580 struct enable_crtc_parameters params = {0}; 581 uint8_t id; 582 583 if (bp->cmd_helper->controller_id_to_atom(controller_id, &id)) 584 params.crtc_id = id; 585 else 586 return BP_RESULT_BADINPUT; 587 588 if (enable) 589 params.enable = ATOM_ENABLE; 590 else 591 params.enable = ATOM_DISABLE; 592 593 if (EXEC_BIOS_CMD_TABLE(enablecrtc, params)) 594 result = BP_RESULT_OK; 595 596 return result; 597 } 598 599 /****************************************************************************** 600 ****************************************************************************** 601 ** 602 ** DISPLAY PLL 603 ** 604 ****************************************************************************** 605 *****************************************************************************/ 606 607 608 609 /****************************************************************************** 610 ****************************************************************************** 611 ** 612 ** EXTERNAL ENCODER CONTROL 613 ** 614 ****************************************************************************** 615 *****************************************************************************/ 616 617 static enum bp_result external_encoder_control_v3( 618 struct bios_parser *bp, 619 struct bp_external_encoder_control *cntl); 620 621 static void init_external_encoder_control( 622 struct bios_parser *bp) 623 { 624 switch (BIOS_CMD_TABLE_PARA_REVISION(externalencodercontrol)) { 625 case 3: 626 bp->cmd_tbl.external_encoder_control = 627 external_encoder_control_v3; 628 break; 629 default: 630 bp->cmd_tbl.external_encoder_control = NULL; 631 break; 632 } 633 } 634 635 static enum bp_result external_encoder_control_v3( 636 struct bios_parser *bp, 637 struct bp_external_encoder_control *cntl) 638 { 639 /* TODO */ 640 return BP_RESULT_OK; 641 } 642 643 /****************************************************************************** 644 ****************************************************************************** 645 ** 646 ** ENABLE DISPLAY POWER GATING 647 ** 648 ****************************************************************************** 649 *****************************************************************************/ 650 651 static enum bp_result enable_disp_power_gating_v2_1( 652 struct bios_parser *bp, 653 enum controller_id crtc_id, 654 enum bp_pipe_control_action action); 655 656 static void init_enable_disp_power_gating( 657 struct bios_parser *bp) 658 { 659 switch (BIOS_CMD_TABLE_PARA_REVISION(enabledisppowergating)) { 660 case 1: 661 bp->cmd_tbl.enable_disp_power_gating = 662 enable_disp_power_gating_v2_1; 663 break; 664 default: 665 bp->cmd_tbl.enable_disp_power_gating = NULL; 666 break; 667 } 668 } 669 670 static enum bp_result enable_disp_power_gating_v2_1( 671 struct bios_parser *bp, 672 enum controller_id crtc_id, 673 enum bp_pipe_control_action action) 674 { 675 enum bp_result result = BP_RESULT_FAILURE; 676 677 678 struct enable_disp_power_gating_ps_allocation ps = { { 0 } }; 679 uint8_t atom_crtc_id; 680 681 if (bp->cmd_helper->controller_id_to_atom(crtc_id, &atom_crtc_id)) 682 ps.param.disp_pipe_id = atom_crtc_id; 683 else 684 return BP_RESULT_BADINPUT; 685 686 ps.param.enable = 687 bp->cmd_helper->disp_power_gating_action_to_atom(action); 688 689 if (EXEC_BIOS_CMD_TABLE(enabledisppowergating, ps.param)) 690 result = BP_RESULT_OK; 691 692 return result; 693 } 694 695 /****************************************************************************** 696 ******************************************************************************* 697 ** 698 ** SET DCE CLOCK 699 ** 700 ******************************************************************************* 701 *******************************************************************************/ 702 703 static enum bp_result set_dce_clock_v2_1( 704 struct bios_parser *bp, 705 struct bp_set_dce_clock_parameters *bp_params); 706 707 static void init_set_dce_clock(struct bios_parser *bp) 708 { 709 switch (BIOS_CMD_TABLE_PARA_REVISION(setdceclock)) { 710 case 1: 711 bp->cmd_tbl.set_dce_clock = set_dce_clock_v2_1; 712 break; 713 default: 714 bp->cmd_tbl.set_dce_clock = NULL; 715 break; 716 } 717 } 718 719 static enum bp_result set_dce_clock_v2_1( 720 struct bios_parser *bp, 721 struct bp_set_dce_clock_parameters *bp_params) 722 { 723 enum bp_result result = BP_RESULT_FAILURE; 724 725 struct set_dce_clock_ps_allocation_v2_1 params; 726 uint32_t atom_pll_id; 727 uint32_t atom_clock_type; 728 const struct command_table_helper *cmd = bp->cmd_helper; 729 730 memset(¶ms, 0, sizeof(params)); 731 732 if (!cmd->clock_source_id_to_atom(bp_params->pll_id, &atom_pll_id) || 733 !cmd->dc_clock_type_to_atom(bp_params->clock_type, 734 &atom_clock_type)) 735 return BP_RESULT_BADINPUT; 736 737 params.param.dceclksrc = atom_pll_id; 738 params.param.dceclktype = atom_clock_type; 739 740 if (bp_params->clock_type == DCECLOCK_TYPE_DPREFCLK) { 741 if (bp_params->flags.USE_GENLOCK_AS_SOURCE_FOR_DPREFCLK) 742 params.param.dceclkflag |= 743 DCE_CLOCK_FLAG_PLL_REFCLK_SRC_GENLK; 744 745 if (bp_params->flags.USE_PCIE_AS_SOURCE_FOR_DPREFCLK) 746 params.param.dceclkflag |= 747 DCE_CLOCK_FLAG_PLL_REFCLK_SRC_PCIE; 748 749 if (bp_params->flags.USE_XTALIN_AS_SOURCE_FOR_DPREFCLK) 750 params.param.dceclkflag |= 751 DCE_CLOCK_FLAG_PLL_REFCLK_SRC_XTALIN; 752 753 if (bp_params->flags.USE_GENERICA_AS_SOURCE_FOR_DPREFCLK) 754 params.param.dceclkflag |= 755 DCE_CLOCK_FLAG_PLL_REFCLK_SRC_GENERICA; 756 } else 757 /* only program clock frequency if display clock is used; 758 * VBIOS will program DPREFCLK 759 * We need to convert from KHz units into 10KHz units 760 */ 761 params.param.dceclk_10khz = cpu_to_le32( 762 bp_params->target_clock_frequency / 10); 763 dm_logger_write(bp->base.ctx->logger, LOG_BIOS, 764 "%s:target_clock_frequency = %d"\ 765 "clock_type = %d \n", __func__,\ 766 bp_params->target_clock_frequency,\ 767 bp_params->clock_type); 768 769 if (EXEC_BIOS_CMD_TABLE(setdceclock, params)) { 770 /* Convert from 10KHz units back to KHz */ 771 bp_params->target_clock_frequency = le32_to_cpu( 772 params.param.dceclk_10khz) * 10; 773 result = BP_RESULT_OK; 774 } 775 776 return result; 777 } 778 779 780 /****************************************************************************** 781 ****************************************************************************** 782 ** 783 ** GET SMU CLOCK INFO 784 ** 785 ****************************************************************************** 786 *****************************************************************************/ 787 788 static unsigned int get_smu_clock_info_v3_1(struct bios_parser *bp); 789 790 static void init_get_smu_clock_info(struct bios_parser *bp) 791 { 792 /* TODO add switch for table vrsion */ 793 bp->cmd_tbl.get_smu_clock_info = get_smu_clock_info_v3_1; 794 795 } 796 797 static unsigned int get_smu_clock_info_v3_1(struct bios_parser *bp) 798 { 799 struct atom_get_smu_clock_info_parameters_v3_1 smu_input = {0}; 800 struct atom_get_smu_clock_info_output_parameters_v3_1 smu_output; 801 802 smu_input.command = GET_SMU_CLOCK_INFO_V3_1_GET_PLLVCO_FREQ; 803 804 /* Get Specific Clock */ 805 if (EXEC_BIOS_CMD_TABLE(getsmuclockinfo, smu_input)) { 806 memmove(&smu_output, &smu_input, sizeof( 807 struct atom_get_smu_clock_info_parameters_v3_1)); 808 return smu_output.atom_smu_outputclkfreq.syspllvcofreq_10khz; 809 } 810 811 return 0; 812 } 813 814