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