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