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