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