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 * phisycal 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 /* votage 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 return result; 1535 } 1536 1537 static enum bp_result adjust_display_pll_v3( 1538 struct bios_parser *bp, 1539 struct bp_adjust_pixel_clock_parameters *bp_params) 1540 { 1541 enum bp_result result = BP_RESULT_FAILURE; 1542 ADJUST_DISPLAY_PLL_PS_ALLOCATION_V3 params; 1543 uint32_t pixel_clk_10_kHz_in = bp_params->pixel_clock / 10; 1544 1545 memset(¶ms, 0, sizeof(params)); 1546 1547 /* We need to convert from KHz units into 10KHz units and then convert 1548 * output pixel clock back 10KHz-->KHz */ 1549 params.sInput.usPixelClock = cpu_to_le16((uint16_t)pixel_clk_10_kHz_in); 1550 params.sInput.ucTransmitterID = 1551 bp->cmd_helper->encoder_id_to_atom( 1552 dal_graphics_object_id_get_encoder_id( 1553 bp_params->encoder_object_id)); 1554 params.sInput.ucEncodeMode = 1555 (uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom( 1556 bp_params->signal_type, false); 1557 1558 if (bp_params->ss_enable == true) 1559 params.sInput.ucDispPllConfig |= DISPPLL_CONFIG_SS_ENABLE; 1560 1561 if (bp_params->signal_type == SIGNAL_TYPE_DVI_DUAL_LINK) 1562 params.sInput.ucDispPllConfig |= DISPPLL_CONFIG_DUAL_LINK; 1563 1564 if (EXEC_BIOS_CMD_TABLE(AdjustDisplayPll, params)) { 1565 /* Convert output pixel clock back 10KHz-->KHz: multiply 1566 * original pixel clock in KHz by ratio 1567 * [output pxlClk/input pxlClk] */ 1568 uint64_t pixel_clk_10_khz_out = 1569 (uint64_t)le32_to_cpu(params.sOutput.ulDispPllFreq); 1570 uint64_t pixel_clk = (uint64_t)bp_params->pixel_clock; 1571 1572 if (pixel_clk_10_kHz_in != 0) { 1573 bp_params->adjusted_pixel_clock = 1574 div_u64(pixel_clk * pixel_clk_10_khz_out, 1575 pixel_clk_10_kHz_in); 1576 } else { 1577 bp_params->adjusted_pixel_clock = 0; 1578 BREAK_TO_DEBUGGER(); 1579 } 1580 1581 bp_params->reference_divider = params.sOutput.ucRefDiv; 1582 bp_params->pixel_clock_post_divider = params.sOutput.ucPostDiv; 1583 1584 result = BP_RESULT_OK; 1585 } 1586 1587 return result; 1588 } 1589 1590 /******************************************************************************* 1591 ******************************************************************************** 1592 ** 1593 ** DAC ENCODER CONTROL 1594 ** 1595 ******************************************************************************** 1596 *******************************************************************************/ 1597 1598 static enum bp_result dac1_encoder_control_v1( 1599 struct bios_parser *bp, 1600 bool enable, 1601 uint32_t pixel_clock, 1602 uint8_t dac_standard); 1603 static enum bp_result dac2_encoder_control_v1( 1604 struct bios_parser *bp, 1605 bool enable, 1606 uint32_t pixel_clock, 1607 uint8_t dac_standard); 1608 1609 static void init_dac_encoder_control(struct bios_parser *bp) 1610 { 1611 switch (BIOS_CMD_TABLE_PARA_REVISION(DAC1EncoderControl)) { 1612 case 1: 1613 bp->cmd_tbl.dac1_encoder_control = dac1_encoder_control_v1; 1614 break; 1615 default: 1616 bp->cmd_tbl.dac1_encoder_control = NULL; 1617 break; 1618 } 1619 switch (BIOS_CMD_TABLE_PARA_REVISION(DAC2EncoderControl)) { 1620 case 1: 1621 bp->cmd_tbl.dac2_encoder_control = dac2_encoder_control_v1; 1622 break; 1623 default: 1624 bp->cmd_tbl.dac2_encoder_control = NULL; 1625 break; 1626 } 1627 } 1628 1629 static void dac_encoder_control_prepare_params( 1630 DAC_ENCODER_CONTROL_PS_ALLOCATION *params, 1631 bool enable, 1632 uint32_t pixel_clock, 1633 uint8_t dac_standard) 1634 { 1635 params->ucDacStandard = dac_standard; 1636 if (enable) 1637 params->ucAction = ATOM_ENABLE; 1638 else 1639 params->ucAction = ATOM_DISABLE; 1640 1641 /* We need to convert from KHz units into 10KHz units 1642 * it looks as if the TvControl do not care about pixel clock 1643 */ 1644 params->usPixelClock = cpu_to_le16((uint16_t)(pixel_clock / 10)); 1645 } 1646 1647 static enum bp_result dac1_encoder_control_v1( 1648 struct bios_parser *bp, 1649 bool enable, 1650 uint32_t pixel_clock, 1651 uint8_t dac_standard) 1652 { 1653 enum bp_result result = BP_RESULT_FAILURE; 1654 DAC_ENCODER_CONTROL_PS_ALLOCATION params; 1655 1656 dac_encoder_control_prepare_params( 1657 ¶ms, 1658 enable, 1659 pixel_clock, 1660 dac_standard); 1661 1662 if (EXEC_BIOS_CMD_TABLE(DAC1EncoderControl, params)) 1663 result = BP_RESULT_OK; 1664 1665 return result; 1666 } 1667 1668 static enum bp_result dac2_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(DAC2EncoderControl, params)) 1684 result = BP_RESULT_OK; 1685 1686 return result; 1687 } 1688 1689 /******************************************************************************* 1690 ******************************************************************************** 1691 ** 1692 ** DAC OUTPUT CONTROL 1693 ** 1694 ******************************************************************************** 1695 *******************************************************************************/ 1696 static enum bp_result dac1_output_control_v1( 1697 struct bios_parser *bp, 1698 bool enable); 1699 static enum bp_result dac2_output_control_v1( 1700 struct bios_parser *bp, 1701 bool enable); 1702 1703 static void init_dac_output_control(struct bios_parser *bp) 1704 { 1705 switch (BIOS_CMD_TABLE_PARA_REVISION(DAC1OutputControl)) { 1706 case 1: 1707 bp->cmd_tbl.dac1_output_control = dac1_output_control_v1; 1708 break; 1709 default: 1710 bp->cmd_tbl.dac1_output_control = NULL; 1711 break; 1712 } 1713 switch (BIOS_CMD_TABLE_PARA_REVISION(DAC2OutputControl)) { 1714 case 1: 1715 bp->cmd_tbl.dac2_output_control = dac2_output_control_v1; 1716 break; 1717 default: 1718 bp->cmd_tbl.dac2_output_control = NULL; 1719 break; 1720 } 1721 } 1722 1723 static enum bp_result dac1_output_control_v1( 1724 struct bios_parser *bp, bool enable) 1725 { 1726 enum bp_result result = BP_RESULT_FAILURE; 1727 DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION params; 1728 1729 if (enable) 1730 params.ucAction = ATOM_ENABLE; 1731 else 1732 params.ucAction = ATOM_DISABLE; 1733 1734 if (EXEC_BIOS_CMD_TABLE(DAC1OutputControl, params)) 1735 result = BP_RESULT_OK; 1736 1737 return result; 1738 } 1739 1740 static enum bp_result dac2_output_control_v1( 1741 struct bios_parser *bp, bool enable) 1742 { 1743 enum bp_result result = BP_RESULT_FAILURE; 1744 DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION params; 1745 1746 if (enable) 1747 params.ucAction = ATOM_ENABLE; 1748 else 1749 params.ucAction = ATOM_DISABLE; 1750 1751 if (EXEC_BIOS_CMD_TABLE(DAC2OutputControl, params)) 1752 result = BP_RESULT_OK; 1753 1754 return result; 1755 } 1756 1757 /******************************************************************************* 1758 ******************************************************************************** 1759 ** 1760 ** SET CRTC TIMING 1761 ** 1762 ******************************************************************************** 1763 *******************************************************************************/ 1764 1765 static enum bp_result set_crtc_using_dtd_timing_v3( 1766 struct bios_parser *bp, 1767 struct bp_hw_crtc_timing_parameters *bp_params); 1768 static enum bp_result set_crtc_timing_v1( 1769 struct bios_parser *bp, 1770 struct bp_hw_crtc_timing_parameters *bp_params); 1771 1772 static void init_set_crtc_timing(struct bios_parser *bp) 1773 { 1774 uint32_t dtd_version = 1775 BIOS_CMD_TABLE_PARA_REVISION(SetCRTC_UsingDTDTiming); 1776 if (dtd_version > 2) 1777 switch (dtd_version) { 1778 case 3: 1779 bp->cmd_tbl.set_crtc_timing = 1780 set_crtc_using_dtd_timing_v3; 1781 break; 1782 default: 1783 dm_output_to_console("Don't have set_crtc_timing for dtd v%d\n", 1784 dtd_version); 1785 bp->cmd_tbl.set_crtc_timing = NULL; 1786 break; 1787 } 1788 else 1789 switch (BIOS_CMD_TABLE_PARA_REVISION(SetCRTC_Timing)) { 1790 case 1: 1791 bp->cmd_tbl.set_crtc_timing = set_crtc_timing_v1; 1792 break; 1793 default: 1794 dm_output_to_console("Don't have set_crtc_timing for v%d\n", 1795 BIOS_CMD_TABLE_PARA_REVISION(SetCRTC_Timing)); 1796 bp->cmd_tbl.set_crtc_timing = NULL; 1797 break; 1798 } 1799 } 1800 1801 static enum bp_result set_crtc_timing_v1( 1802 struct bios_parser *bp, 1803 struct bp_hw_crtc_timing_parameters *bp_params) 1804 { 1805 enum bp_result result = BP_RESULT_FAILURE; 1806 SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION params = {0}; 1807 uint8_t atom_controller_id; 1808 1809 if (bp->cmd_helper->controller_id_to_atom( 1810 bp_params->controller_id, &atom_controller_id)) 1811 params.ucCRTC = atom_controller_id; 1812 1813 params.usH_Total = cpu_to_le16((uint16_t)(bp_params->h_total)); 1814 params.usH_Disp = cpu_to_le16((uint16_t)(bp_params->h_addressable)); 1815 params.usH_SyncStart = cpu_to_le16((uint16_t)(bp_params->h_sync_start)); 1816 params.usH_SyncWidth = cpu_to_le16((uint16_t)(bp_params->h_sync_width)); 1817 params.usV_Total = cpu_to_le16((uint16_t)(bp_params->v_total)); 1818 params.usV_Disp = cpu_to_le16((uint16_t)(bp_params->v_addressable)); 1819 params.usV_SyncStart = 1820 cpu_to_le16((uint16_t)(bp_params->v_sync_start)); 1821 params.usV_SyncWidth = 1822 cpu_to_le16((uint16_t)(bp_params->v_sync_width)); 1823 1824 /* VBIOS does not expect any value except zero into this call, for 1825 * underscan use another entry ProgramOverscan call but when mode 1826 * 1776x1000 with the overscan 72x44 .e.i. 1920x1080 @30 DAL2 is ok, 1827 * but when same ,but 60 Hz there is corruption 1828 * DAL1 does not allow the mode 1776x1000@60 1829 */ 1830 params.ucOverscanRight = (uint8_t)bp_params->h_overscan_right; 1831 params.ucOverscanLeft = (uint8_t)bp_params->h_overscan_left; 1832 params.ucOverscanBottom = (uint8_t)bp_params->v_overscan_bottom; 1833 params.ucOverscanTop = (uint8_t)bp_params->v_overscan_top; 1834 1835 if (0 == bp_params->flags.HSYNC_POSITIVE_POLARITY) 1836 params.susModeMiscInfo.usAccess = 1837 cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_HSYNC_POLARITY); 1838 1839 if (0 == bp_params->flags.VSYNC_POSITIVE_POLARITY) 1840 params.susModeMiscInfo.usAccess = 1841 cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_VSYNC_POLARITY); 1842 1843 if (bp_params->flags.INTERLACE) { 1844 params.susModeMiscInfo.usAccess = 1845 cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_INTERLACE); 1846 1847 /* original DAL code has this condition to apply tis for 1848 * non-TV/CV only due to complex MV testing for possible 1849 * impact 1850 * if (pACParameters->signal != SignalType_YPbPr && 1851 * pACParameters->signal != SignalType_Composite && 1852 * pACParameters->signal != SignalType_SVideo) 1853 */ 1854 /* HW will deduct 0.5 line from 2nd feild. 1855 * i.e. for 1080i, it is 2 lines for 1st field, 2.5 1856 * lines for the 2nd feild. we need input as 5 instead 1857 * of 4, but it is 4 either from Edid data 1858 * (spec CEA 861) or CEA timing table. 1859 */ 1860 params.usV_SyncStart = 1861 cpu_to_le16((uint16_t)(bp_params->v_sync_start + 1)); 1862 } 1863 1864 if (bp_params->flags.HORZ_COUNT_BY_TWO) 1865 params.susModeMiscInfo.usAccess = 1866 cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_DOUBLE_CLOCK_MODE); 1867 1868 if (EXEC_BIOS_CMD_TABLE(SetCRTC_Timing, params)) 1869 result = BP_RESULT_OK; 1870 1871 return result; 1872 } 1873 1874 static enum bp_result set_crtc_using_dtd_timing_v3( 1875 struct bios_parser *bp, 1876 struct bp_hw_crtc_timing_parameters *bp_params) 1877 { 1878 enum bp_result result = BP_RESULT_FAILURE; 1879 SET_CRTC_USING_DTD_TIMING_PARAMETERS params = {0}; 1880 uint8_t atom_controller_id; 1881 1882 if (bp->cmd_helper->controller_id_to_atom( 1883 bp_params->controller_id, &atom_controller_id)) 1884 params.ucCRTC = atom_controller_id; 1885 1886 /* bios usH_Size wants h addressable size */ 1887 params.usH_Size = cpu_to_le16((uint16_t)bp_params->h_addressable); 1888 /* bios usH_Blanking_Time wants borders included in blanking */ 1889 params.usH_Blanking_Time = 1890 cpu_to_le16((uint16_t)(bp_params->h_total - bp_params->h_addressable)); 1891 /* bios usV_Size wants v addressable size */ 1892 params.usV_Size = cpu_to_le16((uint16_t)bp_params->v_addressable); 1893 /* bios usV_Blanking_Time wants borders included in blanking */ 1894 params.usV_Blanking_Time = 1895 cpu_to_le16((uint16_t)(bp_params->v_total - bp_params->v_addressable)); 1896 /* bios usHSyncOffset is the offset from the end of h addressable, 1897 * our horizontalSyncStart is the offset from the beginning 1898 * of h addressable */ 1899 params.usH_SyncOffset = 1900 cpu_to_le16((uint16_t)(bp_params->h_sync_start - bp_params->h_addressable)); 1901 params.usH_SyncWidth = cpu_to_le16((uint16_t)bp_params->h_sync_width); 1902 /* bios usHSyncOffset is the offset from the end of v addressable, 1903 * our verticalSyncStart is the offset from the beginning of 1904 * v addressable */ 1905 params.usV_SyncOffset = 1906 cpu_to_le16((uint16_t)(bp_params->v_sync_start - bp_params->v_addressable)); 1907 params.usV_SyncWidth = cpu_to_le16((uint16_t)bp_params->v_sync_width); 1908 1909 /* we assume that overscan from original timing does not get bigger 1910 * than 255 1911 * we will program all the borders in the Set CRTC Overscan call below 1912 */ 1913 1914 if (0 == bp_params->flags.HSYNC_POSITIVE_POLARITY) 1915 params.susModeMiscInfo.usAccess = 1916 cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_HSYNC_POLARITY); 1917 1918 if (0 == bp_params->flags.VSYNC_POSITIVE_POLARITY) 1919 params.susModeMiscInfo.usAccess = 1920 cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_VSYNC_POLARITY); 1921 1922 if (bp_params->flags.INTERLACE) { 1923 params.susModeMiscInfo.usAccess = 1924 cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_INTERLACE); 1925 1926 /* original DAL code has this condition to apply this 1927 * for non-TV/CV only 1928 * due to complex MV testing for possible impact 1929 * if ( pACParameters->signal != SignalType_YPbPr && 1930 * pACParameters->signal != SignalType_Composite && 1931 * pACParameters->signal != SignalType_SVideo) 1932 */ 1933 { 1934 /* HW will deduct 0.5 line from 2nd feild. 1935 * i.e. for 1080i, it is 2 lines for 1st field, 1936 * 2.5 lines for the 2nd feild. we need input as 5 1937 * instead of 4. 1938 * but it is 4 either from Edid data (spec CEA 861) 1939 * or CEA timing table. 1940 */ 1941 le16_add_cpu(¶ms.usV_SyncOffset, 1); 1942 } 1943 } 1944 1945 if (bp_params->flags.HORZ_COUNT_BY_TWO) 1946 params.susModeMiscInfo.usAccess = 1947 cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_DOUBLE_CLOCK_MODE); 1948 1949 if (EXEC_BIOS_CMD_TABLE(SetCRTC_UsingDTDTiming, params)) 1950 result = BP_RESULT_OK; 1951 1952 return result; 1953 } 1954 1955 /******************************************************************************* 1956 ******************************************************************************** 1957 ** 1958 ** ENABLE CRTC 1959 ** 1960 ******************************************************************************** 1961 *******************************************************************************/ 1962 1963 static enum bp_result enable_crtc_v1( 1964 struct bios_parser *bp, 1965 enum controller_id controller_id, 1966 bool enable); 1967 1968 static void init_enable_crtc(struct bios_parser *bp) 1969 { 1970 switch (BIOS_CMD_TABLE_PARA_REVISION(EnableCRTC)) { 1971 case 1: 1972 bp->cmd_tbl.enable_crtc = enable_crtc_v1; 1973 break; 1974 default: 1975 dm_output_to_console("Don't have enable_crtc for v%d\n", 1976 BIOS_CMD_TABLE_PARA_REVISION(EnableCRTC)); 1977 bp->cmd_tbl.enable_crtc = NULL; 1978 break; 1979 } 1980 } 1981 1982 static enum bp_result enable_crtc_v1( 1983 struct bios_parser *bp, 1984 enum controller_id controller_id, 1985 bool enable) 1986 { 1987 bool result = BP_RESULT_FAILURE; 1988 ENABLE_CRTC_PARAMETERS params = {0}; 1989 uint8_t id; 1990 1991 if (bp->cmd_helper->controller_id_to_atom(controller_id, &id)) 1992 params.ucCRTC = id; 1993 else 1994 return BP_RESULT_BADINPUT; 1995 1996 if (enable) 1997 params.ucEnable = ATOM_ENABLE; 1998 else 1999 params.ucEnable = ATOM_DISABLE; 2000 2001 if (EXEC_BIOS_CMD_TABLE(EnableCRTC, params)) 2002 result = BP_RESULT_OK; 2003 2004 return result; 2005 } 2006 2007 /******************************************************************************* 2008 ******************************************************************************** 2009 ** 2010 ** ENABLE CRTC MEM REQ 2011 ** 2012 ******************************************************************************** 2013 *******************************************************************************/ 2014 2015 static enum bp_result enable_crtc_mem_req_v1( 2016 struct bios_parser *bp, 2017 enum controller_id controller_id, 2018 bool enable); 2019 2020 static void init_enable_crtc_mem_req(struct bios_parser *bp) 2021 { 2022 switch (BIOS_CMD_TABLE_PARA_REVISION(EnableCRTCMemReq)) { 2023 case 1: 2024 bp->cmd_tbl.enable_crtc_mem_req = enable_crtc_mem_req_v1; 2025 break; 2026 default: 2027 bp->cmd_tbl.enable_crtc_mem_req = NULL; 2028 break; 2029 } 2030 } 2031 2032 static enum bp_result enable_crtc_mem_req_v1( 2033 struct bios_parser *bp, 2034 enum controller_id controller_id, 2035 bool enable) 2036 { 2037 bool result = BP_RESULT_BADINPUT; 2038 ENABLE_CRTC_PARAMETERS params = {0}; 2039 uint8_t id; 2040 2041 if (bp->cmd_helper->controller_id_to_atom(controller_id, &id)) { 2042 params.ucCRTC = id; 2043 2044 if (enable) 2045 params.ucEnable = ATOM_ENABLE; 2046 else 2047 params.ucEnable = ATOM_DISABLE; 2048 2049 if (EXEC_BIOS_CMD_TABLE(EnableCRTCMemReq, params)) 2050 result = BP_RESULT_OK; 2051 else 2052 result = BP_RESULT_FAILURE; 2053 } 2054 2055 return result; 2056 } 2057 2058 /******************************************************************************* 2059 ******************************************************************************** 2060 ** 2061 ** DISPLAY PLL 2062 ** 2063 ******************************************************************************** 2064 *******************************************************************************/ 2065 2066 static enum bp_result program_clock_v5( 2067 struct bios_parser *bp, 2068 struct bp_pixel_clock_parameters *bp_params); 2069 static enum bp_result program_clock_v6( 2070 struct bios_parser *bp, 2071 struct bp_pixel_clock_parameters *bp_params); 2072 2073 static void init_program_clock(struct bios_parser *bp) 2074 { 2075 switch (BIOS_CMD_TABLE_PARA_REVISION(SetPixelClock)) { 2076 case 5: 2077 bp->cmd_tbl.program_clock = program_clock_v5; 2078 break; 2079 case 6: 2080 bp->cmd_tbl.program_clock = program_clock_v6; 2081 break; 2082 default: 2083 dm_output_to_console("Don't have program_clock for v%d\n", 2084 BIOS_CMD_TABLE_PARA_REVISION(SetPixelClock)); 2085 bp->cmd_tbl.program_clock = NULL; 2086 break; 2087 } 2088 } 2089 2090 static enum bp_result program_clock_v5( 2091 struct bios_parser *bp, 2092 struct bp_pixel_clock_parameters *bp_params) 2093 { 2094 enum bp_result result = BP_RESULT_FAILURE; 2095 2096 SET_PIXEL_CLOCK_PS_ALLOCATION_V5 params; 2097 uint32_t atom_pll_id; 2098 2099 memset(¶ms, 0, sizeof(params)); 2100 if (!bp->cmd_helper->clock_source_id_to_atom( 2101 bp_params->pll_id, &atom_pll_id)) { 2102 BREAK_TO_DEBUGGER(); /* Invalid Inpute!! */ 2103 return BP_RESULT_BADINPUT; 2104 } 2105 2106 /* We need to convert from KHz units into 10KHz units */ 2107 params.sPCLKInput.ucPpll = (uint8_t) atom_pll_id; 2108 params.sPCLKInput.usPixelClock = 2109 cpu_to_le16((uint16_t) (bp_params->target_pixel_clock_100hz / 100)); 2110 params.sPCLKInput.ucCRTC = (uint8_t) ATOM_CRTC_INVALID; 2111 2112 if (bp_params->flags.SET_EXTERNAL_REF_DIV_SRC) 2113 params.sPCLKInput.ucMiscInfo |= PIXEL_CLOCK_MISC_REF_DIV_SRC; 2114 2115 if (EXEC_BIOS_CMD_TABLE(SetPixelClock, params)) 2116 result = BP_RESULT_OK; 2117 2118 return result; 2119 } 2120 2121 static enum bp_result program_clock_v6( 2122 struct bios_parser *bp, 2123 struct bp_pixel_clock_parameters *bp_params) 2124 { 2125 enum bp_result result = BP_RESULT_FAILURE; 2126 2127 SET_PIXEL_CLOCK_PS_ALLOCATION_V6 params; 2128 uint32_t atom_pll_id; 2129 2130 memset(¶ms, 0, sizeof(params)); 2131 2132 if (!bp->cmd_helper->clock_source_id_to_atom( 2133 bp_params->pll_id, &atom_pll_id)) { 2134 BREAK_TO_DEBUGGER(); /*Invalid Input!!*/ 2135 return BP_RESULT_BADINPUT; 2136 } 2137 2138 /* We need to convert from KHz units into 10KHz units */ 2139 params.sPCLKInput.ucPpll = (uint8_t)atom_pll_id; 2140 params.sPCLKInput.ulDispEngClkFreq = 2141 cpu_to_le32(bp_params->target_pixel_clock_100hz / 100); 2142 2143 if (bp_params->flags.SET_EXTERNAL_REF_DIV_SRC) 2144 params.sPCLKInput.ucMiscInfo |= PIXEL_CLOCK_MISC_REF_DIV_SRC; 2145 2146 if (bp_params->flags.SET_DISPCLK_DFS_BYPASS) 2147 params.sPCLKInput.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_DPREFCLK_BYPASS; 2148 2149 if (EXEC_BIOS_CMD_TABLE(SetPixelClock, params)) { 2150 /* True display clock is returned by VBIOS if DFS bypass 2151 * is enabled. */ 2152 bp_params->dfs_bypass_display_clock = 2153 (uint32_t)(le32_to_cpu(params.sPCLKInput.ulDispEngClkFreq) * 10); 2154 result = BP_RESULT_OK; 2155 } 2156 2157 return result; 2158 } 2159 2160 /******************************************************************************* 2161 ******************************************************************************** 2162 ** 2163 ** EXTERNAL ENCODER CONTROL 2164 ** 2165 ******************************************************************************** 2166 *******************************************************************************/ 2167 2168 static enum bp_result external_encoder_control_v3( 2169 struct bios_parser *bp, 2170 struct bp_external_encoder_control *cntl); 2171 2172 static void init_external_encoder_control( 2173 struct bios_parser *bp) 2174 { 2175 switch (BIOS_CMD_TABLE_PARA_REVISION(ExternalEncoderControl)) { 2176 case 3: 2177 bp->cmd_tbl.external_encoder_control = 2178 external_encoder_control_v3; 2179 break; 2180 default: 2181 bp->cmd_tbl.external_encoder_control = NULL; 2182 break; 2183 } 2184 } 2185 2186 static enum bp_result external_encoder_control_v3( 2187 struct bios_parser *bp, 2188 struct bp_external_encoder_control *cntl) 2189 { 2190 enum bp_result result = BP_RESULT_FAILURE; 2191 2192 /* we need use _PS_Alloc struct */ 2193 EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION_V3 params; 2194 EXTERNAL_ENCODER_CONTROL_PARAMETERS_V3 *cntl_params; 2195 struct graphics_object_id encoder; 2196 bool is_input_signal_dp = false; 2197 2198 memset(¶ms, 0, sizeof(params)); 2199 2200 cntl_params = ¶ms.sExtEncoder; 2201 2202 encoder = cntl->encoder_id; 2203 2204 /* check if encoder supports external encoder control table */ 2205 switch (dal_graphics_object_id_get_encoder_id(encoder)) { 2206 case ENCODER_ID_EXTERNAL_NUTMEG: 2207 case ENCODER_ID_EXTERNAL_TRAVIS: 2208 is_input_signal_dp = true; 2209 break; 2210 2211 default: 2212 BREAK_TO_DEBUGGER(); 2213 return BP_RESULT_BADINPUT; 2214 } 2215 2216 /* Fill information based on the action 2217 * 2218 * Bit[6:4]: indicate external encoder, applied to all functions. 2219 * =0: external encoder1, mapped to external encoder enum id1 2220 * =1: external encoder2, mapped to external encoder enum id2 2221 * 2222 * enum ObjectEnumId 2223 * { 2224 * EnumId_Unknown = 0, 2225 * EnumId_1, 2226 * EnumId_2, 2227 * }; 2228 */ 2229 cntl_params->ucConfig = (uint8_t)((encoder.enum_id - 1) << 4); 2230 2231 switch (cntl->action) { 2232 case EXTERNAL_ENCODER_CONTROL_INIT: 2233 /* output display connector type. Only valid in encoder 2234 * initialization */ 2235 cntl_params->usConnectorId = 2236 cpu_to_le16((uint16_t)cntl->connector_obj_id.id); 2237 break; 2238 case EXTERNAL_ENCODER_CONTROL_SETUP: 2239 /* EXTERNAL_ENCODER_CONTROL_PARAMETERS_V3 pixel clock unit in 2240 * 10KHz 2241 * output display device pixel clock frequency in unit of 10KHz. 2242 * Only valid in setup and enableoutput 2243 */ 2244 cntl_params->usPixelClock = 2245 cpu_to_le16((uint16_t)(cntl->pixel_clock / 10)); 2246 /* Indicate display output signal type drive by external 2247 * encoder, only valid in setup and enableoutput */ 2248 cntl_params->ucEncoderMode = 2249 (uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom( 2250 cntl->signal, false); 2251 2252 if (is_input_signal_dp) { 2253 /* Bit[0]: indicate link rate, =1: 2.7Ghz, =0: 1.62Ghz, 2254 * only valid in encoder setup with DP mode. */ 2255 if (LINK_RATE_HIGH == cntl->link_rate) 2256 cntl_params->ucConfig |= 1; 2257 /* output color depth Indicate encoder data bpc format 2258 * in DP mode, only valid in encoder setup in DP mode. 2259 */ 2260 cntl_params->ucBitPerColor = 2261 (uint8_t)(cntl->color_depth); 2262 } 2263 /* Indicate how many lanes used by external encoder, only valid 2264 * in encoder setup and enableoutput. */ 2265 cntl_params->ucLaneNum = (uint8_t)(cntl->lanes_number); 2266 break; 2267 case EXTERNAL_ENCODER_CONTROL_ENABLE: 2268 cntl_params->usPixelClock = 2269 cpu_to_le16((uint16_t)(cntl->pixel_clock / 10)); 2270 cntl_params->ucEncoderMode = 2271 (uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom( 2272 cntl->signal, false); 2273 cntl_params->ucLaneNum = (uint8_t)cntl->lanes_number; 2274 break; 2275 default: 2276 break; 2277 } 2278 2279 cntl_params->ucAction = (uint8_t)cntl->action; 2280 2281 if (EXEC_BIOS_CMD_TABLE(ExternalEncoderControl, params)) 2282 result = BP_RESULT_OK; 2283 2284 return result; 2285 } 2286 2287 /******************************************************************************* 2288 ******************************************************************************** 2289 ** 2290 ** ENABLE DISPLAY POWER GATING 2291 ** 2292 ******************************************************************************** 2293 *******************************************************************************/ 2294 2295 static enum bp_result enable_disp_power_gating_v2_1( 2296 struct bios_parser *bp, 2297 enum controller_id crtc_id, 2298 enum bp_pipe_control_action action); 2299 2300 static void init_enable_disp_power_gating( 2301 struct bios_parser *bp) 2302 { 2303 switch (BIOS_CMD_TABLE_PARA_REVISION(EnableDispPowerGating)) { 2304 case 1: 2305 bp->cmd_tbl.enable_disp_power_gating = 2306 enable_disp_power_gating_v2_1; 2307 break; 2308 default: 2309 dm_output_to_console("Don't enable_disp_power_gating enable_crtc for v%d\n", 2310 BIOS_CMD_TABLE_PARA_REVISION(EnableDispPowerGating)); 2311 bp->cmd_tbl.enable_disp_power_gating = NULL; 2312 break; 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 enum bp_result result = BP_RESULT_FAILURE; 2322 2323 ENABLE_DISP_POWER_GATING_PS_ALLOCATION params = {0}; 2324 uint8_t atom_crtc_id; 2325 2326 if (bp->cmd_helper->controller_id_to_atom(crtc_id, &atom_crtc_id)) 2327 params.ucDispPipeId = atom_crtc_id; 2328 else 2329 return BP_RESULT_BADINPUT; 2330 2331 params.ucEnable = 2332 bp->cmd_helper->disp_power_gating_action_to_atom(action); 2333 2334 if (EXEC_BIOS_CMD_TABLE(EnableDispPowerGating, params)) 2335 result = BP_RESULT_OK; 2336 2337 return result; 2338 } 2339 2340 /******************************************************************************* 2341 ******************************************************************************** 2342 ** 2343 ** SET DCE CLOCK 2344 ** 2345 ******************************************************************************** 2346 *******************************************************************************/ 2347 static enum bp_result set_dce_clock_v2_1( 2348 struct bios_parser *bp, 2349 struct bp_set_dce_clock_parameters *bp_params); 2350 2351 static void init_set_dce_clock(struct bios_parser *bp) 2352 { 2353 switch (BIOS_CMD_TABLE_PARA_REVISION(SetDCEClock)) { 2354 case 1: 2355 bp->cmd_tbl.set_dce_clock = set_dce_clock_v2_1; 2356 break; 2357 default: 2358 dm_output_to_console("Don't have set_dce_clock for v%d\n", 2359 BIOS_CMD_TABLE_PARA_REVISION(SetDCEClock)); 2360 bp->cmd_tbl.set_dce_clock = NULL; 2361 break; 2362 } 2363 } 2364 2365 static enum bp_result set_dce_clock_v2_1( 2366 struct bios_parser *bp, 2367 struct bp_set_dce_clock_parameters *bp_params) 2368 { 2369 enum bp_result result = BP_RESULT_FAILURE; 2370 2371 SET_DCE_CLOCK_PS_ALLOCATION_V2_1 params; 2372 uint32_t atom_pll_id; 2373 uint32_t atom_clock_type; 2374 const struct command_table_helper *cmd = bp->cmd_helper; 2375 2376 memset(¶ms, 0, sizeof(params)); 2377 2378 if (!cmd->clock_source_id_to_atom(bp_params->pll_id, &atom_pll_id) || 2379 !cmd->dc_clock_type_to_atom(bp_params->clock_type, &atom_clock_type)) 2380 return BP_RESULT_BADINPUT; 2381 2382 params.asParam.ucDCEClkSrc = atom_pll_id; 2383 params.asParam.ucDCEClkType = atom_clock_type; 2384 2385 if (bp_params->clock_type == DCECLOCK_TYPE_DPREFCLK) { 2386 if (bp_params->flags.USE_GENLOCK_AS_SOURCE_FOR_DPREFCLK) 2387 params.asParam.ucDCEClkFlag |= DCE_CLOCK_FLAG_PLL_REFCLK_SRC_GENLK; 2388 2389 if (bp_params->flags.USE_PCIE_AS_SOURCE_FOR_DPREFCLK) 2390 params.asParam.ucDCEClkFlag |= DCE_CLOCK_FLAG_PLL_REFCLK_SRC_PCIE; 2391 2392 if (bp_params->flags.USE_XTALIN_AS_SOURCE_FOR_DPREFCLK) 2393 params.asParam.ucDCEClkFlag |= DCE_CLOCK_FLAG_PLL_REFCLK_SRC_XTALIN; 2394 2395 if (bp_params->flags.USE_GENERICA_AS_SOURCE_FOR_DPREFCLK) 2396 params.asParam.ucDCEClkFlag |= DCE_CLOCK_FLAG_PLL_REFCLK_SRC_GENERICA; 2397 } 2398 else 2399 /* only program clock frequency if display clock is used; VBIOS will program DPREFCLK */ 2400 /* We need to convert from KHz units into 10KHz units */ 2401 params.asParam.ulDCEClkFreq = cpu_to_le32(bp_params->target_clock_frequency / 10); 2402 2403 if (EXEC_BIOS_CMD_TABLE(SetDCEClock, params)) { 2404 /* Convert from 10KHz units back to KHz */ 2405 bp_params->target_clock_frequency = le32_to_cpu(params.asParam.ulDCEClkFreq) * 10; 2406 result = BP_RESULT_OK; 2407 } 2408 2409 return result; 2410 } 2411