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