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 le16_add_cpu(¶ms.v_syncoffset, 1); 573 } 574 } 575 576 if (bp_params->flags.HORZ_COUNT_BY_TWO) 577 params.modemiscinfo = 578 cpu_to_le16(le16_to_cpu(params.modemiscinfo) | 579 0x100); /* ATOM_DOUBLE_CLOCK_MODE */ 580 581 if (EXEC_BIOS_CMD_TABLE(setcrtc_usingdtdtiming, params)) 582 result = BP_RESULT_OK; 583 584 return result; 585 } 586 587 /****************************************************************************** 588 ****************************************************************************** 589 ** 590 ** ENABLE CRTC 591 ** 592 ****************************************************************************** 593 *****************************************************************************/ 594 595 static enum bp_result enable_crtc_v1( 596 struct bios_parser *bp, 597 enum controller_id controller_id, 598 bool enable); 599 600 static void init_enable_crtc(struct bios_parser *bp) 601 { 602 switch (BIOS_CMD_TABLE_PARA_REVISION(enablecrtc)) { 603 case 1: 604 bp->cmd_tbl.enable_crtc = enable_crtc_v1; 605 break; 606 default: 607 dm_output_to_console("Don't have enable_crtc for v%d\n", 608 BIOS_CMD_TABLE_PARA_REVISION(enablecrtc)); 609 bp->cmd_tbl.enable_crtc = NULL; 610 break; 611 } 612 } 613 614 static enum bp_result enable_crtc_v1( 615 struct bios_parser *bp, 616 enum controller_id controller_id, 617 bool enable) 618 { 619 bool result = BP_RESULT_FAILURE; 620 struct enable_crtc_parameters params = {0}; 621 uint8_t id; 622 623 if (bp->cmd_helper->controller_id_to_atom(controller_id, &id)) 624 params.crtc_id = id; 625 else 626 return BP_RESULT_BADINPUT; 627 628 if (enable) 629 params.enable = ATOM_ENABLE; 630 else 631 params.enable = ATOM_DISABLE; 632 633 if (EXEC_BIOS_CMD_TABLE(enablecrtc, params)) 634 result = BP_RESULT_OK; 635 636 return result; 637 } 638 639 /****************************************************************************** 640 ****************************************************************************** 641 ** 642 ** DISPLAY PLL 643 ** 644 ****************************************************************************** 645 *****************************************************************************/ 646 647 648 649 /****************************************************************************** 650 ****************************************************************************** 651 ** 652 ** EXTERNAL ENCODER CONTROL 653 ** 654 ****************************************************************************** 655 *****************************************************************************/ 656 657 static enum bp_result external_encoder_control_v3( 658 struct bios_parser *bp, 659 struct bp_external_encoder_control *cntl); 660 661 static void init_external_encoder_control( 662 struct bios_parser *bp) 663 { 664 switch (BIOS_CMD_TABLE_PARA_REVISION(externalencodercontrol)) { 665 case 3: 666 bp->cmd_tbl.external_encoder_control = 667 external_encoder_control_v3; 668 break; 669 default: 670 bp->cmd_tbl.external_encoder_control = NULL; 671 break; 672 } 673 } 674 675 static enum bp_result external_encoder_control_v3( 676 struct bios_parser *bp, 677 struct bp_external_encoder_control *cntl) 678 { 679 /* TODO */ 680 return BP_RESULT_OK; 681 } 682 683 /****************************************************************************** 684 ****************************************************************************** 685 ** 686 ** ENABLE DISPLAY POWER GATING 687 ** 688 ****************************************************************************** 689 *****************************************************************************/ 690 691 static enum bp_result enable_disp_power_gating_v2_1( 692 struct bios_parser *bp, 693 enum controller_id crtc_id, 694 enum bp_pipe_control_action action); 695 696 static enum bp_result enable_disp_power_gating_fallback( 697 struct bios_parser *bp, 698 enum controller_id crtc_id, 699 enum bp_pipe_control_action action); 700 701 static void init_enable_disp_power_gating( 702 struct bios_parser *bp) 703 { 704 switch (BIOS_CMD_TABLE_PARA_REVISION(enabledisppowergating)) { 705 case 1: 706 bp->cmd_tbl.enable_disp_power_gating = 707 enable_disp_power_gating_v2_1; 708 break; 709 default: 710 dm_output_to_console("Don't enable_disp_power_gating enable_crtc for v%d\n", 711 BIOS_CMD_TABLE_PARA_REVISION(enabledisppowergating)); 712 bp->cmd_tbl.enable_disp_power_gating = enable_disp_power_gating_fallback; 713 break; 714 } 715 } 716 717 static void enable_disp_power_gating_dmcub( 718 struct dc_dmub_srv *dmcub, 719 struct enable_disp_power_gating_parameters_v2_1 *pwr) 720 { 721 union dmub_rb_cmd cmd; 722 723 memset(&cmd, 0, sizeof(cmd)); 724 725 cmd.enable_disp_power_gating.header.type = DMUB_CMD__VBIOS; 726 cmd.enable_disp_power_gating.header.sub_type = 727 DMUB_CMD__VBIOS_ENABLE_DISP_POWER_GATING; 728 cmd.enable_disp_power_gating.header.payload_bytes = 729 sizeof(cmd.enable_disp_power_gating) - 730 sizeof(cmd.enable_disp_power_gating.header); 731 cmd.enable_disp_power_gating.power_gating.pwr = *pwr; 732 733 dc_dmub_srv_cmd_queue(dmcub, &cmd); 734 dc_dmub_srv_cmd_execute(dmcub); 735 dc_dmub_srv_wait_idle(dmcub); 736 } 737 738 static enum bp_result enable_disp_power_gating_v2_1( 739 struct bios_parser *bp, 740 enum controller_id crtc_id, 741 enum bp_pipe_control_action action) 742 { 743 enum bp_result result = BP_RESULT_FAILURE; 744 745 746 struct enable_disp_power_gating_ps_allocation ps = { { 0 } }; 747 uint8_t atom_crtc_id; 748 749 if (bp->cmd_helper->controller_id_to_atom(crtc_id, &atom_crtc_id)) 750 ps.param.disp_pipe_id = atom_crtc_id; 751 else 752 return BP_RESULT_BADINPUT; 753 754 ps.param.enable = 755 bp->cmd_helper->disp_power_gating_action_to_atom(action); 756 757 if (bp->base.ctx->dc->ctx->dmub_srv && 758 bp->base.ctx->dc->debug.dmub_command_table) { 759 enable_disp_power_gating_dmcub(bp->base.ctx->dmub_srv, 760 &ps.param); 761 return BP_RESULT_OK; 762 } 763 764 if (EXEC_BIOS_CMD_TABLE(enabledisppowergating, ps.param)) 765 result = BP_RESULT_OK; 766 767 return result; 768 } 769 770 static enum bp_result enable_disp_power_gating_fallback( 771 struct bios_parser *bp, 772 enum controller_id crtc_id, 773 enum bp_pipe_control_action action) 774 { 775 if (bp->base.ctx->dc->ctx->dmub_srv && 776 bp->base.ctx->dc->debug.dmub_command_table) { 777 return enable_disp_power_gating_v2_1(bp, crtc_id, action); 778 } 779 780 return BP_RESULT_FAILURE; 781 } 782 783 /****************************************************************************** 784 ******************************************************************************* 785 ** 786 ** SET DCE CLOCK 787 ** 788 ******************************************************************************* 789 *******************************************************************************/ 790 791 static enum bp_result set_dce_clock_v2_1( 792 struct bios_parser *bp, 793 struct bp_set_dce_clock_parameters *bp_params); 794 795 static void init_set_dce_clock(struct bios_parser *bp) 796 { 797 switch (BIOS_CMD_TABLE_PARA_REVISION(setdceclock)) { 798 case 1: 799 bp->cmd_tbl.set_dce_clock = set_dce_clock_v2_1; 800 break; 801 default: 802 dm_output_to_console("Don't have set_dce_clock for v%d\n", 803 BIOS_CMD_TABLE_PARA_REVISION(setdceclock)); 804 bp->cmd_tbl.set_dce_clock = NULL; 805 break; 806 } 807 } 808 809 static enum bp_result set_dce_clock_v2_1( 810 struct bios_parser *bp, 811 struct bp_set_dce_clock_parameters *bp_params) 812 { 813 enum bp_result result = BP_RESULT_FAILURE; 814 815 struct set_dce_clock_ps_allocation_v2_1 params; 816 uint32_t atom_pll_id; 817 uint32_t atom_clock_type; 818 const struct command_table_helper *cmd = bp->cmd_helper; 819 820 memset(¶ms, 0, sizeof(params)); 821 822 if (!cmd->clock_source_id_to_atom(bp_params->pll_id, &atom_pll_id) || 823 !cmd->dc_clock_type_to_atom(bp_params->clock_type, 824 &atom_clock_type)) 825 return BP_RESULT_BADINPUT; 826 827 params.param.dceclksrc = atom_pll_id; 828 params.param.dceclktype = atom_clock_type; 829 830 if (bp_params->clock_type == DCECLOCK_TYPE_DPREFCLK) { 831 if (bp_params->flags.USE_GENLOCK_AS_SOURCE_FOR_DPREFCLK) 832 params.param.dceclkflag |= 833 DCE_CLOCK_FLAG_PLL_REFCLK_SRC_GENLK; 834 835 if (bp_params->flags.USE_PCIE_AS_SOURCE_FOR_DPREFCLK) 836 params.param.dceclkflag |= 837 DCE_CLOCK_FLAG_PLL_REFCLK_SRC_PCIE; 838 839 if (bp_params->flags.USE_XTALIN_AS_SOURCE_FOR_DPREFCLK) 840 params.param.dceclkflag |= 841 DCE_CLOCK_FLAG_PLL_REFCLK_SRC_XTALIN; 842 843 if (bp_params->flags.USE_GENERICA_AS_SOURCE_FOR_DPREFCLK) 844 params.param.dceclkflag |= 845 DCE_CLOCK_FLAG_PLL_REFCLK_SRC_GENERICA; 846 } else 847 /* only program clock frequency if display clock is used; 848 * VBIOS will program DPREFCLK 849 * We need to convert from KHz units into 10KHz units 850 */ 851 params.param.dceclk_10khz = cpu_to_le32( 852 bp_params->target_clock_frequency / 10); 853 DC_LOG_BIOS("%s:target_clock_frequency = %d"\ 854 "clock_type = %d \n", __func__,\ 855 bp_params->target_clock_frequency,\ 856 bp_params->clock_type); 857 858 if (EXEC_BIOS_CMD_TABLE(setdceclock, params)) { 859 /* Convert from 10KHz units back to KHz */ 860 bp_params->target_clock_frequency = le32_to_cpu( 861 params.param.dceclk_10khz) * 10; 862 result = BP_RESULT_OK; 863 } 864 865 return result; 866 } 867 868 869 /****************************************************************************** 870 ****************************************************************************** 871 ** 872 ** GET SMU CLOCK INFO 873 ** 874 ****************************************************************************** 875 *****************************************************************************/ 876 877 static unsigned int get_smu_clock_info_v3_1(struct bios_parser *bp, uint8_t id); 878 879 static void init_get_smu_clock_info(struct bios_parser *bp) 880 { 881 /* TODO add switch for table vrsion */ 882 bp->cmd_tbl.get_smu_clock_info = get_smu_clock_info_v3_1; 883 884 } 885 886 static unsigned int get_smu_clock_info_v3_1(struct bios_parser *bp, uint8_t id) 887 { 888 struct atom_get_smu_clock_info_parameters_v3_1 smu_input = {0}; 889 struct atom_get_smu_clock_info_output_parameters_v3_1 smu_output; 890 891 smu_input.command = GET_SMU_CLOCK_INFO_V3_1_GET_PLLVCO_FREQ; 892 smu_input.syspll_id = id; 893 894 /* Get Specific Clock */ 895 if (EXEC_BIOS_CMD_TABLE(getsmuclockinfo, smu_input)) { 896 memmove(&smu_output, &smu_input, sizeof( 897 struct atom_get_smu_clock_info_parameters_v3_1)); 898 return smu_output.atom_smu_outputclkfreq.syspllvcofreq_10khz; 899 } 900 901 return 0; 902 } 903 904 /****************************************************************************** 905 ****************************************************************************** 906 ** 907 ** LVTMA CONTROL 908 ** 909 ****************************************************************************** 910 *****************************************************************************/ 911 912 static enum bp_result enable_lvtma_control( 913 struct bios_parser *bp, 914 uint8_t uc_pwr_on); 915 916 static void init_enable_lvtma_control(struct bios_parser *bp) 917 { 918 /* TODO add switch for table vrsion */ 919 bp->cmd_tbl.enable_lvtma_control = enable_lvtma_control; 920 921 } 922 923 static void enable_lvtma_control_dmcub( 924 struct dc_dmub_srv *dmcub, 925 uint8_t uc_pwr_on) 926 { 927 928 union dmub_rb_cmd cmd; 929 930 memset(&cmd, 0, sizeof(cmd)); 931 932 cmd.cmd_common.header.type = DMUB_CMD__VBIOS; 933 cmd.cmd_common.header.sub_type = 934 DMUB_CMD__VBIOS_LVTMA_CONTROL; 935 cmd.cmd_common.cmd_buffer[0] = 936 uc_pwr_on; 937 938 dc_dmub_srv_cmd_queue(dmcub, &cmd); 939 dc_dmub_srv_cmd_execute(dmcub); 940 dc_dmub_srv_wait_idle(dmcub); 941 942 } 943 944 static enum bp_result enable_lvtma_control( 945 struct bios_parser *bp, 946 uint8_t uc_pwr_on) 947 { 948 enum bp_result result = BP_RESULT_FAILURE; 949 950 if (bp->base.ctx->dc->ctx->dmub_srv && 951 bp->base.ctx->dc->debug.dmub_command_table) { 952 enable_lvtma_control_dmcub(bp->base.ctx->dmub_srv, 953 uc_pwr_on); 954 return BP_RESULT_OK; 955 } 956 return result; 957 } 958 959 void dal_firmware_parser_init_cmd_tbl(struct bios_parser *bp) 960 { 961 init_dig_encoder_control(bp); 962 init_transmitter_control(bp); 963 init_set_pixel_clock(bp); 964 965 init_set_crtc_timing(bp); 966 967 init_enable_crtc(bp); 968 969 init_external_encoder_control(bp); 970 init_enable_disp_power_gating(bp); 971 init_set_dce_clock(bp); 972 init_get_smu_clock_info(bp); 973 974 init_enable_lvtma_control(bp); 975 } 976