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