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