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_INIT) 1878 params->ucAction = ATOM_ENCODER_INIT; 1879 else if (action == ENCODER_CONTROL_ENABLE) 1880 params->ucAction = ATOM_ENABLE; 1881 else 1882 params->ucAction = ATOM_DISABLE; 1883 1884 /* We need to convert from KHz units into 10KHz units 1885 * it looks as if the TvControl do not care about pixel clock 1886 */ 1887 params->usPixelClock = cpu_to_le16((uint16_t)(pixel_clock / 10)); 1888 } 1889 1890 static enum bp_result dac1_encoder_control_v1( 1891 struct bios_parser *bp, 1892 enum bp_encoder_control_action action, 1893 uint32_t pixel_clock, 1894 uint8_t dac_standard) 1895 { 1896 enum bp_result result = BP_RESULT_FAILURE; 1897 DAC_ENCODER_CONTROL_PS_ALLOCATION params; 1898 1899 dac_encoder_control_prepare_params( 1900 ¶ms, 1901 action, 1902 pixel_clock, 1903 dac_standard); 1904 1905 if (EXEC_BIOS_CMD_TABLE(DAC1EncoderControl, params)) 1906 result = BP_RESULT_OK; 1907 1908 return result; 1909 } 1910 1911 static enum bp_result dac2_encoder_control_v1( 1912 struct bios_parser *bp, 1913 enum bp_encoder_control_action action, 1914 uint32_t pixel_clock, 1915 uint8_t dac_standard) 1916 { 1917 enum bp_result result = BP_RESULT_FAILURE; 1918 DAC_ENCODER_CONTROL_PS_ALLOCATION params; 1919 1920 dac_encoder_control_prepare_params( 1921 ¶ms, 1922 action, 1923 pixel_clock, 1924 dac_standard); 1925 1926 if (EXEC_BIOS_CMD_TABLE(DAC2EncoderControl, params)) 1927 result = BP_RESULT_OK; 1928 1929 return result; 1930 } 1931 1932 /******************************************************************************* 1933 ******************************************************************************** 1934 ** 1935 ** DAC LOAD DETECTION 1936 ** 1937 ******************************************************************************** 1938 *******************************************************************************/ 1939 1940 static enum bp_result dac_load_detection_v1( 1941 struct bios_parser *bp, 1942 struct bp_load_detection_parameters *bp_params); 1943 1944 static enum bp_result dac_load_detection_v3( 1945 struct bios_parser *bp, 1946 struct bp_load_detection_parameters *bp_params); 1947 1948 static void init_dac_load_detection(struct bios_parser *bp) 1949 { 1950 switch (BIOS_CMD_TABLE_PARA_REVISION(DAC_LoadDetection)) { 1951 case 1: 1952 case 2: 1953 bp->cmd_tbl.dac_load_detection = dac_load_detection_v1; 1954 break; 1955 case 3: 1956 default: 1957 bp->cmd_tbl.dac_load_detection = dac_load_detection_v3; 1958 break; 1959 } 1960 } 1961 1962 static void dac_load_detect_prepare_params( 1963 struct _DAC_LOAD_DETECTION_PS_ALLOCATION *params, 1964 enum engine_id engine_id, 1965 uint16_t device_id, 1966 uint8_t misc) 1967 { 1968 uint8_t dac_type = ENGINE_ID_DACA; 1969 1970 if (engine_id == ENGINE_ID_DACB) 1971 dac_type = ATOM_DAC_B; 1972 1973 params->sDacload.usDeviceID = cpu_to_le16(device_id); 1974 params->sDacload.ucDacType = dac_type; 1975 params->sDacload.ucMisc = misc; 1976 } 1977 1978 static enum bp_result dac_load_detection_v1( 1979 struct bios_parser *bp, 1980 struct bp_load_detection_parameters *bp_params) 1981 { 1982 enum bp_result result = BP_RESULT_FAILURE; 1983 DAC_LOAD_DETECTION_PS_ALLOCATION params; 1984 1985 dac_load_detect_prepare_params( 1986 ¶ms, 1987 bp_params->engine_id, 1988 bp_params->device_id, 1989 0); 1990 1991 if (EXEC_BIOS_CMD_TABLE(DAC_LoadDetection, params)) 1992 result = BP_RESULT_OK; 1993 1994 return result; 1995 } 1996 1997 static enum bp_result dac_load_detection_v3( 1998 struct bios_parser *bp, 1999 struct bp_load_detection_parameters *bp_params) 2000 { 2001 enum bp_result result = BP_RESULT_FAILURE; 2002 DAC_LOAD_DETECTION_PS_ALLOCATION params; 2003 2004 uint8_t misc = 0; 2005 2006 if (bp_params->device_id == ATOM_DEVICE_CV_SUPPORT || 2007 bp_params->device_id == ATOM_DEVICE_TV1_SUPPORT) 2008 misc = DAC_LOAD_MISC_YPrPb; 2009 2010 dac_load_detect_prepare_params( 2011 ¶ms, 2012 bp_params->engine_id, 2013 bp_params->device_id, 2014 misc); 2015 2016 if (EXEC_BIOS_CMD_TABLE(DAC_LoadDetection, params)) 2017 result = BP_RESULT_OK; 2018 2019 return result; 2020 } 2021 2022 /******************************************************************************* 2023 ******************************************************************************** 2024 ** 2025 ** DAC OUTPUT CONTROL 2026 ** 2027 ******************************************************************************** 2028 *******************************************************************************/ 2029 static enum bp_result dac1_output_control_v1( 2030 struct bios_parser *bp, 2031 bool enable); 2032 static enum bp_result dac2_output_control_v1( 2033 struct bios_parser *bp, 2034 bool enable); 2035 2036 static void init_dac_output_control(struct bios_parser *bp) 2037 { 2038 switch (BIOS_CMD_TABLE_PARA_REVISION(DAC1OutputControl)) { 2039 case 1: 2040 bp->cmd_tbl.dac1_output_control = dac1_output_control_v1; 2041 break; 2042 default: 2043 bp->cmd_tbl.dac1_output_control = NULL; 2044 break; 2045 } 2046 switch (BIOS_CMD_TABLE_PARA_REVISION(DAC2OutputControl)) { 2047 case 1: 2048 bp->cmd_tbl.dac2_output_control = dac2_output_control_v1; 2049 break; 2050 default: 2051 bp->cmd_tbl.dac2_output_control = NULL; 2052 break; 2053 } 2054 } 2055 2056 static enum bp_result dac1_output_control_v1( 2057 struct bios_parser *bp, bool enable) 2058 { 2059 enum bp_result result = BP_RESULT_FAILURE; 2060 DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION params; 2061 2062 if (enable) 2063 params.ucAction = ATOM_ENABLE; 2064 else 2065 params.ucAction = ATOM_DISABLE; 2066 2067 if (EXEC_BIOS_CMD_TABLE(DAC1OutputControl, params)) 2068 result = BP_RESULT_OK; 2069 2070 return result; 2071 } 2072 2073 static enum bp_result dac2_output_control_v1( 2074 struct bios_parser *bp, bool enable) 2075 { 2076 enum bp_result result = BP_RESULT_FAILURE; 2077 DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION params; 2078 2079 if (enable) 2080 params.ucAction = ATOM_ENABLE; 2081 else 2082 params.ucAction = ATOM_DISABLE; 2083 2084 if (EXEC_BIOS_CMD_TABLE(DAC2OutputControl, params)) 2085 result = BP_RESULT_OK; 2086 2087 return result; 2088 } 2089 2090 /******************************************************************************* 2091 ******************************************************************************** 2092 ** 2093 ** SET CRTC TIMING 2094 ** 2095 ******************************************************************************** 2096 *******************************************************************************/ 2097 2098 static enum bp_result set_crtc_using_dtd_timing_v3( 2099 struct bios_parser *bp, 2100 struct bp_hw_crtc_timing_parameters *bp_params); 2101 static enum bp_result set_crtc_timing_v1( 2102 struct bios_parser *bp, 2103 struct bp_hw_crtc_timing_parameters *bp_params); 2104 2105 static void init_set_crtc_timing(struct bios_parser *bp) 2106 { 2107 uint32_t dtd_version = 2108 BIOS_CMD_TABLE_PARA_REVISION(SetCRTC_UsingDTDTiming); 2109 if (dtd_version > 2) 2110 switch (dtd_version) { 2111 case 3: 2112 bp->cmd_tbl.set_crtc_timing = 2113 set_crtc_using_dtd_timing_v3; 2114 break; 2115 default: 2116 dm_output_to_console("Don't have set_crtc_timing for dtd v%d\n", 2117 dtd_version); 2118 bp->cmd_tbl.set_crtc_timing = NULL; 2119 break; 2120 } 2121 else 2122 switch (BIOS_CMD_TABLE_PARA_REVISION(SetCRTC_Timing)) { 2123 case 1: 2124 bp->cmd_tbl.set_crtc_timing = set_crtc_timing_v1; 2125 break; 2126 default: 2127 dm_output_to_console("Don't have set_crtc_timing for v%d\n", 2128 BIOS_CMD_TABLE_PARA_REVISION(SetCRTC_Timing)); 2129 bp->cmd_tbl.set_crtc_timing = NULL; 2130 break; 2131 } 2132 } 2133 2134 static enum bp_result set_crtc_timing_v1( 2135 struct bios_parser *bp, 2136 struct bp_hw_crtc_timing_parameters *bp_params) 2137 { 2138 enum bp_result result = BP_RESULT_FAILURE; 2139 SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION params = {0}; 2140 uint8_t atom_controller_id; 2141 2142 if (bp->cmd_helper->controller_id_to_atom( 2143 bp_params->controller_id, &atom_controller_id)) 2144 params.ucCRTC = atom_controller_id; 2145 2146 params.usH_Total = cpu_to_le16((uint16_t)(bp_params->h_total)); 2147 params.usH_Disp = cpu_to_le16((uint16_t)(bp_params->h_addressable)); 2148 params.usH_SyncStart = cpu_to_le16((uint16_t)(bp_params->h_sync_start)); 2149 params.usH_SyncWidth = cpu_to_le16((uint16_t)(bp_params->h_sync_width)); 2150 params.usV_Total = cpu_to_le16((uint16_t)(bp_params->v_total)); 2151 params.usV_Disp = cpu_to_le16((uint16_t)(bp_params->v_addressable)); 2152 params.usV_SyncStart = 2153 cpu_to_le16((uint16_t)(bp_params->v_sync_start)); 2154 params.usV_SyncWidth = 2155 cpu_to_le16((uint16_t)(bp_params->v_sync_width)); 2156 2157 /* VBIOS does not expect any value except zero into this call, for 2158 * underscan use another entry ProgramOverscan call but when mode 2159 * 1776x1000 with the overscan 72x44 .e.i. 1920x1080 @30 DAL2 is ok, 2160 * but when same ,but 60 Hz there is corruption 2161 * DAL1 does not allow the mode 1776x1000@60 2162 */ 2163 params.ucOverscanRight = (uint8_t)bp_params->h_overscan_right; 2164 params.ucOverscanLeft = (uint8_t)bp_params->h_overscan_left; 2165 params.ucOverscanBottom = (uint8_t)bp_params->v_overscan_bottom; 2166 params.ucOverscanTop = (uint8_t)bp_params->v_overscan_top; 2167 2168 if (0 == bp_params->flags.HSYNC_POSITIVE_POLARITY) 2169 params.susModeMiscInfo.usAccess = 2170 cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_HSYNC_POLARITY); 2171 2172 if (0 == bp_params->flags.VSYNC_POSITIVE_POLARITY) 2173 params.susModeMiscInfo.usAccess = 2174 cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_VSYNC_POLARITY); 2175 2176 if (bp_params->flags.INTERLACE) { 2177 params.susModeMiscInfo.usAccess = 2178 cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_INTERLACE); 2179 2180 /* original DAL code has this condition to apply tis for 2181 * non-TV/CV only due to complex MV testing for possible 2182 * impact 2183 * if (pACParameters->signal != SignalType_YPbPr && 2184 * pACParameters->signal != SignalType_Composite && 2185 * pACParameters->signal != SignalType_SVideo) 2186 */ 2187 /* HW will deduct 0.5 line from 2nd feild. 2188 * i.e. for 1080i, it is 2 lines for 1st field, 2.5 2189 * lines for the 2nd feild. we need input as 5 instead 2190 * of 4, but it is 4 either from Edid data 2191 * (spec CEA 861) or CEA timing table. 2192 */ 2193 params.usV_SyncStart = 2194 cpu_to_le16((uint16_t)(bp_params->v_sync_start + 1)); 2195 } 2196 2197 if (bp_params->flags.HORZ_COUNT_BY_TWO) 2198 params.susModeMiscInfo.usAccess = 2199 cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_DOUBLE_CLOCK_MODE); 2200 2201 if (EXEC_BIOS_CMD_TABLE(SetCRTC_Timing, params)) 2202 result = BP_RESULT_OK; 2203 2204 return result; 2205 } 2206 2207 static enum bp_result set_crtc_using_dtd_timing_v3( 2208 struct bios_parser *bp, 2209 struct bp_hw_crtc_timing_parameters *bp_params) 2210 { 2211 enum bp_result result = BP_RESULT_FAILURE; 2212 SET_CRTC_USING_DTD_TIMING_PARAMETERS params = {0}; 2213 uint8_t atom_controller_id; 2214 2215 if (bp->cmd_helper->controller_id_to_atom( 2216 bp_params->controller_id, &atom_controller_id)) 2217 params.ucCRTC = atom_controller_id; 2218 2219 /* bios usH_Size wants h addressable size */ 2220 params.usH_Size = cpu_to_le16((uint16_t)bp_params->h_addressable); 2221 /* bios usH_Blanking_Time wants borders included in blanking */ 2222 params.usH_Blanking_Time = 2223 cpu_to_le16((uint16_t)(bp_params->h_total - bp_params->h_addressable)); 2224 /* bios usV_Size wants v addressable size */ 2225 params.usV_Size = cpu_to_le16((uint16_t)bp_params->v_addressable); 2226 /* bios usV_Blanking_Time wants borders included in blanking */ 2227 params.usV_Blanking_Time = 2228 cpu_to_le16((uint16_t)(bp_params->v_total - bp_params->v_addressable)); 2229 /* bios usHSyncOffset is the offset from the end of h addressable, 2230 * our horizontalSyncStart is the offset from the beginning 2231 * of h addressable */ 2232 params.usH_SyncOffset = 2233 cpu_to_le16((uint16_t)(bp_params->h_sync_start - bp_params->h_addressable)); 2234 params.usH_SyncWidth = cpu_to_le16((uint16_t)bp_params->h_sync_width); 2235 /* bios usHSyncOffset is the offset from the end of v addressable, 2236 * our verticalSyncStart is the offset from the beginning of 2237 * v addressable */ 2238 params.usV_SyncOffset = 2239 cpu_to_le16((uint16_t)(bp_params->v_sync_start - bp_params->v_addressable)); 2240 params.usV_SyncWidth = cpu_to_le16((uint16_t)bp_params->v_sync_width); 2241 2242 /* we assume that overscan from original timing does not get bigger 2243 * than 255 2244 * we will program all the borders in the Set CRTC Overscan call below 2245 */ 2246 2247 if (0 == bp_params->flags.HSYNC_POSITIVE_POLARITY) 2248 params.susModeMiscInfo.usAccess = 2249 cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_HSYNC_POLARITY); 2250 2251 if (0 == bp_params->flags.VSYNC_POSITIVE_POLARITY) 2252 params.susModeMiscInfo.usAccess = 2253 cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_VSYNC_POLARITY); 2254 2255 if (bp_params->flags.INTERLACE) { 2256 params.susModeMiscInfo.usAccess = 2257 cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_INTERLACE); 2258 2259 /* original DAL code has this condition to apply this 2260 * for non-TV/CV only 2261 * due to complex MV testing for possible impact 2262 * if ( pACParameters->signal != SignalType_YPbPr && 2263 * pACParameters->signal != SignalType_Composite && 2264 * pACParameters->signal != SignalType_SVideo) 2265 */ 2266 { 2267 /* HW will deduct 0.5 line from 2nd feild. 2268 * i.e. for 1080i, it is 2 lines for 1st field, 2269 * 2.5 lines for the 2nd feild. we need input as 5 2270 * instead of 4. 2271 * but it is 4 either from Edid data (spec CEA 861) 2272 * or CEA timing table. 2273 */ 2274 le16_add_cpu(¶ms.usV_SyncOffset, 1); 2275 } 2276 } 2277 2278 if (bp_params->flags.HORZ_COUNT_BY_TWO) 2279 params.susModeMiscInfo.usAccess = 2280 cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_DOUBLE_CLOCK_MODE); 2281 2282 if (EXEC_BIOS_CMD_TABLE(SetCRTC_UsingDTDTiming, params)) 2283 result = BP_RESULT_OK; 2284 2285 return result; 2286 } 2287 2288 /******************************************************************************* 2289 ******************************************************************************** 2290 ** 2291 ** ENABLE CRTC 2292 ** 2293 ******************************************************************************** 2294 *******************************************************************************/ 2295 2296 static enum bp_result enable_crtc_v1( 2297 struct bios_parser *bp, 2298 enum controller_id controller_id, 2299 bool enable); 2300 2301 static void init_enable_crtc(struct bios_parser *bp) 2302 { 2303 switch (BIOS_CMD_TABLE_PARA_REVISION(EnableCRTC)) { 2304 case 1: 2305 bp->cmd_tbl.enable_crtc = enable_crtc_v1; 2306 break; 2307 default: 2308 dm_output_to_console("Don't have enable_crtc for v%d\n", 2309 BIOS_CMD_TABLE_PARA_REVISION(EnableCRTC)); 2310 bp->cmd_tbl.enable_crtc = NULL; 2311 break; 2312 } 2313 } 2314 2315 static enum bp_result enable_crtc_v1( 2316 struct bios_parser *bp, 2317 enum controller_id controller_id, 2318 bool enable) 2319 { 2320 bool result = BP_RESULT_FAILURE; 2321 ENABLE_CRTC_PARAMETERS params = {0}; 2322 uint8_t id; 2323 2324 if (bp->cmd_helper->controller_id_to_atom(controller_id, &id)) 2325 params.ucCRTC = id; 2326 else 2327 return BP_RESULT_BADINPUT; 2328 2329 if (enable) 2330 params.ucEnable = ATOM_ENABLE; 2331 else 2332 params.ucEnable = ATOM_DISABLE; 2333 2334 if (EXEC_BIOS_CMD_TABLE(EnableCRTC, params)) 2335 result = BP_RESULT_OK; 2336 2337 return result; 2338 } 2339 2340 /******************************************************************************* 2341 ******************************************************************************** 2342 ** 2343 ** ENABLE CRTC MEM REQ 2344 ** 2345 ******************************************************************************** 2346 *******************************************************************************/ 2347 2348 static enum bp_result enable_crtc_mem_req_v1( 2349 struct bios_parser *bp, 2350 enum controller_id controller_id, 2351 bool enable); 2352 2353 static void init_enable_crtc_mem_req(struct bios_parser *bp) 2354 { 2355 switch (BIOS_CMD_TABLE_PARA_REVISION(EnableCRTCMemReq)) { 2356 case 1: 2357 bp->cmd_tbl.enable_crtc_mem_req = enable_crtc_mem_req_v1; 2358 break; 2359 default: 2360 bp->cmd_tbl.enable_crtc_mem_req = NULL; 2361 break; 2362 } 2363 } 2364 2365 static enum bp_result enable_crtc_mem_req_v1( 2366 struct bios_parser *bp, 2367 enum controller_id controller_id, 2368 bool enable) 2369 { 2370 bool result = BP_RESULT_BADINPUT; 2371 ENABLE_CRTC_PARAMETERS params = {0}; 2372 uint8_t id; 2373 2374 if (bp->cmd_helper->controller_id_to_atom(controller_id, &id)) { 2375 params.ucCRTC = id; 2376 2377 if (enable) 2378 params.ucEnable = ATOM_ENABLE; 2379 else 2380 params.ucEnable = ATOM_DISABLE; 2381 2382 if (EXEC_BIOS_CMD_TABLE(EnableCRTCMemReq, params)) 2383 result = BP_RESULT_OK; 2384 else 2385 result = BP_RESULT_FAILURE; 2386 } 2387 2388 return result; 2389 } 2390 2391 /******************************************************************************* 2392 ******************************************************************************** 2393 ** 2394 ** DISPLAY PLL 2395 ** 2396 ******************************************************************************** 2397 *******************************************************************************/ 2398 2399 static enum bp_result program_clock_v5( 2400 struct bios_parser *bp, 2401 struct bp_pixel_clock_parameters *bp_params); 2402 static enum bp_result program_clock_v6( 2403 struct bios_parser *bp, 2404 struct bp_pixel_clock_parameters *bp_params); 2405 2406 static void init_program_clock(struct bios_parser *bp) 2407 { 2408 switch (BIOS_CMD_TABLE_PARA_REVISION(SetPixelClock)) { 2409 case 5: 2410 bp->cmd_tbl.program_clock = program_clock_v5; 2411 break; 2412 case 6: 2413 bp->cmd_tbl.program_clock = program_clock_v6; 2414 break; 2415 default: 2416 dm_output_to_console("Don't have program_clock for v%d\n", 2417 BIOS_CMD_TABLE_PARA_REVISION(SetPixelClock)); 2418 bp->cmd_tbl.program_clock = NULL; 2419 break; 2420 } 2421 } 2422 2423 static enum bp_result program_clock_v5( 2424 struct bios_parser *bp, 2425 struct bp_pixel_clock_parameters *bp_params) 2426 { 2427 enum bp_result result = BP_RESULT_FAILURE; 2428 2429 SET_PIXEL_CLOCK_PS_ALLOCATION_V5 params; 2430 uint32_t atom_pll_id; 2431 2432 memset(¶ms, 0, sizeof(params)); 2433 if (!bp->cmd_helper->clock_source_id_to_atom( 2434 bp_params->pll_id, &atom_pll_id)) { 2435 BREAK_TO_DEBUGGER(); /* Invalid Input!! */ 2436 return BP_RESULT_BADINPUT; 2437 } 2438 2439 /* We need to convert from KHz units into 10KHz units */ 2440 params.sPCLKInput.ucPpll = (uint8_t) atom_pll_id; 2441 params.sPCLKInput.usPixelClock = 2442 cpu_to_le16((uint16_t) (bp_params->target_pixel_clock_100hz / 100)); 2443 params.sPCLKInput.ucCRTC = (uint8_t) ATOM_CRTC_INVALID; 2444 2445 if (bp_params->flags.SET_EXTERNAL_REF_DIV_SRC) 2446 params.sPCLKInput.ucMiscInfo |= PIXEL_CLOCK_MISC_REF_DIV_SRC; 2447 2448 if (EXEC_BIOS_CMD_TABLE(SetPixelClock, params)) 2449 result = BP_RESULT_OK; 2450 2451 return result; 2452 } 2453 2454 static enum bp_result program_clock_v6( 2455 struct bios_parser *bp, 2456 struct bp_pixel_clock_parameters *bp_params) 2457 { 2458 enum bp_result result = BP_RESULT_FAILURE; 2459 2460 SET_PIXEL_CLOCK_PS_ALLOCATION_V6 params; 2461 uint32_t atom_pll_id; 2462 2463 memset(¶ms, 0, sizeof(params)); 2464 2465 if (!bp->cmd_helper->clock_source_id_to_atom( 2466 bp_params->pll_id, &atom_pll_id)) { 2467 BREAK_TO_DEBUGGER(); /*Invalid Input!!*/ 2468 return BP_RESULT_BADINPUT; 2469 } 2470 2471 /* We need to convert from KHz units into 10KHz units */ 2472 params.sPCLKInput.ucPpll = (uint8_t)atom_pll_id; 2473 params.sPCLKInput.ulDispEngClkFreq = 2474 cpu_to_le32(bp_params->target_pixel_clock_100hz / 100); 2475 2476 if (bp_params->flags.SET_EXTERNAL_REF_DIV_SRC) 2477 params.sPCLKInput.ucMiscInfo |= PIXEL_CLOCK_MISC_REF_DIV_SRC; 2478 2479 if (bp_params->flags.SET_DISPCLK_DFS_BYPASS) 2480 params.sPCLKInput.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_DPREFCLK_BYPASS; 2481 2482 if (EXEC_BIOS_CMD_TABLE(SetPixelClock, params)) { 2483 /* True display clock is returned by VBIOS if DFS bypass 2484 * is enabled. */ 2485 bp_params->dfs_bypass_display_clock = 2486 (uint32_t)(le32_to_cpu(params.sPCLKInput.ulDispEngClkFreq) * 10); 2487 result = BP_RESULT_OK; 2488 } 2489 2490 return result; 2491 } 2492 2493 /******************************************************************************* 2494 ******************************************************************************** 2495 ** 2496 ** EXTERNAL ENCODER CONTROL 2497 ** 2498 ******************************************************************************** 2499 *******************************************************************************/ 2500 2501 static enum bp_result external_encoder_control_v3( 2502 struct bios_parser *bp, 2503 struct bp_external_encoder_control *cntl); 2504 2505 static void init_external_encoder_control( 2506 struct bios_parser *bp) 2507 { 2508 switch (BIOS_CMD_TABLE_PARA_REVISION(ExternalEncoderControl)) { 2509 case 3: 2510 bp->cmd_tbl.external_encoder_control = 2511 external_encoder_control_v3; 2512 break; 2513 default: 2514 bp->cmd_tbl.external_encoder_control = NULL; 2515 break; 2516 } 2517 } 2518 2519 static enum bp_result external_encoder_control_v3( 2520 struct bios_parser *bp, 2521 struct bp_external_encoder_control *cntl) 2522 { 2523 enum bp_result result = BP_RESULT_FAILURE; 2524 2525 /* we need use _PS_Alloc struct */ 2526 EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION_V3 params; 2527 EXTERNAL_ENCODER_CONTROL_PARAMETERS_V3 *cntl_params; 2528 struct graphics_object_id encoder; 2529 bool is_input_signal_dp = false; 2530 2531 memset(¶ms, 0, sizeof(params)); 2532 2533 cntl_params = ¶ms.sExtEncoder; 2534 2535 encoder = cntl->encoder_id; 2536 2537 /* check if encoder supports external encoder control table */ 2538 switch (dal_graphics_object_id_get_encoder_id(encoder)) { 2539 case ENCODER_ID_EXTERNAL_NUTMEG: 2540 case ENCODER_ID_EXTERNAL_TRAVIS: 2541 is_input_signal_dp = true; 2542 break; 2543 2544 default: 2545 BREAK_TO_DEBUGGER(); 2546 return BP_RESULT_BADINPUT; 2547 } 2548 2549 /* Fill information based on the action 2550 * 2551 * Bit[6:4]: indicate external encoder, applied to all functions. 2552 * =0: external encoder1, mapped to external encoder enum id1 2553 * =1: external encoder2, mapped to external encoder enum id2 2554 * 2555 * enum ObjectEnumId 2556 * { 2557 * EnumId_Unknown = 0, 2558 * EnumId_1, 2559 * EnumId_2, 2560 * }; 2561 */ 2562 cntl_params->ucConfig = (uint8_t)((encoder.enum_id - 1) << 4); 2563 2564 switch (cntl->action) { 2565 case EXTERNAL_ENCODER_CONTROL_INIT: 2566 /* output display connector type. Only valid in encoder 2567 * initialization */ 2568 cntl_params->usConnectorId = 2569 cpu_to_le16((uint16_t)cntl->connector_obj_id.id); 2570 break; 2571 case EXTERNAL_ENCODER_CONTROL_SETUP: 2572 /* EXTERNAL_ENCODER_CONTROL_PARAMETERS_V3 pixel clock unit in 2573 * 10KHz 2574 * output display device pixel clock frequency in unit of 10KHz. 2575 * Only valid in setup and enableoutput 2576 */ 2577 cntl_params->usPixelClock = 2578 cpu_to_le16((uint16_t)(cntl->pixel_clock / 10)); 2579 /* Indicate display output signal type drive by external 2580 * encoder, only valid in setup and enableoutput */ 2581 cntl_params->ucEncoderMode = 2582 (uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom( 2583 cntl->signal, false); 2584 2585 if (is_input_signal_dp) { 2586 /* Bit[0]: indicate link rate, =1: 2.7Ghz, =0: 1.62Ghz, 2587 * only valid in encoder setup with DP mode. */ 2588 if (LINK_RATE_HIGH == cntl->link_rate) 2589 cntl_params->ucConfig |= 1; 2590 /* output color depth Indicate encoder data bpc format 2591 * in DP mode, only valid in encoder setup in DP mode. 2592 */ 2593 cntl_params->ucBitPerColor = 2594 (uint8_t)(cntl->color_depth); 2595 } 2596 /* Indicate how many lanes used by external encoder, only valid 2597 * in encoder setup and enableoutput. */ 2598 cntl_params->ucLaneNum = (uint8_t)(cntl->lanes_number); 2599 break; 2600 case EXTERNAL_ENCODER_CONTROL_ENABLE: 2601 cntl_params->usPixelClock = 2602 cpu_to_le16((uint16_t)(cntl->pixel_clock / 10)); 2603 cntl_params->ucEncoderMode = 2604 (uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom( 2605 cntl->signal, false); 2606 cntl_params->ucLaneNum = (uint8_t)cntl->lanes_number; 2607 break; 2608 default: 2609 break; 2610 } 2611 2612 cntl_params->ucAction = (uint8_t)cntl->action; 2613 2614 if (EXEC_BIOS_CMD_TABLE(ExternalEncoderControl, params)) 2615 result = BP_RESULT_OK; 2616 2617 return result; 2618 } 2619 2620 /******************************************************************************* 2621 ******************************************************************************** 2622 ** 2623 ** ENABLE DISPLAY POWER GATING 2624 ** 2625 ******************************************************************************** 2626 *******************************************************************************/ 2627 2628 static enum bp_result enable_disp_power_gating_v2_1( 2629 struct bios_parser *bp, 2630 enum controller_id crtc_id, 2631 enum bp_pipe_control_action action); 2632 2633 static void init_enable_disp_power_gating( 2634 struct bios_parser *bp) 2635 { 2636 switch (BIOS_CMD_TABLE_PARA_REVISION(EnableDispPowerGating)) { 2637 case 1: 2638 bp->cmd_tbl.enable_disp_power_gating = 2639 enable_disp_power_gating_v2_1; 2640 break; 2641 default: 2642 dm_output_to_console("Don't enable_disp_power_gating enable_crtc for v%d\n", 2643 BIOS_CMD_TABLE_PARA_REVISION(EnableDispPowerGating)); 2644 bp->cmd_tbl.enable_disp_power_gating = NULL; 2645 break; 2646 } 2647 } 2648 2649 static enum bp_result enable_disp_power_gating_v2_1( 2650 struct bios_parser *bp, 2651 enum controller_id crtc_id, 2652 enum bp_pipe_control_action action) 2653 { 2654 enum bp_result result = BP_RESULT_FAILURE; 2655 2656 ENABLE_DISP_POWER_GATING_PS_ALLOCATION params = {0}; 2657 uint8_t atom_crtc_id; 2658 2659 if (bp->cmd_helper->controller_id_to_atom(crtc_id, &atom_crtc_id)) 2660 params.ucDispPipeId = atom_crtc_id; 2661 else 2662 return BP_RESULT_BADINPUT; 2663 2664 params.ucEnable = 2665 bp->cmd_helper->disp_power_gating_action_to_atom(action); 2666 2667 if (EXEC_BIOS_CMD_TABLE(EnableDispPowerGating, params)) 2668 result = BP_RESULT_OK; 2669 2670 return result; 2671 } 2672 2673 /******************************************************************************* 2674 ******************************************************************************** 2675 ** 2676 ** SET DCE CLOCK 2677 ** 2678 ******************************************************************************** 2679 *******************************************************************************/ 2680 static enum bp_result set_dce_clock_v2_1( 2681 struct bios_parser *bp, 2682 struct bp_set_dce_clock_parameters *bp_params); 2683 2684 static void init_set_dce_clock(struct bios_parser *bp) 2685 { 2686 switch (BIOS_CMD_TABLE_PARA_REVISION(SetDCEClock)) { 2687 case 1: 2688 bp->cmd_tbl.set_dce_clock = set_dce_clock_v2_1; 2689 break; 2690 default: 2691 dm_output_to_console("Don't have set_dce_clock for v%d\n", 2692 BIOS_CMD_TABLE_PARA_REVISION(SetDCEClock)); 2693 bp->cmd_tbl.set_dce_clock = NULL; 2694 break; 2695 } 2696 } 2697 2698 static enum bp_result set_dce_clock_v2_1( 2699 struct bios_parser *bp, 2700 struct bp_set_dce_clock_parameters *bp_params) 2701 { 2702 enum bp_result result = BP_RESULT_FAILURE; 2703 2704 SET_DCE_CLOCK_PS_ALLOCATION_V2_1 params; 2705 uint32_t atom_pll_id; 2706 uint32_t atom_clock_type; 2707 const struct command_table_helper *cmd = bp->cmd_helper; 2708 2709 memset(¶ms, 0, sizeof(params)); 2710 2711 if (!cmd->clock_source_id_to_atom(bp_params->pll_id, &atom_pll_id) || 2712 !cmd->dc_clock_type_to_atom(bp_params->clock_type, &atom_clock_type)) 2713 return BP_RESULT_BADINPUT; 2714 2715 params.asParam.ucDCEClkSrc = atom_pll_id; 2716 params.asParam.ucDCEClkType = atom_clock_type; 2717 2718 if (bp_params->clock_type == DCECLOCK_TYPE_DPREFCLK) { 2719 if (bp_params->flags.USE_GENLOCK_AS_SOURCE_FOR_DPREFCLK) 2720 params.asParam.ucDCEClkFlag |= DCE_CLOCK_FLAG_PLL_REFCLK_SRC_GENLK; 2721 2722 if (bp_params->flags.USE_PCIE_AS_SOURCE_FOR_DPREFCLK) 2723 params.asParam.ucDCEClkFlag |= DCE_CLOCK_FLAG_PLL_REFCLK_SRC_PCIE; 2724 2725 if (bp_params->flags.USE_XTALIN_AS_SOURCE_FOR_DPREFCLK) 2726 params.asParam.ucDCEClkFlag |= DCE_CLOCK_FLAG_PLL_REFCLK_SRC_XTALIN; 2727 2728 if (bp_params->flags.USE_GENERICA_AS_SOURCE_FOR_DPREFCLK) 2729 params.asParam.ucDCEClkFlag |= DCE_CLOCK_FLAG_PLL_REFCLK_SRC_GENERICA; 2730 } 2731 else 2732 /* only program clock frequency if display clock is used; VBIOS will program DPREFCLK */ 2733 /* We need to convert from KHz units into 10KHz units */ 2734 params.asParam.ulDCEClkFreq = cpu_to_le32(bp_params->target_clock_frequency / 10); 2735 2736 if (EXEC_BIOS_CMD_TABLE(SetDCEClock, params)) { 2737 /* Convert from 10KHz units back to KHz */ 2738 bp_params->target_clock_frequency = le32_to_cpu(params.asParam.ulDCEClkFreq) * 10; 2739 result = BP_RESULT_OK; 2740 } 2741 2742 return result; 2743 } 2744