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