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