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