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