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