2 * Copyright 2012-15 Advanced Micro Devices, Inc.
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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.
26 #include "dm_services.h"
30 #include "include/bios_parser_interface.h"
32 #include "command_table.h"
33 #include "command_table_helper.h"
34 #include "bios_parser_helper.h"
35 #include "bios_parser_types_internal.h"
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) == 0)
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)
46 #define BIOS_CMD_TABLE_PARA_REVISION(command)\
47 bios_cmd_table_para_revision(bp->base.ctx->driver_context, \
48 GetIndexIntoMasterTable(COMMAND, command))
50 static void init_dig_encoder_control(struct bios_parser *bp);
51 static void init_transmitter_control(struct bios_parser *bp);
52 static void init_set_pixel_clock(struct bios_parser *bp);
53 static void init_enable_spread_spectrum_on_ppll(struct bios_parser *bp);
54 static void init_adjust_display_pll(struct bios_parser *bp);
55 static void init_dac_encoder_control(struct bios_parser *bp);
56 static void init_dac_output_control(struct bios_parser *bp);
57 static void init_set_crtc_timing(struct bios_parser *bp);
58 static void init_select_crtc_source(struct bios_parser *bp);
59 static void init_enable_crtc(struct bios_parser *bp);
60 static void init_enable_crtc_mem_req(struct bios_parser *bp);
61 static void init_external_encoder_control(struct bios_parser *bp);
62 static void init_enable_disp_power_gating(struct bios_parser *bp);
63 static void init_program_clock(struct bios_parser *bp);
64 static void init_set_dce_clock(struct bios_parser *bp);
66 void dal_bios_parser_init_cmd_tbl(struct bios_parser *bp)
68 init_dig_encoder_control(bp);
69 init_transmitter_control(bp);
70 init_set_pixel_clock(bp);
71 init_enable_spread_spectrum_on_ppll(bp);
72 init_adjust_display_pll(bp);
73 init_dac_encoder_control(bp);
74 init_dac_output_control(bp);
75 init_set_crtc_timing(bp);
76 init_select_crtc_source(bp);
78 init_enable_crtc_mem_req(bp);
79 init_program_clock(bp);
80 init_external_encoder_control(bp);
81 init_enable_disp_power_gating(bp);
82 init_set_dce_clock(bp);
85 static uint32_t bios_cmd_table_para_revision(void *dev,
88 struct amdgpu_device *adev = dev;
91 if (amdgpu_atom_parse_cmd_header(adev->mode_info.atom_context,
99 /*******************************************************************************
100 ********************************************************************************
102 ** D I G E N C O D E R C O N T R O L
104 ********************************************************************************
105 *******************************************************************************/
106 static enum bp_result encoder_control_digx_v3(
107 struct bios_parser *bp,
108 struct bp_encoder_control *cntl);
110 static enum bp_result encoder_control_digx_v4(
111 struct bios_parser *bp,
112 struct bp_encoder_control *cntl);
114 static enum bp_result encoder_control_digx_v5(
115 struct bios_parser *bp,
116 struct bp_encoder_control *cntl);
118 static void init_encoder_control_dig_v1(struct bios_parser *bp);
120 static void init_dig_encoder_control(struct bios_parser *bp)
123 BIOS_CMD_TABLE_PARA_REVISION(DIGxEncoderControl);
127 bp->cmd_tbl.dig_encoder_control = encoder_control_digx_v3;
130 bp->cmd_tbl.dig_encoder_control = encoder_control_digx_v4;
134 bp->cmd_tbl.dig_encoder_control = encoder_control_digx_v5;
138 init_encoder_control_dig_v1(bp);
143 static enum bp_result encoder_control_dig_v1(
144 struct bios_parser *bp,
145 struct bp_encoder_control *cntl);
146 static enum bp_result encoder_control_dig1_v1(
147 struct bios_parser *bp,
148 struct bp_encoder_control *cntl);
149 static enum bp_result encoder_control_dig2_v1(
150 struct bios_parser *bp,
151 struct bp_encoder_control *cntl);
153 static void init_encoder_control_dig_v1(struct bios_parser *bp)
155 struct cmd_tbl *cmd_tbl = &bp->cmd_tbl;
157 if (1 == BIOS_CMD_TABLE_PARA_REVISION(DIG1EncoderControl))
158 cmd_tbl->encoder_control_dig1 = encoder_control_dig1_v1;
160 cmd_tbl->encoder_control_dig1 = NULL;
162 if (1 == BIOS_CMD_TABLE_PARA_REVISION(DIG2EncoderControl))
163 cmd_tbl->encoder_control_dig2 = encoder_control_dig2_v1;
165 cmd_tbl->encoder_control_dig2 = NULL;
167 cmd_tbl->dig_encoder_control = encoder_control_dig_v1;
170 static enum bp_result encoder_control_dig_v1(
171 struct bios_parser *bp,
172 struct bp_encoder_control *cntl)
174 enum bp_result result = BP_RESULT_FAILURE;
175 struct cmd_tbl *cmd_tbl = &bp->cmd_tbl;
178 switch (cntl->engine_id) {
180 if (cmd_tbl->encoder_control_dig1 != NULL)
182 cmd_tbl->encoder_control_dig1(bp, cntl);
185 if (cmd_tbl->encoder_control_dig2 != NULL)
187 cmd_tbl->encoder_control_dig2(bp, cntl);
197 static enum bp_result encoder_control_dig1_v1(
198 struct bios_parser *bp,
199 struct bp_encoder_control *cntl)
201 enum bp_result result = BP_RESULT_FAILURE;
202 DIG_ENCODER_CONTROL_PARAMETERS_V2 params = {0};
204 bp->cmd_helper->assign_control_parameter(bp->cmd_helper, cntl, ¶ms);
206 if (EXEC_BIOS_CMD_TABLE(DIG1EncoderControl, params))
207 result = BP_RESULT_OK;
212 static enum bp_result encoder_control_dig2_v1(
213 struct bios_parser *bp,
214 struct bp_encoder_control *cntl)
216 enum bp_result result = BP_RESULT_FAILURE;
217 DIG_ENCODER_CONTROL_PARAMETERS_V2 params = {0};
219 bp->cmd_helper->assign_control_parameter(bp->cmd_helper, cntl, ¶ms);
221 if (EXEC_BIOS_CMD_TABLE(DIG2EncoderControl, params))
222 result = BP_RESULT_OK;
227 static enum bp_result encoder_control_digx_v3(
228 struct bios_parser *bp,
229 struct bp_encoder_control *cntl)
231 enum bp_result result = BP_RESULT_FAILURE;
232 DIG_ENCODER_CONTROL_PARAMETERS_V3 params = {0};
234 if (LANE_COUNT_FOUR < cntl->lanes_number)
235 params.acConfig.ucDPLinkRate = 1; /* dual link 2.7GHz */
237 params.acConfig.ucDPLinkRate = 0; /* single link 1.62GHz */
239 params.acConfig.ucDigSel = (uint8_t)(cntl->engine_id);
241 /* We need to convert from KHz units into 10KHz units */
242 params.ucAction = bp->cmd_helper->encoder_action_to_atom(cntl->action);
243 params.usPixelClock = cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
244 params.ucEncoderMode =
245 (uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom(
247 cntl->enable_dp_audio);
248 params.ucLaneNum = (uint8_t)(cntl->lanes_number);
250 if (EXEC_BIOS_CMD_TABLE(DIGxEncoderControl, params))
251 result = BP_RESULT_OK;
256 static enum bp_result encoder_control_digx_v4(
257 struct bios_parser *bp,
258 struct bp_encoder_control *cntl)
260 enum bp_result result = BP_RESULT_FAILURE;
261 DIG_ENCODER_CONTROL_PARAMETERS_V4 params = {0};
263 if (LANE_COUNT_FOUR < cntl->lanes_number)
264 params.acConfig.ucDPLinkRate = 1; /* dual link 2.7GHz */
266 params.acConfig.ucDPLinkRate = 0; /* single link 1.62GHz */
268 params.acConfig.ucDigSel = (uint8_t)(cntl->engine_id);
270 /* We need to convert from KHz units into 10KHz units */
271 params.ucAction = bp->cmd_helper->encoder_action_to_atom(cntl->action);
272 params.usPixelClock = cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
273 params.ucEncoderMode =
274 (uint8_t)(bp->cmd_helper->encoder_mode_bp_to_atom(
276 cntl->enable_dp_audio));
277 params.ucLaneNum = (uint8_t)(cntl->lanes_number);
279 if (EXEC_BIOS_CMD_TABLE(DIGxEncoderControl, params))
280 result = BP_RESULT_OK;
285 static enum bp_result encoder_control_digx_v5(
286 struct bios_parser *bp,
287 struct bp_encoder_control *cntl)
289 enum bp_result result = BP_RESULT_FAILURE;
290 ENCODER_STREAM_SETUP_PARAMETERS_V5 params = {0};
292 params.ucDigId = (uint8_t)(cntl->engine_id);
293 params.ucAction = bp->cmd_helper->encoder_action_to_atom(cntl->action);
295 params.ulPixelClock = cntl->pixel_clock / 10;
297 (uint8_t)(bp->cmd_helper->encoder_mode_bp_to_atom(
299 cntl->enable_dp_audio));
300 params.ucLaneNum = (uint8_t)(cntl->lanes_number);
302 switch (cntl->color_depth) {
303 case COLOR_DEPTH_888:
304 params.ucBitPerColor = PANEL_8BIT_PER_COLOR;
306 case COLOR_DEPTH_101010:
307 params.ucBitPerColor = PANEL_10BIT_PER_COLOR;
309 case COLOR_DEPTH_121212:
310 params.ucBitPerColor = PANEL_12BIT_PER_COLOR;
312 case COLOR_DEPTH_161616:
313 params.ucBitPerColor = PANEL_16BIT_PER_COLOR;
319 if (cntl->signal == SIGNAL_TYPE_HDMI_TYPE_A)
320 switch (cntl->color_depth) {
321 case COLOR_DEPTH_101010:
322 params.ulPixelClock =
323 (params.ulPixelClock * 30) / 24;
325 case COLOR_DEPTH_121212:
326 params.ulPixelClock =
327 (params.ulPixelClock * 36) / 24;
329 case COLOR_DEPTH_161616:
330 params.ulPixelClock =
331 (params.ulPixelClock * 48) / 24;
337 if (EXEC_BIOS_CMD_TABLE(DIGxEncoderControl, params))
338 result = BP_RESULT_OK;
343 /*******************************************************************************
344 ********************************************************************************
346 ** TRANSMITTER CONTROL
348 ********************************************************************************
349 *******************************************************************************/
351 static enum bp_result transmitter_control_v2(
352 struct bios_parser *bp,
353 struct bp_transmitter_control *cntl);
354 static enum bp_result transmitter_control_v3(
355 struct bios_parser *bp,
356 struct bp_transmitter_control *cntl);
357 static enum bp_result transmitter_control_v4(
358 struct bios_parser *bp,
359 struct bp_transmitter_control *cntl);
360 static enum bp_result transmitter_control_v1_5(
361 struct bios_parser *bp,
362 struct bp_transmitter_control *cntl);
363 static enum bp_result transmitter_control_v1_6(
364 struct bios_parser *bp,
365 struct bp_transmitter_control *cntl);
367 static void init_transmitter_control(struct bios_parser *bp)
372 if (BIOS_CMD_TABLE_REVISION(UNIPHYTransmitterControl,
373 frev, crev) == false)
377 bp->cmd_tbl.transmitter_control = transmitter_control_v2;
380 bp->cmd_tbl.transmitter_control = transmitter_control_v3;
383 bp->cmd_tbl.transmitter_control = transmitter_control_v4;
386 bp->cmd_tbl.transmitter_control = transmitter_control_v1_5;
389 bp->cmd_tbl.transmitter_control = transmitter_control_v1_6;
392 dm_output_to_console("Don't have transmitter_control for v%d\n", crev);
393 bp->cmd_tbl.transmitter_control = NULL;
398 static enum bp_result transmitter_control_v2(
399 struct bios_parser *bp,
400 struct bp_transmitter_control *cntl)
402 enum bp_result result = BP_RESULT_FAILURE;
403 DIG_TRANSMITTER_CONTROL_PARAMETERS_V2 params;
404 enum connector_id connector_id =
405 dal_graphics_object_id_get_connector_id(cntl->connector_obj_id);
407 memset(¶ms, 0, sizeof(params));
409 switch (cntl->transmitter) {
410 case TRANSMITTER_UNIPHY_A:
411 case TRANSMITTER_UNIPHY_B:
412 case TRANSMITTER_UNIPHY_C:
413 case TRANSMITTER_UNIPHY_D:
414 case TRANSMITTER_UNIPHY_E:
415 case TRANSMITTER_UNIPHY_F:
416 case TRANSMITTER_TRAVIS_LCD:
419 return BP_RESULT_BADINPUT;
422 switch (cntl->action) {
423 case TRANSMITTER_CONTROL_INIT:
424 if ((CONNECTOR_ID_DUAL_LINK_DVII == connector_id) ||
425 (CONNECTOR_ID_DUAL_LINK_DVID == connector_id))
426 /* on INIT this bit should be set according to the
428 * Bit0: dual link connector flag
429 * =0 connector is single link connector
430 * =1 connector is dual link connector
432 params.acConfig.fDualLinkConnector = 1;
434 /* connector object id */
436 cpu_to_le16((uint8_t)cntl->connector_obj_id.id);
438 case TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS:
439 /* votage swing and pre-emphsis */
440 params.asMode.ucLaneSel = (uint8_t)cntl->lane_select;
441 params.asMode.ucLaneSet = (uint8_t)cntl->lane_settings;
445 if (LANE_COUNT_FOUR < cntl->lanes_number) {
446 /* on ENABLE/DISABLE this bit should be set according to
447 * actual timing (number of lanes)
448 * Bit0: dual link connector flag
449 * =0 connector is single link connector
450 * =1 connector is dual link connector
452 params.acConfig.fDualLinkConnector = 1;
454 /* link rate, half for dual link
455 * We need to convert from KHz units into 20KHz units
457 params.usPixelClock =
458 cpu_to_le16((uint16_t)(cntl->pixel_clock / 20));
460 /* link rate, half for dual link
461 * We need to convert from KHz units into 10KHz units
463 params.usPixelClock =
464 cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
468 /* 00 - coherent mode
469 * 01 - incoherent mode
472 params.acConfig.fCoherentMode = cntl->coherent;
474 if ((TRANSMITTER_UNIPHY_B == cntl->transmitter)
475 || (TRANSMITTER_UNIPHY_D == cntl->transmitter)
476 || (TRANSMITTER_UNIPHY_F == cntl->transmitter))
477 /* Bit2: Transmitter Link selection
478 * =0 when bit0=0, single link A/C/E, when bit0=1,
480 * =1 when bit0=0, single link B/D/F, when bit0=1,
483 params.acConfig.ucLinkSel = 1;
485 if (ENGINE_ID_DIGB == cntl->engine_id)
486 /* Bit3: Transmitter data source selection
487 * =0 DIGA is data source.
488 * =1 DIGB is data source.
489 * This bit is only useful when ucAction= ATOM_ENABLE
491 params.acConfig.ucEncoderSel = 1;
493 if (CONNECTOR_ID_DISPLAY_PORT == connector_id)
494 /* Bit4: DP connector flag
495 * =0 connector is none-DP connector
496 * =1 connector is DP connector
498 params.acConfig.fDPConnector = 1;
500 /* Bit[7:6]: Transmitter selection
501 * =0 UNIPHY_ENCODER: UNIPHYA/B
502 * =1 UNIPHY1_ENCODER: UNIPHYC/D
503 * =2 UNIPHY2_ENCODER: UNIPHYE/F
506 params.acConfig.ucTransmitterSel =
507 (uint8_t)bp->cmd_helper->transmitter_bp_to_atom(
510 params.ucAction = (uint8_t)cntl->action;
512 if (EXEC_BIOS_CMD_TABLE(UNIPHYTransmitterControl, params))
513 result = BP_RESULT_OK;
518 static enum bp_result transmitter_control_v3(
519 struct bios_parser *bp,
520 struct bp_transmitter_control *cntl)
522 enum bp_result result = BP_RESULT_FAILURE;
523 DIG_TRANSMITTER_CONTROL_PARAMETERS_V3 params;
525 enum connector_id conn_id =
526 dal_graphics_object_id_get_connector_id(cntl->connector_obj_id);
527 const struct command_table_helper *cmd = bp->cmd_helper;
528 bool dual_link_conn = (CONNECTOR_ID_DUAL_LINK_DVII == conn_id)
529 || (CONNECTOR_ID_DUAL_LINK_DVID == conn_id);
531 memset(¶ms, 0, sizeof(params));
533 switch (cntl->transmitter) {
534 case TRANSMITTER_UNIPHY_A:
535 case TRANSMITTER_UNIPHY_B:
536 case TRANSMITTER_UNIPHY_C:
537 case TRANSMITTER_UNIPHY_D:
538 case TRANSMITTER_UNIPHY_E:
539 case TRANSMITTER_UNIPHY_F:
540 case TRANSMITTER_TRAVIS_LCD:
543 return BP_RESULT_BADINPUT;
546 if (!cmd->clock_source_id_to_atom(cntl->pll_id, &pll_id))
547 return BP_RESULT_BADINPUT;
549 /* fill information based on the action */
550 switch (cntl->action) {
551 case TRANSMITTER_CONTROL_INIT:
552 if (dual_link_conn) {
553 /* on INIT this bit should be set according to the
555 * Bit0: dual link connector flag
556 * =0 connector is single link connector
557 * =1 connector is dual link connector
559 params.acConfig.fDualLinkConnector = 1;
562 /* connector object id */
564 cpu_to_le16((uint8_t)(cntl->connector_obj_id.id));
566 case TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS:
567 /* votage swing and pre-emphsis */
568 params.asMode.ucLaneSel = (uint8_t)cntl->lane_select;
569 params.asMode.ucLaneSet = (uint8_t)cntl->lane_settings;
572 if (dual_link_conn && cntl->multi_path)
573 /* on ENABLE/DISABLE this bit should be set according to
574 * actual timing (number of lanes)
575 * Bit0: dual link connector flag
576 * =0 connector is single link connector
577 * =1 connector is dual link connector
579 params.acConfig.fDualLinkConnector = 1;
582 if (LANE_COUNT_FOUR < cntl->lanes_number) {
583 /* on ENABLE/DISABLE this bit should be set according to
584 * actual timing (number of lanes)
585 * Bit0: dual link connector flag
586 * =0 connector is single link connector
587 * =1 connector is dual link connector
589 params.acConfig.fDualLinkConnector = 1;
591 /* link rate, half for dual link
592 * We need to convert from KHz units into 20KHz units
594 params.usPixelClock =
595 cpu_to_le16((uint16_t)(cntl->pixel_clock / 20));
597 /* link rate, half for dual link
598 * We need to convert from KHz units into 10KHz units
600 params.usPixelClock =
601 cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
606 /* 00 - coherent mode
607 * 01 - incoherent mode
610 params.acConfig.fCoherentMode = cntl->coherent;
612 if ((TRANSMITTER_UNIPHY_B == cntl->transmitter)
613 || (TRANSMITTER_UNIPHY_D == cntl->transmitter)
614 || (TRANSMITTER_UNIPHY_F == cntl->transmitter))
615 /* Bit2: Transmitter Link selection
616 * =0 when bit0=0, single link A/C/E, when bit0=1,
618 * =1 when bit0=0, single link B/D/F, when bit0=1,
621 params.acConfig.ucLinkSel = 1;
623 if (ENGINE_ID_DIGB == cntl->engine_id)
624 /* Bit3: Transmitter data source selection
625 * =0 DIGA is data source.
626 * =1 DIGB is data source.
627 * This bit is only useful when ucAction= ATOM_ENABLE
629 params.acConfig.ucEncoderSel = 1;
631 /* Bit[7:6]: Transmitter selection
632 * =0 UNIPHY_ENCODER: UNIPHYA/B
633 * =1 UNIPHY1_ENCODER: UNIPHYC/D
634 * =2 UNIPHY2_ENCODER: UNIPHYE/F
637 params.acConfig.ucTransmitterSel =
638 (uint8_t)cmd->transmitter_bp_to_atom(cntl->transmitter);
640 params.ucLaneNum = (uint8_t)cntl->lanes_number;
642 params.acConfig.ucRefClkSource = (uint8_t)pll_id;
644 params.ucAction = (uint8_t)cntl->action;
646 if (EXEC_BIOS_CMD_TABLE(UNIPHYTransmitterControl, params))
647 result = BP_RESULT_OK;
652 static enum bp_result transmitter_control_v4(
653 struct bios_parser *bp,
654 struct bp_transmitter_control *cntl)
656 enum bp_result result = BP_RESULT_FAILURE;
657 DIG_TRANSMITTER_CONTROL_PARAMETERS_V4 params;
658 uint32_t ref_clk_src_id;
659 enum connector_id conn_id =
660 dal_graphics_object_id_get_connector_id(cntl->connector_obj_id);
661 const struct command_table_helper *cmd = bp->cmd_helper;
663 memset(¶ms, 0, sizeof(params));
665 switch (cntl->transmitter) {
666 case TRANSMITTER_UNIPHY_A:
667 case TRANSMITTER_UNIPHY_B:
668 case TRANSMITTER_UNIPHY_C:
669 case TRANSMITTER_UNIPHY_D:
670 case TRANSMITTER_UNIPHY_E:
671 case TRANSMITTER_UNIPHY_F:
672 case TRANSMITTER_TRAVIS_LCD:
675 return BP_RESULT_BADINPUT;
678 if (!cmd->clock_source_id_to_ref_clk_src(cntl->pll_id, &ref_clk_src_id))
679 return BP_RESULT_BADINPUT;
681 switch (cntl->action) {
682 case TRANSMITTER_CONTROL_INIT:
684 if ((CONNECTOR_ID_DUAL_LINK_DVII == conn_id) ||
685 (CONNECTOR_ID_DUAL_LINK_DVID == conn_id))
686 /* on INIT this bit should be set according to the
688 * Bit0: dual link connector flag
689 * =0 connector is single link connector
690 * =1 connector is dual link connector
692 params.acConfig.fDualLinkConnector = 1;
694 /* connector object id */
696 cpu_to_le16((uint8_t)(cntl->connector_obj_id.id));
699 case TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS:
700 /* votage swing and pre-emphsis */
701 params.asMode.ucLaneSel = (uint8_t)(cntl->lane_select);
702 params.asMode.ucLaneSet = (uint8_t)(cntl->lane_settings);
705 if ((CONNECTOR_ID_DUAL_LINK_DVII == conn_id) ||
706 (CONNECTOR_ID_DUAL_LINK_DVID == conn_id))
707 /* on ENABLE/DISABLE this bit should be set according to
708 * actual timing (number of lanes)
709 * Bit0: dual link connector flag
710 * =0 connector is single link connector
711 * =1 connector is dual link connector
713 params.acConfig.fDualLinkConnector = 1;
716 if (LANE_COUNT_FOUR < cntl->lanes_number)
717 /* link rate, half for dual link
718 * We need to convert from KHz units into 20KHz units
720 params.usPixelClock =
721 cpu_to_le16((uint16_t)(cntl->pixel_clock / 20));
723 /* link rate, half for dual link
724 * We need to convert from KHz units into 10KHz units
726 params.usPixelClock =
727 cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
732 /* 00 - coherent mode
733 * 01 - incoherent mode
736 params.acConfig.fCoherentMode = cntl->coherent;
738 if ((TRANSMITTER_UNIPHY_B == cntl->transmitter)
739 || (TRANSMITTER_UNIPHY_D == cntl->transmitter)
740 || (TRANSMITTER_UNIPHY_F == cntl->transmitter))
741 /* Bit2: Transmitter Link selection
742 * =0 when bit0=0, single link A/C/E, when bit0=1,
744 * =1 when bit0=0, single link B/D/F, when bit0=1,
747 params.acConfig.ucLinkSel = 1;
749 if (ENGINE_ID_DIGB == cntl->engine_id)
750 /* Bit3: Transmitter data source selection
751 * =0 DIGA is data source.
752 * =1 DIGB is data source.
753 * This bit is only useful when ucAction= ATOM_ENABLE
755 params.acConfig.ucEncoderSel = 1;
757 /* Bit[7:6]: Transmitter selection
758 * =0 UNIPHY_ENCODER: UNIPHYA/B
759 * =1 UNIPHY1_ENCODER: UNIPHYC/D
760 * =2 UNIPHY2_ENCODER: UNIPHYE/F
763 params.acConfig.ucTransmitterSel =
764 (uint8_t)(cmd->transmitter_bp_to_atom(cntl->transmitter));
765 params.ucLaneNum = (uint8_t)(cntl->lanes_number);
766 params.acConfig.ucRefClkSource = (uint8_t)(ref_clk_src_id);
767 params.ucAction = (uint8_t)(cntl->action);
769 if (EXEC_BIOS_CMD_TABLE(UNIPHYTransmitterControl, params))
770 result = BP_RESULT_OK;
775 static enum bp_result transmitter_control_v1_5(
776 struct bios_parser *bp,
777 struct bp_transmitter_control *cntl)
779 enum bp_result result = BP_RESULT_FAILURE;
780 const struct command_table_helper *cmd = bp->cmd_helper;
781 DIG_TRANSMITTER_CONTROL_PARAMETERS_V1_5 params;
783 memset(¶ms, 0, sizeof(params));
784 params.ucPhyId = cmd->phy_id_to_atom(cntl->transmitter);
785 params.ucAction = (uint8_t)cntl->action;
786 params.ucLaneNum = (uint8_t)cntl->lanes_number;
787 params.ucConnObjId = (uint8_t)cntl->connector_obj_id.id;
790 cmd->signal_type_to_atom_dig_mode(cntl->signal);
791 params.asConfig.ucPhyClkSrcId =
792 cmd->clock_source_id_to_atom_phy_clk_src_id(cntl->pll_id);
793 /* 00 - coherent mode */
794 params.asConfig.ucCoherentMode = cntl->coherent;
795 params.asConfig.ucHPDSel =
796 cmd->hpd_sel_to_atom(cntl->hpd_sel);
797 params.ucDigEncoderSel =
798 cmd->dig_encoder_sel_to_atom(cntl->engine_id);
799 params.ucDPLaneSet = (uint8_t) cntl->lane_settings;
800 params.usSymClock = cpu_to_le16((uint16_t) (cntl->pixel_clock / 10));
802 * In SI/TN case, caller have to set usPixelClock as following:
803 * DP mode: usPixelClock = DP_LINK_CLOCK/10
804 * (DP_LINK_CLOCK = 1.62GHz, 2.7GHz, 5.4GHz)
805 * DVI single link mode: usPixelClock = pixel clock
806 * DVI dual link mode: usPixelClock = pixel clock
807 * HDMI mode: usPixelClock = pixel clock * deep_color_ratio
808 * (=1: 8bpp, =1.25: 10bpp, =1.5:12bpp, =2: 16bpp)
809 * LVDS mode: usPixelClock = pixel clock
812 if (EXEC_BIOS_CMD_TABLE(UNIPHYTransmitterControl, params))
813 result = BP_RESULT_OK;
818 static enum bp_result transmitter_control_v1_6(
819 struct bios_parser *bp,
820 struct bp_transmitter_control *cntl)
822 enum bp_result result = BP_RESULT_FAILURE;
823 const struct command_table_helper *cmd = bp->cmd_helper;
824 DIG_TRANSMITTER_CONTROL_PARAMETERS_V1_6 params;
826 memset(¶ms, 0, sizeof(params));
827 params.ucPhyId = cmd->phy_id_to_atom(cntl->transmitter);
828 params.ucAction = (uint8_t)cntl->action;
830 if (cntl->action == TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS)
831 params.ucDPLaneSet = (uint8_t)cntl->lane_settings;
833 params.ucDigMode = cmd->signal_type_to_atom_dig_mode(cntl->signal);
835 params.ucLaneNum = (uint8_t)cntl->lanes_number;
836 params.ucHPDSel = cmd->hpd_sel_to_atom(cntl->hpd_sel);
837 params.ucDigEncoderSel = cmd->dig_encoder_sel_to_atom(cntl->engine_id);
838 params.ucConnObjId = (uint8_t)cntl->connector_obj_id.id;
839 params.ulSymClock = cntl->pixel_clock/10;
842 * In SI/TN case, caller have to set usPixelClock as following:
843 * DP mode: usPixelClock = DP_LINK_CLOCK/10
844 * (DP_LINK_CLOCK = 1.62GHz, 2.7GHz, 5.4GHz)
845 * DVI single link mode: usPixelClock = pixel clock
846 * DVI dual link mode: usPixelClock = pixel clock
847 * HDMI mode: usPixelClock = pixel clock * deep_color_ratio
848 * (=1: 8bpp, =1.25: 10bpp, =1.5:12bpp, =2: 16bpp)
849 * LVDS mode: usPixelClock = pixel clock
851 switch (cntl->signal) {
852 case SIGNAL_TYPE_HDMI_TYPE_A:
853 switch (cntl->color_depth) {
854 case COLOR_DEPTH_101010:
856 cpu_to_le16((le16_to_cpu(params.ulSymClock) * 30) / 24);
858 case COLOR_DEPTH_121212:
860 cpu_to_le16((le16_to_cpu(params.ulSymClock) * 36) / 24);
862 case COLOR_DEPTH_161616:
864 cpu_to_le16((le16_to_cpu(params.ulSymClock) * 48) / 24);
874 if (EXEC_BIOS_CMD_TABLE(UNIPHYTransmitterControl, params))
875 result = BP_RESULT_OK;
879 /*******************************************************************************
880 ********************************************************************************
884 ********************************************************************************
885 *******************************************************************************/
887 static enum bp_result set_pixel_clock_v3(
888 struct bios_parser *bp,
889 struct bp_pixel_clock_parameters *bp_params);
890 static enum bp_result set_pixel_clock_v5(
891 struct bios_parser *bp,
892 struct bp_pixel_clock_parameters *bp_params);
893 static enum bp_result set_pixel_clock_v6(
894 struct bios_parser *bp,
895 struct bp_pixel_clock_parameters *bp_params);
896 static enum bp_result set_pixel_clock_v7(
897 struct bios_parser *bp,
898 struct bp_pixel_clock_parameters *bp_params);
900 static void init_set_pixel_clock(struct bios_parser *bp)
902 switch (BIOS_CMD_TABLE_PARA_REVISION(SetPixelClock)) {
904 bp->cmd_tbl.set_pixel_clock = set_pixel_clock_v3;
907 bp->cmd_tbl.set_pixel_clock = set_pixel_clock_v5;
910 bp->cmd_tbl.set_pixel_clock = set_pixel_clock_v6;
913 bp->cmd_tbl.set_pixel_clock = set_pixel_clock_v7;
916 dm_output_to_console("Don't have set_pixel_clock for v%d\n",
917 BIOS_CMD_TABLE_PARA_REVISION(SetPixelClock));
918 bp->cmd_tbl.set_pixel_clock = NULL;
923 static enum bp_result set_pixel_clock_v3(
924 struct bios_parser *bp,
925 struct bp_pixel_clock_parameters *bp_params)
927 enum bp_result result = BP_RESULT_FAILURE;
928 PIXEL_CLOCK_PARAMETERS_V3 *params;
929 SET_PIXEL_CLOCK_PS_ALLOCATION allocation;
931 memset(&allocation, 0, sizeof(allocation));
933 if (CLOCK_SOURCE_ID_PLL1 == bp_params->pll_id)
934 allocation.sPCLKInput.ucPpll = ATOM_PPLL1;
935 else if (CLOCK_SOURCE_ID_PLL2 == bp_params->pll_id)
936 allocation.sPCLKInput.ucPpll = ATOM_PPLL2;
938 return BP_RESULT_BADINPUT;
940 allocation.sPCLKInput.usRefDiv =
941 cpu_to_le16((uint16_t)bp_params->reference_divider);
942 allocation.sPCLKInput.usFbDiv =
943 cpu_to_le16((uint16_t)bp_params->feedback_divider);
944 allocation.sPCLKInput.ucFracFbDiv =
945 (uint8_t)bp_params->fractional_feedback_divider;
946 allocation.sPCLKInput.ucPostDiv =
947 (uint8_t)bp_params->pixel_clock_post_divider;
949 /* We need to convert from KHz units into 10KHz units */
950 allocation.sPCLKInput.usPixelClock =
951 cpu_to_le16((uint16_t)(bp_params->target_pixel_clock / 10));
953 params = (PIXEL_CLOCK_PARAMETERS_V3 *)&allocation.sPCLKInput;
954 params->ucTransmitterId =
955 bp->cmd_helper->encoder_id_to_atom(
956 dal_graphics_object_id_get_encoder_id(
957 bp_params->encoder_object_id));
958 params->ucEncoderMode =
959 (uint8_t)(bp->cmd_helper->encoder_mode_bp_to_atom(
960 bp_params->signal_type, false));
962 if (bp_params->flags.FORCE_PROGRAMMING_OF_PLL)
963 params->ucMiscInfo |= PIXEL_CLOCK_MISC_FORCE_PROG_PPLL;
965 if (bp_params->flags.USE_E_CLOCK_AS_SOURCE_FOR_D_CLOCK)
966 params->ucMiscInfo |= PIXEL_CLOCK_MISC_USE_ENGINE_FOR_DISPCLK;
968 if (CONTROLLER_ID_D1 != bp_params->controller_id)
969 params->ucMiscInfo |= PIXEL_CLOCK_MISC_CRTC_SEL_CRTC2;
971 if (EXEC_BIOS_CMD_TABLE(SetPixelClock, allocation))
972 result = BP_RESULT_OK;
977 #ifndef SET_PIXEL_CLOCK_PS_ALLOCATION_V5
978 /* video bios did not define this: */
979 typedef struct _SET_PIXEL_CLOCK_PS_ALLOCATION_V5 {
980 PIXEL_CLOCK_PARAMETERS_V5 sPCLKInput;
981 /* Caller doesn't need to init this portion */
982 ENABLE_SPREAD_SPECTRUM_ON_PPLL sReserved;
983 } SET_PIXEL_CLOCK_PS_ALLOCATION_V5;
986 #ifndef SET_PIXEL_CLOCK_PS_ALLOCATION_V6
987 /* video bios did not define this: */
988 typedef struct _SET_PIXEL_CLOCK_PS_ALLOCATION_V6 {
989 PIXEL_CLOCK_PARAMETERS_V6 sPCLKInput;
990 /* Caller doesn't need to init this portion */
991 ENABLE_SPREAD_SPECTRUM_ON_PPLL sReserved;
992 } SET_PIXEL_CLOCK_PS_ALLOCATION_V6;
995 static enum bp_result set_pixel_clock_v5(
996 struct bios_parser *bp,
997 struct bp_pixel_clock_parameters *bp_params)
999 enum bp_result result = BP_RESULT_FAILURE;
1000 SET_PIXEL_CLOCK_PS_ALLOCATION_V5 clk;
1001 uint8_t controller_id;
1004 memset(&clk, 0, sizeof(clk));
1006 if (bp->cmd_helper->clock_source_id_to_atom(bp_params->pll_id, &pll_id)
1007 && bp->cmd_helper->controller_id_to_atom(
1008 bp_params->controller_id, &controller_id)) {
1009 clk.sPCLKInput.ucCRTC = controller_id;
1010 clk.sPCLKInput.ucPpll = (uint8_t)pll_id;
1011 clk.sPCLKInput.ucRefDiv =
1012 (uint8_t)(bp_params->reference_divider);
1013 clk.sPCLKInput.usFbDiv =
1014 cpu_to_le16((uint16_t)(bp_params->feedback_divider));
1015 clk.sPCLKInput.ulFbDivDecFrac =
1016 cpu_to_le32(bp_params->fractional_feedback_divider);
1017 clk.sPCLKInput.ucPostDiv =
1018 (uint8_t)(bp_params->pixel_clock_post_divider);
1019 clk.sPCLKInput.ucTransmitterID =
1020 bp->cmd_helper->encoder_id_to_atom(
1021 dal_graphics_object_id_get_encoder_id(
1022 bp_params->encoder_object_id));
1023 clk.sPCLKInput.ucEncoderMode =
1024 (uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom(
1025 bp_params->signal_type, false);
1027 /* We need to convert from KHz units into 10KHz units */
1028 clk.sPCLKInput.usPixelClock =
1029 cpu_to_le16((uint16_t)(bp_params->target_pixel_clock / 10));
1031 if (bp_params->flags.FORCE_PROGRAMMING_OF_PLL)
1032 clk.sPCLKInput.ucMiscInfo |=
1033 PIXEL_CLOCK_MISC_FORCE_PROG_PPLL;
1035 if (bp_params->flags.SET_EXTERNAL_REF_DIV_SRC)
1036 clk.sPCLKInput.ucMiscInfo |=
1037 PIXEL_CLOCK_MISC_REF_DIV_SRC;
1039 /* clkV5.ucMiscInfo bit[3:2]= HDMI panel bit depth: =0: 24bpp
1040 * =1:30bpp, =2:32bpp
1041 * driver choose program it itself, i.e. here we program it
1042 * to 888 by default.
1045 if (EXEC_BIOS_CMD_TABLE(SetPixelClock, clk))
1046 result = BP_RESULT_OK;
1052 static enum bp_result set_pixel_clock_v6(
1053 struct bios_parser *bp,
1054 struct bp_pixel_clock_parameters *bp_params)
1056 enum bp_result result = BP_RESULT_FAILURE;
1057 SET_PIXEL_CLOCK_PS_ALLOCATION_V6 clk;
1058 uint8_t controller_id;
1061 memset(&clk, 0, sizeof(clk));
1063 if (bp->cmd_helper->clock_source_id_to_atom(bp_params->pll_id, &pll_id)
1064 && bp->cmd_helper->controller_id_to_atom(
1065 bp_params->controller_id, &controller_id)) {
1066 /* Note: VBIOS still wants to use ucCRTC name which is now
1068 *typedef struct _CRTC_PIXEL_CLOCK_FREQ
1070 * target the pixel clock to drive the CRTC timing.
1071 * ULONG ulPixelClock:24;
1072 * 0 means disable PPLL/DCPLL. Expanded to 24 bits comparing to
1074 * ATOM_CRTC1~6, indicate the CRTC controller to
1076 * drive the pixel clock. not used for DCPLL case.
1077 *}CRTC_PIXEL_CLOCK_FREQ;
1080 * pixel clock and CRTC id frequency
1081 * CRTC_PIXEL_CLOCK_FREQ ulCrtcPclkFreq;
1082 * ULONG ulDispEngClkFreq; dispclk frequency
1085 clk.sPCLKInput.ulCrtcPclkFreq.ucCRTC = controller_id;
1086 clk.sPCLKInput.ucPpll = (uint8_t) pll_id;
1087 clk.sPCLKInput.ucRefDiv =
1088 (uint8_t) bp_params->reference_divider;
1089 clk.sPCLKInput.usFbDiv =
1090 cpu_to_le16((uint16_t) bp_params->feedback_divider);
1091 clk.sPCLKInput.ulFbDivDecFrac =
1092 cpu_to_le32(bp_params->fractional_feedback_divider);
1093 clk.sPCLKInput.ucPostDiv =
1094 (uint8_t) bp_params->pixel_clock_post_divider;
1095 clk.sPCLKInput.ucTransmitterID =
1096 bp->cmd_helper->encoder_id_to_atom(
1097 dal_graphics_object_id_get_encoder_id(
1098 bp_params->encoder_object_id));
1099 clk.sPCLKInput.ucEncoderMode =
1100 (uint8_t) bp->cmd_helper->encoder_mode_bp_to_atom(
1101 bp_params->signal_type, false);
1103 /* We need to convert from KHz units into 10KHz units */
1104 clk.sPCLKInput.ulCrtcPclkFreq.ulPixelClock =
1105 cpu_to_le32(bp_params->target_pixel_clock / 10);
1107 if (bp_params->flags.FORCE_PROGRAMMING_OF_PLL) {
1108 clk.sPCLKInput.ucMiscInfo |=
1109 PIXEL_CLOCK_V6_MISC_FORCE_PROG_PPLL;
1112 if (bp_params->flags.SET_EXTERNAL_REF_DIV_SRC) {
1113 clk.sPCLKInput.ucMiscInfo |=
1114 PIXEL_CLOCK_V6_MISC_REF_DIV_SRC;
1117 /* clkV6.ucMiscInfo bit[3:2]= HDMI panel bit depth: =0:
1118 * 24bpp =1:30bpp, =2:32bpp
1119 * driver choose program it itself, i.e. here we pass required
1120 * target rate that includes deep color.
1123 if (EXEC_BIOS_CMD_TABLE(SetPixelClock, clk))
1124 result = BP_RESULT_OK;
1130 static enum bp_result set_pixel_clock_v7(
1131 struct bios_parser *bp,
1132 struct bp_pixel_clock_parameters *bp_params)
1134 enum bp_result result = BP_RESULT_FAILURE;
1135 PIXEL_CLOCK_PARAMETERS_V7 clk;
1136 uint8_t controller_id;
1139 memset(&clk, 0, sizeof(clk));
1141 if (bp->cmd_helper->clock_source_id_to_atom(bp_params->pll_id, &pll_id)
1142 && bp->cmd_helper->controller_id_to_atom(bp_params->controller_id, &controller_id)) {
1143 /* Note: VBIOS still wants to use ucCRTC name which is now
1145 *typedef struct _CRTC_PIXEL_CLOCK_FREQ
1147 * target the pixel clock to drive the CRTC timing.
1148 * ULONG ulPixelClock:24;
1149 * 0 means disable PPLL/DCPLL. Expanded to 24 bits comparing to
1151 * ATOM_CRTC1~6, indicate the CRTC controller to
1153 * drive the pixel clock. not used for DCPLL case.
1154 *}CRTC_PIXEL_CLOCK_FREQ;
1157 * pixel clock and CRTC id frequency
1158 * CRTC_PIXEL_CLOCK_FREQ ulCrtcPclkFreq;
1159 * ULONG ulDispEngClkFreq; dispclk frequency
1162 clk.ucCRTC = controller_id;
1163 clk.ucPpll = (uint8_t) pll_id;
1164 clk.ucTransmitterID = bp->cmd_helper->encoder_id_to_atom(dal_graphics_object_id_get_encoder_id(bp_params->encoder_object_id));
1165 clk.ucEncoderMode = (uint8_t) bp->cmd_helper->encoder_mode_bp_to_atom(bp_params->signal_type, false);
1167 /* We need to convert from KHz units into 10KHz units */
1168 clk.ulPixelClock = cpu_to_le32(bp_params->target_pixel_clock * 10);
1170 clk.ucDeepColorRatio = (uint8_t) bp->cmd_helper->transmitter_color_depth_to_atom(bp_params->color_depth);
1172 if (bp_params->flags.FORCE_PROGRAMMING_OF_PLL)
1173 clk.ucMiscInfo |= PIXEL_CLOCK_V7_MISC_FORCE_PROG_PPLL;
1175 if (bp_params->flags.SET_EXTERNAL_REF_DIV_SRC)
1176 clk.ucMiscInfo |= PIXEL_CLOCK_V7_MISC_REF_DIV_SRC;
1178 if (bp_params->flags.PROGRAM_PHY_PLL_ONLY)
1179 clk.ucMiscInfo |= PIXEL_CLOCK_V7_MISC_PROG_PHYPLL;
1181 if (bp_params->flags.SUPPORT_YUV_420)
1182 clk.ucMiscInfo |= PIXEL_CLOCK_V7_MISC_YUV420_MODE;
1184 if (bp_params->flags.SET_XTALIN_REF_SRC)
1185 clk.ucMiscInfo |= PIXEL_CLOCK_V7_MISC_REF_DIV_SRC_XTALIN;
1187 if (bp_params->flags.SET_GENLOCK_REF_DIV_SRC)
1188 clk.ucMiscInfo |= PIXEL_CLOCK_V7_MISC_REF_DIV_SRC_GENLK;
1190 if (bp_params->signal_type == SIGNAL_TYPE_DVI_DUAL_LINK)
1191 clk.ucMiscInfo |= PIXEL_CLOCK_V7_MISC_DVI_DUALLINK_EN;
1193 if (EXEC_BIOS_CMD_TABLE(SetPixelClock, clk))
1194 result = BP_RESULT_OK;
1199 /*******************************************************************************
1200 ********************************************************************************
1202 ** ENABLE PIXEL CLOCK SS
1204 ********************************************************************************
1205 *******************************************************************************/
1206 static enum bp_result enable_spread_spectrum_on_ppll_v1(
1207 struct bios_parser *bp,
1208 struct bp_spread_spectrum_parameters *bp_params,
1210 static enum bp_result enable_spread_spectrum_on_ppll_v2(
1211 struct bios_parser *bp,
1212 struct bp_spread_spectrum_parameters *bp_params,
1214 static enum bp_result enable_spread_spectrum_on_ppll_v3(
1215 struct bios_parser *bp,
1216 struct bp_spread_spectrum_parameters *bp_params,
1219 static void init_enable_spread_spectrum_on_ppll(struct bios_parser *bp)
1221 switch (BIOS_CMD_TABLE_PARA_REVISION(EnableSpreadSpectrumOnPPLL)) {
1223 bp->cmd_tbl.enable_spread_spectrum_on_ppll =
1224 enable_spread_spectrum_on_ppll_v1;
1227 bp->cmd_tbl.enable_spread_spectrum_on_ppll =
1228 enable_spread_spectrum_on_ppll_v2;
1231 bp->cmd_tbl.enable_spread_spectrum_on_ppll =
1232 enable_spread_spectrum_on_ppll_v3;
1235 dm_output_to_console("Don't have enable_spread_spectrum_on_ppll for v%d\n",
1236 BIOS_CMD_TABLE_PARA_REVISION(EnableSpreadSpectrumOnPPLL));
1237 bp->cmd_tbl.enable_spread_spectrum_on_ppll = NULL;
1242 static enum bp_result enable_spread_spectrum_on_ppll_v1(
1243 struct bios_parser *bp,
1244 struct bp_spread_spectrum_parameters *bp_params,
1247 enum bp_result result = BP_RESULT_FAILURE;
1248 ENABLE_SPREAD_SPECTRUM_ON_PPLL params;
1250 memset(¶ms, 0, sizeof(params));
1252 if ((enable == true) && (bp_params->percentage > 0))
1253 params.ucEnable = ATOM_ENABLE;
1255 params.ucEnable = ATOM_DISABLE;
1257 params.usSpreadSpectrumPercentage =
1258 cpu_to_le16((uint16_t)bp_params->percentage);
1259 params.ucSpreadSpectrumStep =
1260 (uint8_t)bp_params->ver1.step;
1261 params.ucSpreadSpectrumDelay =
1262 (uint8_t)bp_params->ver1.delay;
1263 /* convert back to unit of 10KHz */
1264 params.ucSpreadSpectrumRange =
1265 (uint8_t)(bp_params->ver1.range / 10000);
1267 if (bp_params->flags.EXTERNAL_SS)
1268 params.ucSpreadSpectrumType |= ATOM_EXTERNAL_SS_MASK;
1270 if (bp_params->flags.CENTER_SPREAD)
1271 params.ucSpreadSpectrumType |= ATOM_SS_CENTRE_SPREAD_MODE;
1273 if (bp_params->pll_id == CLOCK_SOURCE_ID_PLL1)
1274 params.ucPpll = ATOM_PPLL1;
1275 else if (bp_params->pll_id == CLOCK_SOURCE_ID_PLL2)
1276 params.ucPpll = ATOM_PPLL2;
1278 BREAK_TO_DEBUGGER(); /* Unexpected PLL value!! */
1280 if (EXEC_BIOS_CMD_TABLE(EnableSpreadSpectrumOnPPLL, params))
1281 result = BP_RESULT_OK;
1286 static enum bp_result enable_spread_spectrum_on_ppll_v2(
1287 struct bios_parser *bp,
1288 struct bp_spread_spectrum_parameters *bp_params,
1291 enum bp_result result = BP_RESULT_FAILURE;
1292 ENABLE_SPREAD_SPECTRUM_ON_PPLL_V2 params;
1294 memset(¶ms, 0, sizeof(params));
1296 if (bp_params->pll_id == CLOCK_SOURCE_ID_PLL1)
1297 params.ucSpreadSpectrumType = ATOM_PPLL_SS_TYPE_V2_P1PLL;
1298 else if (bp_params->pll_id == CLOCK_SOURCE_ID_PLL2)
1299 params.ucSpreadSpectrumType = ATOM_PPLL_SS_TYPE_V2_P2PLL;
1301 BREAK_TO_DEBUGGER(); /* Unexpected PLL value!! */
1303 if ((enable == true) && (bp_params->percentage > 0)) {
1304 params.ucEnable = ATOM_ENABLE;
1306 params.usSpreadSpectrumPercentage =
1307 cpu_to_le16((uint16_t)(bp_params->percentage));
1308 params.usSpreadSpectrumStep =
1309 cpu_to_le16((uint16_t)(bp_params->ds.ds_frac_size));
1311 if (bp_params->flags.EXTERNAL_SS)
1312 params.ucSpreadSpectrumType |=
1313 ATOM_PPLL_SS_TYPE_V2_EXT_SPREAD;
1315 if (bp_params->flags.CENTER_SPREAD)
1316 params.ucSpreadSpectrumType |=
1317 ATOM_PPLL_SS_TYPE_V2_CENTRE_SPREAD;
1319 /* Both amounts need to be left shifted first before bit
1320 * comparison. Otherwise, the result will always be zero here
1322 params.usSpreadSpectrumAmount = cpu_to_le16((uint16_t)(
1323 ((bp_params->ds.feedback_amount <<
1324 ATOM_PPLL_SS_AMOUNT_V2_FBDIV_SHIFT) &
1325 ATOM_PPLL_SS_AMOUNT_V2_FBDIV_MASK) |
1326 ((bp_params->ds.nfrac_amount <<
1327 ATOM_PPLL_SS_AMOUNT_V2_NFRAC_SHIFT) &
1328 ATOM_PPLL_SS_AMOUNT_V2_NFRAC_MASK)));
1330 params.ucEnable = ATOM_DISABLE;
1332 if (EXEC_BIOS_CMD_TABLE(EnableSpreadSpectrumOnPPLL, params))
1333 result = BP_RESULT_OK;
1338 static enum bp_result enable_spread_spectrum_on_ppll_v3(
1339 struct bios_parser *bp,
1340 struct bp_spread_spectrum_parameters *bp_params,
1343 enum bp_result result = BP_RESULT_FAILURE;
1344 ENABLE_SPREAD_SPECTRUM_ON_PPLL_V3 params;
1346 memset(¶ms, 0, sizeof(params));
1348 switch (bp_params->pll_id) {
1349 case CLOCK_SOURCE_ID_PLL0:
1350 /* ATOM_PPLL_SS_TYPE_V3_P0PLL; this is pixel clock only,
1351 * not for SI display clock.
1353 params.ucSpreadSpectrumType = ATOM_PPLL_SS_TYPE_V3_DCPLL;
1355 case CLOCK_SOURCE_ID_PLL1:
1356 params.ucSpreadSpectrumType = ATOM_PPLL_SS_TYPE_V3_P1PLL;
1359 case CLOCK_SOURCE_ID_PLL2:
1360 params.ucSpreadSpectrumType = ATOM_PPLL_SS_TYPE_V3_P2PLL;
1363 case CLOCK_SOURCE_ID_DCPLL:
1364 params.ucSpreadSpectrumType = ATOM_PPLL_SS_TYPE_V3_DCPLL;
1368 BREAK_TO_DEBUGGER();
1369 /* Unexpected PLL value!! */
1373 if (enable == true) {
1374 params.ucEnable = ATOM_ENABLE;
1376 params.usSpreadSpectrumAmountFrac =
1377 cpu_to_le16((uint16_t)(bp_params->ds_frac_amount));
1378 params.usSpreadSpectrumStep =
1379 cpu_to_le16((uint16_t)(bp_params->ds.ds_frac_size));
1381 if (bp_params->flags.EXTERNAL_SS)
1382 params.ucSpreadSpectrumType |=
1383 ATOM_PPLL_SS_TYPE_V3_EXT_SPREAD;
1384 if (bp_params->flags.CENTER_SPREAD)
1385 params.ucSpreadSpectrumType |=
1386 ATOM_PPLL_SS_TYPE_V3_CENTRE_SPREAD;
1388 /* Both amounts need to be left shifted first before bit
1389 * comparison. Otherwise, the result will always be zero here
1391 params.usSpreadSpectrumAmount = cpu_to_le16((uint16_t)(
1392 ((bp_params->ds.feedback_amount <<
1393 ATOM_PPLL_SS_AMOUNT_V3_FBDIV_SHIFT) &
1394 ATOM_PPLL_SS_AMOUNT_V3_FBDIV_MASK) |
1395 ((bp_params->ds.nfrac_amount <<
1396 ATOM_PPLL_SS_AMOUNT_V3_NFRAC_SHIFT) &
1397 ATOM_PPLL_SS_AMOUNT_V3_NFRAC_MASK)));
1399 params.ucEnable = ATOM_DISABLE;
1401 if (EXEC_BIOS_CMD_TABLE(EnableSpreadSpectrumOnPPLL, params))
1402 result = BP_RESULT_OK;
1407 /*******************************************************************************
1408 ********************************************************************************
1410 ** ADJUST DISPLAY PLL
1412 ********************************************************************************
1413 *******************************************************************************/
1415 static enum bp_result adjust_display_pll_v2(
1416 struct bios_parser *bp,
1417 struct bp_adjust_pixel_clock_parameters *bp_params);
1418 static enum bp_result adjust_display_pll_v3(
1419 struct bios_parser *bp,
1420 struct bp_adjust_pixel_clock_parameters *bp_params);
1422 static void init_adjust_display_pll(struct bios_parser *bp)
1424 switch (BIOS_CMD_TABLE_PARA_REVISION(AdjustDisplayPll)) {
1426 bp->cmd_tbl.adjust_display_pll = adjust_display_pll_v2;
1429 bp->cmd_tbl.adjust_display_pll = adjust_display_pll_v3;
1432 dm_output_to_console("Don't have adjust_display_pll for v%d\n",
1433 BIOS_CMD_TABLE_PARA_REVISION(AdjustDisplayPll));
1434 bp->cmd_tbl.adjust_display_pll = NULL;
1439 static enum bp_result adjust_display_pll_v2(
1440 struct bios_parser *bp,
1441 struct bp_adjust_pixel_clock_parameters *bp_params)
1443 enum bp_result result = BP_RESULT_FAILURE;
1444 ADJUST_DISPLAY_PLL_PS_ALLOCATION params = { 0 };
1446 /* We need to convert from KHz units into 10KHz units and then convert
1447 * output pixel clock back 10KHz-->KHz */
1448 uint32_t pixel_clock_10KHz_in = bp_params->pixel_clock / 10;
1450 params.usPixelClock = cpu_to_le16((uint16_t)(pixel_clock_10KHz_in));
1451 params.ucTransmitterID =
1452 bp->cmd_helper->encoder_id_to_atom(
1453 dal_graphics_object_id_get_encoder_id(
1454 bp_params->encoder_object_id));
1455 params.ucEncodeMode =
1456 (uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom(
1457 bp_params->signal_type, false);
1461 static enum bp_result adjust_display_pll_v3(
1462 struct bios_parser *bp,
1463 struct bp_adjust_pixel_clock_parameters *bp_params)
1465 enum bp_result result = BP_RESULT_FAILURE;
1466 ADJUST_DISPLAY_PLL_PS_ALLOCATION_V3 params;
1467 uint32_t pixel_clk_10_kHz_in = bp_params->pixel_clock / 10;
1469 memset(¶ms, 0, sizeof(params));
1471 /* We need to convert from KHz units into 10KHz units and then convert
1472 * output pixel clock back 10KHz-->KHz */
1473 params.sInput.usPixelClock = cpu_to_le16((uint16_t)pixel_clk_10_kHz_in);
1474 params.sInput.ucTransmitterID =
1475 bp->cmd_helper->encoder_id_to_atom(
1476 dal_graphics_object_id_get_encoder_id(
1477 bp_params->encoder_object_id));
1478 params.sInput.ucEncodeMode =
1479 (uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom(
1480 bp_params->signal_type, false);
1482 if (bp_params->ss_enable == true)
1483 params.sInput.ucDispPllConfig |= DISPPLL_CONFIG_SS_ENABLE;
1485 if (bp_params->signal_type == SIGNAL_TYPE_DVI_DUAL_LINK)
1486 params.sInput.ucDispPllConfig |= DISPPLL_CONFIG_DUAL_LINK;
1488 if (EXEC_BIOS_CMD_TABLE(AdjustDisplayPll, params)) {
1489 /* Convert output pixel clock back 10KHz-->KHz: multiply
1490 * original pixel clock in KHz by ratio
1491 * [output pxlClk/input pxlClk] */
1492 uint64_t pixel_clk_10_khz_out =
1493 (uint64_t)le32_to_cpu(params.sOutput.ulDispPllFreq);
1494 uint64_t pixel_clk = (uint64_t)bp_params->pixel_clock;
1496 if (pixel_clk_10_kHz_in != 0) {
1497 bp_params->adjusted_pixel_clock =
1498 div_u64(pixel_clk * pixel_clk_10_khz_out,
1499 pixel_clk_10_kHz_in);
1501 bp_params->adjusted_pixel_clock = 0;
1502 BREAK_TO_DEBUGGER();
1505 bp_params->reference_divider = params.sOutput.ucRefDiv;
1506 bp_params->pixel_clock_post_divider = params.sOutput.ucPostDiv;
1508 result = BP_RESULT_OK;
1514 /*******************************************************************************
1515 ********************************************************************************
1517 ** DAC ENCODER CONTROL
1519 ********************************************************************************
1520 *******************************************************************************/
1522 static enum bp_result dac1_encoder_control_v1(
1523 struct bios_parser *bp,
1525 uint32_t pixel_clock,
1526 uint8_t dac_standard);
1527 static enum bp_result dac2_encoder_control_v1(
1528 struct bios_parser *bp,
1530 uint32_t pixel_clock,
1531 uint8_t dac_standard);
1533 static void init_dac_encoder_control(struct bios_parser *bp)
1535 switch (BIOS_CMD_TABLE_PARA_REVISION(DAC1EncoderControl)) {
1537 bp->cmd_tbl.dac1_encoder_control = dac1_encoder_control_v1;
1540 bp->cmd_tbl.dac1_encoder_control = NULL;
1543 switch (BIOS_CMD_TABLE_PARA_REVISION(DAC2EncoderControl)) {
1545 bp->cmd_tbl.dac2_encoder_control = dac2_encoder_control_v1;
1548 bp->cmd_tbl.dac2_encoder_control = NULL;
1553 static void dac_encoder_control_prepare_params(
1554 DAC_ENCODER_CONTROL_PS_ALLOCATION *params,
1556 uint32_t pixel_clock,
1557 uint8_t dac_standard)
1559 params->ucDacStandard = dac_standard;
1561 params->ucAction = ATOM_ENABLE;
1563 params->ucAction = ATOM_DISABLE;
1565 /* We need to convert from KHz units into 10KHz units
1566 * it looks as if the TvControl do not care about pixel clock
1568 params->usPixelClock = cpu_to_le16((uint16_t)(pixel_clock / 10));
1571 static enum bp_result dac1_encoder_control_v1(
1572 struct bios_parser *bp,
1574 uint32_t pixel_clock,
1575 uint8_t dac_standard)
1577 enum bp_result result = BP_RESULT_FAILURE;
1578 DAC_ENCODER_CONTROL_PS_ALLOCATION params;
1580 dac_encoder_control_prepare_params(
1586 if (EXEC_BIOS_CMD_TABLE(DAC1EncoderControl, params))
1587 result = BP_RESULT_OK;
1592 static enum bp_result dac2_encoder_control_v1(
1593 struct bios_parser *bp,
1595 uint32_t pixel_clock,
1596 uint8_t dac_standard)
1598 enum bp_result result = BP_RESULT_FAILURE;
1599 DAC_ENCODER_CONTROL_PS_ALLOCATION params;
1601 dac_encoder_control_prepare_params(
1607 if (EXEC_BIOS_CMD_TABLE(DAC2EncoderControl, params))
1608 result = BP_RESULT_OK;
1613 /*******************************************************************************
1614 ********************************************************************************
1616 ** DAC OUTPUT CONTROL
1618 ********************************************************************************
1619 *******************************************************************************/
1620 static enum bp_result dac1_output_control_v1(
1621 struct bios_parser *bp,
1623 static enum bp_result dac2_output_control_v1(
1624 struct bios_parser *bp,
1627 static void init_dac_output_control(struct bios_parser *bp)
1629 switch (BIOS_CMD_TABLE_PARA_REVISION(DAC1OutputControl)) {
1631 bp->cmd_tbl.dac1_output_control = dac1_output_control_v1;
1634 bp->cmd_tbl.dac1_output_control = NULL;
1637 switch (BIOS_CMD_TABLE_PARA_REVISION(DAC2OutputControl)) {
1639 bp->cmd_tbl.dac2_output_control = dac2_output_control_v1;
1642 bp->cmd_tbl.dac2_output_control = NULL;
1647 static enum bp_result dac1_output_control_v1(
1648 struct bios_parser *bp, bool enable)
1650 enum bp_result result = BP_RESULT_FAILURE;
1651 DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION params;
1654 params.ucAction = ATOM_ENABLE;
1656 params.ucAction = ATOM_DISABLE;
1658 if (EXEC_BIOS_CMD_TABLE(DAC1OutputControl, params))
1659 result = BP_RESULT_OK;
1664 static enum bp_result dac2_output_control_v1(
1665 struct bios_parser *bp, bool enable)
1667 enum bp_result result = BP_RESULT_FAILURE;
1668 DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION params;
1671 params.ucAction = ATOM_ENABLE;
1673 params.ucAction = ATOM_DISABLE;
1675 if (EXEC_BIOS_CMD_TABLE(DAC2OutputControl, params))
1676 result = BP_RESULT_OK;
1681 /*******************************************************************************
1682 ********************************************************************************
1686 ********************************************************************************
1687 *******************************************************************************/
1689 static enum bp_result set_crtc_using_dtd_timing_v3(
1690 struct bios_parser *bp,
1691 struct bp_hw_crtc_timing_parameters *bp_params);
1692 static enum bp_result set_crtc_timing_v1(
1693 struct bios_parser *bp,
1694 struct bp_hw_crtc_timing_parameters *bp_params);
1696 static void init_set_crtc_timing(struct bios_parser *bp)
1698 uint32_t dtd_version =
1699 BIOS_CMD_TABLE_PARA_REVISION(SetCRTC_UsingDTDTiming);
1700 if (dtd_version > 2)
1701 switch (dtd_version) {
1703 bp->cmd_tbl.set_crtc_timing =
1704 set_crtc_using_dtd_timing_v3;
1707 dm_output_to_console("Don't have set_crtc_timing for dtd v%d\n",
1709 bp->cmd_tbl.set_crtc_timing = NULL;
1713 switch (BIOS_CMD_TABLE_PARA_REVISION(SetCRTC_Timing)) {
1715 bp->cmd_tbl.set_crtc_timing = set_crtc_timing_v1;
1718 dm_output_to_console("Don't have set_crtc_timing for v%d\n",
1719 BIOS_CMD_TABLE_PARA_REVISION(SetCRTC_Timing));
1720 bp->cmd_tbl.set_crtc_timing = NULL;
1725 static enum bp_result set_crtc_timing_v1(
1726 struct bios_parser *bp,
1727 struct bp_hw_crtc_timing_parameters *bp_params)
1729 enum bp_result result = BP_RESULT_FAILURE;
1730 SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION params = {0};
1731 uint8_t atom_controller_id;
1733 if (bp->cmd_helper->controller_id_to_atom(
1734 bp_params->controller_id, &atom_controller_id))
1735 params.ucCRTC = atom_controller_id;
1737 params.usH_Total = cpu_to_le16((uint16_t)(bp_params->h_total));
1738 params.usH_Disp = cpu_to_le16((uint16_t)(bp_params->h_addressable));
1739 params.usH_SyncStart = cpu_to_le16((uint16_t)(bp_params->h_sync_start));
1740 params.usH_SyncWidth = cpu_to_le16((uint16_t)(bp_params->h_sync_width));
1741 params.usV_Total = cpu_to_le16((uint16_t)(bp_params->v_total));
1742 params.usV_Disp = cpu_to_le16((uint16_t)(bp_params->v_addressable));
1743 params.usV_SyncStart =
1744 cpu_to_le16((uint16_t)(bp_params->v_sync_start));
1745 params.usV_SyncWidth =
1746 cpu_to_le16((uint16_t)(bp_params->v_sync_width));
1748 /* VBIOS does not expect any value except zero into this call, for
1749 * underscan use another entry ProgramOverscan call but when mode
1750 * 1776x1000 with the overscan 72x44 .e.i. 1920x1080 @30 DAL2 is ok,
1751 * but when same ,but 60 Hz there is corruption
1752 * DAL1 does not allow the mode 1776x1000@60
1754 params.ucOverscanRight = (uint8_t)bp_params->h_overscan_right;
1755 params.ucOverscanLeft = (uint8_t)bp_params->h_overscan_left;
1756 params.ucOverscanBottom = (uint8_t)bp_params->v_overscan_bottom;
1757 params.ucOverscanTop = (uint8_t)bp_params->v_overscan_top;
1759 if (0 == bp_params->flags.HSYNC_POSITIVE_POLARITY)
1760 params.susModeMiscInfo.usAccess =
1761 cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_HSYNC_POLARITY);
1763 if (0 == bp_params->flags.VSYNC_POSITIVE_POLARITY)
1764 params.susModeMiscInfo.usAccess =
1765 cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_VSYNC_POLARITY);
1767 if (bp_params->flags.INTERLACE) {
1768 params.susModeMiscInfo.usAccess =
1769 cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_INTERLACE);
1771 /* original DAL code has this condition to apply tis for
1772 * non-TV/CV only due to complex MV testing for possible
1774 * if (pACParameters->signal != SignalType_YPbPr &&
1775 * pACParameters->signal != SignalType_Composite &&
1776 * pACParameters->signal != SignalType_SVideo)
1778 /* HW will deduct 0.5 line from 2nd feild.
1779 * i.e. for 1080i, it is 2 lines for 1st field, 2.5
1780 * lines for the 2nd feild. we need input as 5 instead
1781 * of 4, but it is 4 either from Edid data
1782 * (spec CEA 861) or CEA timing table.
1784 params.usV_SyncStart =
1785 cpu_to_le16((uint16_t)(bp_params->v_sync_start + 1));
1788 if (bp_params->flags.HORZ_COUNT_BY_TWO)
1789 params.susModeMiscInfo.usAccess =
1790 cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_DOUBLE_CLOCK_MODE);
1792 if (EXEC_BIOS_CMD_TABLE(SetCRTC_Timing, params))
1793 result = BP_RESULT_OK;
1798 static enum bp_result set_crtc_using_dtd_timing_v3(
1799 struct bios_parser *bp,
1800 struct bp_hw_crtc_timing_parameters *bp_params)
1802 enum bp_result result = BP_RESULT_FAILURE;
1803 SET_CRTC_USING_DTD_TIMING_PARAMETERS params = {0};
1804 uint8_t atom_controller_id;
1806 if (bp->cmd_helper->controller_id_to_atom(
1807 bp_params->controller_id, &atom_controller_id))
1808 params.ucCRTC = atom_controller_id;
1810 /* bios usH_Size wants h addressable size */
1811 params.usH_Size = cpu_to_le16((uint16_t)bp_params->h_addressable);
1812 /* bios usH_Blanking_Time wants borders included in blanking */
1813 params.usH_Blanking_Time =
1814 cpu_to_le16((uint16_t)(bp_params->h_total - bp_params->h_addressable));
1815 /* bios usV_Size wants v addressable size */
1816 params.usV_Size = cpu_to_le16((uint16_t)bp_params->v_addressable);
1817 /* bios usV_Blanking_Time wants borders included in blanking */
1818 params.usV_Blanking_Time =
1819 cpu_to_le16((uint16_t)(bp_params->v_total - bp_params->v_addressable));
1820 /* bios usHSyncOffset is the offset from the end of h addressable,
1821 * our horizontalSyncStart is the offset from the beginning
1822 * of h addressable */
1823 params.usH_SyncOffset =
1824 cpu_to_le16((uint16_t)(bp_params->h_sync_start - bp_params->h_addressable));
1825 params.usH_SyncWidth = cpu_to_le16((uint16_t)bp_params->h_sync_width);
1826 /* bios usHSyncOffset is the offset from the end of v addressable,
1827 * our verticalSyncStart is the offset from the beginning of
1829 params.usV_SyncOffset =
1830 cpu_to_le16((uint16_t)(bp_params->v_sync_start - bp_params->v_addressable));
1831 params.usV_SyncWidth = cpu_to_le16((uint16_t)bp_params->v_sync_width);
1833 /* we assume that overscan from original timing does not get bigger
1835 * we will program all the borders in the Set CRTC Overscan call below
1838 if (0 == bp_params->flags.HSYNC_POSITIVE_POLARITY)
1839 params.susModeMiscInfo.usAccess =
1840 cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_HSYNC_POLARITY);
1842 if (0 == bp_params->flags.VSYNC_POSITIVE_POLARITY)
1843 params.susModeMiscInfo.usAccess =
1844 cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_VSYNC_POLARITY);
1846 if (bp_params->flags.INTERLACE) {
1847 params.susModeMiscInfo.usAccess =
1848 cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_INTERLACE);
1850 /* original DAL code has this condition to apply this
1851 * for non-TV/CV only
1852 * due to complex MV testing for possible impact
1853 * if ( pACParameters->signal != SignalType_YPbPr &&
1854 * pACParameters->signal != SignalType_Composite &&
1855 * pACParameters->signal != SignalType_SVideo)
1858 /* HW will deduct 0.5 line from 2nd feild.
1859 * i.e. for 1080i, it is 2 lines for 1st field,
1860 * 2.5 lines for the 2nd feild. we need input as 5
1862 * but it is 4 either from Edid data (spec CEA 861)
1863 * or CEA timing table.
1865 params.usV_SyncOffset =
1866 cpu_to_le16(le16_to_cpu(params.usV_SyncOffset) + 1);
1871 if (bp_params->flags.HORZ_COUNT_BY_TWO)
1872 params.susModeMiscInfo.usAccess =
1873 cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_DOUBLE_CLOCK_MODE);
1875 if (EXEC_BIOS_CMD_TABLE(SetCRTC_UsingDTDTiming, params))
1876 result = BP_RESULT_OK;
1881 /*******************************************************************************
1882 ********************************************************************************
1884 ** SELECT CRTC SOURCE
1886 ********************************************************************************
1887 *******************************************************************************/
1889 static enum bp_result select_crtc_source_v2(
1890 struct bios_parser *bp,
1891 struct bp_crtc_source_select *bp_params);
1892 static enum bp_result select_crtc_source_v3(
1893 struct bios_parser *bp,
1894 struct bp_crtc_source_select *bp_params);
1896 static void init_select_crtc_source(struct bios_parser *bp)
1898 switch (BIOS_CMD_TABLE_PARA_REVISION(SelectCRTC_Source)) {
1900 bp->cmd_tbl.select_crtc_source = select_crtc_source_v2;
1903 bp->cmd_tbl.select_crtc_source = select_crtc_source_v3;
1906 dm_output_to_console("Don't select_crtc_source enable_crtc for v%d\n",
1907 BIOS_CMD_TABLE_PARA_REVISION(SelectCRTC_Source));
1908 bp->cmd_tbl.select_crtc_source = NULL;
1913 static enum bp_result select_crtc_source_v2(
1914 struct bios_parser *bp,
1915 struct bp_crtc_source_select *bp_params)
1917 enum bp_result result = BP_RESULT_FAILURE;
1918 SELECT_CRTC_SOURCE_PARAMETERS_V2 params;
1919 uint8_t atom_controller_id;
1920 uint32_t atom_engine_id;
1921 enum signal_type s = bp_params->signal;
1923 memset(¶ms, 0, sizeof(params));
1925 /* set controller id */
1926 if (bp->cmd_helper->controller_id_to_atom(
1927 bp_params->controller_id, &atom_controller_id))
1928 params.ucCRTC = atom_controller_id;
1930 return BP_RESULT_FAILURE;
1932 /* set encoder id */
1933 if (bp->cmd_helper->engine_bp_to_atom(
1934 bp_params->engine_id, &atom_engine_id))
1935 params.ucEncoderID = (uint8_t)atom_engine_id;
1937 return BP_RESULT_FAILURE;
1939 if (SIGNAL_TYPE_EDP == s ||
1940 (SIGNAL_TYPE_DISPLAY_PORT == s &&
1941 SIGNAL_TYPE_LVDS == bp_params->sink_signal))
1942 s = SIGNAL_TYPE_LVDS;
1944 params.ucEncodeMode =
1945 (uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom(
1946 s, bp_params->enable_dp_audio);
1948 if (EXEC_BIOS_CMD_TABLE(SelectCRTC_Source, params))
1949 result = BP_RESULT_OK;
1954 static enum bp_result select_crtc_source_v3(
1955 struct bios_parser *bp,
1956 struct bp_crtc_source_select *bp_params)
1958 bool result = BP_RESULT_FAILURE;
1959 SELECT_CRTC_SOURCE_PARAMETERS_V3 params;
1960 uint8_t atom_controller_id;
1961 uint32_t atom_engine_id;
1962 enum signal_type s = bp_params->signal;
1964 memset(¶ms, 0, sizeof(params));
1966 if (bp->cmd_helper->controller_id_to_atom(bp_params->controller_id,
1967 &atom_controller_id))
1968 params.ucCRTC = atom_controller_id;
1972 if (bp->cmd_helper->engine_bp_to_atom(bp_params->engine_id,
1974 params.ucEncoderID = (uint8_t)atom_engine_id;
1978 if (SIGNAL_TYPE_EDP == s ||
1979 (SIGNAL_TYPE_DISPLAY_PORT == s &&
1980 SIGNAL_TYPE_LVDS == bp_params->sink_signal))
1981 s = SIGNAL_TYPE_LVDS;
1983 params.ucEncodeMode =
1984 bp->cmd_helper->encoder_mode_bp_to_atom(
1985 s, bp_params->enable_dp_audio);
1986 /* Needed for VBIOS Random Spatial Dithering feature */
1987 params.ucDstBpc = (uint8_t)(bp_params->display_output_bit_depth);
1989 if (EXEC_BIOS_CMD_TABLE(SelectCRTC_Source, params))
1990 result = BP_RESULT_OK;
1995 /*******************************************************************************
1996 ********************************************************************************
2000 ********************************************************************************
2001 *******************************************************************************/
2003 static enum bp_result enable_crtc_v1(
2004 struct bios_parser *bp,
2005 enum controller_id controller_id,
2008 static void init_enable_crtc(struct bios_parser *bp)
2010 switch (BIOS_CMD_TABLE_PARA_REVISION(EnableCRTC)) {
2012 bp->cmd_tbl.enable_crtc = enable_crtc_v1;
2015 dm_output_to_console("Don't have enable_crtc for v%d\n",
2016 BIOS_CMD_TABLE_PARA_REVISION(EnableCRTC));
2017 bp->cmd_tbl.enable_crtc = NULL;
2022 static enum bp_result enable_crtc_v1(
2023 struct bios_parser *bp,
2024 enum controller_id controller_id,
2027 bool result = BP_RESULT_FAILURE;
2028 ENABLE_CRTC_PARAMETERS params = {0};
2031 if (bp->cmd_helper->controller_id_to_atom(controller_id, &id))
2034 return BP_RESULT_BADINPUT;
2037 params.ucEnable = ATOM_ENABLE;
2039 params.ucEnable = ATOM_DISABLE;
2041 if (EXEC_BIOS_CMD_TABLE(EnableCRTC, params))
2042 result = BP_RESULT_OK;
2047 /*******************************************************************************
2048 ********************************************************************************
2050 ** ENABLE CRTC MEM REQ
2052 ********************************************************************************
2053 *******************************************************************************/
2055 static enum bp_result enable_crtc_mem_req_v1(
2056 struct bios_parser *bp,
2057 enum controller_id controller_id,
2060 static void init_enable_crtc_mem_req(struct bios_parser *bp)
2062 switch (BIOS_CMD_TABLE_PARA_REVISION(EnableCRTCMemReq)) {
2064 bp->cmd_tbl.enable_crtc_mem_req = enable_crtc_mem_req_v1;
2067 bp->cmd_tbl.enable_crtc_mem_req = NULL;
2072 static enum bp_result enable_crtc_mem_req_v1(
2073 struct bios_parser *bp,
2074 enum controller_id controller_id,
2077 bool result = BP_RESULT_BADINPUT;
2078 ENABLE_CRTC_PARAMETERS params = {0};
2081 if (bp->cmd_helper->controller_id_to_atom(controller_id, &id)) {
2085 params.ucEnable = ATOM_ENABLE;
2087 params.ucEnable = ATOM_DISABLE;
2089 if (EXEC_BIOS_CMD_TABLE(EnableCRTCMemReq, params))
2090 result = BP_RESULT_OK;
2092 result = BP_RESULT_FAILURE;
2098 /*******************************************************************************
2099 ********************************************************************************
2103 ********************************************************************************
2104 *******************************************************************************/
2106 static enum bp_result program_clock_v5(
2107 struct bios_parser *bp,
2108 struct bp_pixel_clock_parameters *bp_params);
2109 static enum bp_result program_clock_v6(
2110 struct bios_parser *bp,
2111 struct bp_pixel_clock_parameters *bp_params);
2113 static void init_program_clock(struct bios_parser *bp)
2115 switch (BIOS_CMD_TABLE_PARA_REVISION(SetPixelClock)) {
2117 bp->cmd_tbl.program_clock = program_clock_v5;
2120 bp->cmd_tbl.program_clock = program_clock_v6;
2123 dm_output_to_console("Don't have program_clock for v%d\n",
2124 BIOS_CMD_TABLE_PARA_REVISION(SetPixelClock));
2125 bp->cmd_tbl.program_clock = NULL;
2130 static enum bp_result program_clock_v5(
2131 struct bios_parser *bp,
2132 struct bp_pixel_clock_parameters *bp_params)
2134 enum bp_result result = BP_RESULT_FAILURE;
2136 SET_PIXEL_CLOCK_PS_ALLOCATION_V5 params;
2137 uint32_t atom_pll_id;
2139 memset(¶ms, 0, sizeof(params));
2140 if (!bp->cmd_helper->clock_source_id_to_atom(
2141 bp_params->pll_id, &atom_pll_id)) {
2142 BREAK_TO_DEBUGGER(); /* Invalid Inpute!! */
2143 return BP_RESULT_BADINPUT;
2146 /* We need to convert from KHz units into 10KHz units */
2147 params.sPCLKInput.ucPpll = (uint8_t) atom_pll_id;
2148 params.sPCLKInput.usPixelClock =
2149 cpu_to_le16((uint16_t) (bp_params->target_pixel_clock / 10));
2150 params.sPCLKInput.ucCRTC = (uint8_t) ATOM_CRTC_INVALID;
2152 if (bp_params->flags.SET_EXTERNAL_REF_DIV_SRC)
2153 params.sPCLKInput.ucMiscInfo |= PIXEL_CLOCK_MISC_REF_DIV_SRC;
2155 if (EXEC_BIOS_CMD_TABLE(SetPixelClock, params))
2156 result = BP_RESULT_OK;
2161 static enum bp_result program_clock_v6(
2162 struct bios_parser *bp,
2163 struct bp_pixel_clock_parameters *bp_params)
2165 enum bp_result result = BP_RESULT_FAILURE;
2167 SET_PIXEL_CLOCK_PS_ALLOCATION_V6 params;
2168 uint32_t atom_pll_id;
2170 memset(¶ms, 0, sizeof(params));
2172 if (!bp->cmd_helper->clock_source_id_to_atom(
2173 bp_params->pll_id, &atom_pll_id)) {
2174 BREAK_TO_DEBUGGER(); /*Invalid Input!!*/
2175 return BP_RESULT_BADINPUT;
2178 /* We need to convert from KHz units into 10KHz units */
2179 params.sPCLKInput.ucPpll = (uint8_t)atom_pll_id;
2180 params.sPCLKInput.ulDispEngClkFreq =
2181 cpu_to_le32(bp_params->target_pixel_clock / 10);
2183 if (bp_params->flags.SET_EXTERNAL_REF_DIV_SRC)
2184 params.sPCLKInput.ucMiscInfo |= PIXEL_CLOCK_MISC_REF_DIV_SRC;
2186 if (EXEC_BIOS_CMD_TABLE(SetPixelClock, params)) {
2187 /* True display clock is returned by VBIOS if DFS bypass
2189 bp_params->dfs_bypass_display_clock =
2190 (uint32_t)(le32_to_cpu(params.sPCLKInput.ulDispEngClkFreq) * 10);
2191 result = BP_RESULT_OK;
2197 /*******************************************************************************
2198 ********************************************************************************
2200 ** EXTERNAL ENCODER CONTROL
2202 ********************************************************************************
2203 *******************************************************************************/
2205 static enum bp_result external_encoder_control_v3(
2206 struct bios_parser *bp,
2207 struct bp_external_encoder_control *cntl);
2209 static void init_external_encoder_control(
2210 struct bios_parser *bp)
2212 switch (BIOS_CMD_TABLE_PARA_REVISION(ExternalEncoderControl)) {
2214 bp->cmd_tbl.external_encoder_control =
2215 external_encoder_control_v3;
2218 bp->cmd_tbl.external_encoder_control = NULL;
2223 static enum bp_result external_encoder_control_v3(
2224 struct bios_parser *bp,
2225 struct bp_external_encoder_control *cntl)
2227 enum bp_result result = BP_RESULT_FAILURE;
2229 /* we need use _PS_Alloc struct */
2230 EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION_V3 params;
2231 EXTERNAL_ENCODER_CONTROL_PARAMETERS_V3 *cntl_params;
2232 struct graphics_object_id encoder;
2233 bool is_input_signal_dp = false;
2235 memset(¶ms, 0, sizeof(params));
2237 cntl_params = ¶ms.sExtEncoder;
2239 encoder = cntl->encoder_id;
2241 /* check if encoder supports external encoder control table */
2242 switch (dal_graphics_object_id_get_encoder_id(encoder)) {
2243 case ENCODER_ID_EXTERNAL_NUTMEG:
2244 case ENCODER_ID_EXTERNAL_TRAVIS:
2245 is_input_signal_dp = true;
2249 BREAK_TO_DEBUGGER();
2250 return BP_RESULT_BADINPUT;
2253 /* Fill information based on the action
2255 * Bit[6:4]: indicate external encoder, applied to all functions.
2256 * =0: external encoder1, mapped to external encoder enum id1
2257 * =1: external encoder2, mapped to external encoder enum id2
2261 * EnumId_Unknown = 0,
2266 cntl_params->ucConfig = (uint8_t)((encoder.enum_id - 1) << 4);
2268 switch (cntl->action) {
2269 case EXTERNAL_ENCODER_CONTROL_INIT:
2270 /* output display connector type. Only valid in encoder
2272 cntl_params->usConnectorId =
2273 cpu_to_le16((uint16_t)cntl->connector_obj_id.id);
2275 case EXTERNAL_ENCODER_CONTROL_SETUP:
2276 /* EXTERNAL_ENCODER_CONTROL_PARAMETERS_V3 pixel clock unit in
2278 * output display device pixel clock frequency in unit of 10KHz.
2279 * Only valid in setup and enableoutput
2281 cntl_params->usPixelClock =
2282 cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
2283 /* Indicate display output signal type drive by external
2284 * encoder, only valid in setup and enableoutput */
2285 cntl_params->ucEncoderMode =
2286 (uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom(
2287 cntl->signal, false);
2289 if (is_input_signal_dp) {
2290 /* Bit[0]: indicate link rate, =1: 2.7Ghz, =0: 1.62Ghz,
2291 * only valid in encoder setup with DP mode. */
2292 if (LINK_RATE_HIGH == cntl->link_rate)
2293 cntl_params->ucConfig |= 1;
2294 /* output color depth Indicate encoder data bpc format
2295 * in DP mode, only valid in encoder setup in DP mode.
2297 cntl_params->ucBitPerColor =
2298 (uint8_t)(cntl->color_depth);
2300 /* Indicate how many lanes used by external encoder, only valid
2301 * in encoder setup and enableoutput. */
2302 cntl_params->ucLaneNum = (uint8_t)(cntl->lanes_number);
2304 case EXTERNAL_ENCODER_CONTROL_ENABLE:
2305 cntl_params->usPixelClock =
2306 cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
2307 cntl_params->ucEncoderMode =
2308 (uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom(
2309 cntl->signal, false);
2310 cntl_params->ucLaneNum = (uint8_t)cntl->lanes_number;
2316 cntl_params->ucAction = (uint8_t)cntl->action;
2318 if (EXEC_BIOS_CMD_TABLE(ExternalEncoderControl, params))
2319 result = BP_RESULT_OK;
2324 /*******************************************************************************
2325 ********************************************************************************
2327 ** ENABLE DISPLAY POWER GATING
2329 ********************************************************************************
2330 *******************************************************************************/
2332 static enum bp_result enable_disp_power_gating_v2_1(
2333 struct bios_parser *bp,
2334 enum controller_id crtc_id,
2335 enum bp_pipe_control_action action);
2337 static void init_enable_disp_power_gating(
2338 struct bios_parser *bp)
2340 switch (BIOS_CMD_TABLE_PARA_REVISION(EnableDispPowerGating)) {
2342 bp->cmd_tbl.enable_disp_power_gating =
2343 enable_disp_power_gating_v2_1;
2346 dm_output_to_console("Don't enable_disp_power_gating enable_crtc for v%d\n",
2347 BIOS_CMD_TABLE_PARA_REVISION(EnableDispPowerGating));
2348 bp->cmd_tbl.enable_disp_power_gating = NULL;
2353 static enum bp_result enable_disp_power_gating_v2_1(
2354 struct bios_parser *bp,
2355 enum controller_id crtc_id,
2356 enum bp_pipe_control_action action)
2358 enum bp_result result = BP_RESULT_FAILURE;
2360 ENABLE_DISP_POWER_GATING_PS_ALLOCATION params = {0};
2361 uint8_t atom_crtc_id;
2363 if (bp->cmd_helper->controller_id_to_atom(crtc_id, &atom_crtc_id))
2364 params.ucDispPipeId = atom_crtc_id;
2366 return BP_RESULT_BADINPUT;
2369 bp->cmd_helper->disp_power_gating_action_to_atom(action);
2371 if (EXEC_BIOS_CMD_TABLE(EnableDispPowerGating, params))
2372 result = BP_RESULT_OK;
2377 /*******************************************************************************
2378 ********************************************************************************
2382 ********************************************************************************
2383 *******************************************************************************/
2384 static enum bp_result set_dce_clock_v2_1(
2385 struct bios_parser *bp,
2386 struct bp_set_dce_clock_parameters *bp_params);
2388 static void init_set_dce_clock(struct bios_parser *bp)
2390 switch (BIOS_CMD_TABLE_PARA_REVISION(SetDCEClock)) {
2392 bp->cmd_tbl.set_dce_clock = set_dce_clock_v2_1;
2395 dm_output_to_console("Don't have set_dce_clock for v%d\n",
2396 BIOS_CMD_TABLE_PARA_REVISION(SetDCEClock));
2397 bp->cmd_tbl.set_dce_clock = NULL;
2402 static enum bp_result set_dce_clock_v2_1(
2403 struct bios_parser *bp,
2404 struct bp_set_dce_clock_parameters *bp_params)
2406 enum bp_result result = BP_RESULT_FAILURE;
2408 SET_DCE_CLOCK_PS_ALLOCATION_V2_1 params;
2409 uint32_t atom_pll_id;
2410 uint32_t atom_clock_type;
2411 const struct command_table_helper *cmd = bp->cmd_helper;
2413 memset(¶ms, 0, sizeof(params));
2415 if (!cmd->clock_source_id_to_atom(bp_params->pll_id, &atom_pll_id) ||
2416 !cmd->dc_clock_type_to_atom(bp_params->clock_type, &atom_clock_type))
2417 return BP_RESULT_BADINPUT;
2419 params.asParam.ucDCEClkSrc = atom_pll_id;
2420 params.asParam.ucDCEClkType = atom_clock_type;
2422 if (bp_params->clock_type == DCECLOCK_TYPE_DPREFCLK) {
2423 if (bp_params->flags.USE_GENLOCK_AS_SOURCE_FOR_DPREFCLK)
2424 params.asParam.ucDCEClkFlag |= DCE_CLOCK_FLAG_PLL_REFCLK_SRC_GENLK;
2426 if (bp_params->flags.USE_PCIE_AS_SOURCE_FOR_DPREFCLK)
2427 params.asParam.ucDCEClkFlag |= DCE_CLOCK_FLAG_PLL_REFCLK_SRC_PCIE;
2429 if (bp_params->flags.USE_XTALIN_AS_SOURCE_FOR_DPREFCLK)
2430 params.asParam.ucDCEClkFlag |= DCE_CLOCK_FLAG_PLL_REFCLK_SRC_XTALIN;
2432 if (bp_params->flags.USE_GENERICA_AS_SOURCE_FOR_DPREFCLK)
2433 params.asParam.ucDCEClkFlag |= DCE_CLOCK_FLAG_PLL_REFCLK_SRC_GENERICA;
2436 /* only program clock frequency if display clock is used; VBIOS will program DPREFCLK */
2437 /* We need to convert from KHz units into 10KHz units */
2438 params.asParam.ulDCEClkFreq = cpu_to_le32(bp_params->target_clock_frequency / 10);
2440 if (EXEC_BIOS_CMD_TABLE(SetDCEClock, params)) {
2441 /* Convert from 10KHz units back to KHz */
2442 bp_params->target_clock_frequency = le32_to_cpu(params.asParam.ulDCEClkFreq) * 10;
2443 result = BP_RESULT_OK;