]> Git Repo - linux.git/blob - drivers/gpu/drm/amd/display/dc/bios/command_table.c
Merge tag 'trace-v5.13-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt...
[linux.git] / drivers / gpu / drm / amd / display / dc / bios / command_table.c
1 /*
2  * Copyright 2012-15 Advanced Micro Devices, Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20  * OTHER DEALINGS IN THE SOFTWARE.
21  *
22  * Authors: AMD
23  *
24  */
25
26 #include "dm_services.h"
27 #include "amdgpu.h"
28 #include "atom.h"
29
30 #include "include/bios_parser_interface.h"
31
32 #include "command_table.h"
33 #include "command_table_helper.h"
34 #include "bios_parser_helper.h"
35 #include "bios_parser_types_internal.h"
36
37 #define EXEC_BIOS_CMD_TABLE(command, params)\
38         (amdgpu_atom_execute_table(((struct amdgpu_device *)bp->base.ctx->driver_context)->mode_info.atom_context, \
39                 GetIndexIntoMasterTable(COMMAND, command), \
40                 (uint32_t *)&params) == 0)
41
42 #define BIOS_CMD_TABLE_REVISION(command, frev, crev)\
43         amdgpu_atom_parse_cmd_header(((struct amdgpu_device *)bp->base.ctx->driver_context)->mode_info.atom_context, \
44                 GetIndexIntoMasterTable(COMMAND, command), &frev, &crev)
45
46 #define BIOS_CMD_TABLE_PARA_REVISION(command)\
47         bios_cmd_table_para_revision(bp->base.ctx->driver_context, \
48                 GetIndexIntoMasterTable(COMMAND, command))
49
50 static void init_dig_encoder_control(struct bios_parser *bp);
51 static void init_transmitter_control(struct bios_parser *bp);
52 static void init_set_pixel_clock(struct bios_parser *bp);
53 static void init_enable_spread_spectrum_on_ppll(struct bios_parser *bp);
54 static void init_adjust_display_pll(struct bios_parser *bp);
55 static void init_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);
64
65 void 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
83 static 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  **                  D I G E N C O D E R C O N T R O L
101  **
102  ********************************************************************************
103  *******************************************************************************/
104 static enum bp_result encoder_control_digx_v3(
105         struct bios_parser *bp,
106         struct bp_encoder_control *cntl);
107
108 static enum bp_result encoder_control_digx_v4(
109         struct bios_parser *bp,
110         struct bp_encoder_control *cntl);
111
112 static enum bp_result encoder_control_digx_v5(
113         struct bios_parser *bp,
114         struct bp_encoder_control *cntl);
115
116 static void init_encoder_control_dig_v1(struct bios_parser *bp);
117
118 static 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
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);
150
151 static 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
168 static 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
195 static 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, &params);
203
204         if (EXEC_BIOS_CMD_TABLE(DIG1EncoderControl, params))
205                 result = BP_RESULT_OK;
206
207         return result;
208 }
209
210 static 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, &params);
218
219         if (EXEC_BIOS_CMD_TABLE(DIG2EncoderControl, params))
220                 result = BP_RESULT_OK;
221
222         return result;
223 }
224
225 static 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; /* dual link 2.7GHz */
234         else
235                 params.acConfig.ucDPLinkRate = 0; /* single link 1.62GHz */
236
237         params.acConfig.ucDigSel = (uint8_t)(cntl->engine_id);
238
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(
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
271 static 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; /* dual link 2.7GHz */
280         else
281                 params.acConfig.ucDPLinkRate = 0; /* single link 1.62GHz */
282
283         params.acConfig.ucDigSel = (uint8_t)(cntl->engine_id);
284
285         /* We need to convert from KHz units into 10KHz units */
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
317 static 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  **                  TRANSMITTER CONTROL
379  **
380  ********************************************************************************
381  *******************************************************************************/
382
383 static enum bp_result transmitter_control_v2(
384         struct bios_parser *bp,
385         struct bp_transmitter_control *cntl);
386 static enum bp_result transmitter_control_v3(
387         struct bios_parser *bp,
388         struct bp_transmitter_control *cntl);
389 static enum bp_result transmitter_control_v4(
390         struct bios_parser *bp,
391         struct bp_transmitter_control *cntl);
392 static enum bp_result transmitter_control_v1_5(
393         struct bios_parser *bp,
394         struct bp_transmitter_control *cntl);
395 static enum bp_result transmitter_control_v1_6(
396         struct bios_parser *bp,
397         struct bp_transmitter_control *cntl);
398
399 static 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
430 static 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(&params, 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                         /* on INIT this bit should be set according to the
459                          * phisycal connector
460                          * Bit0: dual link connector flag
461                          * =0 connector is single link connector
462                          * =1 connector is dual link connector
463                          */
464                         params.acConfig.fDualLinkConnector = 1;
465
466                 /* connector object id */
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                 /* votage swing and pre-emphsis */
472                 params.asMode.ucLaneSel = (uint8_t)cntl->lane_select;
473                 params.asMode.ucLaneSet = (uint8_t)cntl->lane_settings;
474                 break;
475         default:
476                 /* if dual-link */
477                 if (LANE_COUNT_FOUR < cntl->lanes_number) {
478                         /* on ENABLE/DISABLE this bit should be set according to
479                          * actual timing (number of lanes)
480                          * Bit0: dual link connector flag
481                          * =0 connector is single link connector
482                          * =1 connector is dual link connector
483                          */
484                         params.acConfig.fDualLinkConnector = 1;
485
486                         /* link rate, half for dual link
487                          * We need to convert from KHz units into 20KHz units
488                          */
489                         params.usPixelClock =
490                                         cpu_to_le16((uint16_t)(cntl->pixel_clock / 20));
491                 } else
492                         /* link rate, half for dual link
493                          * We need to convert from KHz units into 10KHz units
494                          */
495                         params.usPixelClock =
496                                         cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
497                 break;
498         }
499
500         /* 00 - coherent mode
501          * 01 - incoherent mode
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                 /* Bit2: Transmitter Link selection
510                  * =0 when bit0=0, single link A/C/E, when bit0=1,
511                  * master link A/C/E
512                  * =1 when bit0=0, single link B/D/F, when bit0=1,
513                  * master link B/D/F
514                  */
515                 params.acConfig.ucLinkSel = 1;
516
517         if (ENGINE_ID_DIGB == cntl->engine_id)
518                 /* Bit3: Transmitter data source selection
519                  * =0 DIGA is data source.
520                  * =1 DIGB is data source.
521                  * This bit is only useful when ucAction= ATOM_ENABLE
522                  */
523                 params.acConfig.ucEncoderSel = 1;
524
525         if (CONNECTOR_ID_DISPLAY_PORT == connector_id)
526                 /* Bit4: DP connector flag
527                  * =0 connector is none-DP connector
528                  * =1 connector is DP connector
529                  */
530                 params.acConfig.fDPConnector = 1;
531
532         /* Bit[7:6]: Transmitter selection
533          * =0 UNIPHY_ENCODER: UNIPHYA/B
534          * =1 UNIPHY1_ENCODER: UNIPHYC/D
535          * =2 UNIPHY2_ENCODER: UNIPHYE/F
536          * =3 reserved
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
550 static 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(&params, 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         /* fill information based on the action */
582         switch (cntl->action) {
583         case TRANSMITTER_CONTROL_INIT:
584                 if (dual_link_conn) {
585                         /* on INIT this bit should be set according to the
586                          * phisycal connector
587                          * Bit0: dual link connector flag
588                          * =0 connector is single link connector
589                          * =1 connector is dual link connector
590                          */
591                         params.acConfig.fDualLinkConnector = 1;
592                 }
593
594                 /* connector object id */
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                 /* votage swing and pre-emphsis */
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                         /* on ENABLE/DISABLE this bit should be set according to
606                          * actual timing (number of lanes)
607                          * Bit0: dual link connector flag
608                          * =0 connector is single link connector
609                          * =1 connector is dual link connector
610                          */
611                         params.acConfig.fDualLinkConnector = 1;
612
613                 /* if dual-link */
614                 if (LANE_COUNT_FOUR < cntl->lanes_number) {
615                         /* on ENABLE/DISABLE this bit should be set according to
616                          * actual timing (number of lanes)
617                          * Bit0: dual link connector flag
618                          * =0 connector is single link connector
619                          * =1 connector is dual link connector
620                          */
621                         params.acConfig.fDualLinkConnector = 1;
622
623                         /* link rate, half for dual link
624                          * We need to convert from KHz units into 20KHz units
625                          */
626                         params.usPixelClock =
627                                         cpu_to_le16((uint16_t)(cntl->pixel_clock / 20));
628                 } else {
629                         /* link rate, half for dual link
630                          * We need to convert from KHz units into 10KHz units
631                          */
632                         params.usPixelClock =
633                                         cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
634                 }
635                 break;
636         }
637
638         /* 00 - coherent mode
639          * 01 - incoherent mode
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                 /* Bit2: Transmitter Link selection
648                  * =0 when bit0=0, single link A/C/E, when bit0=1,
649                  * master link A/C/E
650                  * =1 when bit0=0, single link B/D/F, when bit0=1,
651                  * master link B/D/F
652                  */
653                 params.acConfig.ucLinkSel = 1;
654
655         if (ENGINE_ID_DIGB == cntl->engine_id)
656                 /* Bit3: Transmitter data source selection
657                  * =0 DIGA is data source.
658                  * =1 DIGB is data source.
659                  * This bit is only useful when ucAction= ATOM_ENABLE
660                  */
661                 params.acConfig.ucEncoderSel = 1;
662
663         /* Bit[7:6]: Transmitter selection
664          * =0 UNIPHY_ENCODER: UNIPHYA/B
665          * =1 UNIPHY1_ENCODER: UNIPHYC/D
666          * =2 UNIPHY2_ENCODER: UNIPHYE/F
667          * =3 reserved
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
684 static 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(&params, 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                         /* on INIT this bit should be set according to the
719                          * phisycal connector
720                          * Bit0: dual link connector flag
721                          * =0 connector is single link connector
722                          * =1 connector is dual link connector
723                          */
724                         params.acConfig.fDualLinkConnector = 1;
725
726                 /* connector object id */
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                 /* votage swing and pre-emphsis */
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                         /* on ENABLE/DISABLE this bit should be set according to
740                          * actual timing (number of lanes)
741                          * Bit0: dual link connector flag
742                          * =0 connector is single link connector
743                          * =1 connector is dual link connector
744                          */
745                         params.acConfig.fDualLinkConnector = 1;
746
747                 /* if dual-link */
748                 if (LANE_COUNT_FOUR < cntl->lanes_number)
749                         /* link rate, half for dual link
750                          * We need to convert from KHz units into 20KHz units
751                          */
752                         params.usPixelClock =
753                                         cpu_to_le16((uint16_t)(cntl->pixel_clock / 20));
754                 else {
755                         /* link rate, half for dual link
756                          * We need to convert from KHz units into 10KHz units
757                          */
758                         params.usPixelClock =
759                                         cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
760                 }
761                 break;
762         }
763
764         /* 00 - coherent mode
765          * 01 - incoherent mode
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                 /* Bit2: Transmitter Link selection
774                  * =0 when bit0=0, single link A/C/E, when bit0=1,
775                  * master link A/C/E
776                  * =1 when bit0=0, single link B/D/F, when bit0=1,
777                  * master link B/D/F
778                  */
779                 params.acConfig.ucLinkSel = 1;
780
781         if (ENGINE_ID_DIGB == cntl->engine_id)
782                 /* Bit3: Transmitter data source selection
783                  * =0 DIGA is data source.
784                  * =1 DIGB is data source.
785                  * This bit is only useful when ucAction= ATOM_ENABLE
786                  */
787                 params.acConfig.ucEncoderSel = 1;
788
789         /* Bit[7:6]: Transmitter selection
790          * =0 UNIPHY_ENCODER: UNIPHYA/B
791          * =1 UNIPHY1_ENCODER: UNIPHYC/D
792          * =2 UNIPHY2_ENCODER: UNIPHYE/F
793          * =3 reserved
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
807 static 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(&params, 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         /* 00 - coherent mode */
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          * In SI/TN case, caller have to set usPixelClock as following:
835          * DP mode: usPixelClock = DP_LINK_CLOCK/10
836          * (DP_LINK_CLOCK = 1.62GHz, 2.7GHz, 5.4GHz)
837          * DVI single link mode: usPixelClock = pixel clock
838          * DVI dual link mode: usPixelClock = pixel clock
839          * HDMI mode: usPixelClock = pixel clock * deep_color_ratio
840          * (=1: 8bpp, =1.25: 10bpp, =1.5:12bpp, =2: 16bpp)
841          * LVDS mode: usPixelClock = pixel clock
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
868 static 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(&params, 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          * In SI/TN case, caller have to set usPixelClock as following:
893          * DP mode: usPixelClock = DP_LINK_CLOCK/10
894          * (DP_LINK_CLOCK = 1.62GHz, 2.7GHz, 5.4GHz)
895          * DVI single link mode: usPixelClock = pixel clock
896          * DVI dual link mode: usPixelClock = pixel clock
897          * HDMI mode: usPixelClock = pixel clock * deep_color_ratio
898          * (=1: 8bpp, =1.25: 10bpp, =1.5:12bpp, =2: 16bpp)
899          * LVDS mode: usPixelClock = pixel clock
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  **                  SET PIXEL CLOCK
933  **
934  ********************************************************************************
935  *******************************************************************************/
936
937 static enum bp_result set_pixel_clock_v3(
938         struct bios_parser *bp,
939         struct bp_pixel_clock_parameters *bp_params);
940 static enum bp_result set_pixel_clock_v5(
941         struct bios_parser *bp,
942         struct bp_pixel_clock_parameters *bp_params);
943 static enum bp_result set_pixel_clock_v6(
944         struct bios_parser *bp,
945         struct bp_pixel_clock_parameters *bp_params);
946 static enum bp_result set_pixel_clock_v7(
947         struct bios_parser *bp,
948         struct bp_pixel_clock_parameters *bp_params);
949
950 static 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
973 static 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         /* We need to convert from 100Hz units into 10KHz units */
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 /* video bios did not define this: */
1029 typedef struct _SET_PIXEL_CLOCK_PS_ALLOCATION_V5 {
1030         PIXEL_CLOCK_PARAMETERS_V5 sPCLKInput;
1031         /* Caller doesn't need to init this portion */
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 /* video bios did not define this: */
1038 typedef struct _SET_PIXEL_CLOCK_PS_ALLOCATION_V6 {
1039         PIXEL_CLOCK_PARAMETERS_V6 sPCLKInput;
1040         /* Caller doesn't need to init this portion */
1041         ENABLE_SPREAD_SPECTRUM_ON_PPLL sReserved;
1042 } SET_PIXEL_CLOCK_PS_ALLOCATION_V6;
1043 #endif
1044
1045 static 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                 /* We need to convert from 100Hz units into 10KHz units */
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                 /* clkV5.ucMiscInfo bit[3:2]= HDMI panel bit depth: =0: 24bpp
1090                  * =1:30bpp, =2:32bpp
1091                  * driver choose program it itself, i.e. here we program it
1092                  * to 888 by default.
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                                 /* yes this is correct, the atom define is wrong */
1098                                 clk.sPCLKInput.ucMiscInfo |= PIXEL_CLOCK_V5_MISC_HDMI_32BPP;
1099                                 break;
1100                         case TRANSMITTER_COLOR_DEPTH_36:
1101                                 /* yes this is correct, the atom define is wrong */
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
1115 static 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                 /* Note: VBIOS still wants to use ucCRTC name which is now
1130                  * 1 byte in ULONG
1131                  *typedef struct _CRTC_PIXEL_CLOCK_FREQ
1132                  *{
1133                  * target the pixel clock to drive the CRTC timing.
1134                  * ULONG ulPixelClock:24;
1135                  * 0 means disable PPLL/DCPLL. Expanded to 24 bits comparing to
1136                  * previous version.
1137                  * ATOM_CRTC1~6, indicate the CRTC controller to
1138                  * ULONG ucCRTC:8;
1139                  * drive the pixel clock. not used for DCPLL case.
1140                  *}CRTC_PIXEL_CLOCK_FREQ;
1141                  *union
1142                  *{
1143                  * pixel clock and CRTC id frequency
1144                  * CRTC_PIXEL_CLOCK_FREQ ulCrtcPclkFreq;
1145                  * ULONG ulDispEngClkFreq; dispclk frequency
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                 /* We need to convert from 100 Hz units into 10KHz units */
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                 /* clkV6.ucMiscInfo bit[3:2]= HDMI panel bit depth: =0:
1181                  * 24bpp =1:30bpp, =2:32bpp
1182                  * driver choose program it itself, i.e. here we pass required
1183                  * target rate that includes deep color.
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
1207 static 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                 /* Note: VBIOS still wants to use ucCRTC name which is now
1221                  * 1 byte in ULONG
1222                  *typedef struct _CRTC_PIXEL_CLOCK_FREQ
1223                  *{
1224                  * target the pixel clock to drive the CRTC timing.
1225                  * ULONG ulPixelClock:24;
1226                  * 0 means disable PPLL/DCPLL. Expanded to 24 bits comparing to
1227                  * previous version.
1228                  * ATOM_CRTC1~6, indicate the CRTC controller to
1229                  * ULONG ucCRTC:8;
1230                  * drive the pixel clock. not used for DCPLL case.
1231                  *}CRTC_PIXEL_CLOCK_FREQ;
1232                  *union
1233                  *{
1234                  * pixel clock and CRTC id frequency
1235                  * CRTC_PIXEL_CLOCK_FREQ ulCrtcPclkFreq;
1236                  * ULONG ulDispEngClkFreq; dispclk frequency
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  **                  ENABLE PIXEL CLOCK SS
1279  **
1280  ********************************************************************************
1281  *******************************************************************************/
1282 static 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);
1286 static 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);
1290 static 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
1295 static 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
1318 static 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(&params, 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         /* convert back to unit of 10KHz */
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(); /* Unexpected PLL value!! */
1355
1356         if (EXEC_BIOS_CMD_TABLE(EnableSpreadSpectrumOnPPLL, params))
1357                 result = BP_RESULT_OK;
1358
1359         return result;
1360 }
1361
1362 static 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(&params, 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(); /* Unexpected PLL value!! */
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                 /* Both amounts need to be left shifted first before bit
1396                  * comparison. Otherwise, the result will always be zero here
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
1414 static 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(&params, 0, sizeof(params));
1423
1424         switch (bp_params->pll_id) {
1425         case CLOCK_SOURCE_ID_PLL0:
1426                 /* ATOM_PPLL_SS_TYPE_V3_P0PLL; this is pixel clock only,
1427                  * not for SI display clock.
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                 /* Unexpected PLL value!! */
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                 /* Both amounts need to be left shifted first before bit
1465                  * comparison. Otherwise, the result will always be zero here
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  **                  ADJUST DISPLAY PLL
1487  **
1488  ********************************************************************************
1489  *******************************************************************************/
1490
1491 static enum bp_result adjust_display_pll_v2(
1492         struct bios_parser *bp,
1493         struct bp_adjust_pixel_clock_parameters *bp_params);
1494 static enum bp_result adjust_display_pll_v3(
1495         struct bios_parser *bp,
1496         struct bp_adjust_pixel_clock_parameters *bp_params);
1497
1498 static 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
1515 static 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         /* We need to convert from KHz units into 10KHz units and then convert
1523          * output pixel clock back 10KHz-->KHz */
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                 /* Convert output pixel clock back 10KHz-->KHz: multiply
1537                  * original pixel clock in KHz by ratio
1538                  * [output pxlClk/input pxlClk] */
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
1558 static 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(&params, 0, sizeof(params));
1567
1568         /* We need to convert from KHz units into 10KHz units and then convert
1569          * output pixel clock back 10KHz-->KHz */
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                 /* Convert output pixel clock back 10KHz-->KHz: multiply
1587                  * original pixel clock in KHz by ratio
1588                  * [output pxlClk/input pxlClk] */
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  **                  DAC ENCODER CONTROL
1615  **
1616  ********************************************************************************
1617  *******************************************************************************/
1618
1619 static 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);
1624 static 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
1630 static 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
1650 static 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         /* We need to convert from KHz units into 10KHz units
1663          * it looks as if the TvControl do not care about pixel clock
1664          */
1665         params->usPixelClock = cpu_to_le16((uint16_t)(pixel_clock / 10));
1666 }
1667
1668 static 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                 &params,
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
1689 static 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                 &params,
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  **                  DAC OUTPUT CONTROL
1714  **
1715  ********************************************************************************
1716  *******************************************************************************/
1717 static enum bp_result dac1_output_control_v1(
1718         struct bios_parser *bp,
1719         bool enable);
1720 static enum bp_result dac2_output_control_v1(
1721         struct bios_parser *bp,
1722         bool enable);
1723
1724 static 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
1744 static 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
1761 static 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  **                  SET CRTC TIMING
1782  **
1783  ********************************************************************************
1784  *******************************************************************************/
1785
1786 static enum bp_result set_crtc_using_dtd_timing_v3(
1787         struct bios_parser *bp,
1788         struct bp_hw_crtc_timing_parameters *bp_params);
1789 static enum bp_result set_crtc_timing_v1(
1790         struct bios_parser *bp,
1791         struct bp_hw_crtc_timing_parameters *bp_params);
1792
1793 static 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
1822 static 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         /* VBIOS does not expect any value except zero into this call, for
1846          * underscan use another entry ProgramOverscan call but when mode
1847          * 1776x1000 with the overscan 72x44 .e.i. 1920x1080 @30 DAL2 is ok,
1848          * but when same ,but 60 Hz there is corruption
1849          * DAL1 does not allow the mode 1776x1000@60
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                 /* original DAL code has this condition to apply tis for
1869                  * non-TV/CV only due to complex MV testing for possible
1870                  * impact
1871                  * if (pACParameters->signal != SignalType_YPbPr &&
1872                  *  pACParameters->signal != SignalType_Composite &&
1873                  *  pACParameters->signal != SignalType_SVideo)
1874                  */
1875                 /* HW will deduct 0.5 line from 2nd feild.
1876                  * i.e. for 1080i, it is 2 lines for 1st field, 2.5
1877                  * lines for the 2nd feild. we need input as 5 instead
1878                  * of 4, but it is 4 either from Edid data
1879                  * (spec CEA 861) or CEA timing table.
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
1895 static 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         /* bios usH_Size wants h addressable size */
1908         params.usH_Size = cpu_to_le16((uint16_t)bp_params->h_addressable);
1909         /* bios usH_Blanking_Time wants borders included in blanking */
1910         params.usH_Blanking_Time =
1911                         cpu_to_le16((uint16_t)(bp_params->h_total - bp_params->h_addressable));
1912         /* bios usV_Size wants v addressable size */
1913         params.usV_Size = cpu_to_le16((uint16_t)bp_params->v_addressable);
1914         /* bios usV_Blanking_Time wants borders included in blanking */
1915         params.usV_Blanking_Time =
1916                         cpu_to_le16((uint16_t)(bp_params->v_total - bp_params->v_addressable));
1917         /* bios usHSyncOffset is the offset from the end of h addressable,
1918          * our horizontalSyncStart is the offset from the beginning
1919          * of h addressable */
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         /* bios usHSyncOffset is the offset from the end of v addressable,
1924          * our verticalSyncStart is the offset from the beginning of
1925          * v addressable */
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         /* we assume that overscan from original timing does not get bigger
1931          * than 255
1932          * we will program all the borders in the Set CRTC Overscan call below
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                 /* original DAL code has this condition to apply this
1948                  * for non-TV/CV only
1949                  * due to complex MV testing for possible impact
1950                  * if ( pACParameters->signal != SignalType_YPbPr &&
1951                  *  pACParameters->signal != SignalType_Composite &&
1952                  *  pACParameters->signal != SignalType_SVideo)
1953                  */
1954                 {
1955                         /* HW will deduct 0.5 line from 2nd feild.
1956                          * i.e. for 1080i, it is 2 lines for 1st field,
1957                          * 2.5 lines for the 2nd feild. we need input as 5
1958                          * instead of 4.
1959                          * but it is 4 either from Edid data (spec CEA 861)
1960                          * or CEA timing table.
1961                          */
1962                         le16_add_cpu(&params.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  **                  ENABLE CRTC
1980  **
1981  ********************************************************************************
1982  *******************************************************************************/
1983
1984 static enum bp_result enable_crtc_v1(
1985         struct bios_parser *bp,
1986         enum controller_id controller_id,
1987         bool enable);
1988
1989 static 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
2003 static 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  **                  ENABLE CRTC MEM REQ
2032  **
2033  ********************************************************************************
2034  *******************************************************************************/
2035
2036 static enum bp_result enable_crtc_mem_req_v1(
2037         struct bios_parser *bp,
2038         enum controller_id controller_id,
2039         bool enable);
2040
2041 static 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
2053 static 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  **                  DISPLAY PLL
2083  **
2084  ********************************************************************************
2085  *******************************************************************************/
2086
2087 static enum bp_result program_clock_v5(
2088         struct bios_parser *bp,
2089         struct bp_pixel_clock_parameters *bp_params);
2090 static enum bp_result program_clock_v6(
2091         struct bios_parser *bp,
2092         struct bp_pixel_clock_parameters *bp_params);
2093
2094 static 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
2111 static 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(&params, 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(); /* Invalid Inpute!! */
2124                 return BP_RESULT_BADINPUT;
2125         }
2126
2127         /* We need to convert from KHz units into 10KHz units */
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
2142 static 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(&params, 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(); /*Invalid Input!!*/
2156                 return BP_RESULT_BADINPUT;
2157         }
2158
2159         /* We need to convert from KHz units into 10KHz units */
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                 /* True display clock is returned by VBIOS if DFS bypass
2172                  * is enabled. */
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  **                  EXTERNAL ENCODER CONTROL
2185  **
2186  ********************************************************************************
2187  *******************************************************************************/
2188
2189 static enum bp_result external_encoder_control_v3(
2190         struct bios_parser *bp,
2191         struct bp_external_encoder_control *cntl);
2192
2193 static 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
2207 static 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         /* we need use _PS_Alloc struct */
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(&params, 0, sizeof(params));
2220
2221         cntl_params = &params.sExtEncoder;
2222
2223         encoder = cntl->encoder_id;
2224
2225         /* check if encoder supports external encoder control table */
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         /* Fill information based on the action
2238          *
2239          * Bit[6:4]: indicate external encoder, applied to all functions.
2240          * =0: external encoder1, mapped to external encoder enum id1
2241          * =1: external encoder2, mapped to external encoder enum id2
2242          *
2243          * enum ObjectEnumId
2244          * {
2245          *  EnumId_Unknown = 0,
2246          *  EnumId_1,
2247          *  EnumId_2,
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                 /* output display connector type. Only valid in encoder
2255                  * initialization */
2256                 cntl_params->usConnectorId =
2257                                 cpu_to_le16((uint16_t)cntl->connector_obj_id.id);
2258                 break;
2259         case EXTERNAL_ENCODER_CONTROL_SETUP:
2260                 /* EXTERNAL_ENCODER_CONTROL_PARAMETERS_V3 pixel clock unit in
2261                  * 10KHz
2262                  * output display device pixel clock frequency in unit of 10KHz.
2263                  * Only valid in setup and enableoutput
2264                  */
2265                 cntl_params->usPixelClock =
2266                                 cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
2267                 /* Indicate display output signal type drive by external
2268                  * encoder, only valid in setup and enableoutput */
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                         /* Bit[0]: indicate link rate, =1: 2.7Ghz, =0: 1.62Ghz,
2275                          * only valid in encoder setup with DP mode. */
2276                         if (LINK_RATE_HIGH == cntl->link_rate)
2277                                 cntl_params->ucConfig |= 1;
2278                         /* output color depth Indicate encoder data bpc format
2279                          * in DP mode, only valid in encoder setup in DP mode.
2280                          */
2281                         cntl_params->ucBitPerColor =
2282                                         (uint8_t)(cntl->color_depth);
2283                 }
2284                 /* Indicate how many lanes used by external encoder, only valid
2285                  * in encoder setup and enableoutput. */
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  **                  ENABLE DISPLAY POWER GATING
2312  **
2313  ********************************************************************************
2314  *******************************************************************************/
2315
2316 static 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
2321 static 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
2337 static 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  **                  SET DCE CLOCK
2365  **
2366  ********************************************************************************
2367  *******************************************************************************/
2368 static enum bp_result set_dce_clock_v2_1(
2369         struct bios_parser *bp,
2370         struct bp_set_dce_clock_parameters *bp_params);
2371
2372 static 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
2386 static 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(&params, 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                 /* only program clock frequency if display clock is used; VBIOS will program DPREFCLK */
2421                 /* We need to convert from KHz units into 10KHz units */
2422                 params.asParam.ulDCEClkFreq = cpu_to_le32(bp_params->target_clock_frequency / 10);
2423
2424         if (EXEC_BIOS_CMD_TABLE(SetDCEClock, params)) {
2425                 /* Convert from 10KHz units back to KHz */
2426                 bp_params->target_clock_frequency = le32_to_cpu(params.asParam.ulDCEClkFreq) * 10;
2427                 result = BP_RESULT_OK;
2428         }
2429
2430         return result;
2431 }
This page took 0.185229 seconds and 4 git commands to generate.