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 } 400 401 // Handle PRE_OFF_TO_ON: Process ACPI PHY Transition Interlock 402 if (is_phy_transition_interlock_allowed && action == TRANSMITTER_CONTROL_ENABLE) 403 dm_acpi_process_phy_transition_interlock(bp->base.ctx, process_phy_transition_init_params); 404 405 transmitter_control_dmcub_v1_7(bp->base.ctx->dmub_srv, &dig_v1_7); 406 407 // Handle POST_ON_TO_OFF: Process ACPI PHY Transition Interlock 408 if (is_phy_transition_interlock_allowed && action == TRANSMITTER_CONTROL_DISABLE) 409 dm_acpi_process_phy_transition_interlock(bp->base.ctx, process_phy_transition_init_params); 410 411 return BP_RESULT_OK; 412 } 413 414 /*color_depth not used any more, driver has deep color factor in the Phyclk*/ 415 if (EXEC_BIOS_CMD_TABLE(dig1transmittercontrol, dig_v1_7)) 416 result = BP_RESULT_OK; 417 return result; 418 } 419 420 static enum bp_result transmitter_control_fallback( 421 struct bios_parser *bp, 422 struct bp_transmitter_control *cntl) 423 { 424 if (bp->base.ctx->dc->ctx->dmub_srv && 425 bp->base.ctx->dc->debug.dmub_command_table) { 426 return transmitter_control_v1_7(bp, cntl); 427 } 428 429 return BP_RESULT_FAILURE; 430 } 431 432 /****************************************************************************** 433 ****************************************************************************** 434 ** 435 ** SET PIXEL CLOCK 436 ** 437 ****************************************************************************** 438 *****************************************************************************/ 439 440 static enum bp_result set_pixel_clock_v7( 441 struct bios_parser *bp, 442 struct bp_pixel_clock_parameters *bp_params); 443 444 static enum bp_result set_pixel_clock_fallback( 445 struct bios_parser *bp, 446 struct bp_pixel_clock_parameters *bp_params); 447 448 static void init_set_pixel_clock(struct bios_parser *bp) 449 { 450 switch (BIOS_CMD_TABLE_PARA_REVISION(setpixelclock)) { 451 case 7: 452 bp->cmd_tbl.set_pixel_clock = set_pixel_clock_v7; 453 break; 454 default: 455 bp->cmd_tbl.set_pixel_clock = set_pixel_clock_fallback; 456 break; 457 } 458 } 459 460 static void set_pixel_clock_dmcub( 461 struct dc_dmub_srv *dmcub, 462 struct set_pixel_clock_parameter_v1_7 *clk) 463 { 464 union dmub_rb_cmd cmd; 465 466 memset(&cmd, 0, sizeof(cmd)); 467 468 cmd.set_pixel_clock.header.type = DMUB_CMD__VBIOS; 469 cmd.set_pixel_clock.header.sub_type = DMUB_CMD__VBIOS_SET_PIXEL_CLOCK; 470 cmd.set_pixel_clock.header.payload_bytes = 471 sizeof(cmd.set_pixel_clock) - 472 sizeof(cmd.set_pixel_clock.header); 473 cmd.set_pixel_clock.pixel_clock.clk = *clk; 474 475 dc_wake_and_execute_dmub_cmd(dmcub->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT); 476 } 477 478 static enum bp_result set_pixel_clock_v7( 479 struct bios_parser *bp, 480 struct bp_pixel_clock_parameters *bp_params) 481 { 482 enum bp_result result = BP_RESULT_FAILURE; 483 struct set_pixel_clock_parameter_v1_7 clk; 484 uint8_t controller_id; 485 uint32_t pll_id; 486 487 memset(&clk, 0, sizeof(clk)); 488 489 if (bp->cmd_helper->clock_source_id_to_atom(bp_params->pll_id, &pll_id) 490 && bp->cmd_helper->controller_id_to_atom(bp_params-> 491 controller_id, &controller_id)) { 492 /* Note: VBIOS still wants to use ucCRTC name which is now 493 * 1 byte in ULONG 494 *typedef struct _CRTC_PIXEL_CLOCK_FREQ 495 *{ 496 * target the pixel clock to drive the CRTC timing. 497 * ULONG ulPixelClock:24; 498 * 0 means disable PPLL/DCPLL. Expanded to 24 bits comparing to 499 * previous version. 500 * ATOM_CRTC1~6, indicate the CRTC controller to 501 * ULONG ucCRTC:8; 502 * drive the pixel clock. not used for DCPLL case. 503 *}CRTC_PIXEL_CLOCK_FREQ; 504 *union 505 *{ 506 * pixel clock and CRTC id frequency 507 * CRTC_PIXEL_CLOCK_FREQ ulCrtcPclkFreq; 508 * ULONG ulDispEngClkFreq; dispclk frequency 509 *}; 510 */ 511 clk.crtc_id = controller_id; 512 clk.pll_id = (uint8_t) pll_id; 513 clk.encoderobjid = 514 bp->cmd_helper->encoder_id_to_atom( 515 dal_graphics_object_id_get_encoder_id( 516 bp_params->encoder_object_id)); 517 518 clk.encoder_mode = (uint8_t) bp-> 519 cmd_helper->encoder_mode_bp_to_atom( 520 bp_params->signal_type, false); 521 522 clk.pixclk_100hz = cpu_to_le32(bp_params->target_pixel_clock_100hz); 523 524 clk.deep_color_ratio = 525 (uint8_t) bp->cmd_helper-> 526 transmitter_color_depth_to_atom( 527 bp_params->color_depth); 528 529 DC_LOG_BIOS("%s:program display clock = %d, tg = %d, pll = %d, "\ 530 "colorDepth = %d\n", __func__, 531 bp_params->target_pixel_clock_100hz, (int)controller_id, 532 pll_id, bp_params->color_depth); 533 534 if (bp_params->flags.FORCE_PROGRAMMING_OF_PLL) 535 clk.miscinfo |= PIXEL_CLOCK_V7_MISC_FORCE_PROG_PPLL; 536 537 if (bp_params->flags.PROGRAM_PHY_PLL_ONLY) 538 clk.miscinfo |= PIXEL_CLOCK_V7_MISC_PROG_PHYPLL; 539 540 if (bp_params->flags.SUPPORT_YUV_420) 541 clk.miscinfo |= PIXEL_CLOCK_V7_MISC_YUV420_MODE; 542 543 if (bp_params->flags.SET_XTALIN_REF_SRC) 544 clk.miscinfo |= PIXEL_CLOCK_V7_MISC_REF_DIV_SRC_XTALIN; 545 546 if (bp_params->flags.SET_GENLOCK_REF_DIV_SRC) 547 clk.miscinfo |= PIXEL_CLOCK_V7_MISC_REF_DIV_SRC_GENLK; 548 549 if (bp_params->signal_type == SIGNAL_TYPE_DVI_DUAL_LINK) 550 clk.miscinfo |= PIXEL_CLOCK_V7_MISC_DVI_DUALLINK_EN; 551 552 if (bp->base.ctx->dc->ctx->dmub_srv && 553 bp->base.ctx->dc->debug.dmub_command_table) { 554 set_pixel_clock_dmcub(bp->base.ctx->dmub_srv, &clk); 555 return BP_RESULT_OK; 556 } 557 558 if (EXEC_BIOS_CMD_TABLE(setpixelclock, clk)) 559 result = BP_RESULT_OK; 560 } 561 return result; 562 } 563 564 static enum bp_result set_pixel_clock_fallback( 565 struct bios_parser *bp, 566 struct bp_pixel_clock_parameters *bp_params) 567 { 568 if (bp->base.ctx->dc->ctx->dmub_srv && 569 bp->base.ctx->dc->debug.dmub_command_table) { 570 return set_pixel_clock_v7(bp, bp_params); 571 } 572 573 return BP_RESULT_FAILURE; 574 } 575 576 /****************************************************************************** 577 ****************************************************************************** 578 ** 579 ** SET CRTC TIMING 580 ** 581 ****************************************************************************** 582 *****************************************************************************/ 583 584 static enum bp_result set_crtc_using_dtd_timing_v3( 585 struct bios_parser *bp, 586 struct bp_hw_crtc_timing_parameters *bp_params); 587 588 static void init_set_crtc_timing(struct bios_parser *bp) 589 { 590 uint32_t dtd_version = 591 BIOS_CMD_TABLE_PARA_REVISION(setcrtc_usingdtdtiming); 592 593 switch (dtd_version) { 594 case 3: 595 bp->cmd_tbl.set_crtc_timing = 596 set_crtc_using_dtd_timing_v3; 597 break; 598 default: 599 bp->cmd_tbl.set_crtc_timing = NULL; 600 break; 601 } 602 } 603 604 static enum bp_result set_crtc_using_dtd_timing_v3( 605 struct bios_parser *bp, 606 struct bp_hw_crtc_timing_parameters *bp_params) 607 { 608 enum bp_result result = BP_RESULT_FAILURE; 609 struct set_crtc_using_dtd_timing_parameters params = {0}; 610 uint8_t atom_controller_id; 611 612 if (bp->cmd_helper->controller_id_to_atom( 613 bp_params->controller_id, &atom_controller_id)) 614 params.crtc_id = atom_controller_id; 615 616 /* bios usH_Size wants h addressable size */ 617 params.h_size = cpu_to_le16((uint16_t)bp_params->h_addressable); 618 /* bios usH_Blanking_Time wants borders included in blanking */ 619 params.h_blanking_time = 620 cpu_to_le16((uint16_t)(bp_params->h_total - 621 bp_params->h_addressable)); 622 /* bios usV_Size wants v addressable size */ 623 params.v_size = cpu_to_le16((uint16_t)bp_params->v_addressable); 624 /* bios usV_Blanking_Time wants borders included in blanking */ 625 params.v_blanking_time = 626 cpu_to_le16((uint16_t)(bp_params->v_total - 627 bp_params->v_addressable)); 628 /* bios usHSyncOffset is the offset from the end of h addressable, 629 * our horizontalSyncStart is the offset from the beginning 630 * of h addressable 631 */ 632 params.h_syncoffset = 633 cpu_to_le16((uint16_t)(bp_params->h_sync_start - 634 bp_params->h_addressable)); 635 params.h_syncwidth = cpu_to_le16((uint16_t)bp_params->h_sync_width); 636 /* bios usHSyncOffset is the offset from the end of v addressable, 637 * our verticalSyncStart is the offset from the beginning of 638 * v addressable 639 */ 640 params.v_syncoffset = 641 cpu_to_le16((uint16_t)(bp_params->v_sync_start - 642 bp_params->v_addressable)); 643 params.v_syncwidth = cpu_to_le16((uint16_t)bp_params->v_sync_width); 644 645 /* we assume that overscan from original timing does not get bigger 646 * than 255 647 * we will program all the borders in the Set CRTC Overscan call below 648 */ 649 650 if (bp_params->flags.HSYNC_POSITIVE_POLARITY == 0) 651 params.modemiscinfo = 652 cpu_to_le16(le16_to_cpu(params.modemiscinfo) | 653 ATOM_HSYNC_POLARITY); 654 655 if (bp_params->flags.VSYNC_POSITIVE_POLARITY == 0) 656 params.modemiscinfo = 657 cpu_to_le16(le16_to_cpu(params.modemiscinfo) | 658 ATOM_VSYNC_POLARITY); 659 660 if (bp_params->flags.INTERLACE) { 661 params.modemiscinfo = 662 cpu_to_le16(le16_to_cpu(params.modemiscinfo) | 663 ATOM_INTERLACE); 664 665 /* original DAL code has this condition to apply this 666 * for non-TV/CV only 667 * due to complex MV testing for possible impact 668 * if ( pACParameters->signal != SignalType_YPbPr && 669 * pACParameters->signal != SignalType_Composite && 670 * pACParameters->signal != SignalType_SVideo) 671 */ 672 { 673 /* HW will deduct 0.5 line from 2nd feild. 674 * i.e. for 1080i, it is 2 lines for 1st field, 675 * 2.5 lines for the 2nd feild. we need input as 5 676 * instead of 4. 677 * but it is 4 either from Edid data (spec CEA 861) 678 * or CEA timing table. 679 */ 680 le16_add_cpu(¶ms.v_syncoffset, 1); 681 } 682 } 683 684 if (bp_params->flags.HORZ_COUNT_BY_TWO) 685 params.modemiscinfo = 686 cpu_to_le16(le16_to_cpu(params.modemiscinfo) | 687 0x100); /* ATOM_DOUBLE_CLOCK_MODE */ 688 689 if (EXEC_BIOS_CMD_TABLE(setcrtc_usingdtdtiming, params)) 690 result = BP_RESULT_OK; 691 692 return result; 693 } 694 695 /****************************************************************************** 696 ****************************************************************************** 697 ** 698 ** ENABLE CRTC 699 ** 700 ****************************************************************************** 701 *****************************************************************************/ 702 703 static enum bp_result enable_crtc_v1( 704 struct bios_parser *bp, 705 enum controller_id controller_id, 706 bool enable); 707 708 static void init_enable_crtc(struct bios_parser *bp) 709 { 710 switch (BIOS_CMD_TABLE_PARA_REVISION(enablecrtc)) { 711 case 1: 712 bp->cmd_tbl.enable_crtc = enable_crtc_v1; 713 break; 714 default: 715 bp->cmd_tbl.enable_crtc = NULL; 716 break; 717 } 718 } 719 720 static enum bp_result enable_crtc_v1( 721 struct bios_parser *bp, 722 enum controller_id controller_id, 723 bool enable) 724 { 725 bool result = BP_RESULT_FAILURE; 726 struct enable_crtc_parameters params = {0}; 727 uint8_t id; 728 729 if (bp->cmd_helper->controller_id_to_atom(controller_id, &id)) 730 params.crtc_id = id; 731 else 732 return BP_RESULT_BADINPUT; 733 734 if (enable) 735 params.enable = ATOM_ENABLE; 736 else 737 params.enable = ATOM_DISABLE; 738 739 if (EXEC_BIOS_CMD_TABLE(enablecrtc, params)) 740 result = BP_RESULT_OK; 741 742 return result; 743 } 744 745 /****************************************************************************** 746 ****************************************************************************** 747 ** 748 ** DISPLAY PLL 749 ** 750 ****************************************************************************** 751 *****************************************************************************/ 752 753 754 755 /****************************************************************************** 756 ****************************************************************************** 757 ** 758 ** EXTERNAL ENCODER CONTROL 759 ** 760 ****************************************************************************** 761 *****************************************************************************/ 762 763 static enum bp_result external_encoder_control_v3( 764 struct bios_parser *bp, 765 struct bp_external_encoder_control *cntl); 766 767 static void init_external_encoder_control( 768 struct bios_parser *bp) 769 { 770 switch (BIOS_CMD_TABLE_PARA_REVISION(externalencodercontrol)) { 771 case 3: 772 bp->cmd_tbl.external_encoder_control = 773 external_encoder_control_v3; 774 break; 775 default: 776 bp->cmd_tbl.external_encoder_control = NULL; 777 break; 778 } 779 } 780 781 static enum bp_result external_encoder_control_v3( 782 struct bios_parser *bp, 783 struct bp_external_encoder_control *cntl) 784 { 785 /* TODO */ 786 return BP_RESULT_OK; 787 } 788 789 /****************************************************************************** 790 ****************************************************************************** 791 ** 792 ** ENABLE DISPLAY POWER GATING 793 ** 794 ****************************************************************************** 795 *****************************************************************************/ 796 797 static enum bp_result enable_disp_power_gating_v2_1( 798 struct bios_parser *bp, 799 enum controller_id crtc_id, 800 enum bp_pipe_control_action action); 801 802 static enum bp_result enable_disp_power_gating_fallback( 803 struct bios_parser *bp, 804 enum controller_id crtc_id, 805 enum bp_pipe_control_action action); 806 807 static void init_enable_disp_power_gating( 808 struct bios_parser *bp) 809 { 810 switch (BIOS_CMD_TABLE_PARA_REVISION(enabledisppowergating)) { 811 case 1: 812 bp->cmd_tbl.enable_disp_power_gating = 813 enable_disp_power_gating_v2_1; 814 break; 815 default: 816 dm_output_to_console("Don't enable_disp_power_gating enable_crtc for v%d\n", 817 BIOS_CMD_TABLE_PARA_REVISION(enabledisppowergating)); 818 bp->cmd_tbl.enable_disp_power_gating = enable_disp_power_gating_fallback; 819 break; 820 } 821 } 822 823 static void enable_disp_power_gating_dmcub( 824 struct dc_dmub_srv *dmcub, 825 struct enable_disp_power_gating_parameters_v2_1 *pwr) 826 { 827 union dmub_rb_cmd cmd; 828 829 memset(&cmd, 0, sizeof(cmd)); 830 831 cmd.enable_disp_power_gating.header.type = DMUB_CMD__VBIOS; 832 cmd.enable_disp_power_gating.header.sub_type = 833 DMUB_CMD__VBIOS_ENABLE_DISP_POWER_GATING; 834 cmd.enable_disp_power_gating.header.payload_bytes = 835 sizeof(cmd.enable_disp_power_gating) - 836 sizeof(cmd.enable_disp_power_gating.header); 837 cmd.enable_disp_power_gating.power_gating.pwr = *pwr; 838 839 dc_wake_and_execute_dmub_cmd(dmcub->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT); 840 } 841 842 static enum bp_result enable_disp_power_gating_v2_1( 843 struct bios_parser *bp, 844 enum controller_id crtc_id, 845 enum bp_pipe_control_action action) 846 { 847 enum bp_result result = BP_RESULT_FAILURE; 848 849 850 struct enable_disp_power_gating_ps_allocation ps = { { 0 } }; 851 uint8_t atom_crtc_id; 852 853 if (bp->cmd_helper->controller_id_to_atom(crtc_id, &atom_crtc_id)) 854 ps.param.disp_pipe_id = atom_crtc_id; 855 else 856 return BP_RESULT_BADINPUT; 857 858 ps.param.enable = 859 bp->cmd_helper->disp_power_gating_action_to_atom(action); 860 861 if (bp->base.ctx->dc->ctx->dmub_srv && 862 bp->base.ctx->dc->debug.dmub_command_table) { 863 enable_disp_power_gating_dmcub(bp->base.ctx->dmub_srv, 864 &ps.param); 865 return BP_RESULT_OK; 866 } 867 868 if (EXEC_BIOS_CMD_TABLE(enabledisppowergating, ps.param)) 869 result = BP_RESULT_OK; 870 871 return result; 872 } 873 874 static enum bp_result enable_disp_power_gating_fallback( 875 struct bios_parser *bp, 876 enum controller_id crtc_id, 877 enum bp_pipe_control_action action) 878 { 879 if (bp->base.ctx->dc->ctx->dmub_srv && 880 bp->base.ctx->dc->debug.dmub_command_table) { 881 return enable_disp_power_gating_v2_1(bp, crtc_id, action); 882 } 883 884 return BP_RESULT_FAILURE; 885 } 886 887 /****************************************************************************** 888 ******************************************************************************* 889 ** 890 ** SET DCE CLOCK 891 ** 892 ******************************************************************************* 893 *******************************************************************************/ 894 895 static enum bp_result set_dce_clock_v2_1( 896 struct bios_parser *bp, 897 struct bp_set_dce_clock_parameters *bp_params); 898 899 static void init_set_dce_clock(struct bios_parser *bp) 900 { 901 switch (BIOS_CMD_TABLE_PARA_REVISION(setdceclock)) { 902 case 1: 903 bp->cmd_tbl.set_dce_clock = set_dce_clock_v2_1; 904 break; 905 default: 906 bp->cmd_tbl.set_dce_clock = NULL; 907 break; 908 } 909 } 910 911 static enum bp_result set_dce_clock_v2_1( 912 struct bios_parser *bp, 913 struct bp_set_dce_clock_parameters *bp_params) 914 { 915 enum bp_result result = BP_RESULT_FAILURE; 916 917 struct set_dce_clock_ps_allocation_v2_1 params; 918 uint32_t atom_pll_id; 919 uint32_t atom_clock_type; 920 const struct command_table_helper *cmd = bp->cmd_helper; 921 922 memset(¶ms, 0, sizeof(params)); 923 924 if (!cmd->clock_source_id_to_atom(bp_params->pll_id, &atom_pll_id) || 925 !cmd->dc_clock_type_to_atom(bp_params->clock_type, 926 &atom_clock_type)) 927 return BP_RESULT_BADINPUT; 928 929 params.param.dceclksrc = atom_pll_id; 930 params.param.dceclktype = atom_clock_type; 931 932 if (bp_params->clock_type == DCECLOCK_TYPE_DPREFCLK) { 933 if (bp_params->flags.USE_GENLOCK_AS_SOURCE_FOR_DPREFCLK) 934 params.param.dceclkflag |= 935 DCE_CLOCK_FLAG_PLL_REFCLK_SRC_GENLK; 936 937 if (bp_params->flags.USE_PCIE_AS_SOURCE_FOR_DPREFCLK) 938 params.param.dceclkflag |= 939 DCE_CLOCK_FLAG_PLL_REFCLK_SRC_PCIE; 940 941 if (bp_params->flags.USE_XTALIN_AS_SOURCE_FOR_DPREFCLK) 942 params.param.dceclkflag |= 943 DCE_CLOCK_FLAG_PLL_REFCLK_SRC_XTALIN; 944 945 if (bp_params->flags.USE_GENERICA_AS_SOURCE_FOR_DPREFCLK) 946 params.param.dceclkflag |= 947 DCE_CLOCK_FLAG_PLL_REFCLK_SRC_GENERICA; 948 } else 949 /* only program clock frequency if display clock is used; 950 * VBIOS will program DPREFCLK 951 * We need to convert from KHz units into 10KHz units 952 */ 953 params.param.dceclk_10khz = cpu_to_le32( 954 bp_params->target_clock_frequency / 10); 955 DC_LOG_BIOS("%s:target_clock_frequency = %d"\ 956 "clock_type = %d \n", __func__,\ 957 bp_params->target_clock_frequency,\ 958 bp_params->clock_type); 959 960 if (EXEC_BIOS_CMD_TABLE(setdceclock, params)) { 961 /* Convert from 10KHz units back to KHz */ 962 bp_params->target_clock_frequency = le32_to_cpu( 963 params.param.dceclk_10khz) * 10; 964 result = BP_RESULT_OK; 965 } 966 967 return result; 968 } 969 970 971 /****************************************************************************** 972 ****************************************************************************** 973 ** 974 ** GET SMU CLOCK INFO 975 ** 976 ****************************************************************************** 977 *****************************************************************************/ 978 979 static unsigned int get_smu_clock_info_v3_1(struct bios_parser *bp, uint8_t id); 980 981 static void init_get_smu_clock_info(struct bios_parser *bp) 982 { 983 /* TODO add switch for table vrsion */ 984 bp->cmd_tbl.get_smu_clock_info = get_smu_clock_info_v3_1; 985 986 } 987 988 static unsigned int get_smu_clock_info_v3_1(struct bios_parser *bp, uint8_t id) 989 { 990 struct atom_get_smu_clock_info_parameters_v3_1 smu_input = {0}; 991 struct atom_get_smu_clock_info_output_parameters_v3_1 smu_output; 992 993 smu_input.command = GET_SMU_CLOCK_INFO_V3_1_GET_PLLVCO_FREQ; 994 smu_input.syspll_id = id; 995 996 /* Get Specific Clock */ 997 if (EXEC_BIOS_CMD_TABLE(getsmuclockinfo, smu_input)) { 998 memmove(&smu_output, &smu_input, sizeof( 999 struct atom_get_smu_clock_info_parameters_v3_1)); 1000 return smu_output.atom_smu_outputclkfreq.syspllvcofreq_10khz; 1001 } 1002 1003 return 0; 1004 } 1005 1006 /****************************************************************************** 1007 ****************************************************************************** 1008 ** 1009 ** LVTMA CONTROL 1010 ** 1011 ****************************************************************************** 1012 *****************************************************************************/ 1013 1014 static enum bp_result enable_lvtma_control( 1015 struct bios_parser *bp, 1016 uint8_t uc_pwr_on, 1017 uint8_t pwrseq_instance, 1018 uint8_t bypass_panel_control_wait); 1019 1020 static void init_enable_lvtma_control(struct bios_parser *bp) 1021 { 1022 /* TODO add switch for table vrsion */ 1023 bp->cmd_tbl.enable_lvtma_control = enable_lvtma_control; 1024 1025 } 1026 1027 static void enable_lvtma_control_dmcub( 1028 struct dc_dmub_srv *dmcub, 1029 uint8_t uc_pwr_on, 1030 uint8_t pwrseq_instance, 1031 uint8_t bypass_panel_control_wait) 1032 { 1033 1034 union dmub_rb_cmd cmd; 1035 1036 memset(&cmd, 0, sizeof(cmd)); 1037 1038 cmd.lvtma_control.header.type = DMUB_CMD__VBIOS; 1039 cmd.lvtma_control.header.sub_type = 1040 DMUB_CMD__VBIOS_LVTMA_CONTROL; 1041 cmd.lvtma_control.data.uc_pwr_action = 1042 uc_pwr_on; 1043 cmd.lvtma_control.data.pwrseq_inst = 1044 pwrseq_instance; 1045 cmd.lvtma_control.data.bypass_panel_control_wait = 1046 bypass_panel_control_wait; 1047 dc_wake_and_execute_dmub_cmd(dmcub->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT); 1048 } 1049 1050 static enum bp_result enable_lvtma_control( 1051 struct bios_parser *bp, 1052 uint8_t uc_pwr_on, 1053 uint8_t pwrseq_instance, 1054 uint8_t bypass_panel_control_wait) 1055 { 1056 enum bp_result result = BP_RESULT_FAILURE; 1057 1058 if (bp->base.ctx->dc->ctx->dmub_srv && 1059 bp->base.ctx->dc->debug.dmub_command_table) { 1060 enable_lvtma_control_dmcub(bp->base.ctx->dmub_srv, 1061 uc_pwr_on, 1062 pwrseq_instance, 1063 bypass_panel_control_wait); 1064 return BP_RESULT_OK; 1065 } 1066 return result; 1067 } 1068 1069 void dal_firmware_parser_init_cmd_tbl(struct bios_parser *bp) 1070 { 1071 init_dig_encoder_control(bp); 1072 init_transmitter_control(bp); 1073 init_set_pixel_clock(bp); 1074 1075 init_set_crtc_timing(bp); 1076 1077 init_enable_crtc(bp); 1078 1079 init_external_encoder_control(bp); 1080 init_enable_disp_power_gating(bp); 1081 init_set_dce_clock(bp); 1082 init_get_smu_clock_info(bp); 1083 1084 init_enable_lvtma_control(bp); 1085 } 1086 1087