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