command_table.c (74636B)
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#include "amdgpu.h" 28#include "atom.h" 29 30#include "include/bios_parser_interface.h" 31 32#include "command_table.h" 33#include "command_table_helper.h" 34#include "bios_parser_helper.h" 35#include "bios_parser_types_internal.h" 36 37#define EXEC_BIOS_CMD_TABLE(command, params)\ 38 (amdgpu_atom_execute_table(((struct amdgpu_device *)bp->base.ctx->driver_context)->mode_info.atom_context, \ 39 GetIndexIntoMasterTable(COMMAND, command), \ 40 (uint32_t *)¶ms) == 0) 41 42#define BIOS_CMD_TABLE_REVISION(command, frev, crev)\ 43 amdgpu_atom_parse_cmd_header(((struct amdgpu_device *)bp->base.ctx->driver_context)->mode_info.atom_context, \ 44 GetIndexIntoMasterTable(COMMAND, command), &frev, &crev) 45 46#define BIOS_CMD_TABLE_PARA_REVISION(command)\ 47 bios_cmd_table_para_revision(bp->base.ctx->driver_context, \ 48 GetIndexIntoMasterTable(COMMAND, command)) 49 50static void init_dig_encoder_control(struct bios_parser *bp); 51static void init_transmitter_control(struct bios_parser *bp); 52static void init_set_pixel_clock(struct bios_parser *bp); 53static void init_enable_spread_spectrum_on_ppll(struct bios_parser *bp); 54static void init_adjust_display_pll(struct bios_parser *bp); 55static void init_dac_encoder_control(struct bios_parser *bp); 56static void init_dac_output_control(struct bios_parser *bp); 57static void init_set_crtc_timing(struct bios_parser *bp); 58static void init_enable_crtc(struct bios_parser *bp); 59static void init_enable_crtc_mem_req(struct bios_parser *bp); 60static void init_external_encoder_control(struct bios_parser *bp); 61static void init_enable_disp_power_gating(struct bios_parser *bp); 62static void init_program_clock(struct bios_parser *bp); 63static void init_set_dce_clock(struct bios_parser *bp); 64 65void dal_bios_parser_init_cmd_tbl(struct bios_parser *bp) 66{ 67 init_dig_encoder_control(bp); 68 init_transmitter_control(bp); 69 init_set_pixel_clock(bp); 70 init_enable_spread_spectrum_on_ppll(bp); 71 init_adjust_display_pll(bp); 72 init_dac_encoder_control(bp); 73 init_dac_output_control(bp); 74 init_set_crtc_timing(bp); 75 init_enable_crtc(bp); 76 init_enable_crtc_mem_req(bp); 77 init_program_clock(bp); 78 init_external_encoder_control(bp); 79 init_enable_disp_power_gating(bp); 80 init_set_dce_clock(bp); 81} 82 83static uint32_t bios_cmd_table_para_revision(void *dev, 84 uint32_t index) 85{ 86 struct amdgpu_device *adev = dev; 87 uint8_t frev, crev; 88 89 if (amdgpu_atom_parse_cmd_header(adev->mode_info.atom_context, 90 index, 91 &frev, &crev)) 92 return crev; 93 else 94 return 0; 95} 96 97/******************************************************************************* 98 ******************************************************************************** 99 ** 100 ** D I G E N C O D E R C O N T R O L 101 ** 102 ******************************************************************************** 103 *******************************************************************************/ 104static enum bp_result encoder_control_digx_v3( 105 struct bios_parser *bp, 106 struct bp_encoder_control *cntl); 107 108static enum bp_result encoder_control_digx_v4( 109 struct bios_parser *bp, 110 struct bp_encoder_control *cntl); 111 112static enum bp_result encoder_control_digx_v5( 113 struct bios_parser *bp, 114 struct bp_encoder_control *cntl); 115 116static void init_encoder_control_dig_v1(struct bios_parser *bp); 117 118static void init_dig_encoder_control(struct bios_parser *bp) 119{ 120 uint32_t version = 121 BIOS_CMD_TABLE_PARA_REVISION(DIGxEncoderControl); 122 123 switch (version) { 124 case 2: 125 bp->cmd_tbl.dig_encoder_control = encoder_control_digx_v3; 126 break; 127 case 4: 128 bp->cmd_tbl.dig_encoder_control = encoder_control_digx_v4; 129 break; 130 131 case 5: 132 bp->cmd_tbl.dig_encoder_control = encoder_control_digx_v5; 133 break; 134 135 default: 136 init_encoder_control_dig_v1(bp); 137 break; 138 } 139} 140 141static enum bp_result encoder_control_dig_v1( 142 struct bios_parser *bp, 143 struct bp_encoder_control *cntl); 144static enum bp_result encoder_control_dig1_v1( 145 struct bios_parser *bp, 146 struct bp_encoder_control *cntl); 147static enum bp_result encoder_control_dig2_v1( 148 struct bios_parser *bp, 149 struct bp_encoder_control *cntl); 150 151static void init_encoder_control_dig_v1(struct bios_parser *bp) 152{ 153 struct cmd_tbl *cmd_tbl = &bp->cmd_tbl; 154 155 if (1 == BIOS_CMD_TABLE_PARA_REVISION(DIG1EncoderControl)) 156 cmd_tbl->encoder_control_dig1 = encoder_control_dig1_v1; 157 else 158 cmd_tbl->encoder_control_dig1 = NULL; 159 160 if (1 == BIOS_CMD_TABLE_PARA_REVISION(DIG2EncoderControl)) 161 cmd_tbl->encoder_control_dig2 = encoder_control_dig2_v1; 162 else 163 cmd_tbl->encoder_control_dig2 = NULL; 164 165 cmd_tbl->dig_encoder_control = encoder_control_dig_v1; 166} 167 168static enum bp_result encoder_control_dig_v1( 169 struct bios_parser *bp, 170 struct bp_encoder_control *cntl) 171{ 172 enum bp_result result = BP_RESULT_FAILURE; 173 struct cmd_tbl *cmd_tbl = &bp->cmd_tbl; 174 175 if (cntl != NULL) 176 switch (cntl->engine_id) { 177 case ENGINE_ID_DIGA: 178 if (cmd_tbl->encoder_control_dig1 != NULL) 179 result = 180 cmd_tbl->encoder_control_dig1(bp, cntl); 181 break; 182 case ENGINE_ID_DIGB: 183 if (cmd_tbl->encoder_control_dig2 != NULL) 184 result = 185 cmd_tbl->encoder_control_dig2(bp, cntl); 186 break; 187 188 default: 189 break; 190 } 191 192 return result; 193} 194 195static enum bp_result encoder_control_dig1_v1( 196 struct bios_parser *bp, 197 struct bp_encoder_control *cntl) 198{ 199 enum bp_result result = BP_RESULT_FAILURE; 200 DIG_ENCODER_CONTROL_PARAMETERS_V2 params = {0}; 201 202 bp->cmd_helper->assign_control_parameter(bp->cmd_helper, cntl, ¶ms); 203 204 if (EXEC_BIOS_CMD_TABLE(DIG1EncoderControl, params)) 205 result = BP_RESULT_OK; 206 207 return result; 208} 209 210static enum bp_result encoder_control_dig2_v1( 211 struct bios_parser *bp, 212 struct bp_encoder_control *cntl) 213{ 214 enum bp_result result = BP_RESULT_FAILURE; 215 DIG_ENCODER_CONTROL_PARAMETERS_V2 params = {0}; 216 217 bp->cmd_helper->assign_control_parameter(bp->cmd_helper, cntl, ¶ms); 218 219 if (EXEC_BIOS_CMD_TABLE(DIG2EncoderControl, params)) 220 result = BP_RESULT_OK; 221 222 return result; 223} 224 225static enum bp_result encoder_control_digx_v3( 226 struct bios_parser *bp, 227 struct bp_encoder_control *cntl) 228{ 229 enum bp_result result = BP_RESULT_FAILURE; 230 DIG_ENCODER_CONTROL_PARAMETERS_V3 params = {0}; 231 232 if (LANE_COUNT_FOUR < cntl->lanes_number) 233 params.acConfig.ucDPLinkRate = 1; /* dual link 2.7GHz */ 234 else 235 params.acConfig.ucDPLinkRate = 0; /* single link 1.62GHz */ 236 237 params.acConfig.ucDigSel = (uint8_t)(cntl->engine_id); 238 239 /* We need to convert from KHz units into 10KHz units */ 240 params.ucAction = bp->cmd_helper->encoder_action_to_atom(cntl->action); 241 params.usPixelClock = cpu_to_le16((uint16_t)(cntl->pixel_clock / 10)); 242 params.ucEncoderMode = 243 (uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom( 244 cntl->signal, 245 cntl->enable_dp_audio); 246 params.ucLaneNum = (uint8_t)(cntl->lanes_number); 247 248 switch (cntl->color_depth) { 249 case COLOR_DEPTH_888: 250 params.ucBitPerColor = PANEL_8BIT_PER_COLOR; 251 break; 252 case COLOR_DEPTH_101010: 253 params.ucBitPerColor = PANEL_10BIT_PER_COLOR; 254 break; 255 case COLOR_DEPTH_121212: 256 params.ucBitPerColor = PANEL_12BIT_PER_COLOR; 257 break; 258 case COLOR_DEPTH_161616: 259 params.ucBitPerColor = PANEL_16BIT_PER_COLOR; 260 break; 261 default: 262 break; 263 } 264 265 if (EXEC_BIOS_CMD_TABLE(DIGxEncoderControl, params)) 266 result = BP_RESULT_OK; 267 268 return result; 269} 270 271static enum bp_result encoder_control_digx_v4( 272 struct bios_parser *bp, 273 struct bp_encoder_control *cntl) 274{ 275 enum bp_result result = BP_RESULT_FAILURE; 276 DIG_ENCODER_CONTROL_PARAMETERS_V4 params = {0}; 277 278 if (LANE_COUNT_FOUR < cntl->lanes_number) 279 params.acConfig.ucDPLinkRate = 1; /* dual link 2.7GHz */ 280 else 281 params.acConfig.ucDPLinkRate = 0; /* single link 1.62GHz */ 282 283 params.acConfig.ucDigSel = (uint8_t)(cntl->engine_id); 284 285 /* We need to convert from KHz units into 10KHz units */ 286 params.ucAction = bp->cmd_helper->encoder_action_to_atom(cntl->action); 287 params.usPixelClock = cpu_to_le16((uint16_t)(cntl->pixel_clock / 10)); 288 params.ucEncoderMode = 289 (uint8_t)(bp->cmd_helper->encoder_mode_bp_to_atom( 290 cntl->signal, 291 cntl->enable_dp_audio)); 292 params.ucLaneNum = (uint8_t)(cntl->lanes_number); 293 294 switch (cntl->color_depth) { 295 case COLOR_DEPTH_888: 296 params.ucBitPerColor = PANEL_8BIT_PER_COLOR; 297 break; 298 case COLOR_DEPTH_101010: 299 params.ucBitPerColor = PANEL_10BIT_PER_COLOR; 300 break; 301 case COLOR_DEPTH_121212: 302 params.ucBitPerColor = PANEL_12BIT_PER_COLOR; 303 break; 304 case COLOR_DEPTH_161616: 305 params.ucBitPerColor = PANEL_16BIT_PER_COLOR; 306 break; 307 default: 308 break; 309 } 310 311 if (EXEC_BIOS_CMD_TABLE(DIGxEncoderControl, params)) 312 result = BP_RESULT_OK; 313 314 return result; 315} 316 317static enum bp_result encoder_control_digx_v5( 318 struct bios_parser *bp, 319 struct bp_encoder_control *cntl) 320{ 321 enum bp_result result = BP_RESULT_FAILURE; 322 ENCODER_STREAM_SETUP_PARAMETERS_V5 params = {0}; 323 324 params.ucDigId = (uint8_t)(cntl->engine_id); 325 params.ucAction = bp->cmd_helper->encoder_action_to_atom(cntl->action); 326 327 params.ulPixelClock = cntl->pixel_clock / 10; 328 params.ucDigMode = 329 (uint8_t)(bp->cmd_helper->encoder_mode_bp_to_atom( 330 cntl->signal, 331 cntl->enable_dp_audio)); 332 params.ucLaneNum = (uint8_t)(cntl->lanes_number); 333 334 switch (cntl->color_depth) { 335 case COLOR_DEPTH_888: 336 params.ucBitPerColor = PANEL_8BIT_PER_COLOR; 337 break; 338 case COLOR_DEPTH_101010: 339 params.ucBitPerColor = PANEL_10BIT_PER_COLOR; 340 break; 341 case COLOR_DEPTH_121212: 342 params.ucBitPerColor = PANEL_12BIT_PER_COLOR; 343 break; 344 case COLOR_DEPTH_161616: 345 params.ucBitPerColor = PANEL_16BIT_PER_COLOR; 346 break; 347 default: 348 break; 349 } 350 351 if (cntl->signal == SIGNAL_TYPE_HDMI_TYPE_A) 352 switch (cntl->color_depth) { 353 case COLOR_DEPTH_101010: 354 params.ulPixelClock = 355 (params.ulPixelClock * 30) / 24; 356 break; 357 case COLOR_DEPTH_121212: 358 params.ulPixelClock = 359 (params.ulPixelClock * 36) / 24; 360 break; 361 case COLOR_DEPTH_161616: 362 params.ulPixelClock = 363 (params.ulPixelClock * 48) / 24; 364 break; 365 default: 366 break; 367 } 368 369 if (EXEC_BIOS_CMD_TABLE(DIGxEncoderControl, params)) 370 result = BP_RESULT_OK; 371 372 return result; 373} 374 375/******************************************************************************* 376 ******************************************************************************** 377 ** 378 ** TRANSMITTER CONTROL 379 ** 380 ******************************************************************************** 381 *******************************************************************************/ 382 383static enum bp_result transmitter_control_v2( 384 struct bios_parser *bp, 385 struct bp_transmitter_control *cntl); 386static enum bp_result transmitter_control_v3( 387 struct bios_parser *bp, 388 struct bp_transmitter_control *cntl); 389static enum bp_result transmitter_control_v4( 390 struct bios_parser *bp, 391 struct bp_transmitter_control *cntl); 392static enum bp_result transmitter_control_v1_5( 393 struct bios_parser *bp, 394 struct bp_transmitter_control *cntl); 395static enum bp_result transmitter_control_v1_6( 396 struct bios_parser *bp, 397 struct bp_transmitter_control *cntl); 398 399static void init_transmitter_control(struct bios_parser *bp) 400{ 401 uint8_t frev; 402 uint8_t crev; 403 404 if (BIOS_CMD_TABLE_REVISION(UNIPHYTransmitterControl, 405 frev, crev) == false) 406 BREAK_TO_DEBUGGER(); 407 switch (crev) { 408 case 2: 409 bp->cmd_tbl.transmitter_control = transmitter_control_v2; 410 break; 411 case 3: 412 bp->cmd_tbl.transmitter_control = transmitter_control_v3; 413 break; 414 case 4: 415 bp->cmd_tbl.transmitter_control = transmitter_control_v4; 416 break; 417 case 5: 418 bp->cmd_tbl.transmitter_control = transmitter_control_v1_5; 419 break; 420 case 6: 421 bp->cmd_tbl.transmitter_control = transmitter_control_v1_6; 422 break; 423 default: 424 dm_output_to_console("Don't have transmitter_control for v%d\n", crev); 425 bp->cmd_tbl.transmitter_control = NULL; 426 break; 427 } 428} 429 430static enum bp_result transmitter_control_v2( 431 struct bios_parser *bp, 432 struct bp_transmitter_control *cntl) 433{ 434 enum bp_result result = BP_RESULT_FAILURE; 435 DIG_TRANSMITTER_CONTROL_PARAMETERS_V2 params; 436 enum connector_id connector_id = 437 dal_graphics_object_id_get_connector_id(cntl->connector_obj_id); 438 439 memset(¶ms, 0, sizeof(params)); 440 441 switch (cntl->transmitter) { 442 case TRANSMITTER_UNIPHY_A: 443 case TRANSMITTER_UNIPHY_B: 444 case TRANSMITTER_UNIPHY_C: 445 case TRANSMITTER_UNIPHY_D: 446 case TRANSMITTER_UNIPHY_E: 447 case TRANSMITTER_UNIPHY_F: 448 case TRANSMITTER_TRAVIS_LCD: 449 break; 450 default: 451 return BP_RESULT_BADINPUT; 452 } 453 454 switch (cntl->action) { 455 case TRANSMITTER_CONTROL_INIT: 456 if ((CONNECTOR_ID_DUAL_LINK_DVII == connector_id) || 457 (CONNECTOR_ID_DUAL_LINK_DVID == connector_id)) 458 /* on INIT this bit should be set according to the 459 * physical connector 460 * Bit0: dual link connector flag 461 * =0 connector is single link connector 462 * =1 connector is dual link connector 463 */ 464 params.acConfig.fDualLinkConnector = 1; 465 466 /* connector object id */ 467 params.usInitInfo = 468 cpu_to_le16((uint8_t)cntl->connector_obj_id.id); 469 break; 470 case TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS: 471 /* voltage swing and pre-emphsis */ 472 params.asMode.ucLaneSel = (uint8_t)cntl->lane_select; 473 params.asMode.ucLaneSet = (uint8_t)cntl->lane_settings; 474 break; 475 default: 476 /* if dual-link */ 477 if (LANE_COUNT_FOUR < cntl->lanes_number) { 478 /* on ENABLE/DISABLE this bit should be set according to 479 * actual timing (number of lanes) 480 * Bit0: dual link connector flag 481 * =0 connector is single link connector 482 * =1 connector is dual link connector 483 */ 484 params.acConfig.fDualLinkConnector = 1; 485 486 /* link rate, half for dual link 487 * We need to convert from KHz units into 20KHz units 488 */ 489 params.usPixelClock = 490 cpu_to_le16((uint16_t)(cntl->pixel_clock / 20)); 491 } else 492 /* link rate, half for dual link 493 * We need to convert from KHz units into 10KHz units 494 */ 495 params.usPixelClock = 496 cpu_to_le16((uint16_t)(cntl->pixel_clock / 10)); 497 break; 498 } 499 500 /* 00 - coherent mode 501 * 01 - incoherent mode 502 */ 503 504 params.acConfig.fCoherentMode = cntl->coherent; 505 506 if ((TRANSMITTER_UNIPHY_B == cntl->transmitter) 507 || (TRANSMITTER_UNIPHY_D == cntl->transmitter) 508 || (TRANSMITTER_UNIPHY_F == cntl->transmitter)) 509 /* Bit2: Transmitter Link selection 510 * =0 when bit0=0, single link A/C/E, when bit0=1, 511 * master link A/C/E 512 * =1 when bit0=0, single link B/D/F, when bit0=1, 513 * master link B/D/F 514 */ 515 params.acConfig.ucLinkSel = 1; 516 517 if (ENGINE_ID_DIGB == cntl->engine_id) 518 /* Bit3: Transmitter data source selection 519 * =0 DIGA is data source. 520 * =1 DIGB is data source. 521 * This bit is only useful when ucAction= ATOM_ENABLE 522 */ 523 params.acConfig.ucEncoderSel = 1; 524 525 if (CONNECTOR_ID_DISPLAY_PORT == connector_id 526 || CONNECTOR_ID_USBC == connector_id) 527 /* Bit4: DP connector flag 528 * =0 connector is none-DP connector 529 * =1 connector is DP connector 530 */ 531 params.acConfig.fDPConnector = 1; 532 533 /* Bit[7:6]: Transmitter selection 534 * =0 UNIPHY_ENCODER: UNIPHYA/B 535 * =1 UNIPHY1_ENCODER: UNIPHYC/D 536 * =2 UNIPHY2_ENCODER: UNIPHYE/F 537 * =3 reserved 538 */ 539 params.acConfig.ucTransmitterSel = 540 (uint8_t)bp->cmd_helper->transmitter_bp_to_atom( 541 cntl->transmitter); 542 543 params.ucAction = (uint8_t)cntl->action; 544 545 if (EXEC_BIOS_CMD_TABLE(UNIPHYTransmitterControl, params)) 546 result = BP_RESULT_OK; 547 548 return result; 549} 550 551static enum bp_result transmitter_control_v3( 552 struct bios_parser *bp, 553 struct bp_transmitter_control *cntl) 554{ 555 enum bp_result result = BP_RESULT_FAILURE; 556 DIG_TRANSMITTER_CONTROL_PARAMETERS_V3 params; 557 uint32_t pll_id; 558 enum connector_id conn_id = 559 dal_graphics_object_id_get_connector_id(cntl->connector_obj_id); 560 const struct command_table_helper *cmd = bp->cmd_helper; 561 bool dual_link_conn = (CONNECTOR_ID_DUAL_LINK_DVII == conn_id) 562 || (CONNECTOR_ID_DUAL_LINK_DVID == conn_id); 563 564 memset(¶ms, 0, sizeof(params)); 565 566 switch (cntl->transmitter) { 567 case TRANSMITTER_UNIPHY_A: 568 case TRANSMITTER_UNIPHY_B: 569 case TRANSMITTER_UNIPHY_C: 570 case TRANSMITTER_UNIPHY_D: 571 case TRANSMITTER_UNIPHY_E: 572 case TRANSMITTER_UNIPHY_F: 573 case TRANSMITTER_TRAVIS_LCD: 574 break; 575 default: 576 return BP_RESULT_BADINPUT; 577 } 578 579 if (!cmd->clock_source_id_to_atom(cntl->pll_id, &pll_id)) 580 return BP_RESULT_BADINPUT; 581 582 /* fill information based on the action */ 583 switch (cntl->action) { 584 case TRANSMITTER_CONTROL_INIT: 585 if (dual_link_conn) { 586 /* on INIT this bit should be set according to the 587 * phisycal connector 588 * Bit0: dual link connector flag 589 * =0 connector is single link connector 590 * =1 connector is dual link connector 591 */ 592 params.acConfig.fDualLinkConnector = 1; 593 } 594 595 /* connector object id */ 596 params.usInitInfo = 597 cpu_to_le16((uint8_t)(cntl->connector_obj_id.id)); 598 break; 599 case TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS: 600 /* votage swing and pre-emphsis */ 601 params.asMode.ucLaneSel = (uint8_t)cntl->lane_select; 602 params.asMode.ucLaneSet = (uint8_t)cntl->lane_settings; 603 break; 604 default: 605 if (dual_link_conn && cntl->multi_path) 606 /* on ENABLE/DISABLE this bit should be set according to 607 * actual timing (number of lanes) 608 * Bit0: dual link connector flag 609 * =0 connector is single link connector 610 * =1 connector is dual link connector 611 */ 612 params.acConfig.fDualLinkConnector = 1; 613 614 /* if dual-link */ 615 if (LANE_COUNT_FOUR < cntl->lanes_number) { 616 /* on ENABLE/DISABLE this bit should be set according to 617 * actual timing (number of lanes) 618 * Bit0: dual link connector flag 619 * =0 connector is single link connector 620 * =1 connector is dual link connector 621 */ 622 params.acConfig.fDualLinkConnector = 1; 623 624 /* link rate, half for dual link 625 * We need to convert from KHz units into 20KHz units 626 */ 627 params.usPixelClock = 628 cpu_to_le16((uint16_t)(cntl->pixel_clock / 20)); 629 } else { 630 /* link rate, half for dual link 631 * We need to convert from KHz units into 10KHz units 632 */ 633 params.usPixelClock = 634 cpu_to_le16((uint16_t)(cntl->pixel_clock / 10)); 635 } 636 break; 637 } 638 639 /* 00 - coherent mode 640 * 01 - incoherent mode 641 */ 642 643 params.acConfig.fCoherentMode = cntl->coherent; 644 645 if ((TRANSMITTER_UNIPHY_B == cntl->transmitter) 646 || (TRANSMITTER_UNIPHY_D == cntl->transmitter) 647 || (TRANSMITTER_UNIPHY_F == cntl->transmitter)) 648 /* Bit2: Transmitter Link selection 649 * =0 when bit0=0, single link A/C/E, when bit0=1, 650 * master link A/C/E 651 * =1 when bit0=0, single link B/D/F, when bit0=1, 652 * master link B/D/F 653 */ 654 params.acConfig.ucLinkSel = 1; 655 656 if (ENGINE_ID_DIGB == cntl->engine_id) 657 /* Bit3: Transmitter data source selection 658 * =0 DIGA is data source. 659 * =1 DIGB is data source. 660 * This bit is only useful when ucAction= ATOM_ENABLE 661 */ 662 params.acConfig.ucEncoderSel = 1; 663 664 /* Bit[7:6]: Transmitter selection 665 * =0 UNIPHY_ENCODER: UNIPHYA/B 666 * =1 UNIPHY1_ENCODER: UNIPHYC/D 667 * =2 UNIPHY2_ENCODER: UNIPHYE/F 668 * =3 reserved 669 */ 670 params.acConfig.ucTransmitterSel = 671 (uint8_t)cmd->transmitter_bp_to_atom(cntl->transmitter); 672 673 params.ucLaneNum = (uint8_t)cntl->lanes_number; 674 675 params.acConfig.ucRefClkSource = (uint8_t)pll_id; 676 677 params.ucAction = (uint8_t)cntl->action; 678 679 if (EXEC_BIOS_CMD_TABLE(UNIPHYTransmitterControl, params)) 680 result = BP_RESULT_OK; 681 682 return result; 683} 684 685static enum bp_result transmitter_control_v4( 686 struct bios_parser *bp, 687 struct bp_transmitter_control *cntl) 688{ 689 enum bp_result result = BP_RESULT_FAILURE; 690 DIG_TRANSMITTER_CONTROL_PARAMETERS_V4 params; 691 uint32_t ref_clk_src_id; 692 enum connector_id conn_id = 693 dal_graphics_object_id_get_connector_id(cntl->connector_obj_id); 694 const struct command_table_helper *cmd = bp->cmd_helper; 695 696 memset(¶ms, 0, sizeof(params)); 697 698 switch (cntl->transmitter) { 699 case TRANSMITTER_UNIPHY_A: 700 case TRANSMITTER_UNIPHY_B: 701 case TRANSMITTER_UNIPHY_C: 702 case TRANSMITTER_UNIPHY_D: 703 case TRANSMITTER_UNIPHY_E: 704 case TRANSMITTER_UNIPHY_F: 705 case TRANSMITTER_TRAVIS_LCD: 706 break; 707 default: 708 return BP_RESULT_BADINPUT; 709 } 710 711 if (!cmd->clock_source_id_to_ref_clk_src(cntl->pll_id, &ref_clk_src_id)) 712 return BP_RESULT_BADINPUT; 713 714 switch (cntl->action) { 715 case TRANSMITTER_CONTROL_INIT: 716 { 717 if ((CONNECTOR_ID_DUAL_LINK_DVII == conn_id) || 718 (CONNECTOR_ID_DUAL_LINK_DVID == conn_id)) 719 /* on INIT this bit should be set according to the 720 * phisycal connector 721 * Bit0: dual link connector flag 722 * =0 connector is single link connector 723 * =1 connector is dual link connector 724 */ 725 params.acConfig.fDualLinkConnector = 1; 726 727 /* connector object id */ 728 params.usInitInfo = 729 cpu_to_le16((uint8_t)(cntl->connector_obj_id.id)); 730 } 731 break; 732 case TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS: 733 /* votage swing and pre-emphsis */ 734 params.asMode.ucLaneSel = (uint8_t)(cntl->lane_select); 735 params.asMode.ucLaneSet = (uint8_t)(cntl->lane_settings); 736 break; 737 default: 738 if ((CONNECTOR_ID_DUAL_LINK_DVII == conn_id) || 739 (CONNECTOR_ID_DUAL_LINK_DVID == conn_id)) 740 /* on ENABLE/DISABLE this bit should be set according to 741 * actual timing (number of lanes) 742 * Bit0: dual link connector flag 743 * =0 connector is single link connector 744 * =1 connector is dual link connector 745 */ 746 params.acConfig.fDualLinkConnector = 1; 747 748 /* if dual-link */ 749 if (LANE_COUNT_FOUR < cntl->lanes_number) 750 /* link rate, half for dual link 751 * We need to convert from KHz units into 20KHz units 752 */ 753 params.usPixelClock = 754 cpu_to_le16((uint16_t)(cntl->pixel_clock / 20)); 755 else { 756 /* link rate, half for dual link 757 * We need to convert from KHz units into 10KHz units 758 */ 759 params.usPixelClock = 760 cpu_to_le16((uint16_t)(cntl->pixel_clock / 10)); 761 } 762 break; 763 } 764 765 /* 00 - coherent mode 766 * 01 - incoherent mode 767 */ 768 769 params.acConfig.fCoherentMode = cntl->coherent; 770 771 if ((TRANSMITTER_UNIPHY_B == cntl->transmitter) 772 || (TRANSMITTER_UNIPHY_D == cntl->transmitter) 773 || (TRANSMITTER_UNIPHY_F == cntl->transmitter)) 774 /* Bit2: Transmitter Link selection 775 * =0 when bit0=0, single link A/C/E, when bit0=1, 776 * master link A/C/E 777 * =1 when bit0=0, single link B/D/F, when bit0=1, 778 * master link B/D/F 779 */ 780 params.acConfig.ucLinkSel = 1; 781 782 if (ENGINE_ID_DIGB == cntl->engine_id) 783 /* Bit3: Transmitter data source selection 784 * =0 DIGA is data source. 785 * =1 DIGB is data source. 786 * This bit is only useful when ucAction= ATOM_ENABLE 787 */ 788 params.acConfig.ucEncoderSel = 1; 789 790 /* Bit[7:6]: Transmitter selection 791 * =0 UNIPHY_ENCODER: UNIPHYA/B 792 * =1 UNIPHY1_ENCODER: UNIPHYC/D 793 * =2 UNIPHY2_ENCODER: UNIPHYE/F 794 * =3 reserved 795 */ 796 params.acConfig.ucTransmitterSel = 797 (uint8_t)(cmd->transmitter_bp_to_atom(cntl->transmitter)); 798 params.ucLaneNum = (uint8_t)(cntl->lanes_number); 799 params.acConfig.ucRefClkSource = (uint8_t)(ref_clk_src_id); 800 params.ucAction = (uint8_t)(cntl->action); 801 802 if (EXEC_BIOS_CMD_TABLE(UNIPHYTransmitterControl, params)) 803 result = BP_RESULT_OK; 804 805 return result; 806} 807 808static enum bp_result transmitter_control_v1_5( 809 struct bios_parser *bp, 810 struct bp_transmitter_control *cntl) 811{ 812 enum bp_result result = BP_RESULT_FAILURE; 813 const struct command_table_helper *cmd = bp->cmd_helper; 814 DIG_TRANSMITTER_CONTROL_PARAMETERS_V1_5 params; 815 816 memset(¶ms, 0, sizeof(params)); 817 params.ucPhyId = cmd->phy_id_to_atom(cntl->transmitter); 818 params.ucAction = (uint8_t)cntl->action; 819 params.ucLaneNum = (uint8_t)cntl->lanes_number; 820 params.ucConnObjId = (uint8_t)cntl->connector_obj_id.id; 821 822 params.ucDigMode = 823 cmd->signal_type_to_atom_dig_mode(cntl->signal); 824 params.asConfig.ucPhyClkSrcId = 825 cmd->clock_source_id_to_atom_phy_clk_src_id(cntl->pll_id); 826 /* 00 - coherent mode */ 827 params.asConfig.ucCoherentMode = cntl->coherent; 828 params.asConfig.ucHPDSel = 829 cmd->hpd_sel_to_atom(cntl->hpd_sel); 830 params.ucDigEncoderSel = 831 cmd->dig_encoder_sel_to_atom(cntl->engine_id); 832 params.ucDPLaneSet = (uint8_t) cntl->lane_settings; 833 params.usSymClock = cpu_to_le16((uint16_t) (cntl->pixel_clock / 10)); 834 /* 835 * In SI/TN case, caller have to set usPixelClock as following: 836 * DP mode: usPixelClock = DP_LINK_CLOCK/10 837 * (DP_LINK_CLOCK = 1.62GHz, 2.7GHz, 5.4GHz) 838 * DVI single link mode: usPixelClock = pixel clock 839 * DVI dual link mode: usPixelClock = pixel clock 840 * HDMI mode: usPixelClock = pixel clock * deep_color_ratio 841 * (=1: 8bpp, =1.25: 10bpp, =1.5:12bpp, =2: 16bpp) 842 * LVDS mode: usPixelClock = pixel clock 843 */ 844 if (cntl->signal == SIGNAL_TYPE_HDMI_TYPE_A) { 845 switch (cntl->color_depth) { 846 case COLOR_DEPTH_101010: 847 params.usSymClock = 848 cpu_to_le16((le16_to_cpu(params.usSymClock) * 30) / 24); 849 break; 850 case COLOR_DEPTH_121212: 851 params.usSymClock = 852 cpu_to_le16((le16_to_cpu(params.usSymClock) * 36) / 24); 853 break; 854 case COLOR_DEPTH_161616: 855 params.usSymClock = 856 cpu_to_le16((le16_to_cpu(params.usSymClock) * 48) / 24); 857 break; 858 default: 859 break; 860 } 861 } 862 863 if (EXEC_BIOS_CMD_TABLE(UNIPHYTransmitterControl, params)) 864 result = BP_RESULT_OK; 865 866 return result; 867} 868 869static enum bp_result transmitter_control_v1_6( 870 struct bios_parser *bp, 871 struct bp_transmitter_control *cntl) 872{ 873 enum bp_result result = BP_RESULT_FAILURE; 874 const struct command_table_helper *cmd = bp->cmd_helper; 875 DIG_TRANSMITTER_CONTROL_PARAMETERS_V1_6 params; 876 877 memset(¶ms, 0, sizeof(params)); 878 params.ucPhyId = cmd->phy_id_to_atom(cntl->transmitter); 879 params.ucAction = (uint8_t)cntl->action; 880 881 if (cntl->action == TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS) 882 params.ucDPLaneSet = (uint8_t)cntl->lane_settings; 883 else 884 params.ucDigMode = cmd->signal_type_to_atom_dig_mode(cntl->signal); 885 886 params.ucLaneNum = (uint8_t)cntl->lanes_number; 887 params.ucHPDSel = cmd->hpd_sel_to_atom(cntl->hpd_sel); 888 params.ucDigEncoderSel = cmd->dig_encoder_sel_to_atom(cntl->engine_id); 889 params.ucConnObjId = (uint8_t)cntl->connector_obj_id.id; 890 params.ulSymClock = cntl->pixel_clock/10; 891 892 /* 893 * In SI/TN case, caller have to set usPixelClock as following: 894 * DP mode: usPixelClock = DP_LINK_CLOCK/10 895 * (DP_LINK_CLOCK = 1.62GHz, 2.7GHz, 5.4GHz) 896 * DVI single link mode: usPixelClock = pixel clock 897 * DVI dual link mode: usPixelClock = pixel clock 898 * HDMI mode: usPixelClock = pixel clock * deep_color_ratio 899 * (=1: 8bpp, =1.25: 10bpp, =1.5:12bpp, =2: 16bpp) 900 * LVDS mode: usPixelClock = pixel clock 901 */ 902 switch (cntl->signal) { 903 case SIGNAL_TYPE_HDMI_TYPE_A: 904 switch (cntl->color_depth) { 905 case COLOR_DEPTH_101010: 906 params.ulSymClock = 907 cpu_to_le16((le16_to_cpu(params.ulSymClock) * 30) / 24); 908 break; 909 case COLOR_DEPTH_121212: 910 params.ulSymClock = 911 cpu_to_le16((le16_to_cpu(params.ulSymClock) * 36) / 24); 912 break; 913 case COLOR_DEPTH_161616: 914 params.ulSymClock = 915 cpu_to_le16((le16_to_cpu(params.ulSymClock) * 48) / 24); 916 break; 917 default: 918 break; 919 } 920 break; 921 default: 922 break; 923 } 924 925 if (EXEC_BIOS_CMD_TABLE(UNIPHYTransmitterControl, params)) 926 result = BP_RESULT_OK; 927 return result; 928} 929 930/******************************************************************************* 931 ******************************************************************************** 932 ** 933 ** SET PIXEL CLOCK 934 ** 935 ******************************************************************************** 936 *******************************************************************************/ 937 938static enum bp_result set_pixel_clock_v3( 939 struct bios_parser *bp, 940 struct bp_pixel_clock_parameters *bp_params); 941static enum bp_result set_pixel_clock_v5( 942 struct bios_parser *bp, 943 struct bp_pixel_clock_parameters *bp_params); 944static enum bp_result set_pixel_clock_v6( 945 struct bios_parser *bp, 946 struct bp_pixel_clock_parameters *bp_params); 947static enum bp_result set_pixel_clock_v7( 948 struct bios_parser *bp, 949 struct bp_pixel_clock_parameters *bp_params); 950 951static void init_set_pixel_clock(struct bios_parser *bp) 952{ 953 switch (BIOS_CMD_TABLE_PARA_REVISION(SetPixelClock)) { 954 case 3: 955 bp->cmd_tbl.set_pixel_clock = set_pixel_clock_v3; 956 break; 957 case 5: 958 bp->cmd_tbl.set_pixel_clock = set_pixel_clock_v5; 959 break; 960 case 6: 961 bp->cmd_tbl.set_pixel_clock = set_pixel_clock_v6; 962 break; 963 case 7: 964 bp->cmd_tbl.set_pixel_clock = set_pixel_clock_v7; 965 break; 966 default: 967 dm_output_to_console("Don't have set_pixel_clock for v%d\n", 968 BIOS_CMD_TABLE_PARA_REVISION(SetPixelClock)); 969 bp->cmd_tbl.set_pixel_clock = NULL; 970 break; 971 } 972} 973 974static enum bp_result set_pixel_clock_v3( 975 struct bios_parser *bp, 976 struct bp_pixel_clock_parameters *bp_params) 977{ 978 enum bp_result result = BP_RESULT_FAILURE; 979 PIXEL_CLOCK_PARAMETERS_V3 *params; 980 SET_PIXEL_CLOCK_PS_ALLOCATION allocation; 981 982 memset(&allocation, 0, sizeof(allocation)); 983 984 if (CLOCK_SOURCE_ID_PLL1 == bp_params->pll_id) 985 allocation.sPCLKInput.ucPpll = ATOM_PPLL1; 986 else if (CLOCK_SOURCE_ID_PLL2 == bp_params->pll_id) 987 allocation.sPCLKInput.ucPpll = ATOM_PPLL2; 988 else 989 return BP_RESULT_BADINPUT; 990 991 allocation.sPCLKInput.usRefDiv = 992 cpu_to_le16((uint16_t)bp_params->reference_divider); 993 allocation.sPCLKInput.usFbDiv = 994 cpu_to_le16((uint16_t)bp_params->feedback_divider); 995 allocation.sPCLKInput.ucFracFbDiv = 996 (uint8_t)bp_params->fractional_feedback_divider; 997 allocation.sPCLKInput.ucPostDiv = 998 (uint8_t)bp_params->pixel_clock_post_divider; 999 1000 /* We need to convert from 100Hz units into 10KHz units */ 1001 allocation.sPCLKInput.usPixelClock = 1002 cpu_to_le16((uint16_t)(bp_params->target_pixel_clock_100hz / 100)); 1003 1004 params = (PIXEL_CLOCK_PARAMETERS_V3 *)&allocation.sPCLKInput; 1005 params->ucTransmitterId = 1006 bp->cmd_helper->encoder_id_to_atom( 1007 dal_graphics_object_id_get_encoder_id( 1008 bp_params->encoder_object_id)); 1009 params->ucEncoderMode = 1010 (uint8_t)(bp->cmd_helper->encoder_mode_bp_to_atom( 1011 bp_params->signal_type, false)); 1012 1013 if (bp_params->flags.FORCE_PROGRAMMING_OF_PLL) 1014 params->ucMiscInfo |= PIXEL_CLOCK_MISC_FORCE_PROG_PPLL; 1015 1016 if (bp_params->flags.USE_E_CLOCK_AS_SOURCE_FOR_D_CLOCK) 1017 params->ucMiscInfo |= PIXEL_CLOCK_MISC_USE_ENGINE_FOR_DISPCLK; 1018 1019 if (CONTROLLER_ID_D1 != bp_params->controller_id) 1020 params->ucMiscInfo |= PIXEL_CLOCK_MISC_CRTC_SEL_CRTC2; 1021 1022 if (EXEC_BIOS_CMD_TABLE(SetPixelClock, allocation)) 1023 result = BP_RESULT_OK; 1024 1025 return result; 1026} 1027 1028#ifndef SET_PIXEL_CLOCK_PS_ALLOCATION_V5 1029/* video bios did not define this: */ 1030typedef struct _SET_PIXEL_CLOCK_PS_ALLOCATION_V5 { 1031 PIXEL_CLOCK_PARAMETERS_V5 sPCLKInput; 1032 /* Caller doesn't need to init this portion */ 1033 ENABLE_SPREAD_SPECTRUM_ON_PPLL sReserved; 1034} SET_PIXEL_CLOCK_PS_ALLOCATION_V5; 1035#endif 1036 1037#ifndef SET_PIXEL_CLOCK_PS_ALLOCATION_V6 1038/* video bios did not define this: */ 1039typedef struct _SET_PIXEL_CLOCK_PS_ALLOCATION_V6 { 1040 PIXEL_CLOCK_PARAMETERS_V6 sPCLKInput; 1041 /* Caller doesn't need to init this portion */ 1042 ENABLE_SPREAD_SPECTRUM_ON_PPLL sReserved; 1043} SET_PIXEL_CLOCK_PS_ALLOCATION_V6; 1044#endif 1045 1046static enum bp_result set_pixel_clock_v5( 1047 struct bios_parser *bp, 1048 struct bp_pixel_clock_parameters *bp_params) 1049{ 1050 enum bp_result result = BP_RESULT_FAILURE; 1051 SET_PIXEL_CLOCK_PS_ALLOCATION_V5 clk; 1052 uint8_t controller_id; 1053 uint32_t pll_id; 1054 1055 memset(&clk, 0, sizeof(clk)); 1056 1057 if (bp->cmd_helper->clock_source_id_to_atom(bp_params->pll_id, &pll_id) 1058 && bp->cmd_helper->controller_id_to_atom( 1059 bp_params->controller_id, &controller_id)) { 1060 clk.sPCLKInput.ucCRTC = controller_id; 1061 clk.sPCLKInput.ucPpll = (uint8_t)pll_id; 1062 clk.sPCLKInput.ucRefDiv = 1063 (uint8_t)(bp_params->reference_divider); 1064 clk.sPCLKInput.usFbDiv = 1065 cpu_to_le16((uint16_t)(bp_params->feedback_divider)); 1066 clk.sPCLKInput.ulFbDivDecFrac = 1067 cpu_to_le32(bp_params->fractional_feedback_divider); 1068 clk.sPCLKInput.ucPostDiv = 1069 (uint8_t)(bp_params->pixel_clock_post_divider); 1070 clk.sPCLKInput.ucTransmitterID = 1071 bp->cmd_helper->encoder_id_to_atom( 1072 dal_graphics_object_id_get_encoder_id( 1073 bp_params->encoder_object_id)); 1074 clk.sPCLKInput.ucEncoderMode = 1075 (uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom( 1076 bp_params->signal_type, false); 1077 1078 /* We need to convert from 100Hz units into 10KHz units */ 1079 clk.sPCLKInput.usPixelClock = 1080 cpu_to_le16((uint16_t)(bp_params->target_pixel_clock_100hz / 100)); 1081 1082 if (bp_params->flags.FORCE_PROGRAMMING_OF_PLL) 1083 clk.sPCLKInput.ucMiscInfo |= 1084 PIXEL_CLOCK_MISC_FORCE_PROG_PPLL; 1085 1086 if (bp_params->flags.SET_EXTERNAL_REF_DIV_SRC) 1087 clk.sPCLKInput.ucMiscInfo |= 1088 PIXEL_CLOCK_MISC_REF_DIV_SRC; 1089 1090 /* clkV5.ucMiscInfo bit[3:2]= HDMI panel bit depth: =0: 24bpp 1091 * =1:30bpp, =2:32bpp 1092 * driver choose program it itself, i.e. here we program it 1093 * to 888 by default. 1094 */ 1095 if (bp_params->signal_type == SIGNAL_TYPE_HDMI_TYPE_A) 1096 switch (bp_params->color_depth) { 1097 case TRANSMITTER_COLOR_DEPTH_30: 1098 /* yes this is correct, the atom define is wrong */ 1099 clk.sPCLKInput.ucMiscInfo |= PIXEL_CLOCK_V5_MISC_HDMI_32BPP; 1100 break; 1101 case TRANSMITTER_COLOR_DEPTH_36: 1102 /* yes this is correct, the atom define is wrong */ 1103 clk.sPCLKInput.ucMiscInfo |= PIXEL_CLOCK_V5_MISC_HDMI_30BPP; 1104 break; 1105 default: 1106 break; 1107 } 1108 1109 if (EXEC_BIOS_CMD_TABLE(SetPixelClock, clk)) 1110 result = BP_RESULT_OK; 1111 } 1112 1113 return result; 1114} 1115 1116static enum bp_result set_pixel_clock_v6( 1117 struct bios_parser *bp, 1118 struct bp_pixel_clock_parameters *bp_params) 1119{ 1120 enum bp_result result = BP_RESULT_FAILURE; 1121 SET_PIXEL_CLOCK_PS_ALLOCATION_V6 clk; 1122 uint8_t controller_id; 1123 uint32_t pll_id; 1124 1125 memset(&clk, 0, sizeof(clk)); 1126 1127 if (bp->cmd_helper->clock_source_id_to_atom(bp_params->pll_id, &pll_id) 1128 && bp->cmd_helper->controller_id_to_atom( 1129 bp_params->controller_id, &controller_id)) { 1130 /* Note: VBIOS still wants to use ucCRTC name which is now 1131 * 1 byte in ULONG 1132 *typedef struct _CRTC_PIXEL_CLOCK_FREQ 1133 *{ 1134 * target the pixel clock to drive the CRTC timing. 1135 * ULONG ulPixelClock:24; 1136 * 0 means disable PPLL/DCPLL. Expanded to 24 bits comparing to 1137 * previous version. 1138 * ATOM_CRTC1~6, indicate the CRTC controller to 1139 * ULONG ucCRTC:8; 1140 * drive the pixel clock. not used for DCPLL case. 1141 *}CRTC_PIXEL_CLOCK_FREQ; 1142 *union 1143 *{ 1144 * pixel clock and CRTC id frequency 1145 * CRTC_PIXEL_CLOCK_FREQ ulCrtcPclkFreq; 1146 * ULONG ulDispEngClkFreq; dispclk frequency 1147 *}; 1148 */ 1149 clk.sPCLKInput.ulCrtcPclkFreq.ucCRTC = controller_id; 1150 clk.sPCLKInput.ucPpll = (uint8_t) pll_id; 1151 clk.sPCLKInput.ucRefDiv = 1152 (uint8_t) bp_params->reference_divider; 1153 clk.sPCLKInput.usFbDiv = 1154 cpu_to_le16((uint16_t) bp_params->feedback_divider); 1155 clk.sPCLKInput.ulFbDivDecFrac = 1156 cpu_to_le32(bp_params->fractional_feedback_divider); 1157 clk.sPCLKInput.ucPostDiv = 1158 (uint8_t) bp_params->pixel_clock_post_divider; 1159 clk.sPCLKInput.ucTransmitterID = 1160 bp->cmd_helper->encoder_id_to_atom( 1161 dal_graphics_object_id_get_encoder_id( 1162 bp_params->encoder_object_id)); 1163 clk.sPCLKInput.ucEncoderMode = 1164 (uint8_t) bp->cmd_helper->encoder_mode_bp_to_atom( 1165 bp_params->signal_type, false); 1166 1167 /* We need to convert from 100 Hz units into 10KHz units */ 1168 clk.sPCLKInput.ulCrtcPclkFreq.ulPixelClock = 1169 cpu_to_le32(bp_params->target_pixel_clock_100hz / 100); 1170 1171 if (bp_params->flags.FORCE_PROGRAMMING_OF_PLL) { 1172 clk.sPCLKInput.ucMiscInfo |= 1173 PIXEL_CLOCK_V6_MISC_FORCE_PROG_PPLL; 1174 } 1175 1176 if (bp_params->flags.SET_EXTERNAL_REF_DIV_SRC) { 1177 clk.sPCLKInput.ucMiscInfo |= 1178 PIXEL_CLOCK_V6_MISC_REF_DIV_SRC; 1179 } 1180 1181 /* clkV6.ucMiscInfo bit[3:2]= HDMI panel bit depth: =0: 1182 * 24bpp =1:30bpp, =2:32bpp 1183 * driver choose program it itself, i.e. here we pass required 1184 * target rate that includes deep color. 1185 */ 1186 if (bp_params->signal_type == SIGNAL_TYPE_HDMI_TYPE_A) 1187 switch (bp_params->color_depth) { 1188 case TRANSMITTER_COLOR_DEPTH_30: 1189 clk.sPCLKInput.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_30BPP_V6; 1190 break; 1191 case TRANSMITTER_COLOR_DEPTH_36: 1192 clk.sPCLKInput.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_36BPP_V6; 1193 break; 1194 case TRANSMITTER_COLOR_DEPTH_48: 1195 clk.sPCLKInput.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_48BPP; 1196 break; 1197 default: 1198 break; 1199 } 1200 1201 if (EXEC_BIOS_CMD_TABLE(SetPixelClock, clk)) 1202 result = BP_RESULT_OK; 1203 } 1204 1205 return result; 1206} 1207 1208static enum bp_result set_pixel_clock_v7( 1209 struct bios_parser *bp, 1210 struct bp_pixel_clock_parameters *bp_params) 1211{ 1212 enum bp_result result = BP_RESULT_FAILURE; 1213 PIXEL_CLOCK_PARAMETERS_V7 clk; 1214 uint8_t controller_id; 1215 uint32_t pll_id; 1216 1217 memset(&clk, 0, sizeof(clk)); 1218 1219 if (bp->cmd_helper->clock_source_id_to_atom(bp_params->pll_id, &pll_id) 1220 && bp->cmd_helper->controller_id_to_atom(bp_params->controller_id, &controller_id)) { 1221 /* Note: VBIOS still wants to use ucCRTC name which is now 1222 * 1 byte in ULONG 1223 *typedef struct _CRTC_PIXEL_CLOCK_FREQ 1224 *{ 1225 * target the pixel clock to drive the CRTC timing. 1226 * ULONG ulPixelClock:24; 1227 * 0 means disable PPLL/DCPLL. Expanded to 24 bits comparing to 1228 * previous version. 1229 * ATOM_CRTC1~6, indicate the CRTC controller to 1230 * ULONG ucCRTC:8; 1231 * drive the pixel clock. not used for DCPLL case. 1232 *}CRTC_PIXEL_CLOCK_FREQ; 1233 *union 1234 *{ 1235 * pixel clock and CRTC id frequency 1236 * CRTC_PIXEL_CLOCK_FREQ ulCrtcPclkFreq; 1237 * ULONG ulDispEngClkFreq; dispclk frequency 1238 *}; 1239 */ 1240 clk.ucCRTC = controller_id; 1241 clk.ucPpll = (uint8_t) pll_id; 1242 clk.ucTransmitterID = bp->cmd_helper->encoder_id_to_atom(dal_graphics_object_id_get_encoder_id(bp_params->encoder_object_id)); 1243 clk.ucEncoderMode = (uint8_t) bp->cmd_helper->encoder_mode_bp_to_atom(bp_params->signal_type, false); 1244 1245 clk.ulPixelClock = cpu_to_le32(bp_params->target_pixel_clock_100hz); 1246 1247 clk.ucDeepColorRatio = (uint8_t) bp->cmd_helper->transmitter_color_depth_to_atom(bp_params->color_depth); 1248 1249 if (bp_params->flags.FORCE_PROGRAMMING_OF_PLL) 1250 clk.ucMiscInfo |= PIXEL_CLOCK_V7_MISC_FORCE_PROG_PPLL; 1251 1252 if (bp_params->flags.SET_EXTERNAL_REF_DIV_SRC) 1253 clk.ucMiscInfo |= PIXEL_CLOCK_V7_MISC_REF_DIV_SRC; 1254 1255 if (bp_params->flags.PROGRAM_PHY_PLL_ONLY) 1256 clk.ucMiscInfo |= PIXEL_CLOCK_V7_MISC_PROG_PHYPLL; 1257 1258 if (bp_params->flags.SUPPORT_YUV_420) 1259 clk.ucMiscInfo |= PIXEL_CLOCK_V7_MISC_YUV420_MODE; 1260 1261 if (bp_params->flags.SET_XTALIN_REF_SRC) 1262 clk.ucMiscInfo |= PIXEL_CLOCK_V7_MISC_REF_DIV_SRC_XTALIN; 1263 1264 if (bp_params->flags.SET_GENLOCK_REF_DIV_SRC) 1265 clk.ucMiscInfo |= PIXEL_CLOCK_V7_MISC_REF_DIV_SRC_GENLK; 1266 1267 if (bp_params->signal_type == SIGNAL_TYPE_DVI_DUAL_LINK) 1268 clk.ucMiscInfo |= PIXEL_CLOCK_V7_MISC_DVI_DUALLINK_EN; 1269 1270 if (EXEC_BIOS_CMD_TABLE(SetPixelClock, clk)) 1271 result = BP_RESULT_OK; 1272 } 1273 return result; 1274} 1275 1276/******************************************************************************* 1277 ******************************************************************************** 1278 ** 1279 ** ENABLE PIXEL CLOCK SS 1280 ** 1281 ******************************************************************************** 1282 *******************************************************************************/ 1283static enum bp_result enable_spread_spectrum_on_ppll_v1( 1284 struct bios_parser *bp, 1285 struct bp_spread_spectrum_parameters *bp_params, 1286 bool enable); 1287static enum bp_result enable_spread_spectrum_on_ppll_v2( 1288 struct bios_parser *bp, 1289 struct bp_spread_spectrum_parameters *bp_params, 1290 bool enable); 1291static enum bp_result enable_spread_spectrum_on_ppll_v3( 1292 struct bios_parser *bp, 1293 struct bp_spread_spectrum_parameters *bp_params, 1294 bool enable); 1295 1296static void init_enable_spread_spectrum_on_ppll(struct bios_parser *bp) 1297{ 1298 switch (BIOS_CMD_TABLE_PARA_REVISION(EnableSpreadSpectrumOnPPLL)) { 1299 case 1: 1300 bp->cmd_tbl.enable_spread_spectrum_on_ppll = 1301 enable_spread_spectrum_on_ppll_v1; 1302 break; 1303 case 2: 1304 bp->cmd_tbl.enable_spread_spectrum_on_ppll = 1305 enable_spread_spectrum_on_ppll_v2; 1306 break; 1307 case 3: 1308 bp->cmd_tbl.enable_spread_spectrum_on_ppll = 1309 enable_spread_spectrum_on_ppll_v3; 1310 break; 1311 default: 1312 dm_output_to_console("Don't have enable_spread_spectrum_on_ppll for v%d\n", 1313 BIOS_CMD_TABLE_PARA_REVISION(EnableSpreadSpectrumOnPPLL)); 1314 bp->cmd_tbl.enable_spread_spectrum_on_ppll = NULL; 1315 break; 1316 } 1317} 1318 1319static enum bp_result enable_spread_spectrum_on_ppll_v1( 1320 struct bios_parser *bp, 1321 struct bp_spread_spectrum_parameters *bp_params, 1322 bool enable) 1323{ 1324 enum bp_result result = BP_RESULT_FAILURE; 1325 ENABLE_SPREAD_SPECTRUM_ON_PPLL params; 1326 1327 memset(¶ms, 0, sizeof(params)); 1328 1329 if ((enable == true) && (bp_params->percentage > 0)) 1330 params.ucEnable = ATOM_ENABLE; 1331 else 1332 params.ucEnable = ATOM_DISABLE; 1333 1334 params.usSpreadSpectrumPercentage = 1335 cpu_to_le16((uint16_t)bp_params->percentage); 1336 params.ucSpreadSpectrumStep = 1337 (uint8_t)bp_params->ver1.step; 1338 params.ucSpreadSpectrumDelay = 1339 (uint8_t)bp_params->ver1.delay; 1340 /* convert back to unit of 10KHz */ 1341 params.ucSpreadSpectrumRange = 1342 (uint8_t)(bp_params->ver1.range / 10000); 1343 1344 if (bp_params->flags.EXTERNAL_SS) 1345 params.ucSpreadSpectrumType |= ATOM_EXTERNAL_SS_MASK; 1346 1347 if (bp_params->flags.CENTER_SPREAD) 1348 params.ucSpreadSpectrumType |= ATOM_SS_CENTRE_SPREAD_MODE; 1349 1350 if (bp_params->pll_id == CLOCK_SOURCE_ID_PLL1) 1351 params.ucPpll = ATOM_PPLL1; 1352 else if (bp_params->pll_id == CLOCK_SOURCE_ID_PLL2) 1353 params.ucPpll = ATOM_PPLL2; 1354 else 1355 BREAK_TO_DEBUGGER(); /* Unexpected PLL value!! */ 1356 1357 if (EXEC_BIOS_CMD_TABLE(EnableSpreadSpectrumOnPPLL, params)) 1358 result = BP_RESULT_OK; 1359 1360 return result; 1361} 1362 1363static enum bp_result enable_spread_spectrum_on_ppll_v2( 1364 struct bios_parser *bp, 1365 struct bp_spread_spectrum_parameters *bp_params, 1366 bool enable) 1367{ 1368 enum bp_result result = BP_RESULT_FAILURE; 1369 ENABLE_SPREAD_SPECTRUM_ON_PPLL_V2 params; 1370 1371 memset(¶ms, 0, sizeof(params)); 1372 1373 if (bp_params->pll_id == CLOCK_SOURCE_ID_PLL1) 1374 params.ucSpreadSpectrumType = ATOM_PPLL_SS_TYPE_V2_P1PLL; 1375 else if (bp_params->pll_id == CLOCK_SOURCE_ID_PLL2) 1376 params.ucSpreadSpectrumType = ATOM_PPLL_SS_TYPE_V2_P2PLL; 1377 else 1378 BREAK_TO_DEBUGGER(); /* Unexpected PLL value!! */ 1379 1380 if ((enable == true) && (bp_params->percentage > 0)) { 1381 params.ucEnable = ATOM_ENABLE; 1382 1383 params.usSpreadSpectrumPercentage = 1384 cpu_to_le16((uint16_t)(bp_params->percentage)); 1385 params.usSpreadSpectrumStep = 1386 cpu_to_le16((uint16_t)(bp_params->ds.ds_frac_size)); 1387 1388 if (bp_params->flags.EXTERNAL_SS) 1389 params.ucSpreadSpectrumType |= 1390 ATOM_PPLL_SS_TYPE_V2_EXT_SPREAD; 1391 1392 if (bp_params->flags.CENTER_SPREAD) 1393 params.ucSpreadSpectrumType |= 1394 ATOM_PPLL_SS_TYPE_V2_CENTRE_SPREAD; 1395 1396 /* Both amounts need to be left shifted first before bit 1397 * comparison. Otherwise, the result will always be zero here 1398 */ 1399 params.usSpreadSpectrumAmount = cpu_to_le16((uint16_t)( 1400 ((bp_params->ds.feedback_amount << 1401 ATOM_PPLL_SS_AMOUNT_V2_FBDIV_SHIFT) & 1402 ATOM_PPLL_SS_AMOUNT_V2_FBDIV_MASK) | 1403 ((bp_params->ds.nfrac_amount << 1404 ATOM_PPLL_SS_AMOUNT_V2_NFRAC_SHIFT) & 1405 ATOM_PPLL_SS_AMOUNT_V2_NFRAC_MASK))); 1406 } else 1407 params.ucEnable = ATOM_DISABLE; 1408 1409 if (EXEC_BIOS_CMD_TABLE(EnableSpreadSpectrumOnPPLL, params)) 1410 result = BP_RESULT_OK; 1411 1412 return result; 1413} 1414 1415static enum bp_result enable_spread_spectrum_on_ppll_v3( 1416 struct bios_parser *bp, 1417 struct bp_spread_spectrum_parameters *bp_params, 1418 bool enable) 1419{ 1420 enum bp_result result = BP_RESULT_FAILURE; 1421 ENABLE_SPREAD_SPECTRUM_ON_PPLL_V3 params; 1422 1423 memset(¶ms, 0, sizeof(params)); 1424 1425 switch (bp_params->pll_id) { 1426 case CLOCK_SOURCE_ID_PLL0: 1427 /* ATOM_PPLL_SS_TYPE_V3_P0PLL; this is pixel clock only, 1428 * not for SI display clock. 1429 */ 1430 params.ucSpreadSpectrumType = ATOM_PPLL_SS_TYPE_V3_DCPLL; 1431 break; 1432 case CLOCK_SOURCE_ID_PLL1: 1433 params.ucSpreadSpectrumType = ATOM_PPLL_SS_TYPE_V3_P1PLL; 1434 break; 1435 1436 case CLOCK_SOURCE_ID_PLL2: 1437 params.ucSpreadSpectrumType = ATOM_PPLL_SS_TYPE_V3_P2PLL; 1438 break; 1439 1440 case CLOCK_SOURCE_ID_DCPLL: 1441 params.ucSpreadSpectrumType = ATOM_PPLL_SS_TYPE_V3_DCPLL; 1442 break; 1443 1444 default: 1445 BREAK_TO_DEBUGGER(); 1446 /* Unexpected PLL value!! */ 1447 return result; 1448 } 1449 1450 if (enable == true) { 1451 params.ucEnable = ATOM_ENABLE; 1452 1453 params.usSpreadSpectrumAmountFrac = 1454 cpu_to_le16((uint16_t)(bp_params->ds_frac_amount)); 1455 params.usSpreadSpectrumStep = 1456 cpu_to_le16((uint16_t)(bp_params->ds.ds_frac_size)); 1457 1458 if (bp_params->flags.EXTERNAL_SS) 1459 params.ucSpreadSpectrumType |= 1460 ATOM_PPLL_SS_TYPE_V3_EXT_SPREAD; 1461 if (bp_params->flags.CENTER_SPREAD) 1462 params.ucSpreadSpectrumType |= 1463 ATOM_PPLL_SS_TYPE_V3_CENTRE_SPREAD; 1464 1465 /* Both amounts need to be left shifted first before bit 1466 * comparison. Otherwise, the result will always be zero here 1467 */ 1468 params.usSpreadSpectrumAmount = cpu_to_le16((uint16_t)( 1469 ((bp_params->ds.feedback_amount << 1470 ATOM_PPLL_SS_AMOUNT_V3_FBDIV_SHIFT) & 1471 ATOM_PPLL_SS_AMOUNT_V3_FBDIV_MASK) | 1472 ((bp_params->ds.nfrac_amount << 1473 ATOM_PPLL_SS_AMOUNT_V3_NFRAC_SHIFT) & 1474 ATOM_PPLL_SS_AMOUNT_V3_NFRAC_MASK))); 1475 } else 1476 params.ucEnable = ATOM_DISABLE; 1477 1478 if (EXEC_BIOS_CMD_TABLE(EnableSpreadSpectrumOnPPLL, params)) 1479 result = BP_RESULT_OK; 1480 1481 return result; 1482} 1483 1484/******************************************************************************* 1485 ******************************************************************************** 1486 ** 1487 ** ADJUST DISPLAY PLL 1488 ** 1489 ******************************************************************************** 1490 *******************************************************************************/ 1491 1492static enum bp_result adjust_display_pll_v2( 1493 struct bios_parser *bp, 1494 struct bp_adjust_pixel_clock_parameters *bp_params); 1495static enum bp_result adjust_display_pll_v3( 1496 struct bios_parser *bp, 1497 struct bp_adjust_pixel_clock_parameters *bp_params); 1498 1499static void init_adjust_display_pll(struct bios_parser *bp) 1500{ 1501 switch (BIOS_CMD_TABLE_PARA_REVISION(AdjustDisplayPll)) { 1502 case 2: 1503 bp->cmd_tbl.adjust_display_pll = adjust_display_pll_v2; 1504 break; 1505 case 3: 1506 bp->cmd_tbl.adjust_display_pll = adjust_display_pll_v3; 1507 break; 1508 default: 1509 dm_output_to_console("Don't have adjust_display_pll for v%d\n", 1510 BIOS_CMD_TABLE_PARA_REVISION(AdjustDisplayPll)); 1511 bp->cmd_tbl.adjust_display_pll = NULL; 1512 break; 1513 } 1514} 1515 1516static enum bp_result adjust_display_pll_v2( 1517 struct bios_parser *bp, 1518 struct bp_adjust_pixel_clock_parameters *bp_params) 1519{ 1520 enum bp_result result = BP_RESULT_FAILURE; 1521 ADJUST_DISPLAY_PLL_PS_ALLOCATION params = { 0 }; 1522 1523 /* We need to convert from KHz units into 10KHz units and then convert 1524 * output pixel clock back 10KHz-->KHz */ 1525 uint32_t pixel_clock_10KHz_in = bp_params->pixel_clock / 10; 1526 1527 params.usPixelClock = cpu_to_le16((uint16_t)(pixel_clock_10KHz_in)); 1528 params.ucTransmitterID = 1529 bp->cmd_helper->encoder_id_to_atom( 1530 dal_graphics_object_id_get_encoder_id( 1531 bp_params->encoder_object_id)); 1532 params.ucEncodeMode = 1533 (uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom( 1534 bp_params->signal_type, false); 1535 1536 if (EXEC_BIOS_CMD_TABLE(AdjustDisplayPll, params)) { 1537 /* Convert output pixel clock back 10KHz-->KHz: multiply 1538 * original pixel clock in KHz by ratio 1539 * [output pxlClk/input pxlClk] */ 1540 uint64_t pixel_clk_10_khz_out = 1541 (uint64_t)le16_to_cpu(params.usPixelClock); 1542 uint64_t pixel_clk = (uint64_t)bp_params->pixel_clock; 1543 1544 if (pixel_clock_10KHz_in != 0) { 1545 bp_params->adjusted_pixel_clock = 1546 div_u64(pixel_clk * pixel_clk_10_khz_out, 1547 pixel_clock_10KHz_in); 1548 } else { 1549 bp_params->adjusted_pixel_clock = 0; 1550 BREAK_TO_DEBUGGER(); 1551 } 1552 1553 result = BP_RESULT_OK; 1554 } 1555 1556 return result; 1557} 1558 1559static enum bp_result adjust_display_pll_v3( 1560 struct bios_parser *bp, 1561 struct bp_adjust_pixel_clock_parameters *bp_params) 1562{ 1563 enum bp_result result = BP_RESULT_FAILURE; 1564 ADJUST_DISPLAY_PLL_PS_ALLOCATION_V3 params; 1565 uint32_t pixel_clk_10_kHz_in = bp_params->pixel_clock / 10; 1566 1567 memset(¶ms, 0, sizeof(params)); 1568 1569 /* We need to convert from KHz units into 10KHz units and then convert 1570 * output pixel clock back 10KHz-->KHz */ 1571 params.sInput.usPixelClock = cpu_to_le16((uint16_t)pixel_clk_10_kHz_in); 1572 params.sInput.ucTransmitterID = 1573 bp->cmd_helper->encoder_id_to_atom( 1574 dal_graphics_object_id_get_encoder_id( 1575 bp_params->encoder_object_id)); 1576 params.sInput.ucEncodeMode = 1577 (uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom( 1578 bp_params->signal_type, false); 1579 1580 if (bp_params->ss_enable == true) 1581 params.sInput.ucDispPllConfig |= DISPPLL_CONFIG_SS_ENABLE; 1582 1583 if (bp_params->signal_type == SIGNAL_TYPE_DVI_DUAL_LINK) 1584 params.sInput.ucDispPllConfig |= DISPPLL_CONFIG_DUAL_LINK; 1585 1586 if (EXEC_BIOS_CMD_TABLE(AdjustDisplayPll, params)) { 1587 /* Convert output pixel clock back 10KHz-->KHz: multiply 1588 * original pixel clock in KHz by ratio 1589 * [output pxlClk/input pxlClk] */ 1590 uint64_t pixel_clk_10_khz_out = 1591 (uint64_t)le32_to_cpu(params.sOutput.ulDispPllFreq); 1592 uint64_t pixel_clk = (uint64_t)bp_params->pixel_clock; 1593 1594 if (pixel_clk_10_kHz_in != 0) { 1595 bp_params->adjusted_pixel_clock = 1596 div_u64(pixel_clk * pixel_clk_10_khz_out, 1597 pixel_clk_10_kHz_in); 1598 } else { 1599 bp_params->adjusted_pixel_clock = 0; 1600 BREAK_TO_DEBUGGER(); 1601 } 1602 1603 bp_params->reference_divider = params.sOutput.ucRefDiv; 1604 bp_params->pixel_clock_post_divider = params.sOutput.ucPostDiv; 1605 1606 result = BP_RESULT_OK; 1607 } 1608 1609 return result; 1610} 1611 1612/******************************************************************************* 1613 ******************************************************************************** 1614 ** 1615 ** DAC ENCODER CONTROL 1616 ** 1617 ******************************************************************************** 1618 *******************************************************************************/ 1619 1620static enum bp_result dac1_encoder_control_v1( 1621 struct bios_parser *bp, 1622 bool enable, 1623 uint32_t pixel_clock, 1624 uint8_t dac_standard); 1625static enum bp_result dac2_encoder_control_v1( 1626 struct bios_parser *bp, 1627 bool enable, 1628 uint32_t pixel_clock, 1629 uint8_t dac_standard); 1630 1631static void init_dac_encoder_control(struct bios_parser *bp) 1632{ 1633 switch (BIOS_CMD_TABLE_PARA_REVISION(DAC1EncoderControl)) { 1634 case 1: 1635 bp->cmd_tbl.dac1_encoder_control = dac1_encoder_control_v1; 1636 break; 1637 default: 1638 bp->cmd_tbl.dac1_encoder_control = NULL; 1639 break; 1640 } 1641 switch (BIOS_CMD_TABLE_PARA_REVISION(DAC2EncoderControl)) { 1642 case 1: 1643 bp->cmd_tbl.dac2_encoder_control = dac2_encoder_control_v1; 1644 break; 1645 default: 1646 bp->cmd_tbl.dac2_encoder_control = NULL; 1647 break; 1648 } 1649} 1650 1651static void dac_encoder_control_prepare_params( 1652 DAC_ENCODER_CONTROL_PS_ALLOCATION *params, 1653 bool enable, 1654 uint32_t pixel_clock, 1655 uint8_t dac_standard) 1656{ 1657 params->ucDacStandard = dac_standard; 1658 if (enable) 1659 params->ucAction = ATOM_ENABLE; 1660 else 1661 params->ucAction = ATOM_DISABLE; 1662 1663 /* We need to convert from KHz units into 10KHz units 1664 * it looks as if the TvControl do not care about pixel clock 1665 */ 1666 params->usPixelClock = cpu_to_le16((uint16_t)(pixel_clock / 10)); 1667} 1668 1669static enum bp_result dac1_encoder_control_v1( 1670 struct bios_parser *bp, 1671 bool enable, 1672 uint32_t pixel_clock, 1673 uint8_t dac_standard) 1674{ 1675 enum bp_result result = BP_RESULT_FAILURE; 1676 DAC_ENCODER_CONTROL_PS_ALLOCATION params; 1677 1678 dac_encoder_control_prepare_params( 1679 ¶ms, 1680 enable, 1681 pixel_clock, 1682 dac_standard); 1683 1684 if (EXEC_BIOS_CMD_TABLE(DAC1EncoderControl, params)) 1685 result = BP_RESULT_OK; 1686 1687 return result; 1688} 1689 1690static enum bp_result dac2_encoder_control_v1( 1691 struct bios_parser *bp, 1692 bool enable, 1693 uint32_t pixel_clock, 1694 uint8_t dac_standard) 1695{ 1696 enum bp_result result = BP_RESULT_FAILURE; 1697 DAC_ENCODER_CONTROL_PS_ALLOCATION params; 1698 1699 dac_encoder_control_prepare_params( 1700 ¶ms, 1701 enable, 1702 pixel_clock, 1703 dac_standard); 1704 1705 if (EXEC_BIOS_CMD_TABLE(DAC2EncoderControl, params)) 1706 result = BP_RESULT_OK; 1707 1708 return result; 1709} 1710 1711/******************************************************************************* 1712 ******************************************************************************** 1713 ** 1714 ** DAC OUTPUT CONTROL 1715 ** 1716 ******************************************************************************** 1717 *******************************************************************************/ 1718static enum bp_result dac1_output_control_v1( 1719 struct bios_parser *bp, 1720 bool enable); 1721static enum bp_result dac2_output_control_v1( 1722 struct bios_parser *bp, 1723 bool enable); 1724 1725static void init_dac_output_control(struct bios_parser *bp) 1726{ 1727 switch (BIOS_CMD_TABLE_PARA_REVISION(DAC1OutputControl)) { 1728 case 1: 1729 bp->cmd_tbl.dac1_output_control = dac1_output_control_v1; 1730 break; 1731 default: 1732 bp->cmd_tbl.dac1_output_control = NULL; 1733 break; 1734 } 1735 switch (BIOS_CMD_TABLE_PARA_REVISION(DAC2OutputControl)) { 1736 case 1: 1737 bp->cmd_tbl.dac2_output_control = dac2_output_control_v1; 1738 break; 1739 default: 1740 bp->cmd_tbl.dac2_output_control = NULL; 1741 break; 1742 } 1743} 1744 1745static enum bp_result dac1_output_control_v1( 1746 struct bios_parser *bp, bool enable) 1747{ 1748 enum bp_result result = BP_RESULT_FAILURE; 1749 DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION params; 1750 1751 if (enable) 1752 params.ucAction = ATOM_ENABLE; 1753 else 1754 params.ucAction = ATOM_DISABLE; 1755 1756 if (EXEC_BIOS_CMD_TABLE(DAC1OutputControl, params)) 1757 result = BP_RESULT_OK; 1758 1759 return result; 1760} 1761 1762static enum bp_result dac2_output_control_v1( 1763 struct bios_parser *bp, bool enable) 1764{ 1765 enum bp_result result = BP_RESULT_FAILURE; 1766 DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION params; 1767 1768 if (enable) 1769 params.ucAction = ATOM_ENABLE; 1770 else 1771 params.ucAction = ATOM_DISABLE; 1772 1773 if (EXEC_BIOS_CMD_TABLE(DAC2OutputControl, params)) 1774 result = BP_RESULT_OK; 1775 1776 return result; 1777} 1778 1779/******************************************************************************* 1780 ******************************************************************************** 1781 ** 1782 ** SET CRTC TIMING 1783 ** 1784 ******************************************************************************** 1785 *******************************************************************************/ 1786 1787static enum bp_result set_crtc_using_dtd_timing_v3( 1788 struct bios_parser *bp, 1789 struct bp_hw_crtc_timing_parameters *bp_params); 1790static enum bp_result set_crtc_timing_v1( 1791 struct bios_parser *bp, 1792 struct bp_hw_crtc_timing_parameters *bp_params); 1793 1794static void init_set_crtc_timing(struct bios_parser *bp) 1795{ 1796 uint32_t dtd_version = 1797 BIOS_CMD_TABLE_PARA_REVISION(SetCRTC_UsingDTDTiming); 1798 if (dtd_version > 2) 1799 switch (dtd_version) { 1800 case 3: 1801 bp->cmd_tbl.set_crtc_timing = 1802 set_crtc_using_dtd_timing_v3; 1803 break; 1804 default: 1805 dm_output_to_console("Don't have set_crtc_timing for dtd v%d\n", 1806 dtd_version); 1807 bp->cmd_tbl.set_crtc_timing = NULL; 1808 break; 1809 } 1810 else 1811 switch (BIOS_CMD_TABLE_PARA_REVISION(SetCRTC_Timing)) { 1812 case 1: 1813 bp->cmd_tbl.set_crtc_timing = set_crtc_timing_v1; 1814 break; 1815 default: 1816 dm_output_to_console("Don't have set_crtc_timing for v%d\n", 1817 BIOS_CMD_TABLE_PARA_REVISION(SetCRTC_Timing)); 1818 bp->cmd_tbl.set_crtc_timing = NULL; 1819 break; 1820 } 1821} 1822 1823static enum bp_result set_crtc_timing_v1( 1824 struct bios_parser *bp, 1825 struct bp_hw_crtc_timing_parameters *bp_params) 1826{ 1827 enum bp_result result = BP_RESULT_FAILURE; 1828 SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION params = {0}; 1829 uint8_t atom_controller_id; 1830 1831 if (bp->cmd_helper->controller_id_to_atom( 1832 bp_params->controller_id, &atom_controller_id)) 1833 params.ucCRTC = atom_controller_id; 1834 1835 params.usH_Total = cpu_to_le16((uint16_t)(bp_params->h_total)); 1836 params.usH_Disp = cpu_to_le16((uint16_t)(bp_params->h_addressable)); 1837 params.usH_SyncStart = cpu_to_le16((uint16_t)(bp_params->h_sync_start)); 1838 params.usH_SyncWidth = cpu_to_le16((uint16_t)(bp_params->h_sync_width)); 1839 params.usV_Total = cpu_to_le16((uint16_t)(bp_params->v_total)); 1840 params.usV_Disp = cpu_to_le16((uint16_t)(bp_params->v_addressable)); 1841 params.usV_SyncStart = 1842 cpu_to_le16((uint16_t)(bp_params->v_sync_start)); 1843 params.usV_SyncWidth = 1844 cpu_to_le16((uint16_t)(bp_params->v_sync_width)); 1845 1846 /* VBIOS does not expect any value except zero into this call, for 1847 * underscan use another entry ProgramOverscan call but when mode 1848 * 1776x1000 with the overscan 72x44 .e.i. 1920x1080 @30 DAL2 is ok, 1849 * but when same ,but 60 Hz there is corruption 1850 * DAL1 does not allow the mode 1776x1000@60 1851 */ 1852 params.ucOverscanRight = (uint8_t)bp_params->h_overscan_right; 1853 params.ucOverscanLeft = (uint8_t)bp_params->h_overscan_left; 1854 params.ucOverscanBottom = (uint8_t)bp_params->v_overscan_bottom; 1855 params.ucOverscanTop = (uint8_t)bp_params->v_overscan_top; 1856 1857 if (0 == bp_params->flags.HSYNC_POSITIVE_POLARITY) 1858 params.susModeMiscInfo.usAccess = 1859 cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_HSYNC_POLARITY); 1860 1861 if (0 == bp_params->flags.VSYNC_POSITIVE_POLARITY) 1862 params.susModeMiscInfo.usAccess = 1863 cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_VSYNC_POLARITY); 1864 1865 if (bp_params->flags.INTERLACE) { 1866 params.susModeMiscInfo.usAccess = 1867 cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_INTERLACE); 1868 1869 /* original DAL code has this condition to apply tis for 1870 * non-TV/CV only due to complex MV testing for possible 1871 * impact 1872 * if (pACParameters->signal != SignalType_YPbPr && 1873 * pACParameters->signal != SignalType_Composite && 1874 * pACParameters->signal != SignalType_SVideo) 1875 */ 1876 /* HW will deduct 0.5 line from 2nd feild. 1877 * i.e. for 1080i, it is 2 lines for 1st field, 2.5 1878 * lines for the 2nd feild. we need input as 5 instead 1879 * of 4, but it is 4 either from Edid data 1880 * (spec CEA 861) or CEA timing table. 1881 */ 1882 params.usV_SyncStart = 1883 cpu_to_le16((uint16_t)(bp_params->v_sync_start + 1)); 1884 } 1885 1886 if (bp_params->flags.HORZ_COUNT_BY_TWO) 1887 params.susModeMiscInfo.usAccess = 1888 cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_DOUBLE_CLOCK_MODE); 1889 1890 if (EXEC_BIOS_CMD_TABLE(SetCRTC_Timing, params)) 1891 result = BP_RESULT_OK; 1892 1893 return result; 1894} 1895 1896static enum bp_result set_crtc_using_dtd_timing_v3( 1897 struct bios_parser *bp, 1898 struct bp_hw_crtc_timing_parameters *bp_params) 1899{ 1900 enum bp_result result = BP_RESULT_FAILURE; 1901 SET_CRTC_USING_DTD_TIMING_PARAMETERS params = {0}; 1902 uint8_t atom_controller_id; 1903 1904 if (bp->cmd_helper->controller_id_to_atom( 1905 bp_params->controller_id, &atom_controller_id)) 1906 params.ucCRTC = atom_controller_id; 1907 1908 /* bios usH_Size wants h addressable size */ 1909 params.usH_Size = cpu_to_le16((uint16_t)bp_params->h_addressable); 1910 /* bios usH_Blanking_Time wants borders included in blanking */ 1911 params.usH_Blanking_Time = 1912 cpu_to_le16((uint16_t)(bp_params->h_total - bp_params->h_addressable)); 1913 /* bios usV_Size wants v addressable size */ 1914 params.usV_Size = cpu_to_le16((uint16_t)bp_params->v_addressable); 1915 /* bios usV_Blanking_Time wants borders included in blanking */ 1916 params.usV_Blanking_Time = 1917 cpu_to_le16((uint16_t)(bp_params->v_total - bp_params->v_addressable)); 1918 /* bios usHSyncOffset is the offset from the end of h addressable, 1919 * our horizontalSyncStart is the offset from the beginning 1920 * of h addressable */ 1921 params.usH_SyncOffset = 1922 cpu_to_le16((uint16_t)(bp_params->h_sync_start - bp_params->h_addressable)); 1923 params.usH_SyncWidth = cpu_to_le16((uint16_t)bp_params->h_sync_width); 1924 /* bios usHSyncOffset is the offset from the end of v addressable, 1925 * our verticalSyncStart is the offset from the beginning of 1926 * v addressable */ 1927 params.usV_SyncOffset = 1928 cpu_to_le16((uint16_t)(bp_params->v_sync_start - bp_params->v_addressable)); 1929 params.usV_SyncWidth = cpu_to_le16((uint16_t)bp_params->v_sync_width); 1930 1931 /* we assume that overscan from original timing does not get bigger 1932 * than 255 1933 * we will program all the borders in the Set CRTC Overscan call below 1934 */ 1935 1936 if (0 == bp_params->flags.HSYNC_POSITIVE_POLARITY) 1937 params.susModeMiscInfo.usAccess = 1938 cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_HSYNC_POLARITY); 1939 1940 if (0 == bp_params->flags.VSYNC_POSITIVE_POLARITY) 1941 params.susModeMiscInfo.usAccess = 1942 cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_VSYNC_POLARITY); 1943 1944 if (bp_params->flags.INTERLACE) { 1945 params.susModeMiscInfo.usAccess = 1946 cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_INTERLACE); 1947 1948 /* original DAL code has this condition to apply this 1949 * for non-TV/CV only 1950 * due to complex MV testing for possible impact 1951 * if ( pACParameters->signal != SignalType_YPbPr && 1952 * pACParameters->signal != SignalType_Composite && 1953 * pACParameters->signal != SignalType_SVideo) 1954 */ 1955 { 1956 /* HW will deduct 0.5 line from 2nd feild. 1957 * i.e. for 1080i, it is 2 lines for 1st field, 1958 * 2.5 lines for the 2nd feild. we need input as 5 1959 * instead of 4. 1960 * but it is 4 either from Edid data (spec CEA 861) 1961 * or CEA timing table. 1962 */ 1963 le16_add_cpu(¶ms.usV_SyncOffset, 1); 1964 } 1965 } 1966 1967 if (bp_params->flags.HORZ_COUNT_BY_TWO) 1968 params.susModeMiscInfo.usAccess = 1969 cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_DOUBLE_CLOCK_MODE); 1970 1971 if (EXEC_BIOS_CMD_TABLE(SetCRTC_UsingDTDTiming, params)) 1972 result = BP_RESULT_OK; 1973 1974 return result; 1975} 1976 1977/******************************************************************************* 1978 ******************************************************************************** 1979 ** 1980 ** ENABLE CRTC 1981 ** 1982 ******************************************************************************** 1983 *******************************************************************************/ 1984 1985static enum bp_result enable_crtc_v1( 1986 struct bios_parser *bp, 1987 enum controller_id controller_id, 1988 bool enable); 1989 1990static void init_enable_crtc(struct bios_parser *bp) 1991{ 1992 switch (BIOS_CMD_TABLE_PARA_REVISION(EnableCRTC)) { 1993 case 1: 1994 bp->cmd_tbl.enable_crtc = enable_crtc_v1; 1995 break; 1996 default: 1997 dm_output_to_console("Don't have enable_crtc for v%d\n", 1998 BIOS_CMD_TABLE_PARA_REVISION(EnableCRTC)); 1999 bp->cmd_tbl.enable_crtc = NULL; 2000 break; 2001 } 2002} 2003 2004static enum bp_result enable_crtc_v1( 2005 struct bios_parser *bp, 2006 enum controller_id controller_id, 2007 bool enable) 2008{ 2009 bool result = BP_RESULT_FAILURE; 2010 ENABLE_CRTC_PARAMETERS params = {0}; 2011 uint8_t id; 2012 2013 if (bp->cmd_helper->controller_id_to_atom(controller_id, &id)) 2014 params.ucCRTC = id; 2015 else 2016 return BP_RESULT_BADINPUT; 2017 2018 if (enable) 2019 params.ucEnable = ATOM_ENABLE; 2020 else 2021 params.ucEnable = ATOM_DISABLE; 2022 2023 if (EXEC_BIOS_CMD_TABLE(EnableCRTC, params)) 2024 result = BP_RESULT_OK; 2025 2026 return result; 2027} 2028 2029/******************************************************************************* 2030 ******************************************************************************** 2031 ** 2032 ** ENABLE CRTC MEM REQ 2033 ** 2034 ******************************************************************************** 2035 *******************************************************************************/ 2036 2037static enum bp_result enable_crtc_mem_req_v1( 2038 struct bios_parser *bp, 2039 enum controller_id controller_id, 2040 bool enable); 2041 2042static void init_enable_crtc_mem_req(struct bios_parser *bp) 2043{ 2044 switch (BIOS_CMD_TABLE_PARA_REVISION(EnableCRTCMemReq)) { 2045 case 1: 2046 bp->cmd_tbl.enable_crtc_mem_req = enable_crtc_mem_req_v1; 2047 break; 2048 default: 2049 bp->cmd_tbl.enable_crtc_mem_req = NULL; 2050 break; 2051 } 2052} 2053 2054static enum bp_result enable_crtc_mem_req_v1( 2055 struct bios_parser *bp, 2056 enum controller_id controller_id, 2057 bool enable) 2058{ 2059 bool result = BP_RESULT_BADINPUT; 2060 ENABLE_CRTC_PARAMETERS params = {0}; 2061 uint8_t id; 2062 2063 if (bp->cmd_helper->controller_id_to_atom(controller_id, &id)) { 2064 params.ucCRTC = id; 2065 2066 if (enable) 2067 params.ucEnable = ATOM_ENABLE; 2068 else 2069 params.ucEnable = ATOM_DISABLE; 2070 2071 if (EXEC_BIOS_CMD_TABLE(EnableCRTCMemReq, params)) 2072 result = BP_RESULT_OK; 2073 else 2074 result = BP_RESULT_FAILURE; 2075 } 2076 2077 return result; 2078} 2079 2080/******************************************************************************* 2081 ******************************************************************************** 2082 ** 2083 ** DISPLAY PLL 2084 ** 2085 ******************************************************************************** 2086 *******************************************************************************/ 2087 2088static enum bp_result program_clock_v5( 2089 struct bios_parser *bp, 2090 struct bp_pixel_clock_parameters *bp_params); 2091static enum bp_result program_clock_v6( 2092 struct bios_parser *bp, 2093 struct bp_pixel_clock_parameters *bp_params); 2094 2095static void init_program_clock(struct bios_parser *bp) 2096{ 2097 switch (BIOS_CMD_TABLE_PARA_REVISION(SetPixelClock)) { 2098 case 5: 2099 bp->cmd_tbl.program_clock = program_clock_v5; 2100 break; 2101 case 6: 2102 bp->cmd_tbl.program_clock = program_clock_v6; 2103 break; 2104 default: 2105 dm_output_to_console("Don't have program_clock for v%d\n", 2106 BIOS_CMD_TABLE_PARA_REVISION(SetPixelClock)); 2107 bp->cmd_tbl.program_clock = NULL; 2108 break; 2109 } 2110} 2111 2112static enum bp_result program_clock_v5( 2113 struct bios_parser *bp, 2114 struct bp_pixel_clock_parameters *bp_params) 2115{ 2116 enum bp_result result = BP_RESULT_FAILURE; 2117 2118 SET_PIXEL_CLOCK_PS_ALLOCATION_V5 params; 2119 uint32_t atom_pll_id; 2120 2121 memset(¶ms, 0, sizeof(params)); 2122 if (!bp->cmd_helper->clock_source_id_to_atom( 2123 bp_params->pll_id, &atom_pll_id)) { 2124 BREAK_TO_DEBUGGER(); /* Invalid Input!! */ 2125 return BP_RESULT_BADINPUT; 2126 } 2127 2128 /* We need to convert from KHz units into 10KHz units */ 2129 params.sPCLKInput.ucPpll = (uint8_t) atom_pll_id; 2130 params.sPCLKInput.usPixelClock = 2131 cpu_to_le16((uint16_t) (bp_params->target_pixel_clock_100hz / 100)); 2132 params.sPCLKInput.ucCRTC = (uint8_t) ATOM_CRTC_INVALID; 2133 2134 if (bp_params->flags.SET_EXTERNAL_REF_DIV_SRC) 2135 params.sPCLKInput.ucMiscInfo |= PIXEL_CLOCK_MISC_REF_DIV_SRC; 2136 2137 if (EXEC_BIOS_CMD_TABLE(SetPixelClock, params)) 2138 result = BP_RESULT_OK; 2139 2140 return result; 2141} 2142 2143static enum bp_result program_clock_v6( 2144 struct bios_parser *bp, 2145 struct bp_pixel_clock_parameters *bp_params) 2146{ 2147 enum bp_result result = BP_RESULT_FAILURE; 2148 2149 SET_PIXEL_CLOCK_PS_ALLOCATION_V6 params; 2150 uint32_t atom_pll_id; 2151 2152 memset(¶ms, 0, sizeof(params)); 2153 2154 if (!bp->cmd_helper->clock_source_id_to_atom( 2155 bp_params->pll_id, &atom_pll_id)) { 2156 BREAK_TO_DEBUGGER(); /*Invalid Input!!*/ 2157 return BP_RESULT_BADINPUT; 2158 } 2159 2160 /* We need to convert from KHz units into 10KHz units */ 2161 params.sPCLKInput.ucPpll = (uint8_t)atom_pll_id; 2162 params.sPCLKInput.ulDispEngClkFreq = 2163 cpu_to_le32(bp_params->target_pixel_clock_100hz / 100); 2164 2165 if (bp_params->flags.SET_EXTERNAL_REF_DIV_SRC) 2166 params.sPCLKInput.ucMiscInfo |= PIXEL_CLOCK_MISC_REF_DIV_SRC; 2167 2168 if (bp_params->flags.SET_DISPCLK_DFS_BYPASS) 2169 params.sPCLKInput.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_DPREFCLK_BYPASS; 2170 2171 if (EXEC_BIOS_CMD_TABLE(SetPixelClock, params)) { 2172 /* True display clock is returned by VBIOS if DFS bypass 2173 * is enabled. */ 2174 bp_params->dfs_bypass_display_clock = 2175 (uint32_t)(le32_to_cpu(params.sPCLKInput.ulDispEngClkFreq) * 10); 2176 result = BP_RESULT_OK; 2177 } 2178 2179 return result; 2180} 2181 2182/******************************************************************************* 2183 ******************************************************************************** 2184 ** 2185 ** EXTERNAL ENCODER CONTROL 2186 ** 2187 ******************************************************************************** 2188 *******************************************************************************/ 2189 2190static enum bp_result external_encoder_control_v3( 2191 struct bios_parser *bp, 2192 struct bp_external_encoder_control *cntl); 2193 2194static void init_external_encoder_control( 2195 struct bios_parser *bp) 2196{ 2197 switch (BIOS_CMD_TABLE_PARA_REVISION(ExternalEncoderControl)) { 2198 case 3: 2199 bp->cmd_tbl.external_encoder_control = 2200 external_encoder_control_v3; 2201 break; 2202 default: 2203 bp->cmd_tbl.external_encoder_control = NULL; 2204 break; 2205 } 2206} 2207 2208static enum bp_result external_encoder_control_v3( 2209 struct bios_parser *bp, 2210 struct bp_external_encoder_control *cntl) 2211{ 2212 enum bp_result result = BP_RESULT_FAILURE; 2213 2214 /* we need use _PS_Alloc struct */ 2215 EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION_V3 params; 2216 EXTERNAL_ENCODER_CONTROL_PARAMETERS_V3 *cntl_params; 2217 struct graphics_object_id encoder; 2218 bool is_input_signal_dp = false; 2219 2220 memset(¶ms, 0, sizeof(params)); 2221 2222 cntl_params = ¶ms.sExtEncoder; 2223 2224 encoder = cntl->encoder_id; 2225 2226 /* check if encoder supports external encoder control table */ 2227 switch (dal_graphics_object_id_get_encoder_id(encoder)) { 2228 case ENCODER_ID_EXTERNAL_NUTMEG: 2229 case ENCODER_ID_EXTERNAL_TRAVIS: 2230 is_input_signal_dp = true; 2231 break; 2232 2233 default: 2234 BREAK_TO_DEBUGGER(); 2235 return BP_RESULT_BADINPUT; 2236 } 2237 2238 /* Fill information based on the action 2239 * 2240 * Bit[6:4]: indicate external encoder, applied to all functions. 2241 * =0: external encoder1, mapped to external encoder enum id1 2242 * =1: external encoder2, mapped to external encoder enum id2 2243 * 2244 * enum ObjectEnumId 2245 * { 2246 * EnumId_Unknown = 0, 2247 * EnumId_1, 2248 * EnumId_2, 2249 * }; 2250 */ 2251 cntl_params->ucConfig = (uint8_t)((encoder.enum_id - 1) << 4); 2252 2253 switch (cntl->action) { 2254 case EXTERNAL_ENCODER_CONTROL_INIT: 2255 /* output display connector type. Only valid in encoder 2256 * initialization */ 2257 cntl_params->usConnectorId = 2258 cpu_to_le16((uint16_t)cntl->connector_obj_id.id); 2259 break; 2260 case EXTERNAL_ENCODER_CONTROL_SETUP: 2261 /* EXTERNAL_ENCODER_CONTROL_PARAMETERS_V3 pixel clock unit in 2262 * 10KHz 2263 * output display device pixel clock frequency in unit of 10KHz. 2264 * Only valid in setup and enableoutput 2265 */ 2266 cntl_params->usPixelClock = 2267 cpu_to_le16((uint16_t)(cntl->pixel_clock / 10)); 2268 /* Indicate display output signal type drive by external 2269 * encoder, only valid in setup and enableoutput */ 2270 cntl_params->ucEncoderMode = 2271 (uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom( 2272 cntl->signal, false); 2273 2274 if (is_input_signal_dp) { 2275 /* Bit[0]: indicate link rate, =1: 2.7Ghz, =0: 1.62Ghz, 2276 * only valid in encoder setup with DP mode. */ 2277 if (LINK_RATE_HIGH == cntl->link_rate) 2278 cntl_params->ucConfig |= 1; 2279 /* output color depth Indicate encoder data bpc format 2280 * in DP mode, only valid in encoder setup in DP mode. 2281 */ 2282 cntl_params->ucBitPerColor = 2283 (uint8_t)(cntl->color_depth); 2284 } 2285 /* Indicate how many lanes used by external encoder, only valid 2286 * in encoder setup and enableoutput. */ 2287 cntl_params->ucLaneNum = (uint8_t)(cntl->lanes_number); 2288 break; 2289 case EXTERNAL_ENCODER_CONTROL_ENABLE: 2290 cntl_params->usPixelClock = 2291 cpu_to_le16((uint16_t)(cntl->pixel_clock / 10)); 2292 cntl_params->ucEncoderMode = 2293 (uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom( 2294 cntl->signal, false); 2295 cntl_params->ucLaneNum = (uint8_t)cntl->lanes_number; 2296 break; 2297 default: 2298 break; 2299 } 2300 2301 cntl_params->ucAction = (uint8_t)cntl->action; 2302 2303 if (EXEC_BIOS_CMD_TABLE(ExternalEncoderControl, params)) 2304 result = BP_RESULT_OK; 2305 2306 return result; 2307} 2308 2309/******************************************************************************* 2310 ******************************************************************************** 2311 ** 2312 ** ENABLE DISPLAY POWER GATING 2313 ** 2314 ******************************************************************************** 2315 *******************************************************************************/ 2316 2317static enum bp_result enable_disp_power_gating_v2_1( 2318 struct bios_parser *bp, 2319 enum controller_id crtc_id, 2320 enum bp_pipe_control_action action); 2321 2322static void init_enable_disp_power_gating( 2323 struct bios_parser *bp) 2324{ 2325 switch (BIOS_CMD_TABLE_PARA_REVISION(EnableDispPowerGating)) { 2326 case 1: 2327 bp->cmd_tbl.enable_disp_power_gating = 2328 enable_disp_power_gating_v2_1; 2329 break; 2330 default: 2331 dm_output_to_console("Don't enable_disp_power_gating enable_crtc for v%d\n", 2332 BIOS_CMD_TABLE_PARA_REVISION(EnableDispPowerGating)); 2333 bp->cmd_tbl.enable_disp_power_gating = NULL; 2334 break; 2335 } 2336} 2337 2338static enum bp_result enable_disp_power_gating_v2_1( 2339 struct bios_parser *bp, 2340 enum controller_id crtc_id, 2341 enum bp_pipe_control_action action) 2342{ 2343 enum bp_result result = BP_RESULT_FAILURE; 2344 2345 ENABLE_DISP_POWER_GATING_PS_ALLOCATION params = {0}; 2346 uint8_t atom_crtc_id; 2347 2348 if (bp->cmd_helper->controller_id_to_atom(crtc_id, &atom_crtc_id)) 2349 params.ucDispPipeId = atom_crtc_id; 2350 else 2351 return BP_RESULT_BADINPUT; 2352 2353 params.ucEnable = 2354 bp->cmd_helper->disp_power_gating_action_to_atom(action); 2355 2356 if (EXEC_BIOS_CMD_TABLE(EnableDispPowerGating, params)) 2357 result = BP_RESULT_OK; 2358 2359 return result; 2360} 2361 2362/******************************************************************************* 2363 ******************************************************************************** 2364 ** 2365 ** SET DCE CLOCK 2366 ** 2367 ******************************************************************************** 2368 *******************************************************************************/ 2369static enum bp_result set_dce_clock_v2_1( 2370 struct bios_parser *bp, 2371 struct bp_set_dce_clock_parameters *bp_params); 2372 2373static void init_set_dce_clock(struct bios_parser *bp) 2374{ 2375 switch (BIOS_CMD_TABLE_PARA_REVISION(SetDCEClock)) { 2376 case 1: 2377 bp->cmd_tbl.set_dce_clock = set_dce_clock_v2_1; 2378 break; 2379 default: 2380 dm_output_to_console("Don't have set_dce_clock for v%d\n", 2381 BIOS_CMD_TABLE_PARA_REVISION(SetDCEClock)); 2382 bp->cmd_tbl.set_dce_clock = NULL; 2383 break; 2384 } 2385} 2386 2387static enum bp_result set_dce_clock_v2_1( 2388 struct bios_parser *bp, 2389 struct bp_set_dce_clock_parameters *bp_params) 2390{ 2391 enum bp_result result = BP_RESULT_FAILURE; 2392 2393 SET_DCE_CLOCK_PS_ALLOCATION_V2_1 params; 2394 uint32_t atom_pll_id; 2395 uint32_t atom_clock_type; 2396 const struct command_table_helper *cmd = bp->cmd_helper; 2397 2398 memset(¶ms, 0, sizeof(params)); 2399 2400 if (!cmd->clock_source_id_to_atom(bp_params->pll_id, &atom_pll_id) || 2401 !cmd->dc_clock_type_to_atom(bp_params->clock_type, &atom_clock_type)) 2402 return BP_RESULT_BADINPUT; 2403 2404 params.asParam.ucDCEClkSrc = atom_pll_id; 2405 params.asParam.ucDCEClkType = atom_clock_type; 2406 2407 if (bp_params->clock_type == DCECLOCK_TYPE_DPREFCLK) { 2408 if (bp_params->flags.USE_GENLOCK_AS_SOURCE_FOR_DPREFCLK) 2409 params.asParam.ucDCEClkFlag |= DCE_CLOCK_FLAG_PLL_REFCLK_SRC_GENLK; 2410 2411 if (bp_params->flags.USE_PCIE_AS_SOURCE_FOR_DPREFCLK) 2412 params.asParam.ucDCEClkFlag |= DCE_CLOCK_FLAG_PLL_REFCLK_SRC_PCIE; 2413 2414 if (bp_params->flags.USE_XTALIN_AS_SOURCE_FOR_DPREFCLK) 2415 params.asParam.ucDCEClkFlag |= DCE_CLOCK_FLAG_PLL_REFCLK_SRC_XTALIN; 2416 2417 if (bp_params->flags.USE_GENERICA_AS_SOURCE_FOR_DPREFCLK) 2418 params.asParam.ucDCEClkFlag |= DCE_CLOCK_FLAG_PLL_REFCLK_SRC_GENERICA; 2419 } 2420 else 2421 /* only program clock frequency if display clock is used; VBIOS will program DPREFCLK */ 2422 /* We need to convert from KHz units into 10KHz units */ 2423 params.asParam.ulDCEClkFreq = cpu_to_le32(bp_params->target_clock_frequency / 10); 2424 2425 if (EXEC_BIOS_CMD_TABLE(SetDCEClock, params)) { 2426 /* Convert from 10KHz units back to KHz */ 2427 bp_params->target_clock_frequency = le32_to_cpu(params.asParam.ulDCEClkFreq) * 10; 2428 result = BP_RESULT_OK; 2429 } 2430 2431 return result; 2432}