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