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