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