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