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 /* We need to convert from KHz units into 10KHz units */ 305 clk.pixclk_100hz = cpu_to_le32(bp_params->target_pixel_clock * 306 10); 307 308 clk.deep_color_ratio = 309 (uint8_t) bp->cmd_helper-> 310 transmitter_color_depth_to_atom( 311 bp_params->color_depth); 312 DC_LOG_BIOS("%s:program display clock = %d"\ 313 "colorDepth = %d\n", __func__,\ 314 bp_params->target_pixel_clock, 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 ** SELECT CRTC SOURCE 467 ** 468 ****************************************************************************** 469 *****************************************************************************/ 470 471 472 static enum bp_result select_crtc_source_v3( 473 struct bios_parser *bp, 474 struct bp_crtc_source_select *bp_params); 475 476 static void init_select_crtc_source(struct bios_parser *bp) 477 { 478 switch (BIOS_CMD_TABLE_PARA_REVISION(selectcrtc_source)) { 479 case 3: 480 bp->cmd_tbl.select_crtc_source = select_crtc_source_v3; 481 break; 482 default: 483 dm_output_to_console("Don't select_crtc_source enable_crtc for v%d\n", 484 BIOS_CMD_TABLE_PARA_REVISION(selectcrtc_source)); 485 bp->cmd_tbl.select_crtc_source = NULL; 486 break; 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 bool result = BP_RESULT_FAILURE; 496 struct select_crtc_source_parameters_v2_3 params; 497 uint8_t atom_controller_id; 498 uint32_t atom_engine_id; 499 enum signal_type s = bp_params->signal; 500 501 memset(¶ms, 0, sizeof(params)); 502 503 if (bp->cmd_helper->controller_id_to_atom(bp_params->controller_id, 504 &atom_controller_id)) 505 params.crtc_id = atom_controller_id; 506 else 507 return result; 508 509 if (bp->cmd_helper->engine_bp_to_atom(bp_params->engine_id, 510 &atom_engine_id)) 511 params.encoder_id = (uint8_t)atom_engine_id; 512 else 513 return result; 514 515 if (s == SIGNAL_TYPE_EDP || 516 (s == SIGNAL_TYPE_DISPLAY_PORT && bp_params->sink_signal == 517 SIGNAL_TYPE_LVDS)) 518 s = SIGNAL_TYPE_LVDS; 519 520 params.encode_mode = 521 bp->cmd_helper->encoder_mode_bp_to_atom( 522 s, bp_params->enable_dp_audio); 523 /* Needed for VBIOS Random Spatial Dithering feature */ 524 params.dst_bpc = (uint8_t)(bp_params->display_output_bit_depth); 525 526 if (EXEC_BIOS_CMD_TABLE(selectcrtc_source, params)) 527 result = BP_RESULT_OK; 528 529 return result; 530 } 531 532 /****************************************************************************** 533 ****************************************************************************** 534 ** 535 ** ENABLE CRTC 536 ** 537 ****************************************************************************** 538 *****************************************************************************/ 539 540 static enum bp_result enable_crtc_v1( 541 struct bios_parser *bp, 542 enum controller_id controller_id, 543 bool enable); 544 545 static void init_enable_crtc(struct bios_parser *bp) 546 { 547 switch (BIOS_CMD_TABLE_PARA_REVISION(enablecrtc)) { 548 case 1: 549 bp->cmd_tbl.enable_crtc = enable_crtc_v1; 550 break; 551 default: 552 dm_output_to_console("Don't have enable_crtc for v%d\n", 553 BIOS_CMD_TABLE_PARA_REVISION(enablecrtc)); 554 bp->cmd_tbl.enable_crtc = NULL; 555 break; 556 } 557 } 558 559 static enum bp_result enable_crtc_v1( 560 struct bios_parser *bp, 561 enum controller_id controller_id, 562 bool enable) 563 { 564 bool result = BP_RESULT_FAILURE; 565 struct enable_crtc_parameters params = {0}; 566 uint8_t id; 567 568 if (bp->cmd_helper->controller_id_to_atom(controller_id, &id)) 569 params.crtc_id = id; 570 else 571 return BP_RESULT_BADINPUT; 572 573 if (enable) 574 params.enable = ATOM_ENABLE; 575 else 576 params.enable = ATOM_DISABLE; 577 578 if (EXEC_BIOS_CMD_TABLE(enablecrtc, params)) 579 result = BP_RESULT_OK; 580 581 return result; 582 } 583 584 /****************************************************************************** 585 ****************************************************************************** 586 ** 587 ** DISPLAY PLL 588 ** 589 ****************************************************************************** 590 *****************************************************************************/ 591 592 593 594 /****************************************************************************** 595 ****************************************************************************** 596 ** 597 ** EXTERNAL ENCODER CONTROL 598 ** 599 ****************************************************************************** 600 *****************************************************************************/ 601 602 static enum bp_result external_encoder_control_v3( 603 struct bios_parser *bp, 604 struct bp_external_encoder_control *cntl); 605 606 static void init_external_encoder_control( 607 struct bios_parser *bp) 608 { 609 switch (BIOS_CMD_TABLE_PARA_REVISION(externalencodercontrol)) { 610 case 3: 611 bp->cmd_tbl.external_encoder_control = 612 external_encoder_control_v3; 613 break; 614 default: 615 bp->cmd_tbl.external_encoder_control = NULL; 616 break; 617 } 618 } 619 620 static enum bp_result external_encoder_control_v3( 621 struct bios_parser *bp, 622 struct bp_external_encoder_control *cntl) 623 { 624 /* TODO */ 625 return BP_RESULT_OK; 626 } 627 628 /****************************************************************************** 629 ****************************************************************************** 630 ** 631 ** ENABLE DISPLAY POWER GATING 632 ** 633 ****************************************************************************** 634 *****************************************************************************/ 635 636 static enum bp_result enable_disp_power_gating_v2_1( 637 struct bios_parser *bp, 638 enum controller_id crtc_id, 639 enum bp_pipe_control_action action); 640 641 static void init_enable_disp_power_gating( 642 struct bios_parser *bp) 643 { 644 switch (BIOS_CMD_TABLE_PARA_REVISION(enabledisppowergating)) { 645 case 1: 646 bp->cmd_tbl.enable_disp_power_gating = 647 enable_disp_power_gating_v2_1; 648 break; 649 default: 650 dm_output_to_console("Don't enable_disp_power_gating enable_crtc for v%d\n", 651 BIOS_CMD_TABLE_PARA_REVISION(enabledisppowergating)); 652 bp->cmd_tbl.enable_disp_power_gating = NULL; 653 break; 654 } 655 } 656 657 static enum bp_result enable_disp_power_gating_v2_1( 658 struct bios_parser *bp, 659 enum controller_id crtc_id, 660 enum bp_pipe_control_action action) 661 { 662 enum bp_result result = BP_RESULT_FAILURE; 663 664 665 struct enable_disp_power_gating_ps_allocation ps = { { 0 } }; 666 uint8_t atom_crtc_id; 667 668 if (bp->cmd_helper->controller_id_to_atom(crtc_id, &atom_crtc_id)) 669 ps.param.disp_pipe_id = atom_crtc_id; 670 else 671 return BP_RESULT_BADINPUT; 672 673 ps.param.enable = 674 bp->cmd_helper->disp_power_gating_action_to_atom(action); 675 676 if (EXEC_BIOS_CMD_TABLE(enabledisppowergating, ps.param)) 677 result = BP_RESULT_OK; 678 679 return result; 680 } 681 682 /****************************************************************************** 683 ******************************************************************************* 684 ** 685 ** SET DCE CLOCK 686 ** 687 ******************************************************************************* 688 *******************************************************************************/ 689 690 static enum bp_result set_dce_clock_v2_1( 691 struct bios_parser *bp, 692 struct bp_set_dce_clock_parameters *bp_params); 693 694 static void init_set_dce_clock(struct bios_parser *bp) 695 { 696 switch (BIOS_CMD_TABLE_PARA_REVISION(setdceclock)) { 697 case 1: 698 bp->cmd_tbl.set_dce_clock = set_dce_clock_v2_1; 699 break; 700 default: 701 dm_output_to_console("Don't have set_dce_clock for v%d\n", 702 BIOS_CMD_TABLE_PARA_REVISION(setdceclock)); 703 bp->cmd_tbl.set_dce_clock = NULL; 704 break; 705 } 706 } 707 708 static enum bp_result set_dce_clock_v2_1( 709 struct bios_parser *bp, 710 struct bp_set_dce_clock_parameters *bp_params) 711 { 712 enum bp_result result = BP_RESULT_FAILURE; 713 714 struct set_dce_clock_ps_allocation_v2_1 params; 715 uint32_t atom_pll_id; 716 uint32_t atom_clock_type; 717 const struct command_table_helper *cmd = bp->cmd_helper; 718 719 memset(¶ms, 0, sizeof(params)); 720 721 if (!cmd->clock_source_id_to_atom(bp_params->pll_id, &atom_pll_id) || 722 !cmd->dc_clock_type_to_atom(bp_params->clock_type, 723 &atom_clock_type)) 724 return BP_RESULT_BADINPUT; 725 726 params.param.dceclksrc = atom_pll_id; 727 params.param.dceclktype = atom_clock_type; 728 729 if (bp_params->clock_type == DCECLOCK_TYPE_DPREFCLK) { 730 if (bp_params->flags.USE_GENLOCK_AS_SOURCE_FOR_DPREFCLK) 731 params.param.dceclkflag |= 732 DCE_CLOCK_FLAG_PLL_REFCLK_SRC_GENLK; 733 734 if (bp_params->flags.USE_PCIE_AS_SOURCE_FOR_DPREFCLK) 735 params.param.dceclkflag |= 736 DCE_CLOCK_FLAG_PLL_REFCLK_SRC_PCIE; 737 738 if (bp_params->flags.USE_XTALIN_AS_SOURCE_FOR_DPREFCLK) 739 params.param.dceclkflag |= 740 DCE_CLOCK_FLAG_PLL_REFCLK_SRC_XTALIN; 741 742 if (bp_params->flags.USE_GENERICA_AS_SOURCE_FOR_DPREFCLK) 743 params.param.dceclkflag |= 744 DCE_CLOCK_FLAG_PLL_REFCLK_SRC_GENERICA; 745 } else 746 /* only program clock frequency if display clock is used; 747 * VBIOS will program DPREFCLK 748 * We need to convert from KHz units into 10KHz units 749 */ 750 params.param.dceclk_10khz = cpu_to_le32( 751 bp_params->target_clock_frequency / 10); 752 DC_LOG_BIOS("%s:target_clock_frequency = %d"\ 753 "clock_type = %d \n", __func__,\ 754 bp_params->target_clock_frequency,\ 755 bp_params->clock_type); 756 757 if (EXEC_BIOS_CMD_TABLE(setdceclock, params)) { 758 /* Convert from 10KHz units back to KHz */ 759 bp_params->target_clock_frequency = le32_to_cpu( 760 params.param.dceclk_10khz) * 10; 761 result = BP_RESULT_OK; 762 } 763 764 return result; 765 } 766 767 768 /****************************************************************************** 769 ****************************************************************************** 770 ** 771 ** GET SMU CLOCK INFO 772 ** 773 ****************************************************************************** 774 *****************************************************************************/ 775 776 static unsigned int get_smu_clock_info_v3_1(struct bios_parser *bp, uint8_t id); 777 778 static void init_get_smu_clock_info(struct bios_parser *bp) 779 { 780 /* TODO add switch for table vrsion */ 781 bp->cmd_tbl.get_smu_clock_info = get_smu_clock_info_v3_1; 782 783 } 784 785 static unsigned int get_smu_clock_info_v3_1(struct bios_parser *bp, uint8_t id) 786 { 787 struct atom_get_smu_clock_info_parameters_v3_1 smu_input = {0}; 788 struct atom_get_smu_clock_info_output_parameters_v3_1 smu_output; 789 790 smu_input.command = GET_SMU_CLOCK_INFO_V3_1_GET_PLLVCO_FREQ; 791 smu_input.syspll_id = id; 792 793 /* Get Specific Clock */ 794 if (EXEC_BIOS_CMD_TABLE(getsmuclockinfo, smu_input)) { 795 memmove(&smu_output, &smu_input, sizeof( 796 struct atom_get_smu_clock_info_parameters_v3_1)); 797 return smu_output.atom_smu_outputclkfreq.syspllvcofreq_10khz; 798 } 799 800 return 0; 801 } 802 803 void dal_firmware_parser_init_cmd_tbl(struct bios_parser *bp) 804 { 805 init_dig_encoder_control(bp); 806 init_transmitter_control(bp); 807 init_set_pixel_clock(bp); 808 809 init_set_crtc_timing(bp); 810 811 init_select_crtc_source(bp); 812 init_enable_crtc(bp); 813 814 init_external_encoder_control(bp); 815 init_enable_disp_power_gating(bp); 816 init_set_dce_clock(bp); 817 init_get_smu_clock_info(bp); 818 819 } 820