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