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