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