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