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