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