0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026 #include "dm_services.h"
0027 #include "amdgpu.h"
0028 #include "atom.h"
0029
0030 #include "include/bios_parser_interface.h"
0031
0032 #include "command_table.h"
0033 #include "command_table_helper.h"
0034 #include "bios_parser_helper.h"
0035 #include "bios_parser_types_internal.h"
0036
0037 #define EXEC_BIOS_CMD_TABLE(command, params)\
0038 (amdgpu_atom_execute_table(((struct amdgpu_device *)bp->base.ctx->driver_context)->mode_info.atom_context, \
0039 GetIndexIntoMasterTable(COMMAND, command), \
0040 (uint32_t *)¶ms) == 0)
0041
0042 #define BIOS_CMD_TABLE_REVISION(command, frev, crev)\
0043 amdgpu_atom_parse_cmd_header(((struct amdgpu_device *)bp->base.ctx->driver_context)->mode_info.atom_context, \
0044 GetIndexIntoMasterTable(COMMAND, command), &frev, &crev)
0045
0046 #define BIOS_CMD_TABLE_PARA_REVISION(command)\
0047 bios_cmd_table_para_revision(bp->base.ctx->driver_context, \
0048 GetIndexIntoMasterTable(COMMAND, command))
0049
0050 static void init_dig_encoder_control(struct bios_parser *bp);
0051 static void init_transmitter_control(struct bios_parser *bp);
0052 static void init_set_pixel_clock(struct bios_parser *bp);
0053 static void init_enable_spread_spectrum_on_ppll(struct bios_parser *bp);
0054 static void init_adjust_display_pll(struct bios_parser *bp);
0055 static void init_dac_encoder_control(struct bios_parser *bp);
0056 static void init_dac_output_control(struct bios_parser *bp);
0057 static void init_set_crtc_timing(struct bios_parser *bp);
0058 static void init_enable_crtc(struct bios_parser *bp);
0059 static void init_enable_crtc_mem_req(struct bios_parser *bp);
0060 static void init_external_encoder_control(struct bios_parser *bp);
0061 static void init_enable_disp_power_gating(struct bios_parser *bp);
0062 static void init_program_clock(struct bios_parser *bp);
0063 static void init_set_dce_clock(struct bios_parser *bp);
0064
0065 void dal_bios_parser_init_cmd_tbl(struct bios_parser *bp)
0066 {
0067 init_dig_encoder_control(bp);
0068 init_transmitter_control(bp);
0069 init_set_pixel_clock(bp);
0070 init_enable_spread_spectrum_on_ppll(bp);
0071 init_adjust_display_pll(bp);
0072 init_dac_encoder_control(bp);
0073 init_dac_output_control(bp);
0074 init_set_crtc_timing(bp);
0075 init_enable_crtc(bp);
0076 init_enable_crtc_mem_req(bp);
0077 init_program_clock(bp);
0078 init_external_encoder_control(bp);
0079 init_enable_disp_power_gating(bp);
0080 init_set_dce_clock(bp);
0081 }
0082
0083 static uint32_t bios_cmd_table_para_revision(void *dev,
0084 uint32_t index)
0085 {
0086 struct amdgpu_device *adev = dev;
0087 uint8_t frev, crev;
0088
0089 if (amdgpu_atom_parse_cmd_header(adev->mode_info.atom_context,
0090 index,
0091 &frev, &crev))
0092 return crev;
0093 else
0094 return 0;
0095 }
0096
0097
0098
0099
0100
0101
0102
0103
0104 static enum bp_result encoder_control_digx_v3(
0105 struct bios_parser *bp,
0106 struct bp_encoder_control *cntl);
0107
0108 static enum bp_result encoder_control_digx_v4(
0109 struct bios_parser *bp,
0110 struct bp_encoder_control *cntl);
0111
0112 static enum bp_result encoder_control_digx_v5(
0113 struct bios_parser *bp,
0114 struct bp_encoder_control *cntl);
0115
0116 static void init_encoder_control_dig_v1(struct bios_parser *bp);
0117
0118 static void init_dig_encoder_control(struct bios_parser *bp)
0119 {
0120 uint32_t version =
0121 BIOS_CMD_TABLE_PARA_REVISION(DIGxEncoderControl);
0122
0123 switch (version) {
0124 case 2:
0125 bp->cmd_tbl.dig_encoder_control = encoder_control_digx_v3;
0126 break;
0127 case 4:
0128 bp->cmd_tbl.dig_encoder_control = encoder_control_digx_v4;
0129 break;
0130
0131 case 5:
0132 bp->cmd_tbl.dig_encoder_control = encoder_control_digx_v5;
0133 break;
0134
0135 default:
0136 init_encoder_control_dig_v1(bp);
0137 break;
0138 }
0139 }
0140
0141 static enum bp_result encoder_control_dig_v1(
0142 struct bios_parser *bp,
0143 struct bp_encoder_control *cntl);
0144 static enum bp_result encoder_control_dig1_v1(
0145 struct bios_parser *bp,
0146 struct bp_encoder_control *cntl);
0147 static enum bp_result encoder_control_dig2_v1(
0148 struct bios_parser *bp,
0149 struct bp_encoder_control *cntl);
0150
0151 static void init_encoder_control_dig_v1(struct bios_parser *bp)
0152 {
0153 struct cmd_tbl *cmd_tbl = &bp->cmd_tbl;
0154
0155 if (1 == BIOS_CMD_TABLE_PARA_REVISION(DIG1EncoderControl))
0156 cmd_tbl->encoder_control_dig1 = encoder_control_dig1_v1;
0157 else
0158 cmd_tbl->encoder_control_dig1 = NULL;
0159
0160 if (1 == BIOS_CMD_TABLE_PARA_REVISION(DIG2EncoderControl))
0161 cmd_tbl->encoder_control_dig2 = encoder_control_dig2_v1;
0162 else
0163 cmd_tbl->encoder_control_dig2 = NULL;
0164
0165 cmd_tbl->dig_encoder_control = encoder_control_dig_v1;
0166 }
0167
0168 static enum bp_result encoder_control_dig_v1(
0169 struct bios_parser *bp,
0170 struct bp_encoder_control *cntl)
0171 {
0172 enum bp_result result = BP_RESULT_FAILURE;
0173 struct cmd_tbl *cmd_tbl = &bp->cmd_tbl;
0174
0175 if (cntl != NULL)
0176 switch (cntl->engine_id) {
0177 case ENGINE_ID_DIGA:
0178 if (cmd_tbl->encoder_control_dig1 != NULL)
0179 result =
0180 cmd_tbl->encoder_control_dig1(bp, cntl);
0181 break;
0182 case ENGINE_ID_DIGB:
0183 if (cmd_tbl->encoder_control_dig2 != NULL)
0184 result =
0185 cmd_tbl->encoder_control_dig2(bp, cntl);
0186 break;
0187
0188 default:
0189 break;
0190 }
0191
0192 return result;
0193 }
0194
0195 static enum bp_result encoder_control_dig1_v1(
0196 struct bios_parser *bp,
0197 struct bp_encoder_control *cntl)
0198 {
0199 enum bp_result result = BP_RESULT_FAILURE;
0200 DIG_ENCODER_CONTROL_PARAMETERS_V2 params = {0};
0201
0202 bp->cmd_helper->assign_control_parameter(bp->cmd_helper, cntl, ¶ms);
0203
0204 if (EXEC_BIOS_CMD_TABLE(DIG1EncoderControl, params))
0205 result = BP_RESULT_OK;
0206
0207 return result;
0208 }
0209
0210 static enum bp_result encoder_control_dig2_v1(
0211 struct bios_parser *bp,
0212 struct bp_encoder_control *cntl)
0213 {
0214 enum bp_result result = BP_RESULT_FAILURE;
0215 DIG_ENCODER_CONTROL_PARAMETERS_V2 params = {0};
0216
0217 bp->cmd_helper->assign_control_parameter(bp->cmd_helper, cntl, ¶ms);
0218
0219 if (EXEC_BIOS_CMD_TABLE(DIG2EncoderControl, params))
0220 result = BP_RESULT_OK;
0221
0222 return result;
0223 }
0224
0225 static enum bp_result encoder_control_digx_v3(
0226 struct bios_parser *bp,
0227 struct bp_encoder_control *cntl)
0228 {
0229 enum bp_result result = BP_RESULT_FAILURE;
0230 DIG_ENCODER_CONTROL_PARAMETERS_V3 params = {0};
0231
0232 if (LANE_COUNT_FOUR < cntl->lanes_number)
0233 params.acConfig.ucDPLinkRate = 1;
0234 else
0235 params.acConfig.ucDPLinkRate = 0;
0236
0237 params.acConfig.ucDigSel = (uint8_t)(cntl->engine_id);
0238
0239
0240 params.ucAction = bp->cmd_helper->encoder_action_to_atom(cntl->action);
0241 params.usPixelClock = cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
0242 params.ucEncoderMode =
0243 (uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom(
0244 cntl->signal,
0245 cntl->enable_dp_audio);
0246 params.ucLaneNum = (uint8_t)(cntl->lanes_number);
0247
0248 switch (cntl->color_depth) {
0249 case COLOR_DEPTH_888:
0250 params.ucBitPerColor = PANEL_8BIT_PER_COLOR;
0251 break;
0252 case COLOR_DEPTH_101010:
0253 params.ucBitPerColor = PANEL_10BIT_PER_COLOR;
0254 break;
0255 case COLOR_DEPTH_121212:
0256 params.ucBitPerColor = PANEL_12BIT_PER_COLOR;
0257 break;
0258 case COLOR_DEPTH_161616:
0259 params.ucBitPerColor = PANEL_16BIT_PER_COLOR;
0260 break;
0261 default:
0262 break;
0263 }
0264
0265 if (EXEC_BIOS_CMD_TABLE(DIGxEncoderControl, params))
0266 result = BP_RESULT_OK;
0267
0268 return result;
0269 }
0270
0271 static enum bp_result encoder_control_digx_v4(
0272 struct bios_parser *bp,
0273 struct bp_encoder_control *cntl)
0274 {
0275 enum bp_result result = BP_RESULT_FAILURE;
0276 DIG_ENCODER_CONTROL_PARAMETERS_V4 params = {0};
0277
0278 if (LANE_COUNT_FOUR < cntl->lanes_number)
0279 params.acConfig.ucDPLinkRate = 1;
0280 else
0281 params.acConfig.ucDPLinkRate = 0;
0282
0283 params.acConfig.ucDigSel = (uint8_t)(cntl->engine_id);
0284
0285
0286 params.ucAction = bp->cmd_helper->encoder_action_to_atom(cntl->action);
0287 params.usPixelClock = cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
0288 params.ucEncoderMode =
0289 (uint8_t)(bp->cmd_helper->encoder_mode_bp_to_atom(
0290 cntl->signal,
0291 cntl->enable_dp_audio));
0292 params.ucLaneNum = (uint8_t)(cntl->lanes_number);
0293
0294 switch (cntl->color_depth) {
0295 case COLOR_DEPTH_888:
0296 params.ucBitPerColor = PANEL_8BIT_PER_COLOR;
0297 break;
0298 case COLOR_DEPTH_101010:
0299 params.ucBitPerColor = PANEL_10BIT_PER_COLOR;
0300 break;
0301 case COLOR_DEPTH_121212:
0302 params.ucBitPerColor = PANEL_12BIT_PER_COLOR;
0303 break;
0304 case COLOR_DEPTH_161616:
0305 params.ucBitPerColor = PANEL_16BIT_PER_COLOR;
0306 break;
0307 default:
0308 break;
0309 }
0310
0311 if (EXEC_BIOS_CMD_TABLE(DIGxEncoderControl, params))
0312 result = BP_RESULT_OK;
0313
0314 return result;
0315 }
0316
0317 static enum bp_result encoder_control_digx_v5(
0318 struct bios_parser *bp,
0319 struct bp_encoder_control *cntl)
0320 {
0321 enum bp_result result = BP_RESULT_FAILURE;
0322 ENCODER_STREAM_SETUP_PARAMETERS_V5 params = {0};
0323
0324 params.ucDigId = (uint8_t)(cntl->engine_id);
0325 params.ucAction = bp->cmd_helper->encoder_action_to_atom(cntl->action);
0326
0327 params.ulPixelClock = cntl->pixel_clock / 10;
0328 params.ucDigMode =
0329 (uint8_t)(bp->cmd_helper->encoder_mode_bp_to_atom(
0330 cntl->signal,
0331 cntl->enable_dp_audio));
0332 params.ucLaneNum = (uint8_t)(cntl->lanes_number);
0333
0334 switch (cntl->color_depth) {
0335 case COLOR_DEPTH_888:
0336 params.ucBitPerColor = PANEL_8BIT_PER_COLOR;
0337 break;
0338 case COLOR_DEPTH_101010:
0339 params.ucBitPerColor = PANEL_10BIT_PER_COLOR;
0340 break;
0341 case COLOR_DEPTH_121212:
0342 params.ucBitPerColor = PANEL_12BIT_PER_COLOR;
0343 break;
0344 case COLOR_DEPTH_161616:
0345 params.ucBitPerColor = PANEL_16BIT_PER_COLOR;
0346 break;
0347 default:
0348 break;
0349 }
0350
0351 if (cntl->signal == SIGNAL_TYPE_HDMI_TYPE_A)
0352 switch (cntl->color_depth) {
0353 case COLOR_DEPTH_101010:
0354 params.ulPixelClock =
0355 (params.ulPixelClock * 30) / 24;
0356 break;
0357 case COLOR_DEPTH_121212:
0358 params.ulPixelClock =
0359 (params.ulPixelClock * 36) / 24;
0360 break;
0361 case COLOR_DEPTH_161616:
0362 params.ulPixelClock =
0363 (params.ulPixelClock * 48) / 24;
0364 break;
0365 default:
0366 break;
0367 }
0368
0369 if (EXEC_BIOS_CMD_TABLE(DIGxEncoderControl, params))
0370 result = BP_RESULT_OK;
0371
0372 return result;
0373 }
0374
0375
0376
0377
0378
0379
0380
0381
0382
0383 static enum bp_result transmitter_control_v2(
0384 struct bios_parser *bp,
0385 struct bp_transmitter_control *cntl);
0386 static enum bp_result transmitter_control_v3(
0387 struct bios_parser *bp,
0388 struct bp_transmitter_control *cntl);
0389 static enum bp_result transmitter_control_v4(
0390 struct bios_parser *bp,
0391 struct bp_transmitter_control *cntl);
0392 static enum bp_result transmitter_control_v1_5(
0393 struct bios_parser *bp,
0394 struct bp_transmitter_control *cntl);
0395 static enum bp_result transmitter_control_v1_6(
0396 struct bios_parser *bp,
0397 struct bp_transmitter_control *cntl);
0398
0399 static void init_transmitter_control(struct bios_parser *bp)
0400 {
0401 uint8_t frev;
0402 uint8_t crev;
0403
0404 if (BIOS_CMD_TABLE_REVISION(UNIPHYTransmitterControl,
0405 frev, crev) == false)
0406 BREAK_TO_DEBUGGER();
0407 switch (crev) {
0408 case 2:
0409 bp->cmd_tbl.transmitter_control = transmitter_control_v2;
0410 break;
0411 case 3:
0412 bp->cmd_tbl.transmitter_control = transmitter_control_v3;
0413 break;
0414 case 4:
0415 bp->cmd_tbl.transmitter_control = transmitter_control_v4;
0416 break;
0417 case 5:
0418 bp->cmd_tbl.transmitter_control = transmitter_control_v1_5;
0419 break;
0420 case 6:
0421 bp->cmd_tbl.transmitter_control = transmitter_control_v1_6;
0422 break;
0423 default:
0424 dm_output_to_console("Don't have transmitter_control for v%d\n", crev);
0425 bp->cmd_tbl.transmitter_control = NULL;
0426 break;
0427 }
0428 }
0429
0430 static enum bp_result transmitter_control_v2(
0431 struct bios_parser *bp,
0432 struct bp_transmitter_control *cntl)
0433 {
0434 enum bp_result result = BP_RESULT_FAILURE;
0435 DIG_TRANSMITTER_CONTROL_PARAMETERS_V2 params;
0436 enum connector_id connector_id =
0437 dal_graphics_object_id_get_connector_id(cntl->connector_obj_id);
0438
0439 memset(¶ms, 0, sizeof(params));
0440
0441 switch (cntl->transmitter) {
0442 case TRANSMITTER_UNIPHY_A:
0443 case TRANSMITTER_UNIPHY_B:
0444 case TRANSMITTER_UNIPHY_C:
0445 case TRANSMITTER_UNIPHY_D:
0446 case TRANSMITTER_UNIPHY_E:
0447 case TRANSMITTER_UNIPHY_F:
0448 case TRANSMITTER_TRAVIS_LCD:
0449 break;
0450 default:
0451 return BP_RESULT_BADINPUT;
0452 }
0453
0454 switch (cntl->action) {
0455 case TRANSMITTER_CONTROL_INIT:
0456 if ((CONNECTOR_ID_DUAL_LINK_DVII == connector_id) ||
0457 (CONNECTOR_ID_DUAL_LINK_DVID == connector_id))
0458
0459
0460
0461
0462
0463
0464 params.acConfig.fDualLinkConnector = 1;
0465
0466
0467 params.usInitInfo =
0468 cpu_to_le16((uint8_t)cntl->connector_obj_id.id);
0469 break;
0470 case TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS:
0471
0472 params.asMode.ucLaneSel = (uint8_t)cntl->lane_select;
0473 params.asMode.ucLaneSet = (uint8_t)cntl->lane_settings;
0474 break;
0475 default:
0476
0477 if (LANE_COUNT_FOUR < cntl->lanes_number) {
0478
0479
0480
0481
0482
0483
0484 params.acConfig.fDualLinkConnector = 1;
0485
0486
0487
0488
0489 params.usPixelClock =
0490 cpu_to_le16((uint16_t)(cntl->pixel_clock / 20));
0491 } else
0492
0493
0494
0495 params.usPixelClock =
0496 cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
0497 break;
0498 }
0499
0500
0501
0502
0503
0504 params.acConfig.fCoherentMode = cntl->coherent;
0505
0506 if ((TRANSMITTER_UNIPHY_B == cntl->transmitter)
0507 || (TRANSMITTER_UNIPHY_D == cntl->transmitter)
0508 || (TRANSMITTER_UNIPHY_F == cntl->transmitter))
0509
0510
0511
0512
0513
0514
0515 params.acConfig.ucLinkSel = 1;
0516
0517 if (ENGINE_ID_DIGB == cntl->engine_id)
0518
0519
0520
0521
0522
0523 params.acConfig.ucEncoderSel = 1;
0524
0525 if (CONNECTOR_ID_DISPLAY_PORT == connector_id ||
0526 CONNECTOR_ID_USBC == connector_id)
0527
0528
0529
0530
0531 params.acConfig.fDPConnector = 1;
0532
0533
0534
0535
0536
0537
0538
0539 params.acConfig.ucTransmitterSel =
0540 (uint8_t)bp->cmd_helper->transmitter_bp_to_atom(
0541 cntl->transmitter);
0542
0543 params.ucAction = (uint8_t)cntl->action;
0544
0545 if (EXEC_BIOS_CMD_TABLE(UNIPHYTransmitterControl, params))
0546 result = BP_RESULT_OK;
0547
0548 return result;
0549 }
0550
0551 static enum bp_result transmitter_control_v3(
0552 struct bios_parser *bp,
0553 struct bp_transmitter_control *cntl)
0554 {
0555 enum bp_result result = BP_RESULT_FAILURE;
0556 DIG_TRANSMITTER_CONTROL_PARAMETERS_V3 params;
0557 uint32_t pll_id;
0558 enum connector_id conn_id =
0559 dal_graphics_object_id_get_connector_id(cntl->connector_obj_id);
0560 const struct command_table_helper *cmd = bp->cmd_helper;
0561 bool dual_link_conn = (CONNECTOR_ID_DUAL_LINK_DVII == conn_id)
0562 || (CONNECTOR_ID_DUAL_LINK_DVID == conn_id);
0563
0564 memset(¶ms, 0, sizeof(params));
0565
0566 switch (cntl->transmitter) {
0567 case TRANSMITTER_UNIPHY_A:
0568 case TRANSMITTER_UNIPHY_B:
0569 case TRANSMITTER_UNIPHY_C:
0570 case TRANSMITTER_UNIPHY_D:
0571 case TRANSMITTER_UNIPHY_E:
0572 case TRANSMITTER_UNIPHY_F:
0573 case TRANSMITTER_TRAVIS_LCD:
0574 break;
0575 default:
0576 return BP_RESULT_BADINPUT;
0577 }
0578
0579 if (!cmd->clock_source_id_to_atom(cntl->pll_id, &pll_id))
0580 return BP_RESULT_BADINPUT;
0581
0582
0583 switch (cntl->action) {
0584 case TRANSMITTER_CONTROL_INIT:
0585 if (dual_link_conn) {
0586
0587
0588
0589
0590
0591
0592 params.acConfig.fDualLinkConnector = 1;
0593 }
0594
0595
0596 params.usInitInfo =
0597 cpu_to_le16((uint8_t)(cntl->connector_obj_id.id));
0598 break;
0599 case TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS:
0600
0601 params.asMode.ucLaneSel = (uint8_t)cntl->lane_select;
0602 params.asMode.ucLaneSet = (uint8_t)cntl->lane_settings;
0603 break;
0604 default:
0605 if (dual_link_conn && cntl->multi_path)
0606
0607
0608
0609
0610
0611
0612 params.acConfig.fDualLinkConnector = 1;
0613
0614
0615 if (LANE_COUNT_FOUR < cntl->lanes_number) {
0616
0617
0618
0619
0620
0621
0622 params.acConfig.fDualLinkConnector = 1;
0623
0624
0625
0626
0627 params.usPixelClock =
0628 cpu_to_le16((uint16_t)(cntl->pixel_clock / 20));
0629 } else {
0630
0631
0632
0633 params.usPixelClock =
0634 cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
0635 }
0636 break;
0637 }
0638
0639
0640
0641
0642
0643 params.acConfig.fCoherentMode = cntl->coherent;
0644
0645 if ((TRANSMITTER_UNIPHY_B == cntl->transmitter)
0646 || (TRANSMITTER_UNIPHY_D == cntl->transmitter)
0647 || (TRANSMITTER_UNIPHY_F == cntl->transmitter))
0648
0649
0650
0651
0652
0653
0654 params.acConfig.ucLinkSel = 1;
0655
0656 if (ENGINE_ID_DIGB == cntl->engine_id)
0657
0658
0659
0660
0661
0662 params.acConfig.ucEncoderSel = 1;
0663
0664
0665
0666
0667
0668
0669
0670 params.acConfig.ucTransmitterSel =
0671 (uint8_t)cmd->transmitter_bp_to_atom(cntl->transmitter);
0672
0673 params.ucLaneNum = (uint8_t)cntl->lanes_number;
0674
0675 params.acConfig.ucRefClkSource = (uint8_t)pll_id;
0676
0677 params.ucAction = (uint8_t)cntl->action;
0678
0679 if (EXEC_BIOS_CMD_TABLE(UNIPHYTransmitterControl, params))
0680 result = BP_RESULT_OK;
0681
0682 return result;
0683 }
0684
0685 static enum bp_result transmitter_control_v4(
0686 struct bios_parser *bp,
0687 struct bp_transmitter_control *cntl)
0688 {
0689 enum bp_result result = BP_RESULT_FAILURE;
0690 DIG_TRANSMITTER_CONTROL_PARAMETERS_V4 params;
0691 uint32_t ref_clk_src_id;
0692 enum connector_id conn_id =
0693 dal_graphics_object_id_get_connector_id(cntl->connector_obj_id);
0694 const struct command_table_helper *cmd = bp->cmd_helper;
0695
0696 memset(¶ms, 0, sizeof(params));
0697
0698 switch (cntl->transmitter) {
0699 case TRANSMITTER_UNIPHY_A:
0700 case TRANSMITTER_UNIPHY_B:
0701 case TRANSMITTER_UNIPHY_C:
0702 case TRANSMITTER_UNIPHY_D:
0703 case TRANSMITTER_UNIPHY_E:
0704 case TRANSMITTER_UNIPHY_F:
0705 case TRANSMITTER_TRAVIS_LCD:
0706 break;
0707 default:
0708 return BP_RESULT_BADINPUT;
0709 }
0710
0711 if (!cmd->clock_source_id_to_ref_clk_src(cntl->pll_id, &ref_clk_src_id))
0712 return BP_RESULT_BADINPUT;
0713
0714 switch (cntl->action) {
0715 case TRANSMITTER_CONTROL_INIT:
0716 {
0717 if ((CONNECTOR_ID_DUAL_LINK_DVII == conn_id) ||
0718 (CONNECTOR_ID_DUAL_LINK_DVID == conn_id))
0719
0720
0721
0722
0723
0724
0725 params.acConfig.fDualLinkConnector = 1;
0726
0727
0728 params.usInitInfo =
0729 cpu_to_le16((uint8_t)(cntl->connector_obj_id.id));
0730 }
0731 break;
0732 case TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS:
0733
0734 params.asMode.ucLaneSel = (uint8_t)(cntl->lane_select);
0735 params.asMode.ucLaneSet = (uint8_t)(cntl->lane_settings);
0736 break;
0737 default:
0738 if ((CONNECTOR_ID_DUAL_LINK_DVII == conn_id) ||
0739 (CONNECTOR_ID_DUAL_LINK_DVID == conn_id))
0740
0741
0742
0743
0744
0745
0746 params.acConfig.fDualLinkConnector = 1;
0747
0748
0749 if (LANE_COUNT_FOUR < cntl->lanes_number)
0750
0751
0752
0753 params.usPixelClock =
0754 cpu_to_le16((uint16_t)(cntl->pixel_clock / 20));
0755 else {
0756
0757
0758
0759 params.usPixelClock =
0760 cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
0761 }
0762 break;
0763 }
0764
0765
0766
0767
0768
0769 params.acConfig.fCoherentMode = cntl->coherent;
0770
0771 if ((TRANSMITTER_UNIPHY_B == cntl->transmitter)
0772 || (TRANSMITTER_UNIPHY_D == cntl->transmitter)
0773 || (TRANSMITTER_UNIPHY_F == cntl->transmitter))
0774
0775
0776
0777
0778
0779
0780 params.acConfig.ucLinkSel = 1;
0781
0782 if (ENGINE_ID_DIGB == cntl->engine_id)
0783
0784
0785
0786
0787
0788 params.acConfig.ucEncoderSel = 1;
0789
0790
0791
0792
0793
0794
0795
0796 params.acConfig.ucTransmitterSel =
0797 (uint8_t)(cmd->transmitter_bp_to_atom(cntl->transmitter));
0798 params.ucLaneNum = (uint8_t)(cntl->lanes_number);
0799 params.acConfig.ucRefClkSource = (uint8_t)(ref_clk_src_id);
0800 params.ucAction = (uint8_t)(cntl->action);
0801
0802 if (EXEC_BIOS_CMD_TABLE(UNIPHYTransmitterControl, params))
0803 result = BP_RESULT_OK;
0804
0805 return result;
0806 }
0807
0808 static enum bp_result transmitter_control_v1_5(
0809 struct bios_parser *bp,
0810 struct bp_transmitter_control *cntl)
0811 {
0812 enum bp_result result = BP_RESULT_FAILURE;
0813 const struct command_table_helper *cmd = bp->cmd_helper;
0814 DIG_TRANSMITTER_CONTROL_PARAMETERS_V1_5 params;
0815
0816 memset(¶ms, 0, sizeof(params));
0817 params.ucPhyId = cmd->phy_id_to_atom(cntl->transmitter);
0818 params.ucAction = (uint8_t)cntl->action;
0819 params.ucLaneNum = (uint8_t)cntl->lanes_number;
0820 params.ucConnObjId = (uint8_t)cntl->connector_obj_id.id;
0821
0822 params.ucDigMode =
0823 cmd->signal_type_to_atom_dig_mode(cntl->signal);
0824 params.asConfig.ucPhyClkSrcId =
0825 cmd->clock_source_id_to_atom_phy_clk_src_id(cntl->pll_id);
0826
0827 params.asConfig.ucCoherentMode = cntl->coherent;
0828 params.asConfig.ucHPDSel =
0829 cmd->hpd_sel_to_atom(cntl->hpd_sel);
0830 params.ucDigEncoderSel =
0831 cmd->dig_encoder_sel_to_atom(cntl->engine_id);
0832 params.ucDPLaneSet = (uint8_t) cntl->lane_settings;
0833 params.usSymClock = cpu_to_le16((uint16_t) (cntl->pixel_clock / 10));
0834
0835
0836
0837
0838
0839
0840
0841
0842
0843
0844 if (cntl->signal == SIGNAL_TYPE_HDMI_TYPE_A) {
0845 switch (cntl->color_depth) {
0846 case COLOR_DEPTH_101010:
0847 params.usSymClock =
0848 cpu_to_le16((le16_to_cpu(params.usSymClock) * 30) / 24);
0849 break;
0850 case COLOR_DEPTH_121212:
0851 params.usSymClock =
0852 cpu_to_le16((le16_to_cpu(params.usSymClock) * 36) / 24);
0853 break;
0854 case COLOR_DEPTH_161616:
0855 params.usSymClock =
0856 cpu_to_le16((le16_to_cpu(params.usSymClock) * 48) / 24);
0857 break;
0858 default:
0859 break;
0860 }
0861 }
0862
0863 if (EXEC_BIOS_CMD_TABLE(UNIPHYTransmitterControl, params))
0864 result = BP_RESULT_OK;
0865
0866 return result;
0867 }
0868
0869 static enum bp_result transmitter_control_v1_6(
0870 struct bios_parser *bp,
0871 struct bp_transmitter_control *cntl)
0872 {
0873 enum bp_result result = BP_RESULT_FAILURE;
0874 const struct command_table_helper *cmd = bp->cmd_helper;
0875 DIG_TRANSMITTER_CONTROL_PARAMETERS_V1_6 params;
0876
0877 memset(¶ms, 0, sizeof(params));
0878 params.ucPhyId = cmd->phy_id_to_atom(cntl->transmitter);
0879 params.ucAction = (uint8_t)cntl->action;
0880
0881 if (cntl->action == TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS)
0882 params.ucDPLaneSet = (uint8_t)cntl->lane_settings;
0883 else
0884 params.ucDigMode = cmd->signal_type_to_atom_dig_mode(cntl->signal);
0885
0886 params.ucLaneNum = (uint8_t)cntl->lanes_number;
0887 params.ucHPDSel = cmd->hpd_sel_to_atom(cntl->hpd_sel);
0888 params.ucDigEncoderSel = cmd->dig_encoder_sel_to_atom(cntl->engine_id);
0889 params.ucConnObjId = (uint8_t)cntl->connector_obj_id.id;
0890 params.ulSymClock = cntl->pixel_clock/10;
0891
0892
0893
0894
0895
0896
0897
0898
0899
0900
0901
0902 switch (cntl->signal) {
0903 case SIGNAL_TYPE_HDMI_TYPE_A:
0904 switch (cntl->color_depth) {
0905 case COLOR_DEPTH_101010:
0906 params.ulSymClock =
0907 cpu_to_le16((le16_to_cpu(params.ulSymClock) * 30) / 24);
0908 break;
0909 case COLOR_DEPTH_121212:
0910 params.ulSymClock =
0911 cpu_to_le16((le16_to_cpu(params.ulSymClock) * 36) / 24);
0912 break;
0913 case COLOR_DEPTH_161616:
0914 params.ulSymClock =
0915 cpu_to_le16((le16_to_cpu(params.ulSymClock) * 48) / 24);
0916 break;
0917 default:
0918 break;
0919 }
0920 break;
0921 default:
0922 break;
0923 }
0924
0925 if (EXEC_BIOS_CMD_TABLE(UNIPHYTransmitterControl, params))
0926 result = BP_RESULT_OK;
0927 return result;
0928 }
0929
0930
0931
0932
0933
0934
0935
0936
0937
0938 static enum bp_result set_pixel_clock_v3(
0939 struct bios_parser *bp,
0940 struct bp_pixel_clock_parameters *bp_params);
0941 static enum bp_result set_pixel_clock_v5(
0942 struct bios_parser *bp,
0943 struct bp_pixel_clock_parameters *bp_params);
0944 static enum bp_result set_pixel_clock_v6(
0945 struct bios_parser *bp,
0946 struct bp_pixel_clock_parameters *bp_params);
0947 static enum bp_result set_pixel_clock_v7(
0948 struct bios_parser *bp,
0949 struct bp_pixel_clock_parameters *bp_params);
0950
0951 static void init_set_pixel_clock(struct bios_parser *bp)
0952 {
0953 switch (BIOS_CMD_TABLE_PARA_REVISION(SetPixelClock)) {
0954 case 3:
0955 bp->cmd_tbl.set_pixel_clock = set_pixel_clock_v3;
0956 break;
0957 case 5:
0958 bp->cmd_tbl.set_pixel_clock = set_pixel_clock_v5;
0959 break;
0960 case 6:
0961 bp->cmd_tbl.set_pixel_clock = set_pixel_clock_v6;
0962 break;
0963 case 7:
0964 bp->cmd_tbl.set_pixel_clock = set_pixel_clock_v7;
0965 break;
0966 default:
0967 dm_output_to_console("Don't have set_pixel_clock for v%d\n",
0968 BIOS_CMD_TABLE_PARA_REVISION(SetPixelClock));
0969 bp->cmd_tbl.set_pixel_clock = NULL;
0970 break;
0971 }
0972 }
0973
0974 static enum bp_result set_pixel_clock_v3(
0975 struct bios_parser *bp,
0976 struct bp_pixel_clock_parameters *bp_params)
0977 {
0978 enum bp_result result = BP_RESULT_FAILURE;
0979 PIXEL_CLOCK_PARAMETERS_V3 *params;
0980 SET_PIXEL_CLOCK_PS_ALLOCATION allocation;
0981
0982 memset(&allocation, 0, sizeof(allocation));
0983
0984 if (CLOCK_SOURCE_ID_PLL1 == bp_params->pll_id)
0985 allocation.sPCLKInput.ucPpll = ATOM_PPLL1;
0986 else if (CLOCK_SOURCE_ID_PLL2 == bp_params->pll_id)
0987 allocation.sPCLKInput.ucPpll = ATOM_PPLL2;
0988 else
0989 return BP_RESULT_BADINPUT;
0990
0991 allocation.sPCLKInput.usRefDiv =
0992 cpu_to_le16((uint16_t)bp_params->reference_divider);
0993 allocation.sPCLKInput.usFbDiv =
0994 cpu_to_le16((uint16_t)bp_params->feedback_divider);
0995 allocation.sPCLKInput.ucFracFbDiv =
0996 (uint8_t)bp_params->fractional_feedback_divider;
0997 allocation.sPCLKInput.ucPostDiv =
0998 (uint8_t)bp_params->pixel_clock_post_divider;
0999
1000
1001 allocation.sPCLKInput.usPixelClock =
1002 cpu_to_le16((uint16_t)(bp_params->target_pixel_clock_100hz / 100));
1003
1004 params = (PIXEL_CLOCK_PARAMETERS_V3 *)&allocation.sPCLKInput;
1005 params->ucTransmitterId =
1006 bp->cmd_helper->encoder_id_to_atom(
1007 dal_graphics_object_id_get_encoder_id(
1008 bp_params->encoder_object_id));
1009 params->ucEncoderMode =
1010 (uint8_t)(bp->cmd_helper->encoder_mode_bp_to_atom(
1011 bp_params->signal_type, false));
1012
1013 if (bp_params->flags.FORCE_PROGRAMMING_OF_PLL)
1014 params->ucMiscInfo |= PIXEL_CLOCK_MISC_FORCE_PROG_PPLL;
1015
1016 if (bp_params->flags.USE_E_CLOCK_AS_SOURCE_FOR_D_CLOCK)
1017 params->ucMiscInfo |= PIXEL_CLOCK_MISC_USE_ENGINE_FOR_DISPCLK;
1018
1019 if (CONTROLLER_ID_D1 != bp_params->controller_id)
1020 params->ucMiscInfo |= PIXEL_CLOCK_MISC_CRTC_SEL_CRTC2;
1021
1022 if (EXEC_BIOS_CMD_TABLE(SetPixelClock, allocation))
1023 result = BP_RESULT_OK;
1024
1025 return result;
1026 }
1027
1028 #ifndef SET_PIXEL_CLOCK_PS_ALLOCATION_V5
1029
1030 typedef struct _SET_PIXEL_CLOCK_PS_ALLOCATION_V5 {
1031 PIXEL_CLOCK_PARAMETERS_V5 sPCLKInput;
1032
1033 ENABLE_SPREAD_SPECTRUM_ON_PPLL sReserved;
1034 } SET_PIXEL_CLOCK_PS_ALLOCATION_V5;
1035 #endif
1036
1037 #ifndef SET_PIXEL_CLOCK_PS_ALLOCATION_V6
1038
1039 typedef struct _SET_PIXEL_CLOCK_PS_ALLOCATION_V6 {
1040 PIXEL_CLOCK_PARAMETERS_V6 sPCLKInput;
1041
1042 ENABLE_SPREAD_SPECTRUM_ON_PPLL sReserved;
1043 } SET_PIXEL_CLOCK_PS_ALLOCATION_V6;
1044 #endif
1045
1046 static enum bp_result set_pixel_clock_v5(
1047 struct bios_parser *bp,
1048 struct bp_pixel_clock_parameters *bp_params)
1049 {
1050 enum bp_result result = BP_RESULT_FAILURE;
1051 SET_PIXEL_CLOCK_PS_ALLOCATION_V5 clk;
1052 uint8_t controller_id;
1053 uint32_t pll_id;
1054
1055 memset(&clk, 0, sizeof(clk));
1056
1057 if (bp->cmd_helper->clock_source_id_to_atom(bp_params->pll_id, &pll_id)
1058 && bp->cmd_helper->controller_id_to_atom(
1059 bp_params->controller_id, &controller_id)) {
1060 clk.sPCLKInput.ucCRTC = controller_id;
1061 clk.sPCLKInput.ucPpll = (uint8_t)pll_id;
1062 clk.sPCLKInput.ucRefDiv =
1063 (uint8_t)(bp_params->reference_divider);
1064 clk.sPCLKInput.usFbDiv =
1065 cpu_to_le16((uint16_t)(bp_params->feedback_divider));
1066 clk.sPCLKInput.ulFbDivDecFrac =
1067 cpu_to_le32(bp_params->fractional_feedback_divider);
1068 clk.sPCLKInput.ucPostDiv =
1069 (uint8_t)(bp_params->pixel_clock_post_divider);
1070 clk.sPCLKInput.ucTransmitterID =
1071 bp->cmd_helper->encoder_id_to_atom(
1072 dal_graphics_object_id_get_encoder_id(
1073 bp_params->encoder_object_id));
1074 clk.sPCLKInput.ucEncoderMode =
1075 (uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom(
1076 bp_params->signal_type, false);
1077
1078
1079 clk.sPCLKInput.usPixelClock =
1080 cpu_to_le16((uint16_t)(bp_params->target_pixel_clock_100hz / 100));
1081
1082 if (bp_params->flags.FORCE_PROGRAMMING_OF_PLL)
1083 clk.sPCLKInput.ucMiscInfo |=
1084 PIXEL_CLOCK_MISC_FORCE_PROG_PPLL;
1085
1086 if (bp_params->flags.SET_EXTERNAL_REF_DIV_SRC)
1087 clk.sPCLKInput.ucMiscInfo |=
1088 PIXEL_CLOCK_MISC_REF_DIV_SRC;
1089
1090
1091
1092
1093
1094
1095 if (bp_params->signal_type == SIGNAL_TYPE_HDMI_TYPE_A)
1096 switch (bp_params->color_depth) {
1097 case TRANSMITTER_COLOR_DEPTH_30:
1098
1099 clk.sPCLKInput.ucMiscInfo |= PIXEL_CLOCK_V5_MISC_HDMI_32BPP;
1100 break;
1101 case TRANSMITTER_COLOR_DEPTH_36:
1102
1103 clk.sPCLKInput.ucMiscInfo |= PIXEL_CLOCK_V5_MISC_HDMI_30BPP;
1104 break;
1105 default:
1106 break;
1107 }
1108
1109 if (EXEC_BIOS_CMD_TABLE(SetPixelClock, clk))
1110 result = BP_RESULT_OK;
1111 }
1112
1113 return result;
1114 }
1115
1116 static enum bp_result set_pixel_clock_v6(
1117 struct bios_parser *bp,
1118 struct bp_pixel_clock_parameters *bp_params)
1119 {
1120 enum bp_result result = BP_RESULT_FAILURE;
1121 SET_PIXEL_CLOCK_PS_ALLOCATION_V6 clk;
1122 uint8_t controller_id;
1123 uint32_t pll_id;
1124
1125 memset(&clk, 0, sizeof(clk));
1126
1127 if (bp->cmd_helper->clock_source_id_to_atom(bp_params->pll_id, &pll_id)
1128 && bp->cmd_helper->controller_id_to_atom(
1129 bp_params->controller_id, &controller_id)) {
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149 clk.sPCLKInput.ulCrtcPclkFreq.ucCRTC = controller_id;
1150 clk.sPCLKInput.ucPpll = (uint8_t) pll_id;
1151 clk.sPCLKInput.ucRefDiv =
1152 (uint8_t) bp_params->reference_divider;
1153 clk.sPCLKInput.usFbDiv =
1154 cpu_to_le16((uint16_t) bp_params->feedback_divider);
1155 clk.sPCLKInput.ulFbDivDecFrac =
1156 cpu_to_le32(bp_params->fractional_feedback_divider);
1157 clk.sPCLKInput.ucPostDiv =
1158 (uint8_t) bp_params->pixel_clock_post_divider;
1159 clk.sPCLKInput.ucTransmitterID =
1160 bp->cmd_helper->encoder_id_to_atom(
1161 dal_graphics_object_id_get_encoder_id(
1162 bp_params->encoder_object_id));
1163 clk.sPCLKInput.ucEncoderMode =
1164 (uint8_t) bp->cmd_helper->encoder_mode_bp_to_atom(
1165 bp_params->signal_type, false);
1166
1167
1168 clk.sPCLKInput.ulCrtcPclkFreq.ulPixelClock =
1169 cpu_to_le32(bp_params->target_pixel_clock_100hz / 100);
1170
1171 if (bp_params->flags.FORCE_PROGRAMMING_OF_PLL) {
1172 clk.sPCLKInput.ucMiscInfo |=
1173 PIXEL_CLOCK_V6_MISC_FORCE_PROG_PPLL;
1174 }
1175
1176 if (bp_params->flags.SET_EXTERNAL_REF_DIV_SRC) {
1177 clk.sPCLKInput.ucMiscInfo |=
1178 PIXEL_CLOCK_V6_MISC_REF_DIV_SRC;
1179 }
1180
1181
1182
1183
1184
1185
1186 if (bp_params->signal_type == SIGNAL_TYPE_HDMI_TYPE_A)
1187 switch (bp_params->color_depth) {
1188 case TRANSMITTER_COLOR_DEPTH_30:
1189 clk.sPCLKInput.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_30BPP_V6;
1190 break;
1191 case TRANSMITTER_COLOR_DEPTH_36:
1192 clk.sPCLKInput.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_36BPP_V6;
1193 break;
1194 case TRANSMITTER_COLOR_DEPTH_48:
1195 clk.sPCLKInput.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_48BPP;
1196 break;
1197 default:
1198 break;
1199 }
1200
1201 if (EXEC_BIOS_CMD_TABLE(SetPixelClock, clk))
1202 result = BP_RESULT_OK;
1203 }
1204
1205 return result;
1206 }
1207
1208 static enum bp_result set_pixel_clock_v7(
1209 struct bios_parser *bp,
1210 struct bp_pixel_clock_parameters *bp_params)
1211 {
1212 enum bp_result result = BP_RESULT_FAILURE;
1213 PIXEL_CLOCK_PARAMETERS_V7 clk;
1214 uint8_t controller_id;
1215 uint32_t pll_id;
1216
1217 memset(&clk, 0, sizeof(clk));
1218
1219 if (bp->cmd_helper->clock_source_id_to_atom(bp_params->pll_id, &pll_id)
1220 && bp->cmd_helper->controller_id_to_atom(bp_params->controller_id, &controller_id)) {
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240 clk.ucCRTC = controller_id;
1241 clk.ucPpll = (uint8_t) pll_id;
1242 clk.ucTransmitterID = bp->cmd_helper->encoder_id_to_atom(dal_graphics_object_id_get_encoder_id(bp_params->encoder_object_id));
1243 clk.ucEncoderMode = (uint8_t) bp->cmd_helper->encoder_mode_bp_to_atom(bp_params->signal_type, false);
1244
1245 clk.ulPixelClock = cpu_to_le32(bp_params->target_pixel_clock_100hz);
1246
1247 clk.ucDeepColorRatio = (uint8_t) bp->cmd_helper->transmitter_color_depth_to_atom(bp_params->color_depth);
1248
1249 if (bp_params->flags.FORCE_PROGRAMMING_OF_PLL)
1250 clk.ucMiscInfo |= PIXEL_CLOCK_V7_MISC_FORCE_PROG_PPLL;
1251
1252 if (bp_params->flags.SET_EXTERNAL_REF_DIV_SRC)
1253 clk.ucMiscInfo |= PIXEL_CLOCK_V7_MISC_REF_DIV_SRC;
1254
1255 if (bp_params->flags.PROGRAM_PHY_PLL_ONLY)
1256 clk.ucMiscInfo |= PIXEL_CLOCK_V7_MISC_PROG_PHYPLL;
1257
1258 if (bp_params->flags.SUPPORT_YUV_420)
1259 clk.ucMiscInfo |= PIXEL_CLOCK_V7_MISC_YUV420_MODE;
1260
1261 if (bp_params->flags.SET_XTALIN_REF_SRC)
1262 clk.ucMiscInfo |= PIXEL_CLOCK_V7_MISC_REF_DIV_SRC_XTALIN;
1263
1264 if (bp_params->flags.SET_GENLOCK_REF_DIV_SRC)
1265 clk.ucMiscInfo |= PIXEL_CLOCK_V7_MISC_REF_DIV_SRC_GENLK;
1266
1267 if (bp_params->signal_type == SIGNAL_TYPE_DVI_DUAL_LINK)
1268 clk.ucMiscInfo |= PIXEL_CLOCK_V7_MISC_DVI_DUALLINK_EN;
1269
1270 if (EXEC_BIOS_CMD_TABLE(SetPixelClock, clk))
1271 result = BP_RESULT_OK;
1272 }
1273 return result;
1274 }
1275
1276
1277
1278
1279
1280
1281
1282
1283 static enum bp_result enable_spread_spectrum_on_ppll_v1(
1284 struct bios_parser *bp,
1285 struct bp_spread_spectrum_parameters *bp_params,
1286 bool enable);
1287 static enum bp_result enable_spread_spectrum_on_ppll_v2(
1288 struct bios_parser *bp,
1289 struct bp_spread_spectrum_parameters *bp_params,
1290 bool enable);
1291 static enum bp_result enable_spread_spectrum_on_ppll_v3(
1292 struct bios_parser *bp,
1293 struct bp_spread_spectrum_parameters *bp_params,
1294 bool enable);
1295
1296 static void init_enable_spread_spectrum_on_ppll(struct bios_parser *bp)
1297 {
1298 switch (BIOS_CMD_TABLE_PARA_REVISION(EnableSpreadSpectrumOnPPLL)) {
1299 case 1:
1300 bp->cmd_tbl.enable_spread_spectrum_on_ppll =
1301 enable_spread_spectrum_on_ppll_v1;
1302 break;
1303 case 2:
1304 bp->cmd_tbl.enable_spread_spectrum_on_ppll =
1305 enable_spread_spectrum_on_ppll_v2;
1306 break;
1307 case 3:
1308 bp->cmd_tbl.enable_spread_spectrum_on_ppll =
1309 enable_spread_spectrum_on_ppll_v3;
1310 break;
1311 default:
1312 dm_output_to_console("Don't have enable_spread_spectrum_on_ppll for v%d\n",
1313 BIOS_CMD_TABLE_PARA_REVISION(EnableSpreadSpectrumOnPPLL));
1314 bp->cmd_tbl.enable_spread_spectrum_on_ppll = NULL;
1315 break;
1316 }
1317 }
1318
1319 static enum bp_result enable_spread_spectrum_on_ppll_v1(
1320 struct bios_parser *bp,
1321 struct bp_spread_spectrum_parameters *bp_params,
1322 bool enable)
1323 {
1324 enum bp_result result = BP_RESULT_FAILURE;
1325 ENABLE_SPREAD_SPECTRUM_ON_PPLL params;
1326
1327 memset(¶ms, 0, sizeof(params));
1328
1329 if ((enable == true) && (bp_params->percentage > 0))
1330 params.ucEnable = ATOM_ENABLE;
1331 else
1332 params.ucEnable = ATOM_DISABLE;
1333
1334 params.usSpreadSpectrumPercentage =
1335 cpu_to_le16((uint16_t)bp_params->percentage);
1336 params.ucSpreadSpectrumStep =
1337 (uint8_t)bp_params->ver1.step;
1338 params.ucSpreadSpectrumDelay =
1339 (uint8_t)bp_params->ver1.delay;
1340
1341 params.ucSpreadSpectrumRange =
1342 (uint8_t)(bp_params->ver1.range / 10000);
1343
1344 if (bp_params->flags.EXTERNAL_SS)
1345 params.ucSpreadSpectrumType |= ATOM_EXTERNAL_SS_MASK;
1346
1347 if (bp_params->flags.CENTER_SPREAD)
1348 params.ucSpreadSpectrumType |= ATOM_SS_CENTRE_SPREAD_MODE;
1349
1350 if (bp_params->pll_id == CLOCK_SOURCE_ID_PLL1)
1351 params.ucPpll = ATOM_PPLL1;
1352 else if (bp_params->pll_id == CLOCK_SOURCE_ID_PLL2)
1353 params.ucPpll = ATOM_PPLL2;
1354 else
1355 BREAK_TO_DEBUGGER();
1356
1357 if (EXEC_BIOS_CMD_TABLE(EnableSpreadSpectrumOnPPLL, params))
1358 result = BP_RESULT_OK;
1359
1360 return result;
1361 }
1362
1363 static enum bp_result enable_spread_spectrum_on_ppll_v2(
1364 struct bios_parser *bp,
1365 struct bp_spread_spectrum_parameters *bp_params,
1366 bool enable)
1367 {
1368 enum bp_result result = BP_RESULT_FAILURE;
1369 ENABLE_SPREAD_SPECTRUM_ON_PPLL_V2 params;
1370
1371 memset(¶ms, 0, sizeof(params));
1372
1373 if (bp_params->pll_id == CLOCK_SOURCE_ID_PLL1)
1374 params.ucSpreadSpectrumType = ATOM_PPLL_SS_TYPE_V2_P1PLL;
1375 else if (bp_params->pll_id == CLOCK_SOURCE_ID_PLL2)
1376 params.ucSpreadSpectrumType = ATOM_PPLL_SS_TYPE_V2_P2PLL;
1377 else
1378 BREAK_TO_DEBUGGER();
1379
1380 if ((enable == true) && (bp_params->percentage > 0)) {
1381 params.ucEnable = ATOM_ENABLE;
1382
1383 params.usSpreadSpectrumPercentage =
1384 cpu_to_le16((uint16_t)(bp_params->percentage));
1385 params.usSpreadSpectrumStep =
1386 cpu_to_le16((uint16_t)(bp_params->ds.ds_frac_size));
1387
1388 if (bp_params->flags.EXTERNAL_SS)
1389 params.ucSpreadSpectrumType |=
1390 ATOM_PPLL_SS_TYPE_V2_EXT_SPREAD;
1391
1392 if (bp_params->flags.CENTER_SPREAD)
1393 params.ucSpreadSpectrumType |=
1394 ATOM_PPLL_SS_TYPE_V2_CENTRE_SPREAD;
1395
1396
1397
1398
1399 params.usSpreadSpectrumAmount = cpu_to_le16((uint16_t)(
1400 ((bp_params->ds.feedback_amount <<
1401 ATOM_PPLL_SS_AMOUNT_V2_FBDIV_SHIFT) &
1402 ATOM_PPLL_SS_AMOUNT_V2_FBDIV_MASK) |
1403 ((bp_params->ds.nfrac_amount <<
1404 ATOM_PPLL_SS_AMOUNT_V2_NFRAC_SHIFT) &
1405 ATOM_PPLL_SS_AMOUNT_V2_NFRAC_MASK)));
1406 } else
1407 params.ucEnable = ATOM_DISABLE;
1408
1409 if (EXEC_BIOS_CMD_TABLE(EnableSpreadSpectrumOnPPLL, params))
1410 result = BP_RESULT_OK;
1411
1412 return result;
1413 }
1414
1415 static enum bp_result enable_spread_spectrum_on_ppll_v3(
1416 struct bios_parser *bp,
1417 struct bp_spread_spectrum_parameters *bp_params,
1418 bool enable)
1419 {
1420 enum bp_result result = BP_RESULT_FAILURE;
1421 ENABLE_SPREAD_SPECTRUM_ON_PPLL_V3 params;
1422
1423 memset(¶ms, 0, sizeof(params));
1424
1425 switch (bp_params->pll_id) {
1426 case CLOCK_SOURCE_ID_PLL0:
1427
1428
1429
1430 params.ucSpreadSpectrumType = ATOM_PPLL_SS_TYPE_V3_DCPLL;
1431 break;
1432 case CLOCK_SOURCE_ID_PLL1:
1433 params.ucSpreadSpectrumType = ATOM_PPLL_SS_TYPE_V3_P1PLL;
1434 break;
1435
1436 case CLOCK_SOURCE_ID_PLL2:
1437 params.ucSpreadSpectrumType = ATOM_PPLL_SS_TYPE_V3_P2PLL;
1438 break;
1439
1440 case CLOCK_SOURCE_ID_DCPLL:
1441 params.ucSpreadSpectrumType = ATOM_PPLL_SS_TYPE_V3_DCPLL;
1442 break;
1443
1444 default:
1445 BREAK_TO_DEBUGGER();
1446
1447 return result;
1448 }
1449
1450 if (enable == true) {
1451 params.ucEnable = ATOM_ENABLE;
1452
1453 params.usSpreadSpectrumAmountFrac =
1454 cpu_to_le16((uint16_t)(bp_params->ds_frac_amount));
1455 params.usSpreadSpectrumStep =
1456 cpu_to_le16((uint16_t)(bp_params->ds.ds_frac_size));
1457
1458 if (bp_params->flags.EXTERNAL_SS)
1459 params.ucSpreadSpectrumType |=
1460 ATOM_PPLL_SS_TYPE_V3_EXT_SPREAD;
1461 if (bp_params->flags.CENTER_SPREAD)
1462 params.ucSpreadSpectrumType |=
1463 ATOM_PPLL_SS_TYPE_V3_CENTRE_SPREAD;
1464
1465
1466
1467
1468 params.usSpreadSpectrumAmount = cpu_to_le16((uint16_t)(
1469 ((bp_params->ds.feedback_amount <<
1470 ATOM_PPLL_SS_AMOUNT_V3_FBDIV_SHIFT) &
1471 ATOM_PPLL_SS_AMOUNT_V3_FBDIV_MASK) |
1472 ((bp_params->ds.nfrac_amount <<
1473 ATOM_PPLL_SS_AMOUNT_V3_NFRAC_SHIFT) &
1474 ATOM_PPLL_SS_AMOUNT_V3_NFRAC_MASK)));
1475 } else
1476 params.ucEnable = ATOM_DISABLE;
1477
1478 if (EXEC_BIOS_CMD_TABLE(EnableSpreadSpectrumOnPPLL, params))
1479 result = BP_RESULT_OK;
1480
1481 return result;
1482 }
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492 static enum bp_result adjust_display_pll_v2(
1493 struct bios_parser *bp,
1494 struct bp_adjust_pixel_clock_parameters *bp_params);
1495 static enum bp_result adjust_display_pll_v3(
1496 struct bios_parser *bp,
1497 struct bp_adjust_pixel_clock_parameters *bp_params);
1498
1499 static void init_adjust_display_pll(struct bios_parser *bp)
1500 {
1501 switch (BIOS_CMD_TABLE_PARA_REVISION(AdjustDisplayPll)) {
1502 case 2:
1503 bp->cmd_tbl.adjust_display_pll = adjust_display_pll_v2;
1504 break;
1505 case 3:
1506 bp->cmd_tbl.adjust_display_pll = adjust_display_pll_v3;
1507 break;
1508 default:
1509 dm_output_to_console("Don't have adjust_display_pll for v%d\n",
1510 BIOS_CMD_TABLE_PARA_REVISION(AdjustDisplayPll));
1511 bp->cmd_tbl.adjust_display_pll = NULL;
1512 break;
1513 }
1514 }
1515
1516 static enum bp_result adjust_display_pll_v2(
1517 struct bios_parser *bp,
1518 struct bp_adjust_pixel_clock_parameters *bp_params)
1519 {
1520 enum bp_result result = BP_RESULT_FAILURE;
1521 ADJUST_DISPLAY_PLL_PS_ALLOCATION params = { 0 };
1522
1523
1524
1525 uint32_t pixel_clock_10KHz_in = bp_params->pixel_clock / 10;
1526
1527 params.usPixelClock = cpu_to_le16((uint16_t)(pixel_clock_10KHz_in));
1528 params.ucTransmitterID =
1529 bp->cmd_helper->encoder_id_to_atom(
1530 dal_graphics_object_id_get_encoder_id(
1531 bp_params->encoder_object_id));
1532 params.ucEncodeMode =
1533 (uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom(
1534 bp_params->signal_type, false);
1535
1536 if (EXEC_BIOS_CMD_TABLE(AdjustDisplayPll, params)) {
1537
1538
1539
1540 uint64_t pixel_clk_10_khz_out =
1541 (uint64_t)le16_to_cpu(params.usPixelClock);
1542 uint64_t pixel_clk = (uint64_t)bp_params->pixel_clock;
1543
1544 if (pixel_clock_10KHz_in != 0) {
1545 bp_params->adjusted_pixel_clock =
1546 div_u64(pixel_clk * pixel_clk_10_khz_out,
1547 pixel_clock_10KHz_in);
1548 } else {
1549 bp_params->adjusted_pixel_clock = 0;
1550 BREAK_TO_DEBUGGER();
1551 }
1552
1553 result = BP_RESULT_OK;
1554 }
1555
1556 return result;
1557 }
1558
1559 static enum bp_result adjust_display_pll_v3(
1560 struct bios_parser *bp,
1561 struct bp_adjust_pixel_clock_parameters *bp_params)
1562 {
1563 enum bp_result result = BP_RESULT_FAILURE;
1564 ADJUST_DISPLAY_PLL_PS_ALLOCATION_V3 params;
1565 uint32_t pixel_clk_10_kHz_in = bp_params->pixel_clock / 10;
1566
1567 memset(¶ms, 0, sizeof(params));
1568
1569
1570
1571 params.sInput.usPixelClock = cpu_to_le16((uint16_t)pixel_clk_10_kHz_in);
1572 params.sInput.ucTransmitterID =
1573 bp->cmd_helper->encoder_id_to_atom(
1574 dal_graphics_object_id_get_encoder_id(
1575 bp_params->encoder_object_id));
1576 params.sInput.ucEncodeMode =
1577 (uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom(
1578 bp_params->signal_type, false);
1579
1580 if (bp_params->ss_enable == true)
1581 params.sInput.ucDispPllConfig |= DISPPLL_CONFIG_SS_ENABLE;
1582
1583 if (bp_params->signal_type == SIGNAL_TYPE_DVI_DUAL_LINK)
1584 params.sInput.ucDispPllConfig |= DISPPLL_CONFIG_DUAL_LINK;
1585
1586 if (EXEC_BIOS_CMD_TABLE(AdjustDisplayPll, params)) {
1587
1588
1589
1590 uint64_t pixel_clk_10_khz_out =
1591 (uint64_t)le32_to_cpu(params.sOutput.ulDispPllFreq);
1592 uint64_t pixel_clk = (uint64_t)bp_params->pixel_clock;
1593
1594 if (pixel_clk_10_kHz_in != 0) {
1595 bp_params->adjusted_pixel_clock =
1596 div_u64(pixel_clk * pixel_clk_10_khz_out,
1597 pixel_clk_10_kHz_in);
1598 } else {
1599 bp_params->adjusted_pixel_clock = 0;
1600 BREAK_TO_DEBUGGER();
1601 }
1602
1603 bp_params->reference_divider = params.sOutput.ucRefDiv;
1604 bp_params->pixel_clock_post_divider = params.sOutput.ucPostDiv;
1605
1606 result = BP_RESULT_OK;
1607 }
1608
1609 return result;
1610 }
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620 static enum bp_result dac1_encoder_control_v1(
1621 struct bios_parser *bp,
1622 bool enable,
1623 uint32_t pixel_clock,
1624 uint8_t dac_standard);
1625 static enum bp_result dac2_encoder_control_v1(
1626 struct bios_parser *bp,
1627 bool enable,
1628 uint32_t pixel_clock,
1629 uint8_t dac_standard);
1630
1631 static void init_dac_encoder_control(struct bios_parser *bp)
1632 {
1633 switch (BIOS_CMD_TABLE_PARA_REVISION(DAC1EncoderControl)) {
1634 case 1:
1635 bp->cmd_tbl.dac1_encoder_control = dac1_encoder_control_v1;
1636 break;
1637 default:
1638 bp->cmd_tbl.dac1_encoder_control = NULL;
1639 break;
1640 }
1641 switch (BIOS_CMD_TABLE_PARA_REVISION(DAC2EncoderControl)) {
1642 case 1:
1643 bp->cmd_tbl.dac2_encoder_control = dac2_encoder_control_v1;
1644 break;
1645 default:
1646 bp->cmd_tbl.dac2_encoder_control = NULL;
1647 break;
1648 }
1649 }
1650
1651 static void dac_encoder_control_prepare_params(
1652 DAC_ENCODER_CONTROL_PS_ALLOCATION *params,
1653 bool enable,
1654 uint32_t pixel_clock,
1655 uint8_t dac_standard)
1656 {
1657 params->ucDacStandard = dac_standard;
1658 if (enable)
1659 params->ucAction = ATOM_ENABLE;
1660 else
1661 params->ucAction = ATOM_DISABLE;
1662
1663
1664
1665
1666 params->usPixelClock = cpu_to_le16((uint16_t)(pixel_clock / 10));
1667 }
1668
1669 static enum bp_result dac1_encoder_control_v1(
1670 struct bios_parser *bp,
1671 bool enable,
1672 uint32_t pixel_clock,
1673 uint8_t dac_standard)
1674 {
1675 enum bp_result result = BP_RESULT_FAILURE;
1676 DAC_ENCODER_CONTROL_PS_ALLOCATION params;
1677
1678 dac_encoder_control_prepare_params(
1679 ¶ms,
1680 enable,
1681 pixel_clock,
1682 dac_standard);
1683
1684 if (EXEC_BIOS_CMD_TABLE(DAC1EncoderControl, params))
1685 result = BP_RESULT_OK;
1686
1687 return result;
1688 }
1689
1690 static enum bp_result dac2_encoder_control_v1(
1691 struct bios_parser *bp,
1692 bool enable,
1693 uint32_t pixel_clock,
1694 uint8_t dac_standard)
1695 {
1696 enum bp_result result = BP_RESULT_FAILURE;
1697 DAC_ENCODER_CONTROL_PS_ALLOCATION params;
1698
1699 dac_encoder_control_prepare_params(
1700 ¶ms,
1701 enable,
1702 pixel_clock,
1703 dac_standard);
1704
1705 if (EXEC_BIOS_CMD_TABLE(DAC2EncoderControl, params))
1706 result = BP_RESULT_OK;
1707
1708 return result;
1709 }
1710
1711
1712
1713
1714
1715
1716
1717
1718 static enum bp_result dac1_output_control_v1(
1719 struct bios_parser *bp,
1720 bool enable);
1721 static enum bp_result dac2_output_control_v1(
1722 struct bios_parser *bp,
1723 bool enable);
1724
1725 static void init_dac_output_control(struct bios_parser *bp)
1726 {
1727 switch (BIOS_CMD_TABLE_PARA_REVISION(DAC1OutputControl)) {
1728 case 1:
1729 bp->cmd_tbl.dac1_output_control = dac1_output_control_v1;
1730 break;
1731 default:
1732 bp->cmd_tbl.dac1_output_control = NULL;
1733 break;
1734 }
1735 switch (BIOS_CMD_TABLE_PARA_REVISION(DAC2OutputControl)) {
1736 case 1:
1737 bp->cmd_tbl.dac2_output_control = dac2_output_control_v1;
1738 break;
1739 default:
1740 bp->cmd_tbl.dac2_output_control = NULL;
1741 break;
1742 }
1743 }
1744
1745 static enum bp_result dac1_output_control_v1(
1746 struct bios_parser *bp, bool enable)
1747 {
1748 enum bp_result result = BP_RESULT_FAILURE;
1749 DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION params;
1750
1751 if (enable)
1752 params.ucAction = ATOM_ENABLE;
1753 else
1754 params.ucAction = ATOM_DISABLE;
1755
1756 if (EXEC_BIOS_CMD_TABLE(DAC1OutputControl, params))
1757 result = BP_RESULT_OK;
1758
1759 return result;
1760 }
1761
1762 static enum bp_result dac2_output_control_v1(
1763 struct bios_parser *bp, bool enable)
1764 {
1765 enum bp_result result = BP_RESULT_FAILURE;
1766 DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION params;
1767
1768 if (enable)
1769 params.ucAction = ATOM_ENABLE;
1770 else
1771 params.ucAction = ATOM_DISABLE;
1772
1773 if (EXEC_BIOS_CMD_TABLE(DAC2OutputControl, params))
1774 result = BP_RESULT_OK;
1775
1776 return result;
1777 }
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787 static enum bp_result set_crtc_using_dtd_timing_v3(
1788 struct bios_parser *bp,
1789 struct bp_hw_crtc_timing_parameters *bp_params);
1790 static enum bp_result set_crtc_timing_v1(
1791 struct bios_parser *bp,
1792 struct bp_hw_crtc_timing_parameters *bp_params);
1793
1794 static void init_set_crtc_timing(struct bios_parser *bp)
1795 {
1796 uint32_t dtd_version =
1797 BIOS_CMD_TABLE_PARA_REVISION(SetCRTC_UsingDTDTiming);
1798 if (dtd_version > 2)
1799 switch (dtd_version) {
1800 case 3:
1801 bp->cmd_tbl.set_crtc_timing =
1802 set_crtc_using_dtd_timing_v3;
1803 break;
1804 default:
1805 dm_output_to_console("Don't have set_crtc_timing for dtd v%d\n",
1806 dtd_version);
1807 bp->cmd_tbl.set_crtc_timing = NULL;
1808 break;
1809 }
1810 else
1811 switch (BIOS_CMD_TABLE_PARA_REVISION(SetCRTC_Timing)) {
1812 case 1:
1813 bp->cmd_tbl.set_crtc_timing = set_crtc_timing_v1;
1814 break;
1815 default:
1816 dm_output_to_console("Don't have set_crtc_timing for v%d\n",
1817 BIOS_CMD_TABLE_PARA_REVISION(SetCRTC_Timing));
1818 bp->cmd_tbl.set_crtc_timing = NULL;
1819 break;
1820 }
1821 }
1822
1823 static enum bp_result set_crtc_timing_v1(
1824 struct bios_parser *bp,
1825 struct bp_hw_crtc_timing_parameters *bp_params)
1826 {
1827 enum bp_result result = BP_RESULT_FAILURE;
1828 SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION params = {0};
1829 uint8_t atom_controller_id;
1830
1831 if (bp->cmd_helper->controller_id_to_atom(
1832 bp_params->controller_id, &atom_controller_id))
1833 params.ucCRTC = atom_controller_id;
1834
1835 params.usH_Total = cpu_to_le16((uint16_t)(bp_params->h_total));
1836 params.usH_Disp = cpu_to_le16((uint16_t)(bp_params->h_addressable));
1837 params.usH_SyncStart = cpu_to_le16((uint16_t)(bp_params->h_sync_start));
1838 params.usH_SyncWidth = cpu_to_le16((uint16_t)(bp_params->h_sync_width));
1839 params.usV_Total = cpu_to_le16((uint16_t)(bp_params->v_total));
1840 params.usV_Disp = cpu_to_le16((uint16_t)(bp_params->v_addressable));
1841 params.usV_SyncStart =
1842 cpu_to_le16((uint16_t)(bp_params->v_sync_start));
1843 params.usV_SyncWidth =
1844 cpu_to_le16((uint16_t)(bp_params->v_sync_width));
1845
1846
1847
1848
1849
1850
1851
1852 params.ucOverscanRight = (uint8_t)bp_params->h_overscan_right;
1853 params.ucOverscanLeft = (uint8_t)bp_params->h_overscan_left;
1854 params.ucOverscanBottom = (uint8_t)bp_params->v_overscan_bottom;
1855 params.ucOverscanTop = (uint8_t)bp_params->v_overscan_top;
1856
1857 if (0 == bp_params->flags.HSYNC_POSITIVE_POLARITY)
1858 params.susModeMiscInfo.usAccess =
1859 cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_HSYNC_POLARITY);
1860
1861 if (0 == bp_params->flags.VSYNC_POSITIVE_POLARITY)
1862 params.susModeMiscInfo.usAccess =
1863 cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_VSYNC_POLARITY);
1864
1865 if (bp_params->flags.INTERLACE) {
1866 params.susModeMiscInfo.usAccess =
1867 cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_INTERLACE);
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882 params.usV_SyncStart =
1883 cpu_to_le16((uint16_t)(bp_params->v_sync_start + 1));
1884 }
1885
1886 if (bp_params->flags.HORZ_COUNT_BY_TWO)
1887 params.susModeMiscInfo.usAccess =
1888 cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_DOUBLE_CLOCK_MODE);
1889
1890 if (EXEC_BIOS_CMD_TABLE(SetCRTC_Timing, params))
1891 result = BP_RESULT_OK;
1892
1893 return result;
1894 }
1895
1896 static enum bp_result set_crtc_using_dtd_timing_v3(
1897 struct bios_parser *bp,
1898 struct bp_hw_crtc_timing_parameters *bp_params)
1899 {
1900 enum bp_result result = BP_RESULT_FAILURE;
1901 SET_CRTC_USING_DTD_TIMING_PARAMETERS params = {0};
1902 uint8_t atom_controller_id;
1903
1904 if (bp->cmd_helper->controller_id_to_atom(
1905 bp_params->controller_id, &atom_controller_id))
1906 params.ucCRTC = atom_controller_id;
1907
1908
1909 params.usH_Size = cpu_to_le16((uint16_t)bp_params->h_addressable);
1910
1911 params.usH_Blanking_Time =
1912 cpu_to_le16((uint16_t)(bp_params->h_total - bp_params->h_addressable));
1913
1914 params.usV_Size = cpu_to_le16((uint16_t)bp_params->v_addressable);
1915
1916 params.usV_Blanking_Time =
1917 cpu_to_le16((uint16_t)(bp_params->v_total - bp_params->v_addressable));
1918
1919
1920
1921 params.usH_SyncOffset =
1922 cpu_to_le16((uint16_t)(bp_params->h_sync_start - bp_params->h_addressable));
1923 params.usH_SyncWidth = cpu_to_le16((uint16_t)bp_params->h_sync_width);
1924
1925
1926
1927 params.usV_SyncOffset =
1928 cpu_to_le16((uint16_t)(bp_params->v_sync_start - bp_params->v_addressable));
1929 params.usV_SyncWidth = cpu_to_le16((uint16_t)bp_params->v_sync_width);
1930
1931
1932
1933
1934
1935
1936 if (0 == bp_params->flags.HSYNC_POSITIVE_POLARITY)
1937 params.susModeMiscInfo.usAccess =
1938 cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_HSYNC_POLARITY);
1939
1940 if (0 == bp_params->flags.VSYNC_POSITIVE_POLARITY)
1941 params.susModeMiscInfo.usAccess =
1942 cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_VSYNC_POLARITY);
1943
1944 if (bp_params->flags.INTERLACE) {
1945 params.susModeMiscInfo.usAccess =
1946 cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_INTERLACE);
1947
1948
1949
1950
1951
1952
1953
1954
1955 {
1956
1957
1958
1959
1960
1961
1962
1963 le16_add_cpu(¶ms.usV_SyncOffset, 1);
1964 }
1965 }
1966
1967 if (bp_params->flags.HORZ_COUNT_BY_TWO)
1968 params.susModeMiscInfo.usAccess =
1969 cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_DOUBLE_CLOCK_MODE);
1970
1971 if (EXEC_BIOS_CMD_TABLE(SetCRTC_UsingDTDTiming, params))
1972 result = BP_RESULT_OK;
1973
1974 return result;
1975 }
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985 static enum bp_result enable_crtc_v1(
1986 struct bios_parser *bp,
1987 enum controller_id controller_id,
1988 bool enable);
1989
1990 static void init_enable_crtc(struct bios_parser *bp)
1991 {
1992 switch (BIOS_CMD_TABLE_PARA_REVISION(EnableCRTC)) {
1993 case 1:
1994 bp->cmd_tbl.enable_crtc = enable_crtc_v1;
1995 break;
1996 default:
1997 dm_output_to_console("Don't have enable_crtc for v%d\n",
1998 BIOS_CMD_TABLE_PARA_REVISION(EnableCRTC));
1999 bp->cmd_tbl.enable_crtc = NULL;
2000 break;
2001 }
2002 }
2003
2004 static enum bp_result enable_crtc_v1(
2005 struct bios_parser *bp,
2006 enum controller_id controller_id,
2007 bool enable)
2008 {
2009 bool result = BP_RESULT_FAILURE;
2010 ENABLE_CRTC_PARAMETERS params = {0};
2011 uint8_t id;
2012
2013 if (bp->cmd_helper->controller_id_to_atom(controller_id, &id))
2014 params.ucCRTC = id;
2015 else
2016 return BP_RESULT_BADINPUT;
2017
2018 if (enable)
2019 params.ucEnable = ATOM_ENABLE;
2020 else
2021 params.ucEnable = ATOM_DISABLE;
2022
2023 if (EXEC_BIOS_CMD_TABLE(EnableCRTC, params))
2024 result = BP_RESULT_OK;
2025
2026 return result;
2027 }
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037 static enum bp_result enable_crtc_mem_req_v1(
2038 struct bios_parser *bp,
2039 enum controller_id controller_id,
2040 bool enable);
2041
2042 static void init_enable_crtc_mem_req(struct bios_parser *bp)
2043 {
2044 switch (BIOS_CMD_TABLE_PARA_REVISION(EnableCRTCMemReq)) {
2045 case 1:
2046 bp->cmd_tbl.enable_crtc_mem_req = enable_crtc_mem_req_v1;
2047 break;
2048 default:
2049 bp->cmd_tbl.enable_crtc_mem_req = NULL;
2050 break;
2051 }
2052 }
2053
2054 static enum bp_result enable_crtc_mem_req_v1(
2055 struct bios_parser *bp,
2056 enum controller_id controller_id,
2057 bool enable)
2058 {
2059 bool result = BP_RESULT_BADINPUT;
2060 ENABLE_CRTC_PARAMETERS params = {0};
2061 uint8_t id;
2062
2063 if (bp->cmd_helper->controller_id_to_atom(controller_id, &id)) {
2064 params.ucCRTC = id;
2065
2066 if (enable)
2067 params.ucEnable = ATOM_ENABLE;
2068 else
2069 params.ucEnable = ATOM_DISABLE;
2070
2071 if (EXEC_BIOS_CMD_TABLE(EnableCRTCMemReq, params))
2072 result = BP_RESULT_OK;
2073 else
2074 result = BP_RESULT_FAILURE;
2075 }
2076
2077 return result;
2078 }
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088 static enum bp_result program_clock_v5(
2089 struct bios_parser *bp,
2090 struct bp_pixel_clock_parameters *bp_params);
2091 static enum bp_result program_clock_v6(
2092 struct bios_parser *bp,
2093 struct bp_pixel_clock_parameters *bp_params);
2094
2095 static void init_program_clock(struct bios_parser *bp)
2096 {
2097 switch (BIOS_CMD_TABLE_PARA_REVISION(SetPixelClock)) {
2098 case 5:
2099 bp->cmd_tbl.program_clock = program_clock_v5;
2100 break;
2101 case 6:
2102 bp->cmd_tbl.program_clock = program_clock_v6;
2103 break;
2104 default:
2105 dm_output_to_console("Don't have program_clock for v%d\n",
2106 BIOS_CMD_TABLE_PARA_REVISION(SetPixelClock));
2107 bp->cmd_tbl.program_clock = NULL;
2108 break;
2109 }
2110 }
2111
2112 static enum bp_result program_clock_v5(
2113 struct bios_parser *bp,
2114 struct bp_pixel_clock_parameters *bp_params)
2115 {
2116 enum bp_result result = BP_RESULT_FAILURE;
2117
2118 SET_PIXEL_CLOCK_PS_ALLOCATION_V5 params;
2119 uint32_t atom_pll_id;
2120
2121 memset(¶ms, 0, sizeof(params));
2122 if (!bp->cmd_helper->clock_source_id_to_atom(
2123 bp_params->pll_id, &atom_pll_id)) {
2124 BREAK_TO_DEBUGGER();
2125 return BP_RESULT_BADINPUT;
2126 }
2127
2128
2129 params.sPCLKInput.ucPpll = (uint8_t) atom_pll_id;
2130 params.sPCLKInput.usPixelClock =
2131 cpu_to_le16((uint16_t) (bp_params->target_pixel_clock_100hz / 100));
2132 params.sPCLKInput.ucCRTC = (uint8_t) ATOM_CRTC_INVALID;
2133
2134 if (bp_params->flags.SET_EXTERNAL_REF_DIV_SRC)
2135 params.sPCLKInput.ucMiscInfo |= PIXEL_CLOCK_MISC_REF_DIV_SRC;
2136
2137 if (EXEC_BIOS_CMD_TABLE(SetPixelClock, params))
2138 result = BP_RESULT_OK;
2139
2140 return result;
2141 }
2142
2143 static enum bp_result program_clock_v6(
2144 struct bios_parser *bp,
2145 struct bp_pixel_clock_parameters *bp_params)
2146 {
2147 enum bp_result result = BP_RESULT_FAILURE;
2148
2149 SET_PIXEL_CLOCK_PS_ALLOCATION_V6 params;
2150 uint32_t atom_pll_id;
2151
2152 memset(¶ms, 0, sizeof(params));
2153
2154 if (!bp->cmd_helper->clock_source_id_to_atom(
2155 bp_params->pll_id, &atom_pll_id)) {
2156 BREAK_TO_DEBUGGER();
2157 return BP_RESULT_BADINPUT;
2158 }
2159
2160
2161 params.sPCLKInput.ucPpll = (uint8_t)atom_pll_id;
2162 params.sPCLKInput.ulDispEngClkFreq =
2163 cpu_to_le32(bp_params->target_pixel_clock_100hz / 100);
2164
2165 if (bp_params->flags.SET_EXTERNAL_REF_DIV_SRC)
2166 params.sPCLKInput.ucMiscInfo |= PIXEL_CLOCK_MISC_REF_DIV_SRC;
2167
2168 if (bp_params->flags.SET_DISPCLK_DFS_BYPASS)
2169 params.sPCLKInput.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_DPREFCLK_BYPASS;
2170
2171 if (EXEC_BIOS_CMD_TABLE(SetPixelClock, params)) {
2172
2173
2174 bp_params->dfs_bypass_display_clock =
2175 (uint32_t)(le32_to_cpu(params.sPCLKInput.ulDispEngClkFreq) * 10);
2176 result = BP_RESULT_OK;
2177 }
2178
2179 return result;
2180 }
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190 static enum bp_result external_encoder_control_v3(
2191 struct bios_parser *bp,
2192 struct bp_external_encoder_control *cntl);
2193
2194 static void init_external_encoder_control(
2195 struct bios_parser *bp)
2196 {
2197 switch (BIOS_CMD_TABLE_PARA_REVISION(ExternalEncoderControl)) {
2198 case 3:
2199 bp->cmd_tbl.external_encoder_control =
2200 external_encoder_control_v3;
2201 break;
2202 default:
2203 bp->cmd_tbl.external_encoder_control = NULL;
2204 break;
2205 }
2206 }
2207
2208 static enum bp_result external_encoder_control_v3(
2209 struct bios_parser *bp,
2210 struct bp_external_encoder_control *cntl)
2211 {
2212 enum bp_result result = BP_RESULT_FAILURE;
2213
2214
2215 EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION_V3 params;
2216 EXTERNAL_ENCODER_CONTROL_PARAMETERS_V3 *cntl_params;
2217 struct graphics_object_id encoder;
2218 bool is_input_signal_dp = false;
2219
2220 memset(¶ms, 0, sizeof(params));
2221
2222 cntl_params = ¶ms.sExtEncoder;
2223
2224 encoder = cntl->encoder_id;
2225
2226
2227 switch (dal_graphics_object_id_get_encoder_id(encoder)) {
2228 case ENCODER_ID_EXTERNAL_NUTMEG:
2229 case ENCODER_ID_EXTERNAL_TRAVIS:
2230 is_input_signal_dp = true;
2231 break;
2232
2233 default:
2234 BREAK_TO_DEBUGGER();
2235 return BP_RESULT_BADINPUT;
2236 }
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251 cntl_params->ucConfig = (uint8_t)((encoder.enum_id - 1) << 4);
2252
2253 switch (cntl->action) {
2254 case EXTERNAL_ENCODER_CONTROL_INIT:
2255
2256
2257 cntl_params->usConnectorId =
2258 cpu_to_le16((uint16_t)cntl->connector_obj_id.id);
2259 break;
2260 case EXTERNAL_ENCODER_CONTROL_SETUP:
2261
2262
2263
2264
2265
2266 cntl_params->usPixelClock =
2267 cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
2268
2269
2270 cntl_params->ucEncoderMode =
2271 (uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom(
2272 cntl->signal, false);
2273
2274 if (is_input_signal_dp) {
2275
2276
2277 if (LINK_RATE_HIGH == cntl->link_rate)
2278 cntl_params->ucConfig |= 1;
2279
2280
2281
2282 cntl_params->ucBitPerColor =
2283 (uint8_t)(cntl->color_depth);
2284 }
2285
2286
2287 cntl_params->ucLaneNum = (uint8_t)(cntl->lanes_number);
2288 break;
2289 case EXTERNAL_ENCODER_CONTROL_ENABLE:
2290 cntl_params->usPixelClock =
2291 cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
2292 cntl_params->ucEncoderMode =
2293 (uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom(
2294 cntl->signal, false);
2295 cntl_params->ucLaneNum = (uint8_t)cntl->lanes_number;
2296 break;
2297 default:
2298 break;
2299 }
2300
2301 cntl_params->ucAction = (uint8_t)cntl->action;
2302
2303 if (EXEC_BIOS_CMD_TABLE(ExternalEncoderControl, params))
2304 result = BP_RESULT_OK;
2305
2306 return result;
2307 }
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317 static enum bp_result enable_disp_power_gating_v2_1(
2318 struct bios_parser *bp,
2319 enum controller_id crtc_id,
2320 enum bp_pipe_control_action action);
2321
2322 static void init_enable_disp_power_gating(
2323 struct bios_parser *bp)
2324 {
2325 switch (BIOS_CMD_TABLE_PARA_REVISION(EnableDispPowerGating)) {
2326 case 1:
2327 bp->cmd_tbl.enable_disp_power_gating =
2328 enable_disp_power_gating_v2_1;
2329 break;
2330 default:
2331 dm_output_to_console("Don't enable_disp_power_gating enable_crtc for v%d\n",
2332 BIOS_CMD_TABLE_PARA_REVISION(EnableDispPowerGating));
2333 bp->cmd_tbl.enable_disp_power_gating = NULL;
2334 break;
2335 }
2336 }
2337
2338 static enum bp_result enable_disp_power_gating_v2_1(
2339 struct bios_parser *bp,
2340 enum controller_id crtc_id,
2341 enum bp_pipe_control_action action)
2342 {
2343 enum bp_result result = BP_RESULT_FAILURE;
2344
2345 ENABLE_DISP_POWER_GATING_PS_ALLOCATION params = {0};
2346 uint8_t atom_crtc_id;
2347
2348 if (bp->cmd_helper->controller_id_to_atom(crtc_id, &atom_crtc_id))
2349 params.ucDispPipeId = atom_crtc_id;
2350 else
2351 return BP_RESULT_BADINPUT;
2352
2353 params.ucEnable =
2354 bp->cmd_helper->disp_power_gating_action_to_atom(action);
2355
2356 if (EXEC_BIOS_CMD_TABLE(EnableDispPowerGating, params))
2357 result = BP_RESULT_OK;
2358
2359 return result;
2360 }
2361
2362
2363
2364
2365
2366
2367
2368
2369 static enum bp_result set_dce_clock_v2_1(
2370 struct bios_parser *bp,
2371 struct bp_set_dce_clock_parameters *bp_params);
2372
2373 static void init_set_dce_clock(struct bios_parser *bp)
2374 {
2375 switch (BIOS_CMD_TABLE_PARA_REVISION(SetDCEClock)) {
2376 case 1:
2377 bp->cmd_tbl.set_dce_clock = set_dce_clock_v2_1;
2378 break;
2379 default:
2380 dm_output_to_console("Don't have set_dce_clock for v%d\n",
2381 BIOS_CMD_TABLE_PARA_REVISION(SetDCEClock));
2382 bp->cmd_tbl.set_dce_clock = NULL;
2383 break;
2384 }
2385 }
2386
2387 static enum bp_result set_dce_clock_v2_1(
2388 struct bios_parser *bp,
2389 struct bp_set_dce_clock_parameters *bp_params)
2390 {
2391 enum bp_result result = BP_RESULT_FAILURE;
2392
2393 SET_DCE_CLOCK_PS_ALLOCATION_V2_1 params;
2394 uint32_t atom_pll_id;
2395 uint32_t atom_clock_type;
2396 const struct command_table_helper *cmd = bp->cmd_helper;
2397
2398 memset(¶ms, 0, sizeof(params));
2399
2400 if (!cmd->clock_source_id_to_atom(bp_params->pll_id, &atom_pll_id) ||
2401 !cmd->dc_clock_type_to_atom(bp_params->clock_type, &atom_clock_type))
2402 return BP_RESULT_BADINPUT;
2403
2404 params.asParam.ucDCEClkSrc = atom_pll_id;
2405 params.asParam.ucDCEClkType = atom_clock_type;
2406
2407 if (bp_params->clock_type == DCECLOCK_TYPE_DPREFCLK) {
2408 if (bp_params->flags.USE_GENLOCK_AS_SOURCE_FOR_DPREFCLK)
2409 params.asParam.ucDCEClkFlag |= DCE_CLOCK_FLAG_PLL_REFCLK_SRC_GENLK;
2410
2411 if (bp_params->flags.USE_PCIE_AS_SOURCE_FOR_DPREFCLK)
2412 params.asParam.ucDCEClkFlag |= DCE_CLOCK_FLAG_PLL_REFCLK_SRC_PCIE;
2413
2414 if (bp_params->flags.USE_XTALIN_AS_SOURCE_FOR_DPREFCLK)
2415 params.asParam.ucDCEClkFlag |= DCE_CLOCK_FLAG_PLL_REFCLK_SRC_XTALIN;
2416
2417 if (bp_params->flags.USE_GENERICA_AS_SOURCE_FOR_DPREFCLK)
2418 params.asParam.ucDCEClkFlag |= DCE_CLOCK_FLAG_PLL_REFCLK_SRC_GENERICA;
2419 }
2420 else
2421
2422
2423 params.asParam.ulDCEClkFreq = cpu_to_le32(bp_params->target_clock_frequency / 10);
2424
2425 if (EXEC_BIOS_CMD_TABLE(SetDCEClock, params)) {
2426
2427 bp_params->target_clock_frequency = le32_to_cpu(params.asParam.ulDCEClkFreq) * 10;
2428 result = BP_RESULT_OK;
2429 }
2430
2431 return result;
2432 }