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