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_enable_crtc(struct bios_parser
*bp
);
59 static void init_enable_crtc_mem_req(struct bios_parser
*bp
);
60 static void init_external_encoder_control(struct bios_parser
*bp
);
61 static void init_enable_disp_power_gating(struct bios_parser
*bp
);
62 static void init_program_clock(struct bios_parser
*bp
);
63 static void init_set_dce_clock(struct bios_parser
*bp
);
65 void dal_bios_parser_init_cmd_tbl(struct bios_parser
*bp
)
67 init_dig_encoder_control(bp
);
68 init_transmitter_control(bp
);
69 init_set_pixel_clock(bp
);
70 init_enable_spread_spectrum_on_ppll(bp
);
71 init_adjust_display_pll(bp
);
72 init_dac_encoder_control(bp
);
73 init_dac_output_control(bp
);
74 init_set_crtc_timing(bp
);
76 init_enable_crtc_mem_req(bp
);
77 init_program_clock(bp
);
78 init_external_encoder_control(bp
);
79 init_enable_disp_power_gating(bp
);
80 init_set_dce_clock(bp
);
83 static uint32_t bios_cmd_table_para_revision(void *dev
,
86 struct amdgpu_device
*adev
= dev
;
89 if (amdgpu_atom_parse_cmd_header(adev
->mode_info
.atom_context
,
97 /*******************************************************************************
98 ********************************************************************************
100 ** D I G E N C O D E R C O N T R O L
102 ********************************************************************************
103 *******************************************************************************/
104 static enum bp_result
encoder_control_digx_v3(
105 struct bios_parser
*bp
,
106 struct bp_encoder_control
*cntl
);
108 static enum bp_result
encoder_control_digx_v4(
109 struct bios_parser
*bp
,
110 struct bp_encoder_control
*cntl
);
112 static enum bp_result
encoder_control_digx_v5(
113 struct bios_parser
*bp
,
114 struct bp_encoder_control
*cntl
);
116 static void init_encoder_control_dig_v1(struct bios_parser
*bp
);
118 static void init_dig_encoder_control(struct bios_parser
*bp
)
121 BIOS_CMD_TABLE_PARA_REVISION(DIGxEncoderControl
);
125 bp
->cmd_tbl
.dig_encoder_control
= encoder_control_digx_v3
;
128 bp
->cmd_tbl
.dig_encoder_control
= encoder_control_digx_v4
;
132 bp
->cmd_tbl
.dig_encoder_control
= encoder_control_digx_v5
;
136 init_encoder_control_dig_v1(bp
);
141 static enum bp_result
encoder_control_dig_v1(
142 struct bios_parser
*bp
,
143 struct bp_encoder_control
*cntl
);
144 static enum bp_result
encoder_control_dig1_v1(
145 struct bios_parser
*bp
,
146 struct bp_encoder_control
*cntl
);
147 static enum bp_result
encoder_control_dig2_v1(
148 struct bios_parser
*bp
,
149 struct bp_encoder_control
*cntl
);
151 static void init_encoder_control_dig_v1(struct bios_parser
*bp
)
153 struct cmd_tbl
*cmd_tbl
= &bp
->cmd_tbl
;
155 if (1 == BIOS_CMD_TABLE_PARA_REVISION(DIG1EncoderControl
))
156 cmd_tbl
->encoder_control_dig1
= encoder_control_dig1_v1
;
158 cmd_tbl
->encoder_control_dig1
= NULL
;
160 if (1 == BIOS_CMD_TABLE_PARA_REVISION(DIG2EncoderControl
))
161 cmd_tbl
->encoder_control_dig2
= encoder_control_dig2_v1
;
163 cmd_tbl
->encoder_control_dig2
= NULL
;
165 cmd_tbl
->dig_encoder_control
= encoder_control_dig_v1
;
168 static enum bp_result
encoder_control_dig_v1(
169 struct bios_parser
*bp
,
170 struct bp_encoder_control
*cntl
)
172 enum bp_result result
= BP_RESULT_FAILURE
;
173 struct cmd_tbl
*cmd_tbl
= &bp
->cmd_tbl
;
176 switch (cntl
->engine_id
) {
178 if (cmd_tbl
->encoder_control_dig1
!= NULL
)
180 cmd_tbl
->encoder_control_dig1(bp
, cntl
);
183 if (cmd_tbl
->encoder_control_dig2
!= NULL
)
185 cmd_tbl
->encoder_control_dig2(bp
, cntl
);
195 static enum bp_result
encoder_control_dig1_v1(
196 struct bios_parser
*bp
,
197 struct bp_encoder_control
*cntl
)
199 enum bp_result result
= BP_RESULT_FAILURE
;
200 DIG_ENCODER_CONTROL_PARAMETERS_V2 params
= {0};
202 bp
->cmd_helper
->assign_control_parameter(bp
->cmd_helper
, cntl
, ¶ms
);
204 if (EXEC_BIOS_CMD_TABLE(DIG1EncoderControl
, params
))
205 result
= BP_RESULT_OK
;
210 static enum bp_result
encoder_control_dig2_v1(
211 struct bios_parser
*bp
,
212 struct bp_encoder_control
*cntl
)
214 enum bp_result result
= BP_RESULT_FAILURE
;
215 DIG_ENCODER_CONTROL_PARAMETERS_V2 params
= {0};
217 bp
->cmd_helper
->assign_control_parameter(bp
->cmd_helper
, cntl
, ¶ms
);
219 if (EXEC_BIOS_CMD_TABLE(DIG2EncoderControl
, params
))
220 result
= BP_RESULT_OK
;
225 static enum bp_result
encoder_control_digx_v3(
226 struct bios_parser
*bp
,
227 struct bp_encoder_control
*cntl
)
229 enum bp_result result
= BP_RESULT_FAILURE
;
230 DIG_ENCODER_CONTROL_PARAMETERS_V3 params
= {0};
232 if (LANE_COUNT_FOUR
< cntl
->lanes_number
)
233 params
.acConfig
.ucDPLinkRate
= 1; /* dual link 2.7GHz */
235 params
.acConfig
.ucDPLinkRate
= 0; /* single link 1.62GHz */
237 params
.acConfig
.ucDigSel
= (uint8_t)(cntl
->engine_id
);
239 /* We need to convert from KHz units into 10KHz units */
240 params
.ucAction
= bp
->cmd_helper
->encoder_action_to_atom(cntl
->action
);
241 params
.usPixelClock
= cpu_to_le16((uint16_t)(cntl
->pixel_clock
/ 10));
242 params
.ucEncoderMode
=
243 (uint8_t)bp
->cmd_helper
->encoder_mode_bp_to_atom(
245 cntl
->enable_dp_audio
);
246 params
.ucLaneNum
= (uint8_t)(cntl
->lanes_number
);
248 if (EXEC_BIOS_CMD_TABLE(DIGxEncoderControl
, params
))
249 result
= BP_RESULT_OK
;
254 static enum bp_result
encoder_control_digx_v4(
255 struct bios_parser
*bp
,
256 struct bp_encoder_control
*cntl
)
258 enum bp_result result
= BP_RESULT_FAILURE
;
259 DIG_ENCODER_CONTROL_PARAMETERS_V4 params
= {0};
261 if (LANE_COUNT_FOUR
< cntl
->lanes_number
)
262 params
.acConfig
.ucDPLinkRate
= 1; /* dual link 2.7GHz */
264 params
.acConfig
.ucDPLinkRate
= 0; /* single link 1.62GHz */
266 params
.acConfig
.ucDigSel
= (uint8_t)(cntl
->engine_id
);
268 /* We need to convert from KHz units into 10KHz units */
269 params
.ucAction
= bp
->cmd_helper
->encoder_action_to_atom(cntl
->action
);
270 params
.usPixelClock
= cpu_to_le16((uint16_t)(cntl
->pixel_clock
/ 10));
271 params
.ucEncoderMode
=
272 (uint8_t)(bp
->cmd_helper
->encoder_mode_bp_to_atom(
274 cntl
->enable_dp_audio
));
275 params
.ucLaneNum
= (uint8_t)(cntl
->lanes_number
);
277 if (EXEC_BIOS_CMD_TABLE(DIGxEncoderControl
, params
))
278 result
= BP_RESULT_OK
;
283 static enum bp_result
encoder_control_digx_v5(
284 struct bios_parser
*bp
,
285 struct bp_encoder_control
*cntl
)
287 enum bp_result result
= BP_RESULT_FAILURE
;
288 ENCODER_STREAM_SETUP_PARAMETERS_V5 params
= {0};
290 params
.ucDigId
= (uint8_t)(cntl
->engine_id
);
291 params
.ucAction
= bp
->cmd_helper
->encoder_action_to_atom(cntl
->action
);
293 params
.ulPixelClock
= cntl
->pixel_clock
/ 10;
295 (uint8_t)(bp
->cmd_helper
->encoder_mode_bp_to_atom(
297 cntl
->enable_dp_audio
));
298 params
.ucLaneNum
= (uint8_t)(cntl
->lanes_number
);
300 switch (cntl
->color_depth
) {
301 case COLOR_DEPTH_888
:
302 params
.ucBitPerColor
= PANEL_8BIT_PER_COLOR
;
304 case COLOR_DEPTH_101010
:
305 params
.ucBitPerColor
= PANEL_10BIT_PER_COLOR
;
307 case COLOR_DEPTH_121212
:
308 params
.ucBitPerColor
= PANEL_12BIT_PER_COLOR
;
310 case COLOR_DEPTH_161616
:
311 params
.ucBitPerColor
= PANEL_16BIT_PER_COLOR
;
317 if (cntl
->signal
== SIGNAL_TYPE_HDMI_TYPE_A
)
318 switch (cntl
->color_depth
) {
319 case COLOR_DEPTH_101010
:
320 params
.ulPixelClock
=
321 (params
.ulPixelClock
* 30) / 24;
323 case COLOR_DEPTH_121212
:
324 params
.ulPixelClock
=
325 (params
.ulPixelClock
* 36) / 24;
327 case COLOR_DEPTH_161616
:
328 params
.ulPixelClock
=
329 (params
.ulPixelClock
* 48) / 24;
335 if (EXEC_BIOS_CMD_TABLE(DIGxEncoderControl
, params
))
336 result
= BP_RESULT_OK
;
341 /*******************************************************************************
342 ********************************************************************************
344 ** TRANSMITTER CONTROL
346 ********************************************************************************
347 *******************************************************************************/
349 static enum bp_result
transmitter_control_v2(
350 struct bios_parser
*bp
,
351 struct bp_transmitter_control
*cntl
);
352 static enum bp_result
transmitter_control_v3(
353 struct bios_parser
*bp
,
354 struct bp_transmitter_control
*cntl
);
355 static enum bp_result
transmitter_control_v4(
356 struct bios_parser
*bp
,
357 struct bp_transmitter_control
*cntl
);
358 static enum bp_result
transmitter_control_v1_5(
359 struct bios_parser
*bp
,
360 struct bp_transmitter_control
*cntl
);
361 static enum bp_result
transmitter_control_v1_6(
362 struct bios_parser
*bp
,
363 struct bp_transmitter_control
*cntl
);
365 static void init_transmitter_control(struct bios_parser
*bp
)
370 if (BIOS_CMD_TABLE_REVISION(UNIPHYTransmitterControl
,
371 frev
, crev
) == false)
375 bp
->cmd_tbl
.transmitter_control
= transmitter_control_v2
;
378 bp
->cmd_tbl
.transmitter_control
= transmitter_control_v3
;
381 bp
->cmd_tbl
.transmitter_control
= transmitter_control_v4
;
384 bp
->cmd_tbl
.transmitter_control
= transmitter_control_v1_5
;
387 bp
->cmd_tbl
.transmitter_control
= transmitter_control_v1_6
;
390 dm_output_to_console("Don't have transmitter_control for v%d\n", crev
);
391 bp
->cmd_tbl
.transmitter_control
= NULL
;
396 static enum bp_result
transmitter_control_v2(
397 struct bios_parser
*bp
,
398 struct bp_transmitter_control
*cntl
)
400 enum bp_result result
= BP_RESULT_FAILURE
;
401 DIG_TRANSMITTER_CONTROL_PARAMETERS_V2 params
;
402 enum connector_id connector_id
=
403 dal_graphics_object_id_get_connector_id(cntl
->connector_obj_id
);
405 memset(¶ms
, 0, sizeof(params
));
407 switch (cntl
->transmitter
) {
408 case TRANSMITTER_UNIPHY_A
:
409 case TRANSMITTER_UNIPHY_B
:
410 case TRANSMITTER_UNIPHY_C
:
411 case TRANSMITTER_UNIPHY_D
:
412 case TRANSMITTER_UNIPHY_E
:
413 case TRANSMITTER_UNIPHY_F
:
414 case TRANSMITTER_TRAVIS_LCD
:
417 return BP_RESULT_BADINPUT
;
420 switch (cntl
->action
) {
421 case TRANSMITTER_CONTROL_INIT
:
422 if ((CONNECTOR_ID_DUAL_LINK_DVII
== connector_id
) ||
423 (CONNECTOR_ID_DUAL_LINK_DVID
== connector_id
))
424 /* on INIT this bit should be set according to the
426 * Bit0: dual link connector flag
427 * =0 connector is single link connector
428 * =1 connector is dual link connector
430 params
.acConfig
.fDualLinkConnector
= 1;
432 /* connector object id */
434 cpu_to_le16((uint8_t)cntl
->connector_obj_id
.id
);
436 case TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS
:
437 /* votage swing and pre-emphsis */
438 params
.asMode
.ucLaneSel
= (uint8_t)cntl
->lane_select
;
439 params
.asMode
.ucLaneSet
= (uint8_t)cntl
->lane_settings
;
443 if (LANE_COUNT_FOUR
< cntl
->lanes_number
) {
444 /* on ENABLE/DISABLE this bit should be set according to
445 * actual timing (number of lanes)
446 * Bit0: dual link connector flag
447 * =0 connector is single link connector
448 * =1 connector is dual link connector
450 params
.acConfig
.fDualLinkConnector
= 1;
452 /* link rate, half for dual link
453 * We need to convert from KHz units into 20KHz units
455 params
.usPixelClock
=
456 cpu_to_le16((uint16_t)(cntl
->pixel_clock
/ 20));
458 /* link rate, half for dual link
459 * We need to convert from KHz units into 10KHz units
461 params
.usPixelClock
=
462 cpu_to_le16((uint16_t)(cntl
->pixel_clock
/ 10));
466 /* 00 - coherent mode
467 * 01 - incoherent mode
470 params
.acConfig
.fCoherentMode
= cntl
->coherent
;
472 if ((TRANSMITTER_UNIPHY_B
== cntl
->transmitter
)
473 || (TRANSMITTER_UNIPHY_D
== cntl
->transmitter
)
474 || (TRANSMITTER_UNIPHY_F
== cntl
->transmitter
))
475 /* Bit2: Transmitter Link selection
476 * =0 when bit0=0, single link A/C/E, when bit0=1,
478 * =1 when bit0=0, single link B/D/F, when bit0=1,
481 params
.acConfig
.ucLinkSel
= 1;
483 if (ENGINE_ID_DIGB
== cntl
->engine_id
)
484 /* Bit3: Transmitter data source selection
485 * =0 DIGA is data source.
486 * =1 DIGB is data source.
487 * This bit is only useful when ucAction= ATOM_ENABLE
489 params
.acConfig
.ucEncoderSel
= 1;
491 if (CONNECTOR_ID_DISPLAY_PORT
== connector_id
)
492 /* Bit4: DP connector flag
493 * =0 connector is none-DP connector
494 * =1 connector is DP connector
496 params
.acConfig
.fDPConnector
= 1;
498 /* Bit[7:6]: Transmitter selection
499 * =0 UNIPHY_ENCODER: UNIPHYA/B
500 * =1 UNIPHY1_ENCODER: UNIPHYC/D
501 * =2 UNIPHY2_ENCODER: UNIPHYE/F
504 params
.acConfig
.ucTransmitterSel
=
505 (uint8_t)bp
->cmd_helper
->transmitter_bp_to_atom(
508 params
.ucAction
= (uint8_t)cntl
->action
;
510 if (EXEC_BIOS_CMD_TABLE(UNIPHYTransmitterControl
, params
))
511 result
= BP_RESULT_OK
;
516 static enum bp_result
transmitter_control_v3(
517 struct bios_parser
*bp
,
518 struct bp_transmitter_control
*cntl
)
520 enum bp_result result
= BP_RESULT_FAILURE
;
521 DIG_TRANSMITTER_CONTROL_PARAMETERS_V3 params
;
523 enum connector_id conn_id
=
524 dal_graphics_object_id_get_connector_id(cntl
->connector_obj_id
);
525 const struct command_table_helper
*cmd
= bp
->cmd_helper
;
526 bool dual_link_conn
= (CONNECTOR_ID_DUAL_LINK_DVII
== conn_id
)
527 || (CONNECTOR_ID_DUAL_LINK_DVID
== conn_id
);
529 memset(¶ms
, 0, sizeof(params
));
531 switch (cntl
->transmitter
) {
532 case TRANSMITTER_UNIPHY_A
:
533 case TRANSMITTER_UNIPHY_B
:
534 case TRANSMITTER_UNIPHY_C
:
535 case TRANSMITTER_UNIPHY_D
:
536 case TRANSMITTER_UNIPHY_E
:
537 case TRANSMITTER_UNIPHY_F
:
538 case TRANSMITTER_TRAVIS_LCD
:
541 return BP_RESULT_BADINPUT
;
544 if (!cmd
->clock_source_id_to_atom(cntl
->pll_id
, &pll_id
))
545 return BP_RESULT_BADINPUT
;
547 /* fill information based on the action */
548 switch (cntl
->action
) {
549 case TRANSMITTER_CONTROL_INIT
:
550 if (dual_link_conn
) {
551 /* on INIT this bit should be set according to the
553 * Bit0: dual link connector flag
554 * =0 connector is single link connector
555 * =1 connector is dual link connector
557 params
.acConfig
.fDualLinkConnector
= 1;
560 /* connector object id */
562 cpu_to_le16((uint8_t)(cntl
->connector_obj_id
.id
));
564 case TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS
:
565 /* votage swing and pre-emphsis */
566 params
.asMode
.ucLaneSel
= (uint8_t)cntl
->lane_select
;
567 params
.asMode
.ucLaneSet
= (uint8_t)cntl
->lane_settings
;
570 if (dual_link_conn
&& cntl
->multi_path
)
571 /* on ENABLE/DISABLE this bit should be set according to
572 * actual timing (number of lanes)
573 * Bit0: dual link connector flag
574 * =0 connector is single link connector
575 * =1 connector is dual link connector
577 params
.acConfig
.fDualLinkConnector
= 1;
580 if (LANE_COUNT_FOUR
< cntl
->lanes_number
) {
581 /* on ENABLE/DISABLE this bit should be set according to
582 * actual timing (number of lanes)
583 * Bit0: dual link connector flag
584 * =0 connector is single link connector
585 * =1 connector is dual link connector
587 params
.acConfig
.fDualLinkConnector
= 1;
589 /* link rate, half for dual link
590 * We need to convert from KHz units into 20KHz units
592 params
.usPixelClock
=
593 cpu_to_le16((uint16_t)(cntl
->pixel_clock
/ 20));
595 /* link rate, half for dual link
596 * We need to convert from KHz units into 10KHz units
598 params
.usPixelClock
=
599 cpu_to_le16((uint16_t)(cntl
->pixel_clock
/ 10));
604 /* 00 - coherent mode
605 * 01 - incoherent mode
608 params
.acConfig
.fCoherentMode
= cntl
->coherent
;
610 if ((TRANSMITTER_UNIPHY_B
== cntl
->transmitter
)
611 || (TRANSMITTER_UNIPHY_D
== cntl
->transmitter
)
612 || (TRANSMITTER_UNIPHY_F
== cntl
->transmitter
))
613 /* Bit2: Transmitter Link selection
614 * =0 when bit0=0, single link A/C/E, when bit0=1,
616 * =1 when bit0=0, single link B/D/F, when bit0=1,
619 params
.acConfig
.ucLinkSel
= 1;
621 if (ENGINE_ID_DIGB
== cntl
->engine_id
)
622 /* Bit3: Transmitter data source selection
623 * =0 DIGA is data source.
624 * =1 DIGB is data source.
625 * This bit is only useful when ucAction= ATOM_ENABLE
627 params
.acConfig
.ucEncoderSel
= 1;
629 /* Bit[7:6]: Transmitter selection
630 * =0 UNIPHY_ENCODER: UNIPHYA/B
631 * =1 UNIPHY1_ENCODER: UNIPHYC/D
632 * =2 UNIPHY2_ENCODER: UNIPHYE/F
635 params
.acConfig
.ucTransmitterSel
=
636 (uint8_t)cmd
->transmitter_bp_to_atom(cntl
->transmitter
);
638 params
.ucLaneNum
= (uint8_t)cntl
->lanes_number
;
640 params
.acConfig
.ucRefClkSource
= (uint8_t)pll_id
;
642 params
.ucAction
= (uint8_t)cntl
->action
;
644 if (EXEC_BIOS_CMD_TABLE(UNIPHYTransmitterControl
, params
))
645 result
= BP_RESULT_OK
;
650 static enum bp_result
transmitter_control_v4(
651 struct bios_parser
*bp
,
652 struct bp_transmitter_control
*cntl
)
654 enum bp_result result
= BP_RESULT_FAILURE
;
655 DIG_TRANSMITTER_CONTROL_PARAMETERS_V4 params
;
656 uint32_t ref_clk_src_id
;
657 enum connector_id conn_id
=
658 dal_graphics_object_id_get_connector_id(cntl
->connector_obj_id
);
659 const struct command_table_helper
*cmd
= bp
->cmd_helper
;
661 memset(¶ms
, 0, sizeof(params
));
663 switch (cntl
->transmitter
) {
664 case TRANSMITTER_UNIPHY_A
:
665 case TRANSMITTER_UNIPHY_B
:
666 case TRANSMITTER_UNIPHY_C
:
667 case TRANSMITTER_UNIPHY_D
:
668 case TRANSMITTER_UNIPHY_E
:
669 case TRANSMITTER_UNIPHY_F
:
670 case TRANSMITTER_TRAVIS_LCD
:
673 return BP_RESULT_BADINPUT
;
676 if (!cmd
->clock_source_id_to_ref_clk_src(cntl
->pll_id
, &ref_clk_src_id
))
677 return BP_RESULT_BADINPUT
;
679 switch (cntl
->action
) {
680 case TRANSMITTER_CONTROL_INIT
:
682 if ((CONNECTOR_ID_DUAL_LINK_DVII
== conn_id
) ||
683 (CONNECTOR_ID_DUAL_LINK_DVID
== conn_id
))
684 /* on INIT this bit should be set according to the
686 * Bit0: dual link connector flag
687 * =0 connector is single link connector
688 * =1 connector is dual link connector
690 params
.acConfig
.fDualLinkConnector
= 1;
692 /* connector object id */
694 cpu_to_le16((uint8_t)(cntl
->connector_obj_id
.id
));
697 case TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS
:
698 /* votage swing and pre-emphsis */
699 params
.asMode
.ucLaneSel
= (uint8_t)(cntl
->lane_select
);
700 params
.asMode
.ucLaneSet
= (uint8_t)(cntl
->lane_settings
);
703 if ((CONNECTOR_ID_DUAL_LINK_DVII
== conn_id
) ||
704 (CONNECTOR_ID_DUAL_LINK_DVID
== conn_id
))
705 /* on ENABLE/DISABLE this bit should be set according to
706 * actual timing (number of lanes)
707 * Bit0: dual link connector flag
708 * =0 connector is single link connector
709 * =1 connector is dual link connector
711 params
.acConfig
.fDualLinkConnector
= 1;
714 if (LANE_COUNT_FOUR
< cntl
->lanes_number
)
715 /* link rate, half for dual link
716 * We need to convert from KHz units into 20KHz units
718 params
.usPixelClock
=
719 cpu_to_le16((uint16_t)(cntl
->pixel_clock
/ 20));
721 /* link rate, half for dual link
722 * We need to convert from KHz units into 10KHz units
724 params
.usPixelClock
=
725 cpu_to_le16((uint16_t)(cntl
->pixel_clock
/ 10));
730 /* 00 - coherent mode
731 * 01 - incoherent mode
734 params
.acConfig
.fCoherentMode
= cntl
->coherent
;
736 if ((TRANSMITTER_UNIPHY_B
== cntl
->transmitter
)
737 || (TRANSMITTER_UNIPHY_D
== cntl
->transmitter
)
738 || (TRANSMITTER_UNIPHY_F
== cntl
->transmitter
))
739 /* Bit2: Transmitter Link selection
740 * =0 when bit0=0, single link A/C/E, when bit0=1,
742 * =1 when bit0=0, single link B/D/F, when bit0=1,
745 params
.acConfig
.ucLinkSel
= 1;
747 if (ENGINE_ID_DIGB
== cntl
->engine_id
)
748 /* Bit3: Transmitter data source selection
749 * =0 DIGA is data source.
750 * =1 DIGB is data source.
751 * This bit is only useful when ucAction= ATOM_ENABLE
753 params
.acConfig
.ucEncoderSel
= 1;
755 /* Bit[7:6]: Transmitter selection
756 * =0 UNIPHY_ENCODER: UNIPHYA/B
757 * =1 UNIPHY1_ENCODER: UNIPHYC/D
758 * =2 UNIPHY2_ENCODER: UNIPHYE/F
761 params
.acConfig
.ucTransmitterSel
=
762 (uint8_t)(cmd
->transmitter_bp_to_atom(cntl
->transmitter
));
763 params
.ucLaneNum
= (uint8_t)(cntl
->lanes_number
);
764 params
.acConfig
.ucRefClkSource
= (uint8_t)(ref_clk_src_id
);
765 params
.ucAction
= (uint8_t)(cntl
->action
);
767 if (EXEC_BIOS_CMD_TABLE(UNIPHYTransmitterControl
, params
))
768 result
= BP_RESULT_OK
;
773 static enum bp_result
transmitter_control_v1_5(
774 struct bios_parser
*bp
,
775 struct bp_transmitter_control
*cntl
)
777 enum bp_result result
= BP_RESULT_FAILURE
;
778 const struct command_table_helper
*cmd
= bp
->cmd_helper
;
779 DIG_TRANSMITTER_CONTROL_PARAMETERS_V1_5 params
;
781 memset(¶ms
, 0, sizeof(params
));
782 params
.ucPhyId
= cmd
->phy_id_to_atom(cntl
->transmitter
);
783 params
.ucAction
= (uint8_t)cntl
->action
;
784 params
.ucLaneNum
= (uint8_t)cntl
->lanes_number
;
785 params
.ucConnObjId
= (uint8_t)cntl
->connector_obj_id
.id
;
788 cmd
->signal_type_to_atom_dig_mode(cntl
->signal
);
789 params
.asConfig
.ucPhyClkSrcId
=
790 cmd
->clock_source_id_to_atom_phy_clk_src_id(cntl
->pll_id
);
791 /* 00 - coherent mode */
792 params
.asConfig
.ucCoherentMode
= cntl
->coherent
;
793 params
.asConfig
.ucHPDSel
=
794 cmd
->hpd_sel_to_atom(cntl
->hpd_sel
);
795 params
.ucDigEncoderSel
=
796 cmd
->dig_encoder_sel_to_atom(cntl
->engine_id
);
797 params
.ucDPLaneSet
= (uint8_t) cntl
->lane_settings
;
798 params
.usSymClock
= cpu_to_le16((uint16_t) (cntl
->pixel_clock
/ 10));
800 * In SI/TN case, caller have to set usPixelClock as following:
801 * DP mode: usPixelClock = DP_LINK_CLOCK/10
802 * (DP_LINK_CLOCK = 1.62GHz, 2.7GHz, 5.4GHz)
803 * DVI single link mode: usPixelClock = pixel clock
804 * DVI dual link mode: usPixelClock = pixel clock
805 * HDMI mode: usPixelClock = pixel clock * deep_color_ratio
806 * (=1: 8bpp, =1.25: 10bpp, =1.5:12bpp, =2: 16bpp)
807 * LVDS mode: usPixelClock = pixel clock
809 if (cntl
->signal
== SIGNAL_TYPE_HDMI_TYPE_A
) {
810 switch (cntl
->color_depth
) {
811 case COLOR_DEPTH_101010
:
813 cpu_to_le16((le16_to_cpu(params
.usSymClock
) * 30) / 24);
815 case COLOR_DEPTH_121212
:
817 cpu_to_le16((le16_to_cpu(params
.usSymClock
) * 36) / 24);
819 case COLOR_DEPTH_161616
:
821 cpu_to_le16((le16_to_cpu(params
.usSymClock
) * 48) / 24);
828 if (EXEC_BIOS_CMD_TABLE(UNIPHYTransmitterControl
, params
))
829 result
= BP_RESULT_OK
;
834 static enum bp_result
transmitter_control_v1_6(
835 struct bios_parser
*bp
,
836 struct bp_transmitter_control
*cntl
)
838 enum bp_result result
= BP_RESULT_FAILURE
;
839 const struct command_table_helper
*cmd
= bp
->cmd_helper
;
840 DIG_TRANSMITTER_CONTROL_PARAMETERS_V1_6 params
;
842 memset(¶ms
, 0, sizeof(params
));
843 params
.ucPhyId
= cmd
->phy_id_to_atom(cntl
->transmitter
);
844 params
.ucAction
= (uint8_t)cntl
->action
;
846 if (cntl
->action
== TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS
)
847 params
.ucDPLaneSet
= (uint8_t)cntl
->lane_settings
;
849 params
.ucDigMode
= cmd
->signal_type_to_atom_dig_mode(cntl
->signal
);
851 params
.ucLaneNum
= (uint8_t)cntl
->lanes_number
;
852 params
.ucHPDSel
= cmd
->hpd_sel_to_atom(cntl
->hpd_sel
);
853 params
.ucDigEncoderSel
= cmd
->dig_encoder_sel_to_atom(cntl
->engine_id
);
854 params
.ucConnObjId
= (uint8_t)cntl
->connector_obj_id
.id
;
855 params
.ulSymClock
= cntl
->pixel_clock
/10;
858 * In SI/TN case, caller have to set usPixelClock as following:
859 * DP mode: usPixelClock = DP_LINK_CLOCK/10
860 * (DP_LINK_CLOCK = 1.62GHz, 2.7GHz, 5.4GHz)
861 * DVI single link mode: usPixelClock = pixel clock
862 * DVI dual link mode: usPixelClock = pixel clock
863 * HDMI mode: usPixelClock = pixel clock * deep_color_ratio
864 * (=1: 8bpp, =1.25: 10bpp, =1.5:12bpp, =2: 16bpp)
865 * LVDS mode: usPixelClock = pixel clock
867 switch (cntl
->signal
) {
868 case SIGNAL_TYPE_HDMI_TYPE_A
:
869 switch (cntl
->color_depth
) {
870 case COLOR_DEPTH_101010
:
872 cpu_to_le16((le16_to_cpu(params
.ulSymClock
) * 30) / 24);
874 case COLOR_DEPTH_121212
:
876 cpu_to_le16((le16_to_cpu(params
.ulSymClock
) * 36) / 24);
878 case COLOR_DEPTH_161616
:
880 cpu_to_le16((le16_to_cpu(params
.ulSymClock
) * 48) / 24);
890 if (EXEC_BIOS_CMD_TABLE(UNIPHYTransmitterControl
, params
))
891 result
= BP_RESULT_OK
;
895 /*******************************************************************************
896 ********************************************************************************
900 ********************************************************************************
901 *******************************************************************************/
903 static enum bp_result
set_pixel_clock_v3(
904 struct bios_parser
*bp
,
905 struct bp_pixel_clock_parameters
*bp_params
);
906 static enum bp_result
set_pixel_clock_v5(
907 struct bios_parser
*bp
,
908 struct bp_pixel_clock_parameters
*bp_params
);
909 static enum bp_result
set_pixel_clock_v6(
910 struct bios_parser
*bp
,
911 struct bp_pixel_clock_parameters
*bp_params
);
912 static enum bp_result
set_pixel_clock_v7(
913 struct bios_parser
*bp
,
914 struct bp_pixel_clock_parameters
*bp_params
);
916 static void init_set_pixel_clock(struct bios_parser
*bp
)
918 switch (BIOS_CMD_TABLE_PARA_REVISION(SetPixelClock
)) {
920 bp
->cmd_tbl
.set_pixel_clock
= set_pixel_clock_v3
;
923 bp
->cmd_tbl
.set_pixel_clock
= set_pixel_clock_v5
;
926 bp
->cmd_tbl
.set_pixel_clock
= set_pixel_clock_v6
;
929 bp
->cmd_tbl
.set_pixel_clock
= set_pixel_clock_v7
;
932 dm_output_to_console("Don't have set_pixel_clock for v%d\n",
933 BIOS_CMD_TABLE_PARA_REVISION(SetPixelClock
));
934 bp
->cmd_tbl
.set_pixel_clock
= NULL
;
939 static enum bp_result
set_pixel_clock_v3(
940 struct bios_parser
*bp
,
941 struct bp_pixel_clock_parameters
*bp_params
)
943 enum bp_result result
= BP_RESULT_FAILURE
;
944 PIXEL_CLOCK_PARAMETERS_V3
*params
;
945 SET_PIXEL_CLOCK_PS_ALLOCATION allocation
;
947 memset(&allocation
, 0, sizeof(allocation
));
949 if (CLOCK_SOURCE_ID_PLL1
== bp_params
->pll_id
)
950 allocation
.sPCLKInput
.ucPpll
= ATOM_PPLL1
;
951 else if (CLOCK_SOURCE_ID_PLL2
== bp_params
->pll_id
)
952 allocation
.sPCLKInput
.ucPpll
= ATOM_PPLL2
;
954 return BP_RESULT_BADINPUT
;
956 allocation
.sPCLKInput
.usRefDiv
=
957 cpu_to_le16((uint16_t)bp_params
->reference_divider
);
958 allocation
.sPCLKInput
.usFbDiv
=
959 cpu_to_le16((uint16_t)bp_params
->feedback_divider
);
960 allocation
.sPCLKInput
.ucFracFbDiv
=
961 (uint8_t)bp_params
->fractional_feedback_divider
;
962 allocation
.sPCLKInput
.ucPostDiv
=
963 (uint8_t)bp_params
->pixel_clock_post_divider
;
965 /* We need to convert from 100Hz units into 10KHz units */
966 allocation
.sPCLKInput
.usPixelClock
=
967 cpu_to_le16((uint16_t)(bp_params
->target_pixel_clock_100hz
/ 100));
969 params
= (PIXEL_CLOCK_PARAMETERS_V3
*)&allocation
.sPCLKInput
;
970 params
->ucTransmitterId
=
971 bp
->cmd_helper
->encoder_id_to_atom(
972 dal_graphics_object_id_get_encoder_id(
973 bp_params
->encoder_object_id
));
974 params
->ucEncoderMode
=
975 (uint8_t)(bp
->cmd_helper
->encoder_mode_bp_to_atom(
976 bp_params
->signal_type
, false));
978 if (bp_params
->flags
.FORCE_PROGRAMMING_OF_PLL
)
979 params
->ucMiscInfo
|= PIXEL_CLOCK_MISC_FORCE_PROG_PPLL
;
981 if (bp_params
->flags
.USE_E_CLOCK_AS_SOURCE_FOR_D_CLOCK
)
982 params
->ucMiscInfo
|= PIXEL_CLOCK_MISC_USE_ENGINE_FOR_DISPCLK
;
984 if (CONTROLLER_ID_D1
!= bp_params
->controller_id
)
985 params
->ucMiscInfo
|= PIXEL_CLOCK_MISC_CRTC_SEL_CRTC2
;
987 if (EXEC_BIOS_CMD_TABLE(SetPixelClock
, allocation
))
988 result
= BP_RESULT_OK
;
993 #ifndef SET_PIXEL_CLOCK_PS_ALLOCATION_V5
994 /* video bios did not define this: */
995 typedef struct _SET_PIXEL_CLOCK_PS_ALLOCATION_V5
{
996 PIXEL_CLOCK_PARAMETERS_V5 sPCLKInput
;
997 /* Caller doesn't need to init this portion */
998 ENABLE_SPREAD_SPECTRUM_ON_PPLL sReserved
;
999 } SET_PIXEL_CLOCK_PS_ALLOCATION_V5
;
1002 #ifndef SET_PIXEL_CLOCK_PS_ALLOCATION_V6
1003 /* video bios did not define this: */
1004 typedef struct _SET_PIXEL_CLOCK_PS_ALLOCATION_V6
{
1005 PIXEL_CLOCK_PARAMETERS_V6 sPCLKInput
;
1006 /* Caller doesn't need to init this portion */
1007 ENABLE_SPREAD_SPECTRUM_ON_PPLL sReserved
;
1008 } SET_PIXEL_CLOCK_PS_ALLOCATION_V6
;
1011 static enum bp_result
set_pixel_clock_v5(
1012 struct bios_parser
*bp
,
1013 struct bp_pixel_clock_parameters
*bp_params
)
1015 enum bp_result result
= BP_RESULT_FAILURE
;
1016 SET_PIXEL_CLOCK_PS_ALLOCATION_V5 clk
;
1017 uint8_t controller_id
;
1020 memset(&clk
, 0, sizeof(clk
));
1022 if (bp
->cmd_helper
->clock_source_id_to_atom(bp_params
->pll_id
, &pll_id
)
1023 && bp
->cmd_helper
->controller_id_to_atom(
1024 bp_params
->controller_id
, &controller_id
)) {
1025 clk
.sPCLKInput
.ucCRTC
= controller_id
;
1026 clk
.sPCLKInput
.ucPpll
= (uint8_t)pll_id
;
1027 clk
.sPCLKInput
.ucRefDiv
=
1028 (uint8_t)(bp_params
->reference_divider
);
1029 clk
.sPCLKInput
.usFbDiv
=
1030 cpu_to_le16((uint16_t)(bp_params
->feedback_divider
));
1031 clk
.sPCLKInput
.ulFbDivDecFrac
=
1032 cpu_to_le32(bp_params
->fractional_feedback_divider
);
1033 clk
.sPCLKInput
.ucPostDiv
=
1034 (uint8_t)(bp_params
->pixel_clock_post_divider
);
1035 clk
.sPCLKInput
.ucTransmitterID
=
1036 bp
->cmd_helper
->encoder_id_to_atom(
1037 dal_graphics_object_id_get_encoder_id(
1038 bp_params
->encoder_object_id
));
1039 clk
.sPCLKInput
.ucEncoderMode
=
1040 (uint8_t)bp
->cmd_helper
->encoder_mode_bp_to_atom(
1041 bp_params
->signal_type
, false);
1043 /* We need to convert from 100Hz units into 10KHz units */
1044 clk
.sPCLKInput
.usPixelClock
=
1045 cpu_to_le16((uint16_t)(bp_params
->target_pixel_clock_100hz
/ 100));
1047 if (bp_params
->flags
.FORCE_PROGRAMMING_OF_PLL
)
1048 clk
.sPCLKInput
.ucMiscInfo
|=
1049 PIXEL_CLOCK_MISC_FORCE_PROG_PPLL
;
1051 if (bp_params
->flags
.SET_EXTERNAL_REF_DIV_SRC
)
1052 clk
.sPCLKInput
.ucMiscInfo
|=
1053 PIXEL_CLOCK_MISC_REF_DIV_SRC
;
1055 /* clkV5.ucMiscInfo bit[3:2]= HDMI panel bit depth: =0: 24bpp
1056 * =1:30bpp, =2:32bpp
1057 * driver choose program it itself, i.e. here we program it
1058 * to 888 by default.
1061 if (EXEC_BIOS_CMD_TABLE(SetPixelClock
, clk
))
1062 result
= BP_RESULT_OK
;
1068 static enum bp_result
set_pixel_clock_v6(
1069 struct bios_parser
*bp
,
1070 struct bp_pixel_clock_parameters
*bp_params
)
1072 enum bp_result result
= BP_RESULT_FAILURE
;
1073 SET_PIXEL_CLOCK_PS_ALLOCATION_V6 clk
;
1074 uint8_t controller_id
;
1077 memset(&clk
, 0, sizeof(clk
));
1079 if (bp
->cmd_helper
->clock_source_id_to_atom(bp_params
->pll_id
, &pll_id
)
1080 && bp
->cmd_helper
->controller_id_to_atom(
1081 bp_params
->controller_id
, &controller_id
)) {
1082 /* Note: VBIOS still wants to use ucCRTC name which is now
1084 *typedef struct _CRTC_PIXEL_CLOCK_FREQ
1086 * target the pixel clock to drive the CRTC timing.
1087 * ULONG ulPixelClock:24;
1088 * 0 means disable PPLL/DCPLL. Expanded to 24 bits comparing to
1090 * ATOM_CRTC1~6, indicate the CRTC controller to
1092 * drive the pixel clock. not used for DCPLL case.
1093 *}CRTC_PIXEL_CLOCK_FREQ;
1096 * pixel clock and CRTC id frequency
1097 * CRTC_PIXEL_CLOCK_FREQ ulCrtcPclkFreq;
1098 * ULONG ulDispEngClkFreq; dispclk frequency
1101 clk
.sPCLKInput
.ulCrtcPclkFreq
.ucCRTC
= controller_id
;
1102 clk
.sPCLKInput
.ucPpll
= (uint8_t) pll_id
;
1103 clk
.sPCLKInput
.ucRefDiv
=
1104 (uint8_t) bp_params
->reference_divider
;
1105 clk
.sPCLKInput
.usFbDiv
=
1106 cpu_to_le16((uint16_t) bp_params
->feedback_divider
);
1107 clk
.sPCLKInput
.ulFbDivDecFrac
=
1108 cpu_to_le32(bp_params
->fractional_feedback_divider
);
1109 clk
.sPCLKInput
.ucPostDiv
=
1110 (uint8_t) bp_params
->pixel_clock_post_divider
;
1111 clk
.sPCLKInput
.ucTransmitterID
=
1112 bp
->cmd_helper
->encoder_id_to_atom(
1113 dal_graphics_object_id_get_encoder_id(
1114 bp_params
->encoder_object_id
));
1115 clk
.sPCLKInput
.ucEncoderMode
=
1116 (uint8_t) bp
->cmd_helper
->encoder_mode_bp_to_atom(
1117 bp_params
->signal_type
, false);
1119 /* We need to convert from 100 Hz units into 10KHz units */
1120 clk
.sPCLKInput
.ulCrtcPclkFreq
.ulPixelClock
=
1121 cpu_to_le32(bp_params
->target_pixel_clock_100hz
/ 100);
1123 if (bp_params
->flags
.FORCE_PROGRAMMING_OF_PLL
) {
1124 clk
.sPCLKInput
.ucMiscInfo
|=
1125 PIXEL_CLOCK_V6_MISC_FORCE_PROG_PPLL
;
1128 if (bp_params
->flags
.SET_EXTERNAL_REF_DIV_SRC
) {
1129 clk
.sPCLKInput
.ucMiscInfo
|=
1130 PIXEL_CLOCK_V6_MISC_REF_DIV_SRC
;
1133 /* clkV6.ucMiscInfo bit[3:2]= HDMI panel bit depth: =0:
1134 * 24bpp =1:30bpp, =2:32bpp
1135 * driver choose program it itself, i.e. here we pass required
1136 * target rate that includes deep color.
1139 if (EXEC_BIOS_CMD_TABLE(SetPixelClock
, clk
))
1140 result
= BP_RESULT_OK
;
1146 static enum bp_result
set_pixel_clock_v7(
1147 struct bios_parser
*bp
,
1148 struct bp_pixel_clock_parameters
*bp_params
)
1150 enum bp_result result
= BP_RESULT_FAILURE
;
1151 PIXEL_CLOCK_PARAMETERS_V7 clk
;
1152 uint8_t controller_id
;
1155 memset(&clk
, 0, sizeof(clk
));
1157 if (bp
->cmd_helper
->clock_source_id_to_atom(bp_params
->pll_id
, &pll_id
)
1158 && bp
->cmd_helper
->controller_id_to_atom(bp_params
->controller_id
, &controller_id
)) {
1159 /* Note: VBIOS still wants to use ucCRTC name which is now
1161 *typedef struct _CRTC_PIXEL_CLOCK_FREQ
1163 * target the pixel clock to drive the CRTC timing.
1164 * ULONG ulPixelClock:24;
1165 * 0 means disable PPLL/DCPLL. Expanded to 24 bits comparing to
1167 * ATOM_CRTC1~6, indicate the CRTC controller to
1169 * drive the pixel clock. not used for DCPLL case.
1170 *}CRTC_PIXEL_CLOCK_FREQ;
1173 * pixel clock and CRTC id frequency
1174 * CRTC_PIXEL_CLOCK_FREQ ulCrtcPclkFreq;
1175 * ULONG ulDispEngClkFreq; dispclk frequency
1178 clk
.ucCRTC
= controller_id
;
1179 clk
.ucPpll
= (uint8_t) pll_id
;
1180 clk
.ucTransmitterID
= bp
->cmd_helper
->encoder_id_to_atom(dal_graphics_object_id_get_encoder_id(bp_params
->encoder_object_id
));
1181 clk
.ucEncoderMode
= (uint8_t) bp
->cmd_helper
->encoder_mode_bp_to_atom(bp_params
->signal_type
, false);
1183 clk
.ulPixelClock
= cpu_to_le32(bp_params
->target_pixel_clock_100hz
);
1185 clk
.ucDeepColorRatio
= (uint8_t) bp
->cmd_helper
->transmitter_color_depth_to_atom(bp_params
->color_depth
);
1187 if (bp_params
->flags
.FORCE_PROGRAMMING_OF_PLL
)
1188 clk
.ucMiscInfo
|= PIXEL_CLOCK_V7_MISC_FORCE_PROG_PPLL
;
1190 if (bp_params
->flags
.SET_EXTERNAL_REF_DIV_SRC
)
1191 clk
.ucMiscInfo
|= PIXEL_CLOCK_V7_MISC_REF_DIV_SRC
;
1193 if (bp_params
->flags
.PROGRAM_PHY_PLL_ONLY
)
1194 clk
.ucMiscInfo
|= PIXEL_CLOCK_V7_MISC_PROG_PHYPLL
;
1196 if (bp_params
->flags
.SUPPORT_YUV_420
)
1197 clk
.ucMiscInfo
|= PIXEL_CLOCK_V7_MISC_YUV420_MODE
;
1199 if (bp_params
->flags
.SET_XTALIN_REF_SRC
)
1200 clk
.ucMiscInfo
|= PIXEL_CLOCK_V7_MISC_REF_DIV_SRC_XTALIN
;
1202 if (bp_params
->flags
.SET_GENLOCK_REF_DIV_SRC
)
1203 clk
.ucMiscInfo
|= PIXEL_CLOCK_V7_MISC_REF_DIV_SRC_GENLK
;
1205 if (bp_params
->signal_type
== SIGNAL_TYPE_DVI_DUAL_LINK
)
1206 clk
.ucMiscInfo
|= PIXEL_CLOCK_V7_MISC_DVI_DUALLINK_EN
;
1208 if (EXEC_BIOS_CMD_TABLE(SetPixelClock
, clk
))
1209 result
= BP_RESULT_OK
;
1214 /*******************************************************************************
1215 ********************************************************************************
1217 ** ENABLE PIXEL CLOCK SS
1219 ********************************************************************************
1220 *******************************************************************************/
1221 static enum bp_result
enable_spread_spectrum_on_ppll_v1(
1222 struct bios_parser
*bp
,
1223 struct bp_spread_spectrum_parameters
*bp_params
,
1225 static enum bp_result
enable_spread_spectrum_on_ppll_v2(
1226 struct bios_parser
*bp
,
1227 struct bp_spread_spectrum_parameters
*bp_params
,
1229 static enum bp_result
enable_spread_spectrum_on_ppll_v3(
1230 struct bios_parser
*bp
,
1231 struct bp_spread_spectrum_parameters
*bp_params
,
1234 static void init_enable_spread_spectrum_on_ppll(struct bios_parser
*bp
)
1236 switch (BIOS_CMD_TABLE_PARA_REVISION(EnableSpreadSpectrumOnPPLL
)) {
1238 bp
->cmd_tbl
.enable_spread_spectrum_on_ppll
=
1239 enable_spread_spectrum_on_ppll_v1
;
1242 bp
->cmd_tbl
.enable_spread_spectrum_on_ppll
=
1243 enable_spread_spectrum_on_ppll_v2
;
1246 bp
->cmd_tbl
.enable_spread_spectrum_on_ppll
=
1247 enable_spread_spectrum_on_ppll_v3
;
1250 dm_output_to_console("Don't have enable_spread_spectrum_on_ppll for v%d\n",
1251 BIOS_CMD_TABLE_PARA_REVISION(EnableSpreadSpectrumOnPPLL
));
1252 bp
->cmd_tbl
.enable_spread_spectrum_on_ppll
= NULL
;
1257 static enum bp_result
enable_spread_spectrum_on_ppll_v1(
1258 struct bios_parser
*bp
,
1259 struct bp_spread_spectrum_parameters
*bp_params
,
1262 enum bp_result result
= BP_RESULT_FAILURE
;
1263 ENABLE_SPREAD_SPECTRUM_ON_PPLL params
;
1265 memset(¶ms
, 0, sizeof(params
));
1267 if ((enable
== true) && (bp_params
->percentage
> 0))
1268 params
.ucEnable
= ATOM_ENABLE
;
1270 params
.ucEnable
= ATOM_DISABLE
;
1272 params
.usSpreadSpectrumPercentage
=
1273 cpu_to_le16((uint16_t)bp_params
->percentage
);
1274 params
.ucSpreadSpectrumStep
=
1275 (uint8_t)bp_params
->ver1
.step
;
1276 params
.ucSpreadSpectrumDelay
=
1277 (uint8_t)bp_params
->ver1
.delay
;
1278 /* convert back to unit of 10KHz */
1279 params
.ucSpreadSpectrumRange
=
1280 (uint8_t)(bp_params
->ver1
.range
/ 10000);
1282 if (bp_params
->flags
.EXTERNAL_SS
)
1283 params
.ucSpreadSpectrumType
|= ATOM_EXTERNAL_SS_MASK
;
1285 if (bp_params
->flags
.CENTER_SPREAD
)
1286 params
.ucSpreadSpectrumType
|= ATOM_SS_CENTRE_SPREAD_MODE
;
1288 if (bp_params
->pll_id
== CLOCK_SOURCE_ID_PLL1
)
1289 params
.ucPpll
= ATOM_PPLL1
;
1290 else if (bp_params
->pll_id
== CLOCK_SOURCE_ID_PLL2
)
1291 params
.ucPpll
= ATOM_PPLL2
;
1293 BREAK_TO_DEBUGGER(); /* Unexpected PLL value!! */
1295 if (EXEC_BIOS_CMD_TABLE(EnableSpreadSpectrumOnPPLL
, params
))
1296 result
= BP_RESULT_OK
;
1301 static enum bp_result
enable_spread_spectrum_on_ppll_v2(
1302 struct bios_parser
*bp
,
1303 struct bp_spread_spectrum_parameters
*bp_params
,
1306 enum bp_result result
= BP_RESULT_FAILURE
;
1307 ENABLE_SPREAD_SPECTRUM_ON_PPLL_V2 params
;
1309 memset(¶ms
, 0, sizeof(params
));
1311 if (bp_params
->pll_id
== CLOCK_SOURCE_ID_PLL1
)
1312 params
.ucSpreadSpectrumType
= ATOM_PPLL_SS_TYPE_V2_P1PLL
;
1313 else if (bp_params
->pll_id
== CLOCK_SOURCE_ID_PLL2
)
1314 params
.ucSpreadSpectrumType
= ATOM_PPLL_SS_TYPE_V2_P2PLL
;
1316 BREAK_TO_DEBUGGER(); /* Unexpected PLL value!! */
1318 if ((enable
== true) && (bp_params
->percentage
> 0)) {
1319 params
.ucEnable
= ATOM_ENABLE
;
1321 params
.usSpreadSpectrumPercentage
=
1322 cpu_to_le16((uint16_t)(bp_params
->percentage
));
1323 params
.usSpreadSpectrumStep
=
1324 cpu_to_le16((uint16_t)(bp_params
->ds
.ds_frac_size
));
1326 if (bp_params
->flags
.EXTERNAL_SS
)
1327 params
.ucSpreadSpectrumType
|=
1328 ATOM_PPLL_SS_TYPE_V2_EXT_SPREAD
;
1330 if (bp_params
->flags
.CENTER_SPREAD
)
1331 params
.ucSpreadSpectrumType
|=
1332 ATOM_PPLL_SS_TYPE_V2_CENTRE_SPREAD
;
1334 /* Both amounts need to be left shifted first before bit
1335 * comparison. Otherwise, the result will always be zero here
1337 params
.usSpreadSpectrumAmount
= cpu_to_le16((uint16_t)(
1338 ((bp_params
->ds
.feedback_amount
<<
1339 ATOM_PPLL_SS_AMOUNT_V2_FBDIV_SHIFT
) &
1340 ATOM_PPLL_SS_AMOUNT_V2_FBDIV_MASK
) |
1341 ((bp_params
->ds
.nfrac_amount
<<
1342 ATOM_PPLL_SS_AMOUNT_V2_NFRAC_SHIFT
) &
1343 ATOM_PPLL_SS_AMOUNT_V2_NFRAC_MASK
)));
1345 params
.ucEnable
= ATOM_DISABLE
;
1347 if (EXEC_BIOS_CMD_TABLE(EnableSpreadSpectrumOnPPLL
, params
))
1348 result
= BP_RESULT_OK
;
1353 static enum bp_result
enable_spread_spectrum_on_ppll_v3(
1354 struct bios_parser
*bp
,
1355 struct bp_spread_spectrum_parameters
*bp_params
,
1358 enum bp_result result
= BP_RESULT_FAILURE
;
1359 ENABLE_SPREAD_SPECTRUM_ON_PPLL_V3 params
;
1361 memset(¶ms
, 0, sizeof(params
));
1363 switch (bp_params
->pll_id
) {
1364 case CLOCK_SOURCE_ID_PLL0
:
1365 /* ATOM_PPLL_SS_TYPE_V3_P0PLL; this is pixel clock only,
1366 * not for SI display clock.
1368 params
.ucSpreadSpectrumType
= ATOM_PPLL_SS_TYPE_V3_DCPLL
;
1370 case CLOCK_SOURCE_ID_PLL1
:
1371 params
.ucSpreadSpectrumType
= ATOM_PPLL_SS_TYPE_V3_P1PLL
;
1374 case CLOCK_SOURCE_ID_PLL2
:
1375 params
.ucSpreadSpectrumType
= ATOM_PPLL_SS_TYPE_V3_P2PLL
;
1378 case CLOCK_SOURCE_ID_DCPLL
:
1379 params
.ucSpreadSpectrumType
= ATOM_PPLL_SS_TYPE_V3_DCPLL
;
1383 BREAK_TO_DEBUGGER();
1384 /* Unexpected PLL value!! */
1388 if (enable
== true) {
1389 params
.ucEnable
= ATOM_ENABLE
;
1391 params
.usSpreadSpectrumAmountFrac
=
1392 cpu_to_le16((uint16_t)(bp_params
->ds_frac_amount
));
1393 params
.usSpreadSpectrumStep
=
1394 cpu_to_le16((uint16_t)(bp_params
->ds
.ds_frac_size
));
1396 if (bp_params
->flags
.EXTERNAL_SS
)
1397 params
.ucSpreadSpectrumType
|=
1398 ATOM_PPLL_SS_TYPE_V3_EXT_SPREAD
;
1399 if (bp_params
->flags
.CENTER_SPREAD
)
1400 params
.ucSpreadSpectrumType
|=
1401 ATOM_PPLL_SS_TYPE_V3_CENTRE_SPREAD
;
1403 /* Both amounts need to be left shifted first before bit
1404 * comparison. Otherwise, the result will always be zero here
1406 params
.usSpreadSpectrumAmount
= cpu_to_le16((uint16_t)(
1407 ((bp_params
->ds
.feedback_amount
<<
1408 ATOM_PPLL_SS_AMOUNT_V3_FBDIV_SHIFT
) &
1409 ATOM_PPLL_SS_AMOUNT_V3_FBDIV_MASK
) |
1410 ((bp_params
->ds
.nfrac_amount
<<
1411 ATOM_PPLL_SS_AMOUNT_V3_NFRAC_SHIFT
) &
1412 ATOM_PPLL_SS_AMOUNT_V3_NFRAC_MASK
)));
1414 params
.ucEnable
= ATOM_DISABLE
;
1416 if (EXEC_BIOS_CMD_TABLE(EnableSpreadSpectrumOnPPLL
, params
))
1417 result
= BP_RESULT_OK
;
1422 /*******************************************************************************
1423 ********************************************************************************
1425 ** ADJUST DISPLAY PLL
1427 ********************************************************************************
1428 *******************************************************************************/
1430 static enum bp_result
adjust_display_pll_v2(
1431 struct bios_parser
*bp
,
1432 struct bp_adjust_pixel_clock_parameters
*bp_params
);
1433 static enum bp_result
adjust_display_pll_v3(
1434 struct bios_parser
*bp
,
1435 struct bp_adjust_pixel_clock_parameters
*bp_params
);
1437 static void init_adjust_display_pll(struct bios_parser
*bp
)
1439 switch (BIOS_CMD_TABLE_PARA_REVISION(AdjustDisplayPll
)) {
1441 bp
->cmd_tbl
.adjust_display_pll
= adjust_display_pll_v2
;
1444 bp
->cmd_tbl
.adjust_display_pll
= adjust_display_pll_v3
;
1447 dm_output_to_console("Don't have adjust_display_pll for v%d\n",
1448 BIOS_CMD_TABLE_PARA_REVISION(AdjustDisplayPll
));
1449 bp
->cmd_tbl
.adjust_display_pll
= NULL
;
1454 static enum bp_result
adjust_display_pll_v2(
1455 struct bios_parser
*bp
,
1456 struct bp_adjust_pixel_clock_parameters
*bp_params
)
1458 enum bp_result result
= BP_RESULT_FAILURE
;
1459 ADJUST_DISPLAY_PLL_PS_ALLOCATION params
= { 0 };
1461 /* We need to convert from KHz units into 10KHz units and then convert
1462 * output pixel clock back 10KHz-->KHz */
1463 uint32_t pixel_clock_10KHz_in
= bp_params
->pixel_clock
/ 10;
1465 params
.usPixelClock
= cpu_to_le16((uint16_t)(pixel_clock_10KHz_in
));
1466 params
.ucTransmitterID
=
1467 bp
->cmd_helper
->encoder_id_to_atom(
1468 dal_graphics_object_id_get_encoder_id(
1469 bp_params
->encoder_object_id
));
1470 params
.ucEncodeMode
=
1471 (uint8_t)bp
->cmd_helper
->encoder_mode_bp_to_atom(
1472 bp_params
->signal_type
, false);
1476 static enum bp_result
adjust_display_pll_v3(
1477 struct bios_parser
*bp
,
1478 struct bp_adjust_pixel_clock_parameters
*bp_params
)
1480 enum bp_result result
= BP_RESULT_FAILURE
;
1481 ADJUST_DISPLAY_PLL_PS_ALLOCATION_V3 params
;
1482 uint32_t pixel_clk_10_kHz_in
= bp_params
->pixel_clock
/ 10;
1484 memset(¶ms
, 0, sizeof(params
));
1486 /* We need to convert from KHz units into 10KHz units and then convert
1487 * output pixel clock back 10KHz-->KHz */
1488 params
.sInput
.usPixelClock
= cpu_to_le16((uint16_t)pixel_clk_10_kHz_in
);
1489 params
.sInput
.ucTransmitterID
=
1490 bp
->cmd_helper
->encoder_id_to_atom(
1491 dal_graphics_object_id_get_encoder_id(
1492 bp_params
->encoder_object_id
));
1493 params
.sInput
.ucEncodeMode
=
1494 (uint8_t)bp
->cmd_helper
->encoder_mode_bp_to_atom(
1495 bp_params
->signal_type
, false);
1497 if (bp_params
->ss_enable
== true)
1498 params
.sInput
.ucDispPllConfig
|= DISPPLL_CONFIG_SS_ENABLE
;
1500 if (bp_params
->signal_type
== SIGNAL_TYPE_DVI_DUAL_LINK
)
1501 params
.sInput
.ucDispPllConfig
|= DISPPLL_CONFIG_DUAL_LINK
;
1503 if (EXEC_BIOS_CMD_TABLE(AdjustDisplayPll
, params
)) {
1504 /* Convert output pixel clock back 10KHz-->KHz: multiply
1505 * original pixel clock in KHz by ratio
1506 * [output pxlClk/input pxlClk] */
1507 uint64_t pixel_clk_10_khz_out
=
1508 (uint64_t)le32_to_cpu(params
.sOutput
.ulDispPllFreq
);
1509 uint64_t pixel_clk
= (uint64_t)bp_params
->pixel_clock
;
1511 if (pixel_clk_10_kHz_in
!= 0) {
1512 bp_params
->adjusted_pixel_clock
=
1513 div_u64(pixel_clk
* pixel_clk_10_khz_out
,
1514 pixel_clk_10_kHz_in
);
1516 bp_params
->adjusted_pixel_clock
= 0;
1517 BREAK_TO_DEBUGGER();
1520 bp_params
->reference_divider
= params
.sOutput
.ucRefDiv
;
1521 bp_params
->pixel_clock_post_divider
= params
.sOutput
.ucPostDiv
;
1523 result
= BP_RESULT_OK
;
1529 /*******************************************************************************
1530 ********************************************************************************
1532 ** DAC ENCODER CONTROL
1534 ********************************************************************************
1535 *******************************************************************************/
1537 static enum bp_result
dac1_encoder_control_v1(
1538 struct bios_parser
*bp
,
1540 uint32_t pixel_clock
,
1541 uint8_t dac_standard
);
1542 static enum bp_result
dac2_encoder_control_v1(
1543 struct bios_parser
*bp
,
1545 uint32_t pixel_clock
,
1546 uint8_t dac_standard
);
1548 static void init_dac_encoder_control(struct bios_parser
*bp
)
1550 switch (BIOS_CMD_TABLE_PARA_REVISION(DAC1EncoderControl
)) {
1552 bp
->cmd_tbl
.dac1_encoder_control
= dac1_encoder_control_v1
;
1555 bp
->cmd_tbl
.dac1_encoder_control
= NULL
;
1558 switch (BIOS_CMD_TABLE_PARA_REVISION(DAC2EncoderControl
)) {
1560 bp
->cmd_tbl
.dac2_encoder_control
= dac2_encoder_control_v1
;
1563 bp
->cmd_tbl
.dac2_encoder_control
= NULL
;
1568 static void dac_encoder_control_prepare_params(
1569 DAC_ENCODER_CONTROL_PS_ALLOCATION
*params
,
1571 uint32_t pixel_clock
,
1572 uint8_t dac_standard
)
1574 params
->ucDacStandard
= dac_standard
;
1576 params
->ucAction
= ATOM_ENABLE
;
1578 params
->ucAction
= ATOM_DISABLE
;
1580 /* We need to convert from KHz units into 10KHz units
1581 * it looks as if the TvControl do not care about pixel clock
1583 params
->usPixelClock
= cpu_to_le16((uint16_t)(pixel_clock
/ 10));
1586 static enum bp_result
dac1_encoder_control_v1(
1587 struct bios_parser
*bp
,
1589 uint32_t pixel_clock
,
1590 uint8_t dac_standard
)
1592 enum bp_result result
= BP_RESULT_FAILURE
;
1593 DAC_ENCODER_CONTROL_PS_ALLOCATION params
;
1595 dac_encoder_control_prepare_params(
1601 if (EXEC_BIOS_CMD_TABLE(DAC1EncoderControl
, params
))
1602 result
= BP_RESULT_OK
;
1607 static enum bp_result
dac2_encoder_control_v1(
1608 struct bios_parser
*bp
,
1610 uint32_t pixel_clock
,
1611 uint8_t dac_standard
)
1613 enum bp_result result
= BP_RESULT_FAILURE
;
1614 DAC_ENCODER_CONTROL_PS_ALLOCATION params
;
1616 dac_encoder_control_prepare_params(
1622 if (EXEC_BIOS_CMD_TABLE(DAC2EncoderControl
, params
))
1623 result
= BP_RESULT_OK
;
1628 /*******************************************************************************
1629 ********************************************************************************
1631 ** DAC OUTPUT CONTROL
1633 ********************************************************************************
1634 *******************************************************************************/
1635 static enum bp_result
dac1_output_control_v1(
1636 struct bios_parser
*bp
,
1638 static enum bp_result
dac2_output_control_v1(
1639 struct bios_parser
*bp
,
1642 static void init_dac_output_control(struct bios_parser
*bp
)
1644 switch (BIOS_CMD_TABLE_PARA_REVISION(DAC1OutputControl
)) {
1646 bp
->cmd_tbl
.dac1_output_control
= dac1_output_control_v1
;
1649 bp
->cmd_tbl
.dac1_output_control
= NULL
;
1652 switch (BIOS_CMD_TABLE_PARA_REVISION(DAC2OutputControl
)) {
1654 bp
->cmd_tbl
.dac2_output_control
= dac2_output_control_v1
;
1657 bp
->cmd_tbl
.dac2_output_control
= NULL
;
1662 static enum bp_result
dac1_output_control_v1(
1663 struct bios_parser
*bp
, bool enable
)
1665 enum bp_result result
= BP_RESULT_FAILURE
;
1666 DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION params
;
1669 params
.ucAction
= ATOM_ENABLE
;
1671 params
.ucAction
= ATOM_DISABLE
;
1673 if (EXEC_BIOS_CMD_TABLE(DAC1OutputControl
, params
))
1674 result
= BP_RESULT_OK
;
1679 static enum bp_result
dac2_output_control_v1(
1680 struct bios_parser
*bp
, bool enable
)
1682 enum bp_result result
= BP_RESULT_FAILURE
;
1683 DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION params
;
1686 params
.ucAction
= ATOM_ENABLE
;
1688 params
.ucAction
= ATOM_DISABLE
;
1690 if (EXEC_BIOS_CMD_TABLE(DAC2OutputControl
, params
))
1691 result
= BP_RESULT_OK
;
1696 /*******************************************************************************
1697 ********************************************************************************
1701 ********************************************************************************
1702 *******************************************************************************/
1704 static enum bp_result
set_crtc_using_dtd_timing_v3(
1705 struct bios_parser
*bp
,
1706 struct bp_hw_crtc_timing_parameters
*bp_params
);
1707 static enum bp_result
set_crtc_timing_v1(
1708 struct bios_parser
*bp
,
1709 struct bp_hw_crtc_timing_parameters
*bp_params
);
1711 static void init_set_crtc_timing(struct bios_parser
*bp
)
1713 uint32_t dtd_version
=
1714 BIOS_CMD_TABLE_PARA_REVISION(SetCRTC_UsingDTDTiming
);
1715 if (dtd_version
> 2)
1716 switch (dtd_version
) {
1718 bp
->cmd_tbl
.set_crtc_timing
=
1719 set_crtc_using_dtd_timing_v3
;
1722 dm_output_to_console("Don't have set_crtc_timing for dtd v%d\n",
1724 bp
->cmd_tbl
.set_crtc_timing
= NULL
;
1728 switch (BIOS_CMD_TABLE_PARA_REVISION(SetCRTC_Timing
)) {
1730 bp
->cmd_tbl
.set_crtc_timing
= set_crtc_timing_v1
;
1733 dm_output_to_console("Don't have set_crtc_timing for v%d\n",
1734 BIOS_CMD_TABLE_PARA_REVISION(SetCRTC_Timing
));
1735 bp
->cmd_tbl
.set_crtc_timing
= NULL
;
1740 static enum bp_result
set_crtc_timing_v1(
1741 struct bios_parser
*bp
,
1742 struct bp_hw_crtc_timing_parameters
*bp_params
)
1744 enum bp_result result
= BP_RESULT_FAILURE
;
1745 SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION params
= {0};
1746 uint8_t atom_controller_id
;
1748 if (bp
->cmd_helper
->controller_id_to_atom(
1749 bp_params
->controller_id
, &atom_controller_id
))
1750 params
.ucCRTC
= atom_controller_id
;
1752 params
.usH_Total
= cpu_to_le16((uint16_t)(bp_params
->h_total
));
1753 params
.usH_Disp
= cpu_to_le16((uint16_t)(bp_params
->h_addressable
));
1754 params
.usH_SyncStart
= cpu_to_le16((uint16_t)(bp_params
->h_sync_start
));
1755 params
.usH_SyncWidth
= cpu_to_le16((uint16_t)(bp_params
->h_sync_width
));
1756 params
.usV_Total
= cpu_to_le16((uint16_t)(bp_params
->v_total
));
1757 params
.usV_Disp
= cpu_to_le16((uint16_t)(bp_params
->v_addressable
));
1758 params
.usV_SyncStart
=
1759 cpu_to_le16((uint16_t)(bp_params
->v_sync_start
));
1760 params
.usV_SyncWidth
=
1761 cpu_to_le16((uint16_t)(bp_params
->v_sync_width
));
1763 /* VBIOS does not expect any value except zero into this call, for
1764 * underscan use another entry ProgramOverscan call but when mode
1765 * 1776x1000 with the overscan 72x44 .e.i. 1920x1080 @30 DAL2 is ok,
1766 * but when same ,but 60 Hz there is corruption
1767 * DAL1 does not allow the mode 1776x1000@60
1769 params
.ucOverscanRight
= (uint8_t)bp_params
->h_overscan_right
;
1770 params
.ucOverscanLeft
= (uint8_t)bp_params
->h_overscan_left
;
1771 params
.ucOverscanBottom
= (uint8_t)bp_params
->v_overscan_bottom
;
1772 params
.ucOverscanTop
= (uint8_t)bp_params
->v_overscan_top
;
1774 if (0 == bp_params
->flags
.HSYNC_POSITIVE_POLARITY
)
1775 params
.susModeMiscInfo
.usAccess
=
1776 cpu_to_le16(le16_to_cpu(params
.susModeMiscInfo
.usAccess
) | ATOM_HSYNC_POLARITY
);
1778 if (0 == bp_params
->flags
.VSYNC_POSITIVE_POLARITY
)
1779 params
.susModeMiscInfo
.usAccess
=
1780 cpu_to_le16(le16_to_cpu(params
.susModeMiscInfo
.usAccess
) | ATOM_VSYNC_POLARITY
);
1782 if (bp_params
->flags
.INTERLACE
) {
1783 params
.susModeMiscInfo
.usAccess
=
1784 cpu_to_le16(le16_to_cpu(params
.susModeMiscInfo
.usAccess
) | ATOM_INTERLACE
);
1786 /* original DAL code has this condition to apply tis for
1787 * non-TV/CV only due to complex MV testing for possible
1789 * if (pACParameters->signal != SignalType_YPbPr &&
1790 * pACParameters->signal != SignalType_Composite &&
1791 * pACParameters->signal != SignalType_SVideo)
1793 /* HW will deduct 0.5 line from 2nd feild.
1794 * i.e. for 1080i, it is 2 lines for 1st field, 2.5
1795 * lines for the 2nd feild. we need input as 5 instead
1796 * of 4, but it is 4 either from Edid data
1797 * (spec CEA 861) or CEA timing table.
1799 params
.usV_SyncStart
=
1800 cpu_to_le16((uint16_t)(bp_params
->v_sync_start
+ 1));
1803 if (bp_params
->flags
.HORZ_COUNT_BY_TWO
)
1804 params
.susModeMiscInfo
.usAccess
=
1805 cpu_to_le16(le16_to_cpu(params
.susModeMiscInfo
.usAccess
) | ATOM_DOUBLE_CLOCK_MODE
);
1807 if (EXEC_BIOS_CMD_TABLE(SetCRTC_Timing
, params
))
1808 result
= BP_RESULT_OK
;
1813 static enum bp_result
set_crtc_using_dtd_timing_v3(
1814 struct bios_parser
*bp
,
1815 struct bp_hw_crtc_timing_parameters
*bp_params
)
1817 enum bp_result result
= BP_RESULT_FAILURE
;
1818 SET_CRTC_USING_DTD_TIMING_PARAMETERS params
= {0};
1819 uint8_t atom_controller_id
;
1821 if (bp
->cmd_helper
->controller_id_to_atom(
1822 bp_params
->controller_id
, &atom_controller_id
))
1823 params
.ucCRTC
= atom_controller_id
;
1825 /* bios usH_Size wants h addressable size */
1826 params
.usH_Size
= cpu_to_le16((uint16_t)bp_params
->h_addressable
);
1827 /* bios usH_Blanking_Time wants borders included in blanking */
1828 params
.usH_Blanking_Time
=
1829 cpu_to_le16((uint16_t)(bp_params
->h_total
- bp_params
->h_addressable
));
1830 /* bios usV_Size wants v addressable size */
1831 params
.usV_Size
= cpu_to_le16((uint16_t)bp_params
->v_addressable
);
1832 /* bios usV_Blanking_Time wants borders included in blanking */
1833 params
.usV_Blanking_Time
=
1834 cpu_to_le16((uint16_t)(bp_params
->v_total
- bp_params
->v_addressable
));
1835 /* bios usHSyncOffset is the offset from the end of h addressable,
1836 * our horizontalSyncStart is the offset from the beginning
1837 * of h addressable */
1838 params
.usH_SyncOffset
=
1839 cpu_to_le16((uint16_t)(bp_params
->h_sync_start
- bp_params
->h_addressable
));
1840 params
.usH_SyncWidth
= cpu_to_le16((uint16_t)bp_params
->h_sync_width
);
1841 /* bios usHSyncOffset is the offset from the end of v addressable,
1842 * our verticalSyncStart is the offset from the beginning of
1844 params
.usV_SyncOffset
=
1845 cpu_to_le16((uint16_t)(bp_params
->v_sync_start
- bp_params
->v_addressable
));
1846 params
.usV_SyncWidth
= cpu_to_le16((uint16_t)bp_params
->v_sync_width
);
1848 /* we assume that overscan from original timing does not get bigger
1850 * we will program all the borders in the Set CRTC Overscan call below
1853 if (0 == bp_params
->flags
.HSYNC_POSITIVE_POLARITY
)
1854 params
.susModeMiscInfo
.usAccess
=
1855 cpu_to_le16(le16_to_cpu(params
.susModeMiscInfo
.usAccess
) | ATOM_HSYNC_POLARITY
);
1857 if (0 == bp_params
->flags
.VSYNC_POSITIVE_POLARITY
)
1858 params
.susModeMiscInfo
.usAccess
=
1859 cpu_to_le16(le16_to_cpu(params
.susModeMiscInfo
.usAccess
) | ATOM_VSYNC_POLARITY
);
1861 if (bp_params
->flags
.INTERLACE
) {
1862 params
.susModeMiscInfo
.usAccess
=
1863 cpu_to_le16(le16_to_cpu(params
.susModeMiscInfo
.usAccess
) | ATOM_INTERLACE
);
1865 /* original DAL code has this condition to apply this
1866 * for non-TV/CV only
1867 * due to complex MV testing for possible impact
1868 * if ( pACParameters->signal != SignalType_YPbPr &&
1869 * pACParameters->signal != SignalType_Composite &&
1870 * pACParameters->signal != SignalType_SVideo)
1873 /* HW will deduct 0.5 line from 2nd feild.
1874 * i.e. for 1080i, it is 2 lines for 1st field,
1875 * 2.5 lines for the 2nd feild. we need input as 5
1877 * but it is 4 either from Edid data (spec CEA 861)
1878 * or CEA timing table.
1880 le16_add_cpu(¶ms
.usV_SyncOffset
, 1);
1884 if (bp_params
->flags
.HORZ_COUNT_BY_TWO
)
1885 params
.susModeMiscInfo
.usAccess
=
1886 cpu_to_le16(le16_to_cpu(params
.susModeMiscInfo
.usAccess
) | ATOM_DOUBLE_CLOCK_MODE
);
1888 if (EXEC_BIOS_CMD_TABLE(SetCRTC_UsingDTDTiming
, params
))
1889 result
= BP_RESULT_OK
;
1894 /*******************************************************************************
1895 ********************************************************************************
1899 ********************************************************************************
1900 *******************************************************************************/
1902 static enum bp_result
enable_crtc_v1(
1903 struct bios_parser
*bp
,
1904 enum controller_id controller_id
,
1907 static void init_enable_crtc(struct bios_parser
*bp
)
1909 switch (BIOS_CMD_TABLE_PARA_REVISION(EnableCRTC
)) {
1911 bp
->cmd_tbl
.enable_crtc
= enable_crtc_v1
;
1914 dm_output_to_console("Don't have enable_crtc for v%d\n",
1915 BIOS_CMD_TABLE_PARA_REVISION(EnableCRTC
));
1916 bp
->cmd_tbl
.enable_crtc
= NULL
;
1921 static enum bp_result
enable_crtc_v1(
1922 struct bios_parser
*bp
,
1923 enum controller_id controller_id
,
1926 bool result
= BP_RESULT_FAILURE
;
1927 ENABLE_CRTC_PARAMETERS params
= {0};
1930 if (bp
->cmd_helper
->controller_id_to_atom(controller_id
, &id
))
1933 return BP_RESULT_BADINPUT
;
1936 params
.ucEnable
= ATOM_ENABLE
;
1938 params
.ucEnable
= ATOM_DISABLE
;
1940 if (EXEC_BIOS_CMD_TABLE(EnableCRTC
, params
))
1941 result
= BP_RESULT_OK
;
1946 /*******************************************************************************
1947 ********************************************************************************
1949 ** ENABLE CRTC MEM REQ
1951 ********************************************************************************
1952 *******************************************************************************/
1954 static enum bp_result
enable_crtc_mem_req_v1(
1955 struct bios_parser
*bp
,
1956 enum controller_id controller_id
,
1959 static void init_enable_crtc_mem_req(struct bios_parser
*bp
)
1961 switch (BIOS_CMD_TABLE_PARA_REVISION(EnableCRTCMemReq
)) {
1963 bp
->cmd_tbl
.enable_crtc_mem_req
= enable_crtc_mem_req_v1
;
1966 bp
->cmd_tbl
.enable_crtc_mem_req
= NULL
;
1971 static enum bp_result
enable_crtc_mem_req_v1(
1972 struct bios_parser
*bp
,
1973 enum controller_id controller_id
,
1976 bool result
= BP_RESULT_BADINPUT
;
1977 ENABLE_CRTC_PARAMETERS params
= {0};
1980 if (bp
->cmd_helper
->controller_id_to_atom(controller_id
, &id
)) {
1984 params
.ucEnable
= ATOM_ENABLE
;
1986 params
.ucEnable
= ATOM_DISABLE
;
1988 if (EXEC_BIOS_CMD_TABLE(EnableCRTCMemReq
, params
))
1989 result
= BP_RESULT_OK
;
1991 result
= BP_RESULT_FAILURE
;
1997 /*******************************************************************************
1998 ********************************************************************************
2002 ********************************************************************************
2003 *******************************************************************************/
2005 static enum bp_result
program_clock_v5(
2006 struct bios_parser
*bp
,
2007 struct bp_pixel_clock_parameters
*bp_params
);
2008 static enum bp_result
program_clock_v6(
2009 struct bios_parser
*bp
,
2010 struct bp_pixel_clock_parameters
*bp_params
);
2012 static void init_program_clock(struct bios_parser
*bp
)
2014 switch (BIOS_CMD_TABLE_PARA_REVISION(SetPixelClock
)) {
2016 bp
->cmd_tbl
.program_clock
= program_clock_v5
;
2019 bp
->cmd_tbl
.program_clock
= program_clock_v6
;
2022 dm_output_to_console("Don't have program_clock for v%d\n",
2023 BIOS_CMD_TABLE_PARA_REVISION(SetPixelClock
));
2024 bp
->cmd_tbl
.program_clock
= NULL
;
2029 static enum bp_result
program_clock_v5(
2030 struct bios_parser
*bp
,
2031 struct bp_pixel_clock_parameters
*bp_params
)
2033 enum bp_result result
= BP_RESULT_FAILURE
;
2035 SET_PIXEL_CLOCK_PS_ALLOCATION_V5 params
;
2036 uint32_t atom_pll_id
;
2038 memset(¶ms
, 0, sizeof(params
));
2039 if (!bp
->cmd_helper
->clock_source_id_to_atom(
2040 bp_params
->pll_id
, &atom_pll_id
)) {
2041 BREAK_TO_DEBUGGER(); /* Invalid Inpute!! */
2042 return BP_RESULT_BADINPUT
;
2045 /* We need to convert from KHz units into 10KHz units */
2046 params
.sPCLKInput
.ucPpll
= (uint8_t) atom_pll_id
;
2047 params
.sPCLKInput
.usPixelClock
=
2048 cpu_to_le16((uint16_t) (bp_params
->target_pixel_clock_100hz
/ 100));
2049 params
.sPCLKInput
.ucCRTC
= (uint8_t) ATOM_CRTC_INVALID
;
2051 if (bp_params
->flags
.SET_EXTERNAL_REF_DIV_SRC
)
2052 params
.sPCLKInput
.ucMiscInfo
|= PIXEL_CLOCK_MISC_REF_DIV_SRC
;
2054 if (EXEC_BIOS_CMD_TABLE(SetPixelClock
, params
))
2055 result
= BP_RESULT_OK
;
2060 static enum bp_result
program_clock_v6(
2061 struct bios_parser
*bp
,
2062 struct bp_pixel_clock_parameters
*bp_params
)
2064 enum bp_result result
= BP_RESULT_FAILURE
;
2066 SET_PIXEL_CLOCK_PS_ALLOCATION_V6 params
;
2067 uint32_t atom_pll_id
;
2069 memset(¶ms
, 0, sizeof(params
));
2071 if (!bp
->cmd_helper
->clock_source_id_to_atom(
2072 bp_params
->pll_id
, &atom_pll_id
)) {
2073 BREAK_TO_DEBUGGER(); /*Invalid Input!!*/
2074 return BP_RESULT_BADINPUT
;
2077 /* We need to convert from KHz units into 10KHz units */
2078 params
.sPCLKInput
.ucPpll
= (uint8_t)atom_pll_id
;
2079 params
.sPCLKInput
.ulDispEngClkFreq
=
2080 cpu_to_le32(bp_params
->target_pixel_clock_100hz
/ 100);
2082 if (bp_params
->flags
.SET_EXTERNAL_REF_DIV_SRC
)
2083 params
.sPCLKInput
.ucMiscInfo
|= PIXEL_CLOCK_MISC_REF_DIV_SRC
;
2085 if (bp_params
->flags
.SET_DISPCLK_DFS_BYPASS
)
2086 params
.sPCLKInput
.ucMiscInfo
|= PIXEL_CLOCK_V6_MISC_DPREFCLK_BYPASS
;
2088 if (EXEC_BIOS_CMD_TABLE(SetPixelClock
, params
)) {
2089 /* True display clock is returned by VBIOS if DFS bypass
2091 bp_params
->dfs_bypass_display_clock
=
2092 (uint32_t)(le32_to_cpu(params
.sPCLKInput
.ulDispEngClkFreq
) * 10);
2093 result
= BP_RESULT_OK
;
2099 /*******************************************************************************
2100 ********************************************************************************
2102 ** EXTERNAL ENCODER CONTROL
2104 ********************************************************************************
2105 *******************************************************************************/
2107 static enum bp_result
external_encoder_control_v3(
2108 struct bios_parser
*bp
,
2109 struct bp_external_encoder_control
*cntl
);
2111 static void init_external_encoder_control(
2112 struct bios_parser
*bp
)
2114 switch (BIOS_CMD_TABLE_PARA_REVISION(ExternalEncoderControl
)) {
2116 bp
->cmd_tbl
.external_encoder_control
=
2117 external_encoder_control_v3
;
2120 bp
->cmd_tbl
.external_encoder_control
= NULL
;
2125 static enum bp_result
external_encoder_control_v3(
2126 struct bios_parser
*bp
,
2127 struct bp_external_encoder_control
*cntl
)
2129 enum bp_result result
= BP_RESULT_FAILURE
;
2131 /* we need use _PS_Alloc struct */
2132 EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION_V3 params
;
2133 EXTERNAL_ENCODER_CONTROL_PARAMETERS_V3
*cntl_params
;
2134 struct graphics_object_id encoder
;
2135 bool is_input_signal_dp
= false;
2137 memset(¶ms
, 0, sizeof(params
));
2139 cntl_params
= ¶ms
.sExtEncoder
;
2141 encoder
= cntl
->encoder_id
;
2143 /* check if encoder supports external encoder control table */
2144 switch (dal_graphics_object_id_get_encoder_id(encoder
)) {
2145 case ENCODER_ID_EXTERNAL_NUTMEG
:
2146 case ENCODER_ID_EXTERNAL_TRAVIS
:
2147 is_input_signal_dp
= true;
2151 BREAK_TO_DEBUGGER();
2152 return BP_RESULT_BADINPUT
;
2155 /* Fill information based on the action
2157 * Bit[6:4]: indicate external encoder, applied to all functions.
2158 * =0: external encoder1, mapped to external encoder enum id1
2159 * =1: external encoder2, mapped to external encoder enum id2
2163 * EnumId_Unknown = 0,
2168 cntl_params
->ucConfig
= (uint8_t)((encoder
.enum_id
- 1) << 4);
2170 switch (cntl
->action
) {
2171 case EXTERNAL_ENCODER_CONTROL_INIT
:
2172 /* output display connector type. Only valid in encoder
2174 cntl_params
->usConnectorId
=
2175 cpu_to_le16((uint16_t)cntl
->connector_obj_id
.id
);
2177 case EXTERNAL_ENCODER_CONTROL_SETUP
:
2178 /* EXTERNAL_ENCODER_CONTROL_PARAMETERS_V3 pixel clock unit in
2180 * output display device pixel clock frequency in unit of 10KHz.
2181 * Only valid in setup and enableoutput
2183 cntl_params
->usPixelClock
=
2184 cpu_to_le16((uint16_t)(cntl
->pixel_clock
/ 10));
2185 /* Indicate display output signal type drive by external
2186 * encoder, only valid in setup and enableoutput */
2187 cntl_params
->ucEncoderMode
=
2188 (uint8_t)bp
->cmd_helper
->encoder_mode_bp_to_atom(
2189 cntl
->signal
, false);
2191 if (is_input_signal_dp
) {
2192 /* Bit[0]: indicate link rate, =1: 2.7Ghz, =0: 1.62Ghz,
2193 * only valid in encoder setup with DP mode. */
2194 if (LINK_RATE_HIGH
== cntl
->link_rate
)
2195 cntl_params
->ucConfig
|= 1;
2196 /* output color depth Indicate encoder data bpc format
2197 * in DP mode, only valid in encoder setup in DP mode.
2199 cntl_params
->ucBitPerColor
=
2200 (uint8_t)(cntl
->color_depth
);
2202 /* Indicate how many lanes used by external encoder, only valid
2203 * in encoder setup and enableoutput. */
2204 cntl_params
->ucLaneNum
= (uint8_t)(cntl
->lanes_number
);
2206 case EXTERNAL_ENCODER_CONTROL_ENABLE
:
2207 cntl_params
->usPixelClock
=
2208 cpu_to_le16((uint16_t)(cntl
->pixel_clock
/ 10));
2209 cntl_params
->ucEncoderMode
=
2210 (uint8_t)bp
->cmd_helper
->encoder_mode_bp_to_atom(
2211 cntl
->signal
, false);
2212 cntl_params
->ucLaneNum
= (uint8_t)cntl
->lanes_number
;
2218 cntl_params
->ucAction
= (uint8_t)cntl
->action
;
2220 if (EXEC_BIOS_CMD_TABLE(ExternalEncoderControl
, params
))
2221 result
= BP_RESULT_OK
;
2226 /*******************************************************************************
2227 ********************************************************************************
2229 ** ENABLE DISPLAY POWER GATING
2231 ********************************************************************************
2232 *******************************************************************************/
2234 static enum bp_result
enable_disp_power_gating_v2_1(
2235 struct bios_parser
*bp
,
2236 enum controller_id crtc_id
,
2237 enum bp_pipe_control_action action
);
2239 static void init_enable_disp_power_gating(
2240 struct bios_parser
*bp
)
2242 switch (BIOS_CMD_TABLE_PARA_REVISION(EnableDispPowerGating
)) {
2244 bp
->cmd_tbl
.enable_disp_power_gating
=
2245 enable_disp_power_gating_v2_1
;
2248 dm_output_to_console("Don't enable_disp_power_gating enable_crtc for v%d\n",
2249 BIOS_CMD_TABLE_PARA_REVISION(EnableDispPowerGating
));
2250 bp
->cmd_tbl
.enable_disp_power_gating
= NULL
;
2255 static enum bp_result
enable_disp_power_gating_v2_1(
2256 struct bios_parser
*bp
,
2257 enum controller_id crtc_id
,
2258 enum bp_pipe_control_action action
)
2260 enum bp_result result
= BP_RESULT_FAILURE
;
2262 ENABLE_DISP_POWER_GATING_PS_ALLOCATION params
= {0};
2263 uint8_t atom_crtc_id
;
2265 if (bp
->cmd_helper
->controller_id_to_atom(crtc_id
, &atom_crtc_id
))
2266 params
.ucDispPipeId
= atom_crtc_id
;
2268 return BP_RESULT_BADINPUT
;
2271 bp
->cmd_helper
->disp_power_gating_action_to_atom(action
);
2273 if (EXEC_BIOS_CMD_TABLE(EnableDispPowerGating
, params
))
2274 result
= BP_RESULT_OK
;
2279 /*******************************************************************************
2280 ********************************************************************************
2284 ********************************************************************************
2285 *******************************************************************************/
2286 static enum bp_result
set_dce_clock_v2_1(
2287 struct bios_parser
*bp
,
2288 struct bp_set_dce_clock_parameters
*bp_params
);
2290 static void init_set_dce_clock(struct bios_parser
*bp
)
2292 switch (BIOS_CMD_TABLE_PARA_REVISION(SetDCEClock
)) {
2294 bp
->cmd_tbl
.set_dce_clock
= set_dce_clock_v2_1
;
2297 dm_output_to_console("Don't have set_dce_clock for v%d\n",
2298 BIOS_CMD_TABLE_PARA_REVISION(SetDCEClock
));
2299 bp
->cmd_tbl
.set_dce_clock
= NULL
;
2304 static enum bp_result
set_dce_clock_v2_1(
2305 struct bios_parser
*bp
,
2306 struct bp_set_dce_clock_parameters
*bp_params
)
2308 enum bp_result result
= BP_RESULT_FAILURE
;
2310 SET_DCE_CLOCK_PS_ALLOCATION_V2_1 params
;
2311 uint32_t atom_pll_id
;
2312 uint32_t atom_clock_type
;
2313 const struct command_table_helper
*cmd
= bp
->cmd_helper
;
2315 memset(¶ms
, 0, sizeof(params
));
2317 if (!cmd
->clock_source_id_to_atom(bp_params
->pll_id
, &atom_pll_id
) ||
2318 !cmd
->dc_clock_type_to_atom(bp_params
->clock_type
, &atom_clock_type
))
2319 return BP_RESULT_BADINPUT
;
2321 params
.asParam
.ucDCEClkSrc
= atom_pll_id
;
2322 params
.asParam
.ucDCEClkType
= atom_clock_type
;
2324 if (bp_params
->clock_type
== DCECLOCK_TYPE_DPREFCLK
) {
2325 if (bp_params
->flags
.USE_GENLOCK_AS_SOURCE_FOR_DPREFCLK
)
2326 params
.asParam
.ucDCEClkFlag
|= DCE_CLOCK_FLAG_PLL_REFCLK_SRC_GENLK
;
2328 if (bp_params
->flags
.USE_PCIE_AS_SOURCE_FOR_DPREFCLK
)
2329 params
.asParam
.ucDCEClkFlag
|= DCE_CLOCK_FLAG_PLL_REFCLK_SRC_PCIE
;
2331 if (bp_params
->flags
.USE_XTALIN_AS_SOURCE_FOR_DPREFCLK
)
2332 params
.asParam
.ucDCEClkFlag
|= DCE_CLOCK_FLAG_PLL_REFCLK_SRC_XTALIN
;
2334 if (bp_params
->flags
.USE_GENERICA_AS_SOURCE_FOR_DPREFCLK
)
2335 params
.asParam
.ucDCEClkFlag
|= DCE_CLOCK_FLAG_PLL_REFCLK_SRC_GENERICA
;
2338 /* only program clock frequency if display clock is used; VBIOS will program DPREFCLK */
2339 /* We need to convert from KHz units into 10KHz units */
2340 params
.asParam
.ulDCEClkFreq
= cpu_to_le32(bp_params
->target_clock_frequency
/ 10);
2342 if (EXEC_BIOS_CMD_TABLE(SetDCEClock
, params
)) {
2343 /* Convert from 10KHz units back to KHz */
2344 bp_params
->target_clock_frequency
= le32_to_cpu(params
.asParam
.ulDCEClkFreq
) * 10;
2345 result
= BP_RESULT_OK
;