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