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 if (dc_is_hdmi_frl_signal(cntl->signal)) 375 DC_LOG_BIOS("%s:dig_v1_7.symclk_units.symclk_Hz = %d\n", 376 __func__, dig_v1_7.symclk_units.symclk_Hz); 377 else 378 DC_LOG_BIOS("%s:dig_v1_7.symclk_units.symclk_10khz = %d\n", 379 __func__, dig_v1_7.symclk_units.symclk_10khz); 380 } 381 382 if (bp->base.ctx->dc->ctx->dmub_srv && 383 bp->base.ctx->dc->debug.dmub_command_table) { 384 struct dm_process_phy_transition_init_params process_phy_transition_init_params = {0}; 385 struct dc_link *link = get_link_by_phy_id(bp->base.ctx->dc, dig_v1_7.phyid); 386 bool is_phy_transition_interlock_allowed = false; 387 uint8_t action = dig_v1_7.action; 388 389 if (link) { 390 if (link->phy_transition_bitmask && 391 (action == TRANSMITTER_CONTROL_ENABLE || action == TRANSMITTER_CONTROL_DISABLE)) { 392 is_phy_transition_interlock_allowed = true; 393 394 // Prepare input parameters for processing ACPI retimers 395 process_phy_transition_init_params.action = action; 396 process_phy_transition_init_params.display_port_lanes_count = cntl->lanes_number; 397 process_phy_transition_init_params.phy_id = dig_v1_7.phyid; 398 process_phy_transition_init_params.signal = cntl->signal; 399 process_phy_transition_init_params.sym_clock_10khz = dig_v1_7.symclk_units.symclk_10khz; 400 process_phy_transition_init_params.display_port_link_rate = link->cur_link_settings.link_rate; 401 process_phy_transition_init_params.transition_bitmask = link->phy_transition_bitmask; 402 process_phy_transition_init_params.hdmi_frl_num_lanes = link->frl_link_settings.frl_num_lanes; 403 process_phy_transition_init_params.hdmi_frl_link_rate = link->frl_link_settings.frl_link_rate; 404 } 405 dig_v1_7.skip_phy_ssc_reduction = link->wa_flags.skip_phy_ssc_reduction; 406 } 407 408 // Handle PRE_OFF_TO_ON: Process ACPI PHY Transition Interlock 409 if (is_phy_transition_interlock_allowed && action == TRANSMITTER_CONTROL_ENABLE) 410 dm_acpi_process_phy_transition_interlock(bp->base.ctx, process_phy_transition_init_params); 411 412 transmitter_control_dmcub_v1_7(bp->base.ctx->dmub_srv, &dig_v1_7); 413 414 // Handle POST_ON_TO_OFF: Process ACPI PHY Transition Interlock 415 if (is_phy_transition_interlock_allowed && action == TRANSMITTER_CONTROL_DISABLE) 416 dm_acpi_process_phy_transition_interlock(bp->base.ctx, process_phy_transition_init_params); 417 418 return BP_RESULT_OK; 419 } 420 421 /*color_depth not used any more, driver has deep color factor in the Phyclk*/ 422 if (EXEC_BIOS_CMD_TABLE(dig1transmittercontrol, dig_v1_7)) 423 result = BP_RESULT_OK; 424 return result; 425 } 426 427 static enum bp_result transmitter_control_fallback( 428 struct bios_parser *bp, 429 struct bp_transmitter_control *cntl) 430 { 431 if (bp->base.ctx->dc->ctx->dmub_srv && 432 bp->base.ctx->dc->debug.dmub_command_table) { 433 return transmitter_control_v1_7(bp, cntl); 434 } 435 436 return BP_RESULT_FAILURE; 437 } 438 439 /****************************************************************************** 440 ****************************************************************************** 441 ** 442 ** SET PIXEL CLOCK 443 ** 444 ****************************************************************************** 445 *****************************************************************************/ 446 447 static enum bp_result set_pixel_clock_v7( 448 struct bios_parser *bp, 449 struct bp_pixel_clock_parameters *bp_params); 450 451 static enum bp_result set_pixel_clock_fallback( 452 struct bios_parser *bp, 453 struct bp_pixel_clock_parameters *bp_params); 454 455 static void init_set_pixel_clock(struct bios_parser *bp) 456 { 457 switch (BIOS_CMD_TABLE_PARA_REVISION(setpixelclock)) { 458 case 7: 459 bp->cmd_tbl.set_pixel_clock = set_pixel_clock_v7; 460 break; 461 default: 462 bp->cmd_tbl.set_pixel_clock = set_pixel_clock_fallback; 463 break; 464 } 465 } 466 467 static void set_pixel_clock_dmcub( 468 struct dc_dmub_srv *dmcub, 469 struct set_pixel_clock_parameter_v1_7 *clk) 470 { 471 union dmub_rb_cmd cmd; 472 473 memset(&cmd, 0, sizeof(cmd)); 474 475 cmd.set_pixel_clock.header.type = DMUB_CMD__VBIOS; 476 cmd.set_pixel_clock.header.sub_type = DMUB_CMD__VBIOS_SET_PIXEL_CLOCK; 477 cmd.set_pixel_clock.header.payload_bytes = 478 sizeof(cmd.set_pixel_clock) - 479 sizeof(cmd.set_pixel_clock.header); 480 cmd.set_pixel_clock.pixel_clock.clk = *clk; 481 482 dc_wake_and_execute_dmub_cmd(dmcub->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT); 483 } 484 485 static enum bp_result set_pixel_clock_v7( 486 struct bios_parser *bp, 487 struct bp_pixel_clock_parameters *bp_params) 488 { 489 enum bp_result result = BP_RESULT_FAILURE; 490 struct set_pixel_clock_parameter_v1_7 clk; 491 uint8_t controller_id; 492 uint32_t pll_id; 493 494 memset(&clk, 0, sizeof(clk)); 495 496 if (bp->cmd_helper->clock_source_id_to_atom(bp_params->pll_id, &pll_id) 497 && bp->cmd_helper->controller_id_to_atom(bp_params-> 498 controller_id, &controller_id)) { 499 /* Note: VBIOS still wants to use ucCRTC name which is now 500 * 1 byte in ULONG 501 *typedef struct _CRTC_PIXEL_CLOCK_FREQ 502 *{ 503 * target the pixel clock to drive the CRTC timing. 504 * ULONG ulPixelClock:24; 505 * 0 means disable PPLL/DCPLL. Expanded to 24 bits comparing to 506 * previous version. 507 * ATOM_CRTC1~6, indicate the CRTC controller to 508 * ULONG ucCRTC:8; 509 * drive the pixel clock. not used for DCPLL case. 510 *}CRTC_PIXEL_CLOCK_FREQ; 511 *union 512 *{ 513 * pixel clock and CRTC id frequency 514 * CRTC_PIXEL_CLOCK_FREQ ulCrtcPclkFreq; 515 * ULONG ulDispEngClkFreq; dispclk frequency 516 *}; 517 */ 518 clk.crtc_id = controller_id; 519 clk.pll_id = (uint8_t) pll_id; 520 clk.encoderobjid = 521 bp->cmd_helper->encoder_id_to_atom( 522 dal_graphics_object_id_get_encoder_id( 523 bp_params->encoder_object_id)); 524 525 clk.encoder_mode = (uint8_t) bp-> 526 cmd_helper->encoder_mode_bp_to_atom( 527 bp_params->signal_type, false); 528 529 clk.pixclk_100hz = cpu_to_le32(bp_params->target_pixel_clock_100hz); 530 531 clk.deep_color_ratio = 532 (uint8_t) bp->cmd_helper-> 533 transmitter_color_depth_to_atom( 534 bp_params->color_depth); 535 536 DC_LOG_BIOS("%s:program display clock = %d, tg = %d, pll = %d, "\ 537 "colorDepth = %d\n", __func__, 538 bp_params->target_pixel_clock_100hz, (int)controller_id, 539 pll_id, bp_params->color_depth); 540 541 if (bp_params->flags.FORCE_PROGRAMMING_OF_PLL) 542 clk.miscinfo |= PIXEL_CLOCK_V7_MISC_FORCE_PROG_PPLL; 543 544 if (bp_params->flags.PROGRAM_PHY_PLL_ONLY) 545 clk.miscinfo |= PIXEL_CLOCK_V7_MISC_PROG_PHYPLL; 546 547 if (bp_params->flags.SUPPORT_YUV_420) 548 clk.miscinfo |= PIXEL_CLOCK_V7_MISC_YUV420_MODE; 549 550 if (bp_params->flags.SET_XTALIN_REF_SRC) 551 clk.miscinfo |= PIXEL_CLOCK_V7_MISC_REF_DIV_SRC_XTALIN; 552 553 if (bp_params->flags.SET_GENLOCK_REF_DIV_SRC) 554 clk.miscinfo |= PIXEL_CLOCK_V7_MISC_REF_DIV_SRC_GENLK; 555 556 if (bp_params->signal_type == SIGNAL_TYPE_DVI_DUAL_LINK) 557 clk.miscinfo |= PIXEL_CLOCK_V7_MISC_DVI_DUALLINK_EN; 558 559 if (bp->base.ctx->dc->ctx->dmub_srv && 560 bp->base.ctx->dc->debug.dmub_command_table) { 561 set_pixel_clock_dmcub(bp->base.ctx->dmub_srv, &clk); 562 return BP_RESULT_OK; 563 } 564 565 if (EXEC_BIOS_CMD_TABLE(setpixelclock, clk)) 566 result = BP_RESULT_OK; 567 } 568 return result; 569 } 570 571 static enum bp_result set_pixel_clock_fallback( 572 struct bios_parser *bp, 573 struct bp_pixel_clock_parameters *bp_params) 574 { 575 if (bp->base.ctx->dc->ctx->dmub_srv && 576 bp->base.ctx->dc->debug.dmub_command_table) { 577 return set_pixel_clock_v7(bp, bp_params); 578 } 579 580 return BP_RESULT_FAILURE; 581 } 582 583 /****************************************************************************** 584 ****************************************************************************** 585 ** 586 ** SET CRTC TIMING 587 ** 588 ****************************************************************************** 589 *****************************************************************************/ 590 591 static enum bp_result set_crtc_using_dtd_timing_v3( 592 struct bios_parser *bp, 593 struct bp_hw_crtc_timing_parameters *bp_params); 594 595 static void init_set_crtc_timing(struct bios_parser *bp) 596 { 597 uint32_t dtd_version = 598 BIOS_CMD_TABLE_PARA_REVISION(setcrtc_usingdtdtiming); 599 600 switch (dtd_version) { 601 case 3: 602 bp->cmd_tbl.set_crtc_timing = 603 set_crtc_using_dtd_timing_v3; 604 break; 605 default: 606 bp->cmd_tbl.set_crtc_timing = NULL; 607 break; 608 } 609 } 610 611 static enum bp_result set_crtc_using_dtd_timing_v3( 612 struct bios_parser *bp, 613 struct bp_hw_crtc_timing_parameters *bp_params) 614 { 615 enum bp_result result = BP_RESULT_FAILURE; 616 struct set_crtc_using_dtd_timing_parameters params = {0}; 617 uint8_t atom_controller_id; 618 619 if (bp->cmd_helper->controller_id_to_atom( 620 bp_params->controller_id, &atom_controller_id)) 621 params.crtc_id = atom_controller_id; 622 623 /* bios usH_Size wants h addressable size */ 624 params.h_size = cpu_to_le16((uint16_t)bp_params->h_addressable); 625 /* bios usH_Blanking_Time wants borders included in blanking */ 626 params.h_blanking_time = 627 cpu_to_le16((uint16_t)(bp_params->h_total - 628 bp_params->h_addressable)); 629 /* bios usV_Size wants v addressable size */ 630 params.v_size = cpu_to_le16((uint16_t)bp_params->v_addressable); 631 /* bios usV_Blanking_Time wants borders included in blanking */ 632 params.v_blanking_time = 633 cpu_to_le16((uint16_t)(bp_params->v_total - 634 bp_params->v_addressable)); 635 /* bios usHSyncOffset is the offset from the end of h addressable, 636 * our horizontalSyncStart is the offset from the beginning 637 * of h addressable 638 */ 639 params.h_syncoffset = 640 cpu_to_le16((uint16_t)(bp_params->h_sync_start - 641 bp_params->h_addressable)); 642 params.h_syncwidth = cpu_to_le16((uint16_t)bp_params->h_sync_width); 643 /* bios usHSyncOffset is the offset from the end of v addressable, 644 * our verticalSyncStart is the offset from the beginning of 645 * v addressable 646 */ 647 params.v_syncoffset = 648 cpu_to_le16((uint16_t)(bp_params->v_sync_start - 649 bp_params->v_addressable)); 650 params.v_syncwidth = cpu_to_le16((uint16_t)bp_params->v_sync_width); 651 652 /* we assume that overscan from original timing does not get bigger 653 * than 255 654 * we will program all the borders in the Set CRTC Overscan call below 655 */ 656 657 if (bp_params->flags.HSYNC_POSITIVE_POLARITY == 0) 658 params.modemiscinfo = 659 cpu_to_le16(le16_to_cpu(params.modemiscinfo) | 660 ATOM_HSYNC_POLARITY); 661 662 if (bp_params->flags.VSYNC_POSITIVE_POLARITY == 0) 663 params.modemiscinfo = 664 cpu_to_le16(le16_to_cpu(params.modemiscinfo) | 665 ATOM_VSYNC_POLARITY); 666 667 if (bp_params->flags.INTERLACE) { 668 params.modemiscinfo = 669 cpu_to_le16(le16_to_cpu(params.modemiscinfo) | 670 ATOM_INTERLACE); 671 672 /* original DAL code has this condition to apply this 673 * for non-TV/CV only 674 * due to complex MV testing for possible impact 675 * if ( pACParameters->signal != SignalType_YPbPr && 676 * pACParameters->signal != SignalType_Composite && 677 * pACParameters->signal != SignalType_SVideo) 678 */ 679 { 680 /* HW will deduct 0.5 line from 2nd feild. 681 * i.e. for 1080i, it is 2 lines for 1st field, 682 * 2.5 lines for the 2nd feild. we need input as 5 683 * instead of 4. 684 * but it is 4 either from Edid data (spec CEA 861) 685 * or CEA timing table. 686 */ 687 le16_add_cpu(¶ms.v_syncoffset, 1); 688 } 689 } 690 691 if (bp_params->flags.HORZ_COUNT_BY_TWO) 692 params.modemiscinfo = 693 cpu_to_le16(le16_to_cpu(params.modemiscinfo) | 694 0x100); /* ATOM_DOUBLE_CLOCK_MODE */ 695 696 if (EXEC_BIOS_CMD_TABLE(setcrtc_usingdtdtiming, params)) 697 result = BP_RESULT_OK; 698 699 return result; 700 } 701 702 /****************************************************************************** 703 ****************************************************************************** 704 ** 705 ** ENABLE CRTC 706 ** 707 ****************************************************************************** 708 *****************************************************************************/ 709 710 static enum bp_result enable_crtc_v1( 711 struct bios_parser *bp, 712 enum controller_id controller_id, 713 bool enable); 714 715 static void init_enable_crtc(struct bios_parser *bp) 716 { 717 switch (BIOS_CMD_TABLE_PARA_REVISION(enablecrtc)) { 718 case 1: 719 bp->cmd_tbl.enable_crtc = enable_crtc_v1; 720 break; 721 default: 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 (void)bp; 793 (void)cntl; 794 /* TODO */ 795 return BP_RESULT_OK; 796 } 797 798 /****************************************************************************** 799 ****************************************************************************** 800 ** 801 ** ENABLE DISPLAY POWER GATING 802 ** 803 ****************************************************************************** 804 *****************************************************************************/ 805 806 static enum bp_result enable_disp_power_gating_v2_1( 807 struct bios_parser *bp, 808 enum controller_id crtc_id, 809 enum bp_pipe_control_action action); 810 811 static enum bp_result enable_disp_power_gating_fallback( 812 struct bios_parser *bp, 813 enum controller_id crtc_id, 814 enum bp_pipe_control_action action); 815 816 static void init_enable_disp_power_gating( 817 struct bios_parser *bp) 818 { 819 switch (BIOS_CMD_TABLE_PARA_REVISION(enabledisppowergating)) { 820 case 1: 821 bp->cmd_tbl.enable_disp_power_gating = 822 enable_disp_power_gating_v2_1; 823 break; 824 default: 825 dm_output_to_console("Don't enable_disp_power_gating enable_crtc for v%d\n", 826 BIOS_CMD_TABLE_PARA_REVISION(enabledisppowergating)); 827 bp->cmd_tbl.enable_disp_power_gating = enable_disp_power_gating_fallback; 828 break; 829 } 830 } 831 832 static void enable_disp_power_gating_dmcub( 833 struct dc_dmub_srv *dmcub, 834 struct enable_disp_power_gating_parameters_v2_1 *pwr) 835 { 836 union dmub_rb_cmd cmd; 837 838 memset(&cmd, 0, sizeof(cmd)); 839 840 cmd.enable_disp_power_gating.header.type = DMUB_CMD__VBIOS; 841 cmd.enable_disp_power_gating.header.sub_type = 842 DMUB_CMD__VBIOS_ENABLE_DISP_POWER_GATING; 843 cmd.enable_disp_power_gating.header.payload_bytes = 844 sizeof(cmd.enable_disp_power_gating) - 845 sizeof(cmd.enable_disp_power_gating.header); 846 cmd.enable_disp_power_gating.power_gating.pwr = *pwr; 847 848 dc_wake_and_execute_dmub_cmd(dmcub->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT); 849 } 850 851 static enum bp_result enable_disp_power_gating_v2_1( 852 struct bios_parser *bp, 853 enum controller_id crtc_id, 854 enum bp_pipe_control_action action) 855 { 856 enum bp_result result = BP_RESULT_FAILURE; 857 858 859 struct enable_disp_power_gating_ps_allocation ps = { { 0 } }; 860 uint8_t atom_crtc_id; 861 862 if (bp->cmd_helper->controller_id_to_atom(crtc_id, &atom_crtc_id)) 863 ps.param.disp_pipe_id = atom_crtc_id; 864 else 865 return BP_RESULT_BADINPUT; 866 867 ps.param.enable = 868 bp->cmd_helper->disp_power_gating_action_to_atom(action); 869 870 if (bp->base.ctx->dc->ctx->dmub_srv && 871 bp->base.ctx->dc->debug.dmub_command_table) { 872 enable_disp_power_gating_dmcub(bp->base.ctx->dmub_srv, 873 &ps.param); 874 return BP_RESULT_OK; 875 } 876 877 if (EXEC_BIOS_CMD_TABLE(enabledisppowergating, ps.param)) 878 result = BP_RESULT_OK; 879 880 return result; 881 } 882 883 static enum bp_result enable_disp_power_gating_fallback( 884 struct bios_parser *bp, 885 enum controller_id crtc_id, 886 enum bp_pipe_control_action action) 887 { 888 if (bp->base.ctx->dc->ctx->dmub_srv && 889 bp->base.ctx->dc->debug.dmub_command_table) { 890 return enable_disp_power_gating_v2_1(bp, crtc_id, action); 891 } 892 893 return BP_RESULT_FAILURE; 894 } 895 896 /****************************************************************************** 897 ******************************************************************************* 898 ** 899 ** SET DCE CLOCK 900 ** 901 ******************************************************************************* 902 *******************************************************************************/ 903 904 static enum bp_result set_dce_clock_v2_1( 905 struct bios_parser *bp, 906 struct bp_set_dce_clock_parameters *bp_params); 907 908 static void init_set_dce_clock(struct bios_parser *bp) 909 { 910 switch (BIOS_CMD_TABLE_PARA_REVISION(setdceclock)) { 911 case 1: 912 bp->cmd_tbl.set_dce_clock = set_dce_clock_v2_1; 913 break; 914 default: 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 = (uint8_t)atom_pll_id; 939 params.param.dceclktype = (uint8_t)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