1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26#include "dm_services.h"
27
28#include "ObjectID.h"
29
30#include "atomfirmware.h"
31#include "atom.h"
32#include "include/bios_parser_interface.h"
33
34#include "command_table2.h"
35#include "command_table_helper2.h"
36#include "bios_parser_helper.h"
37#include "bios_parser_types_internal2.h"
38#include "amdgpu.h"
39
40#include "dc_dmub_srv.h"
41#include "dc.h"
42
43#define DC_LOGGER \
44 bp->base.ctx->logger
45
46#define GET_INDEX_INTO_MASTER_TABLE(MasterOrData, FieldName)\
47 (((char *)(&((\
48 struct atom_master_list_of_##MasterOrData##_functions_v2_1 *)0)\
49 ->FieldName)-(char *)0)/sizeof(uint16_t))
50
51#define EXEC_BIOS_CMD_TABLE(fname, params)\
52 (amdgpu_atom_execute_table(((struct amdgpu_device *)bp->base.ctx->driver_context)->mode_info.atom_context, \
53 GET_INDEX_INTO_MASTER_TABLE(command, fname), \
54 (uint32_t *)¶ms) == 0)
55
56#define BIOS_CMD_TABLE_REVISION(fname, frev, crev)\
57 amdgpu_atom_parse_cmd_header(((struct amdgpu_device *)bp->base.ctx->driver_context)->mode_info.atom_context, \
58 GET_INDEX_INTO_MASTER_TABLE(command, fname), &frev, &crev)
59
60#define BIOS_CMD_TABLE_PARA_REVISION(fname)\
61 bios_cmd_table_para_revision(bp->base.ctx->driver_context, \
62 GET_INDEX_INTO_MASTER_TABLE(command, fname))
63
64
65
66static uint32_t bios_cmd_table_para_revision(void *dev,
67 uint32_t index)
68{
69 struct amdgpu_device *adev = dev;
70 uint8_t frev, crev;
71
72 if (amdgpu_atom_parse_cmd_header(adev->mode_info.atom_context,
73 index,
74 &frev, &crev))
75 return crev;
76 else
77 return 0;
78}
79
80
81
82
83
84
85
86
87
88static enum bp_result encoder_control_digx_v1_5(
89 struct bios_parser *bp,
90 struct bp_encoder_control *cntl);
91
92static enum bp_result encoder_control_fallback(
93 struct bios_parser *bp,
94 struct bp_encoder_control *cntl);
95
96static void init_dig_encoder_control(struct bios_parser *bp)
97{
98 uint32_t version =
99 BIOS_CMD_TABLE_PARA_REVISION(digxencodercontrol);
100
101 switch (version) {
102 case 5:
103 bp->cmd_tbl.dig_encoder_control = encoder_control_digx_v1_5;
104 break;
105 default:
106 dm_output_to_console("Don't have dig_encoder_control for v%d\n", version);
107 bp->cmd_tbl.dig_encoder_control = encoder_control_fallback;
108 break;
109 }
110}
111
112static void encoder_control_dmcub(
113 struct dc_dmub_srv *dmcub,
114 struct dig_encoder_stream_setup_parameters_v1_5 *dig)
115{
116 union dmub_rb_cmd cmd;
117
118 memset(&cmd, 0, sizeof(cmd));
119
120 cmd.digx_encoder_control.header.type = DMUB_CMD__VBIOS;
121 cmd.digx_encoder_control.header.sub_type =
122 DMUB_CMD__VBIOS_DIGX_ENCODER_CONTROL;
123 cmd.digx_encoder_control.header.payload_bytes =
124 sizeof(cmd.digx_encoder_control) -
125 sizeof(cmd.digx_encoder_control.header);
126 cmd.digx_encoder_control.encoder_control.dig.stream_param = *dig;
127
128 dc_dmub_srv_cmd_queue(dmcub, &cmd);
129 dc_dmub_srv_cmd_execute(dmcub);
130 dc_dmub_srv_wait_idle(dmcub);
131}
132
133static enum bp_result encoder_control_digx_v1_5(
134 struct bios_parser *bp,
135 struct bp_encoder_control *cntl)
136{
137 enum bp_result result = BP_RESULT_FAILURE;
138 struct dig_encoder_stream_setup_parameters_v1_5 params = {0};
139
140 params.digid = (uint8_t)(cntl->engine_id);
141 params.action = bp->cmd_helper->encoder_action_to_atom(cntl->action);
142
143 params.pclk_10khz = cntl->pixel_clock / 10;
144 params.digmode =
145 (uint8_t)(bp->cmd_helper->encoder_mode_bp_to_atom(
146 cntl->signal,
147 cntl->enable_dp_audio));
148 params.lanenum = (uint8_t)(cntl->lanes_number);
149
150 switch (cntl->color_depth) {
151 case COLOR_DEPTH_888:
152 params.bitpercolor = PANEL_8BIT_PER_COLOR;
153 break;
154 case COLOR_DEPTH_101010:
155 params.bitpercolor = PANEL_10BIT_PER_COLOR;
156 break;
157 case COLOR_DEPTH_121212:
158 params.bitpercolor = PANEL_12BIT_PER_COLOR;
159 break;
160 case COLOR_DEPTH_161616:
161 params.bitpercolor = PANEL_16BIT_PER_COLOR;
162 break;
163 default:
164 break;
165 }
166
167 if (cntl->signal == SIGNAL_TYPE_HDMI_TYPE_A)
168 switch (cntl->color_depth) {
169 case COLOR_DEPTH_101010:
170 params.pclk_10khz =
171 (params.pclk_10khz * 30) / 24;
172 break;
173 case COLOR_DEPTH_121212:
174 params.pclk_10khz =
175 (params.pclk_10khz * 36) / 24;
176 break;
177 case COLOR_DEPTH_161616:
178 params.pclk_10khz =
179 (params.pclk_10khz * 48) / 24;
180 break;
181 default:
182 break;
183 }
184
185 if (bp->base.ctx->dc->ctx->dmub_srv &&
186 bp->base.ctx->dc->debug.dmub_command_table) {
187 encoder_control_dmcub(bp->base.ctx->dmub_srv, ¶ms);
188 return BP_RESULT_OK;
189 }
190
191 if (EXEC_BIOS_CMD_TABLE(digxencodercontrol, params))
192 result = BP_RESULT_OK;
193
194 return result;
195}
196
197static enum bp_result encoder_control_fallback(
198 struct bios_parser *bp,
199 struct bp_encoder_control *cntl)
200{
201 if (bp->base.ctx->dc->ctx->dmub_srv &&
202 bp->base.ctx->dc->debug.dmub_command_table) {
203 return encoder_control_digx_v1_5(bp, cntl);
204 }
205
206 return BP_RESULT_FAILURE;
207}
208
209
210
211
212
213
214
215
216
217static enum bp_result transmitter_control_v1_6(
218 struct bios_parser *bp,
219 struct bp_transmitter_control *cntl);
220
221static enum bp_result transmitter_control_v1_7(
222 struct bios_parser *bp,
223 struct bp_transmitter_control *cntl);
224
225static enum bp_result transmitter_control_fallback(
226 struct bios_parser *bp,
227 struct bp_transmitter_control *cntl);
228
229static void init_transmitter_control(struct bios_parser *bp)
230{
231 uint8_t frev;
232 uint8_t crev;
233
234 BIOS_CMD_TABLE_REVISION(dig1transmittercontrol, frev, crev);
235
236 switch (crev) {
237 case 6:
238 bp->cmd_tbl.transmitter_control = transmitter_control_v1_6;
239 break;
240 case 7:
241 bp->cmd_tbl.transmitter_control = transmitter_control_v1_7;
242 break;
243 default:
244 dm_output_to_console("Don't have transmitter_control for v%d\n", crev);
245 bp->cmd_tbl.transmitter_control = transmitter_control_fallback;
246 break;
247 }
248}
249
250static void transmitter_control_dmcub(
251 struct dc_dmub_srv *dmcub,
252 struct dig_transmitter_control_parameters_v1_6 *dig)
253{
254 union dmub_rb_cmd cmd;
255
256 memset(&cmd, 0, sizeof(cmd));
257
258 cmd.dig1_transmitter_control.header.type = DMUB_CMD__VBIOS;
259 cmd.dig1_transmitter_control.header.sub_type =
260 DMUB_CMD__VBIOS_DIG1_TRANSMITTER_CONTROL;
261 cmd.dig1_transmitter_control.header.payload_bytes =
262 sizeof(cmd.dig1_transmitter_control) -
263 sizeof(cmd.dig1_transmitter_control.header);
264 cmd.dig1_transmitter_control.transmitter_control.dig = *dig;
265
266 dc_dmub_srv_cmd_queue(dmcub, &cmd);
267 dc_dmub_srv_cmd_execute(dmcub);
268 dc_dmub_srv_wait_idle(dmcub);
269}
270
271static enum bp_result transmitter_control_v1_6(
272 struct bios_parser *bp,
273 struct bp_transmitter_control *cntl)
274{
275 enum bp_result result = BP_RESULT_FAILURE;
276 const struct command_table_helper *cmd = bp->cmd_helper;
277 struct dig_transmitter_control_ps_allocation_v1_6 ps = { { 0 } };
278
279 ps.param.phyid = cmd->phy_id_to_atom(cntl->transmitter);
280 ps.param.action = (uint8_t)cntl->action;
281
282 if (cntl->action == TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS)
283 ps.param.mode_laneset.dplaneset = (uint8_t)cntl->lane_settings;
284 else
285 ps.param.mode_laneset.digmode =
286 cmd->signal_type_to_atom_dig_mode(cntl->signal);
287
288 ps.param.lanenum = (uint8_t)cntl->lanes_number;
289 ps.param.hpdsel = cmd->hpd_sel_to_atom(cntl->hpd_sel);
290 ps.param.digfe_sel = cmd->dig_encoder_sel_to_atom(cntl->engine_id);
291 ps.param.connobj_id = (uint8_t)cntl->connector_obj_id.id;
292 ps.param.symclk_10khz = cntl->pixel_clock/10;
293
294
295 if (cntl->action == TRANSMITTER_CONTROL_ENABLE ||
296 cntl->action == TRANSMITTER_CONTROL_ACTIAVATE ||
297 cntl->action == TRANSMITTER_CONTROL_DEACTIVATE) {
298 DC_LOG_BIOS("%s:ps.param.symclk_10khz = %d\n",\
299 __func__, ps.param.symclk_10khz);
300 }
301
302 if (bp->base.ctx->dc->ctx->dmub_srv &&
303 bp->base.ctx->dc->debug.dmub_command_table) {
304 transmitter_control_dmcub(bp->base.ctx->dmub_srv, &ps.param);
305 return BP_RESULT_OK;
306 }
307
308
309 if (EXEC_BIOS_CMD_TABLE(dig1transmittercontrol, ps))
310 result = BP_RESULT_OK;
311 return result;
312}
313
314static void transmitter_control_dmcub_v1_7(
315 struct dc_dmub_srv *dmcub,
316 struct dmub_dig_transmitter_control_data_v1_7 *dig)
317{
318 union dmub_rb_cmd cmd;
319
320 memset(&cmd, 0, sizeof(cmd));
321
322 cmd.dig1_transmitter_control.header.type = DMUB_CMD__VBIOS;
323 cmd.dig1_transmitter_control.header.sub_type =
324 DMUB_CMD__VBIOS_DIG1_TRANSMITTER_CONTROL;
325 cmd.dig1_transmitter_control.header.payload_bytes =
326 sizeof(cmd.dig1_transmitter_control) -
327 sizeof(cmd.dig1_transmitter_control.header);
328 cmd.dig1_transmitter_control.transmitter_control.dig_v1_7 = *dig;
329
330 dc_dmub_srv_cmd_queue(dmcub, &cmd);
331 dc_dmub_srv_cmd_execute(dmcub);
332 dc_dmub_srv_wait_idle(dmcub);
333}
334
335static enum bp_result transmitter_control_v1_7(
336 struct bios_parser *bp,
337 struct bp_transmitter_control *cntl)
338{
339 enum bp_result result = BP_RESULT_FAILURE;
340 const struct command_table_helper *cmd = bp->cmd_helper;
341 struct dmub_dig_transmitter_control_data_v1_7 dig_v1_7 = {0};
342
343 dig_v1_7.phyid = cmd->phy_id_to_atom(cntl->transmitter);
344 dig_v1_7.action = (uint8_t)cntl->action;
345
346 if (cntl->action == TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS)
347 dig_v1_7.mode_laneset.dplaneset = (uint8_t)cntl->lane_settings;
348 else
349 dig_v1_7.mode_laneset.digmode =
350 cmd->signal_type_to_atom_dig_mode(cntl->signal);
351
352 dig_v1_7.lanenum = (uint8_t)cntl->lanes_number;
353 dig_v1_7.hpdsel = cmd->hpd_sel_to_atom(cntl->hpd_sel);
354 dig_v1_7.digfe_sel = cmd->dig_encoder_sel_to_atom(cntl->engine_id);
355 dig_v1_7.connobj_id = (uint8_t)cntl->connector_obj_id.id;
356 dig_v1_7.symclk_units.symclk_10khz = cntl->pixel_clock/10;
357
358 if (cntl->action == TRANSMITTER_CONTROL_ENABLE ||
359 cntl->action == TRANSMITTER_CONTROL_ACTIAVATE ||
360 cntl->action == TRANSMITTER_CONTROL_DEACTIVATE) {
361 DC_LOG_BIOS("%s:dig_v1_7.symclk_units.symclk_10khz = %d\n",
362 __func__, dig_v1_7.symclk_units.symclk_10khz);
363 }
364
365 if (bp->base.ctx->dc->ctx->dmub_srv &&
366 bp->base.ctx->dc->debug.dmub_command_table) {
367 transmitter_control_dmcub_v1_7(bp->base.ctx->dmub_srv, &dig_v1_7);
368 return BP_RESULT_OK;
369 }
370
371
372 if (EXEC_BIOS_CMD_TABLE(dig1transmittercontrol, dig_v1_7))
373 result = BP_RESULT_OK;
374 return result;
375}
376
377static enum bp_result transmitter_control_fallback(
378 struct bios_parser *bp,
379 struct bp_transmitter_control *cntl)
380{
381 if (bp->base.ctx->dc->ctx->dmub_srv &&
382 bp->base.ctx->dc->debug.dmub_command_table) {
383 return transmitter_control_v1_7(bp, cntl);
384 }
385
386 return BP_RESULT_FAILURE;
387}
388
389
390
391
392
393
394
395
396
397static enum bp_result set_pixel_clock_v7(
398 struct bios_parser *bp,
399 struct bp_pixel_clock_parameters *bp_params);
400
401static enum bp_result set_pixel_clock_fallback(
402 struct bios_parser *bp,
403 struct bp_pixel_clock_parameters *bp_params);
404
405static void init_set_pixel_clock(struct bios_parser *bp)
406{
407 switch (BIOS_CMD_TABLE_PARA_REVISION(setpixelclock)) {
408 case 7:
409 bp->cmd_tbl.set_pixel_clock = set_pixel_clock_v7;
410 break;
411 default:
412 dm_output_to_console("Don't have set_pixel_clock for v%d\n",
413 BIOS_CMD_TABLE_PARA_REVISION(setpixelclock));
414 bp->cmd_tbl.set_pixel_clock = set_pixel_clock_fallback;
415 break;
416 }
417}
418
419static void set_pixel_clock_dmcub(
420 struct dc_dmub_srv *dmcub,
421 struct set_pixel_clock_parameter_v1_7 *clk)
422{
423 union dmub_rb_cmd cmd;
424
425 memset(&cmd, 0, sizeof(cmd));
426
427 cmd.set_pixel_clock.header.type = DMUB_CMD__VBIOS;
428 cmd.set_pixel_clock.header.sub_type = DMUB_CMD__VBIOS_SET_PIXEL_CLOCK;
429 cmd.set_pixel_clock.header.payload_bytes =
430 sizeof(cmd.set_pixel_clock) -
431 sizeof(cmd.set_pixel_clock.header);
432 cmd.set_pixel_clock.pixel_clock.clk = *clk;
433
434 dc_dmub_srv_cmd_queue(dmcub, &cmd);
435 dc_dmub_srv_cmd_execute(dmcub);
436 dc_dmub_srv_wait_idle(dmcub);
437}
438
439static enum bp_result set_pixel_clock_v7(
440 struct bios_parser *bp,
441 struct bp_pixel_clock_parameters *bp_params)
442{
443 enum bp_result result = BP_RESULT_FAILURE;
444 struct set_pixel_clock_parameter_v1_7 clk;
445 uint8_t controller_id;
446 uint32_t pll_id;
447
448 memset(&clk, 0, sizeof(clk));
449
450 if (bp->cmd_helper->clock_source_id_to_atom(bp_params->pll_id, &pll_id)
451 && bp->cmd_helper->controller_id_to_atom(bp_params->
452 controller_id, &controller_id)) {
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472 clk.crtc_id = controller_id;
473 clk.pll_id = (uint8_t) pll_id;
474 clk.encoderobjid =
475 bp->cmd_helper->encoder_id_to_atom(
476 dal_graphics_object_id_get_encoder_id(
477 bp_params->encoder_object_id));
478
479 clk.encoder_mode = (uint8_t) bp->
480 cmd_helper->encoder_mode_bp_to_atom(
481 bp_params->signal_type, false);
482
483 clk.pixclk_100hz = cpu_to_le32(bp_params->target_pixel_clock_100hz);
484
485 clk.deep_color_ratio =
486 (uint8_t) bp->cmd_helper->
487 transmitter_color_depth_to_atom(
488 bp_params->color_depth);
489
490 DC_LOG_BIOS("%s:program display clock = %d, tg = %d, pll = %d, "\
491 "colorDepth = %d\n", __func__,
492 bp_params->target_pixel_clock_100hz, (int)controller_id,
493 pll_id, bp_params->color_depth);
494
495 if (bp_params->flags.FORCE_PROGRAMMING_OF_PLL)
496 clk.miscinfo |= PIXEL_CLOCK_V7_MISC_FORCE_PROG_PPLL;
497
498 if (bp_params->flags.PROGRAM_PHY_PLL_ONLY)
499 clk.miscinfo |= PIXEL_CLOCK_V7_MISC_PROG_PHYPLL;
500
501 if (bp_params->flags.SUPPORT_YUV_420)
502 clk.miscinfo |= PIXEL_CLOCK_V7_MISC_YUV420_MODE;
503
504 if (bp_params->flags.SET_XTALIN_REF_SRC)
505 clk.miscinfo |= PIXEL_CLOCK_V7_MISC_REF_DIV_SRC_XTALIN;
506
507 if (bp_params->flags.SET_GENLOCK_REF_DIV_SRC)
508 clk.miscinfo |= PIXEL_CLOCK_V7_MISC_REF_DIV_SRC_GENLK;
509
510 if (bp_params->signal_type == SIGNAL_TYPE_DVI_DUAL_LINK)
511 clk.miscinfo |= PIXEL_CLOCK_V7_MISC_DVI_DUALLINK_EN;
512
513 if (bp->base.ctx->dc->ctx->dmub_srv &&
514 bp->base.ctx->dc->debug.dmub_command_table) {
515 set_pixel_clock_dmcub(bp->base.ctx->dmub_srv, &clk);
516 return BP_RESULT_OK;
517 }
518
519 if (EXEC_BIOS_CMD_TABLE(setpixelclock, clk))
520 result = BP_RESULT_OK;
521 }
522 return result;
523}
524
525static enum bp_result set_pixel_clock_fallback(
526 struct bios_parser *bp,
527 struct bp_pixel_clock_parameters *bp_params)
528{
529 if (bp->base.ctx->dc->ctx->dmub_srv &&
530 bp->base.ctx->dc->debug.dmub_command_table) {
531 return set_pixel_clock_v7(bp, bp_params);
532 }
533
534 return BP_RESULT_FAILURE;
535}
536
537
538
539
540
541
542
543
544
545static enum bp_result set_crtc_using_dtd_timing_v3(
546 struct bios_parser *bp,
547 struct bp_hw_crtc_timing_parameters *bp_params);
548
549static void init_set_crtc_timing(struct bios_parser *bp)
550{
551 uint32_t dtd_version =
552 BIOS_CMD_TABLE_PARA_REVISION(setcrtc_usingdtdtiming);
553
554 switch (dtd_version) {
555 case 3:
556 bp->cmd_tbl.set_crtc_timing =
557 set_crtc_using_dtd_timing_v3;
558 break;
559 default:
560 dm_output_to_console("Don't have set_crtc_timing for v%d\n", dtd_version);
561 bp->cmd_tbl.set_crtc_timing = NULL;
562 break;
563 }
564}
565
566static enum bp_result set_crtc_using_dtd_timing_v3(
567 struct bios_parser *bp,
568 struct bp_hw_crtc_timing_parameters *bp_params)
569{
570 enum bp_result result = BP_RESULT_FAILURE;
571 struct set_crtc_using_dtd_timing_parameters params = {0};
572 uint8_t atom_controller_id;
573
574 if (bp->cmd_helper->controller_id_to_atom(
575 bp_params->controller_id, &atom_controller_id))
576 params.crtc_id = atom_controller_id;
577
578
579 params.h_size = cpu_to_le16((uint16_t)bp_params->h_addressable);
580
581 params.h_blanking_time =
582 cpu_to_le16((uint16_t)(bp_params->h_total -
583 bp_params->h_addressable));
584
585 params.v_size = cpu_to_le16((uint16_t)bp_params->v_addressable);
586
587 params.v_blanking_time =
588 cpu_to_le16((uint16_t)(bp_params->v_total -
589 bp_params->v_addressable));
590
591
592
593
594 params.h_syncoffset =
595 cpu_to_le16((uint16_t)(bp_params->h_sync_start -
596 bp_params->h_addressable));
597 params.h_syncwidth = cpu_to_le16((uint16_t)bp_params->h_sync_width);
598
599
600
601
602 params.v_syncoffset =
603 cpu_to_le16((uint16_t)(bp_params->v_sync_start -
604 bp_params->v_addressable));
605 params.v_syncwidth = cpu_to_le16((uint16_t)bp_params->v_sync_width);
606
607
608
609
610
611
612 if (bp_params->flags.HSYNC_POSITIVE_POLARITY == 0)
613 params.modemiscinfo =
614 cpu_to_le16(le16_to_cpu(params.modemiscinfo) |
615 ATOM_HSYNC_POLARITY);
616
617 if (bp_params->flags.VSYNC_POSITIVE_POLARITY == 0)
618 params.modemiscinfo =
619 cpu_to_le16(le16_to_cpu(params.modemiscinfo) |
620 ATOM_VSYNC_POLARITY);
621
622 if (bp_params->flags.INTERLACE) {
623 params.modemiscinfo =
624 cpu_to_le16(le16_to_cpu(params.modemiscinfo) |
625 ATOM_INTERLACE);
626
627
628
629
630
631
632
633
634 {
635
636
637
638
639
640
641
642 le16_add_cpu(¶ms.v_syncoffset, 1);
643 }
644 }
645
646 if (bp_params->flags.HORZ_COUNT_BY_TWO)
647 params.modemiscinfo =
648 cpu_to_le16(le16_to_cpu(params.modemiscinfo) |
649 0x100);
650
651 if (EXEC_BIOS_CMD_TABLE(setcrtc_usingdtdtiming, params))
652 result = BP_RESULT_OK;
653
654 return result;
655}
656
657
658
659
660
661
662
663
664
665static enum bp_result enable_crtc_v1(
666 struct bios_parser *bp,
667 enum controller_id controller_id,
668 bool enable);
669
670static void init_enable_crtc(struct bios_parser *bp)
671{
672 switch (BIOS_CMD_TABLE_PARA_REVISION(enablecrtc)) {
673 case 1:
674 bp->cmd_tbl.enable_crtc = enable_crtc_v1;
675 break;
676 default:
677 dm_output_to_console("Don't have enable_crtc for v%d\n",
678 BIOS_CMD_TABLE_PARA_REVISION(enablecrtc));
679 bp->cmd_tbl.enable_crtc = NULL;
680 break;
681 }
682}
683
684static enum bp_result enable_crtc_v1(
685 struct bios_parser *bp,
686 enum controller_id controller_id,
687 bool enable)
688{
689 bool result = BP_RESULT_FAILURE;
690 struct enable_crtc_parameters params = {0};
691 uint8_t id;
692
693 if (bp->cmd_helper->controller_id_to_atom(controller_id, &id))
694 params.crtc_id = id;
695 else
696 return BP_RESULT_BADINPUT;
697
698 if (enable)
699 params.enable = ATOM_ENABLE;
700 else
701 params.enable = ATOM_DISABLE;
702
703 if (EXEC_BIOS_CMD_TABLE(enablecrtc, params))
704 result = BP_RESULT_OK;
705
706 return result;
707}
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727static enum bp_result external_encoder_control_v3(
728 struct bios_parser *bp,
729 struct bp_external_encoder_control *cntl);
730
731static void init_external_encoder_control(
732 struct bios_parser *bp)
733{
734 switch (BIOS_CMD_TABLE_PARA_REVISION(externalencodercontrol)) {
735 case 3:
736 bp->cmd_tbl.external_encoder_control =
737 external_encoder_control_v3;
738 break;
739 default:
740 bp->cmd_tbl.external_encoder_control = NULL;
741 break;
742 }
743}
744
745static enum bp_result external_encoder_control_v3(
746 struct bios_parser *bp,
747 struct bp_external_encoder_control *cntl)
748{
749
750 return BP_RESULT_OK;
751}
752
753
754
755
756
757
758
759
760
761static enum bp_result enable_disp_power_gating_v2_1(
762 struct bios_parser *bp,
763 enum controller_id crtc_id,
764 enum bp_pipe_control_action action);
765
766static enum bp_result enable_disp_power_gating_fallback(
767 struct bios_parser *bp,
768 enum controller_id crtc_id,
769 enum bp_pipe_control_action action);
770
771static void init_enable_disp_power_gating(
772 struct bios_parser *bp)
773{
774 switch (BIOS_CMD_TABLE_PARA_REVISION(enabledisppowergating)) {
775 case 1:
776 bp->cmd_tbl.enable_disp_power_gating =
777 enable_disp_power_gating_v2_1;
778 break;
779 default:
780 dm_output_to_console("Don't enable_disp_power_gating enable_crtc for v%d\n",
781 BIOS_CMD_TABLE_PARA_REVISION(enabledisppowergating));
782 bp->cmd_tbl.enable_disp_power_gating = enable_disp_power_gating_fallback;
783 break;
784 }
785}
786
787static void enable_disp_power_gating_dmcub(
788 struct dc_dmub_srv *dmcub,
789 struct enable_disp_power_gating_parameters_v2_1 *pwr)
790{
791 union dmub_rb_cmd cmd;
792
793 memset(&cmd, 0, sizeof(cmd));
794
795 cmd.enable_disp_power_gating.header.type = DMUB_CMD__VBIOS;
796 cmd.enable_disp_power_gating.header.sub_type =
797 DMUB_CMD__VBIOS_ENABLE_DISP_POWER_GATING;
798 cmd.enable_disp_power_gating.header.payload_bytes =
799 sizeof(cmd.enable_disp_power_gating) -
800 sizeof(cmd.enable_disp_power_gating.header);
801 cmd.enable_disp_power_gating.power_gating.pwr = *pwr;
802
803 dc_dmub_srv_cmd_queue(dmcub, &cmd);
804 dc_dmub_srv_cmd_execute(dmcub);
805 dc_dmub_srv_wait_idle(dmcub);
806}
807
808static enum bp_result enable_disp_power_gating_v2_1(
809 struct bios_parser *bp,
810 enum controller_id crtc_id,
811 enum bp_pipe_control_action action)
812{
813 enum bp_result result = BP_RESULT_FAILURE;
814
815
816 struct enable_disp_power_gating_ps_allocation ps = { { 0 } };
817 uint8_t atom_crtc_id;
818
819 if (bp->cmd_helper->controller_id_to_atom(crtc_id, &atom_crtc_id))
820 ps.param.disp_pipe_id = atom_crtc_id;
821 else
822 return BP_RESULT_BADINPUT;
823
824 ps.param.enable =
825 bp->cmd_helper->disp_power_gating_action_to_atom(action);
826
827 if (bp->base.ctx->dc->ctx->dmub_srv &&
828 bp->base.ctx->dc->debug.dmub_command_table) {
829 enable_disp_power_gating_dmcub(bp->base.ctx->dmub_srv,
830 &ps.param);
831 return BP_RESULT_OK;
832 }
833
834 if (EXEC_BIOS_CMD_TABLE(enabledisppowergating, ps.param))
835 result = BP_RESULT_OK;
836
837 return result;
838}
839
840static enum bp_result enable_disp_power_gating_fallback(
841 struct bios_parser *bp,
842 enum controller_id crtc_id,
843 enum bp_pipe_control_action action)
844{
845 if (bp->base.ctx->dc->ctx->dmub_srv &&
846 bp->base.ctx->dc->debug.dmub_command_table) {
847 return enable_disp_power_gating_v2_1(bp, crtc_id, action);
848 }
849
850 return BP_RESULT_FAILURE;
851}
852
853
854
855
856
857
858
859
860
861static enum bp_result set_dce_clock_v2_1(
862 struct bios_parser *bp,
863 struct bp_set_dce_clock_parameters *bp_params);
864
865static void init_set_dce_clock(struct bios_parser *bp)
866{
867 switch (BIOS_CMD_TABLE_PARA_REVISION(setdceclock)) {
868 case 1:
869 bp->cmd_tbl.set_dce_clock = set_dce_clock_v2_1;
870 break;
871 default:
872 dm_output_to_console("Don't have set_dce_clock for v%d\n",
873 BIOS_CMD_TABLE_PARA_REVISION(setdceclock));
874 bp->cmd_tbl.set_dce_clock = NULL;
875 break;
876 }
877}
878
879static enum bp_result set_dce_clock_v2_1(
880 struct bios_parser *bp,
881 struct bp_set_dce_clock_parameters *bp_params)
882{
883 enum bp_result result = BP_RESULT_FAILURE;
884
885 struct set_dce_clock_ps_allocation_v2_1 params;
886 uint32_t atom_pll_id;
887 uint32_t atom_clock_type;
888 const struct command_table_helper *cmd = bp->cmd_helper;
889
890 memset(¶ms, 0, sizeof(params));
891
892 if (!cmd->clock_source_id_to_atom(bp_params->pll_id, &atom_pll_id) ||
893 !cmd->dc_clock_type_to_atom(bp_params->clock_type,
894 &atom_clock_type))
895 return BP_RESULT_BADINPUT;
896
897 params.param.dceclksrc = atom_pll_id;
898 params.param.dceclktype = atom_clock_type;
899
900 if (bp_params->clock_type == DCECLOCK_TYPE_DPREFCLK) {
901 if (bp_params->flags.USE_GENLOCK_AS_SOURCE_FOR_DPREFCLK)
902 params.param.dceclkflag |=
903 DCE_CLOCK_FLAG_PLL_REFCLK_SRC_GENLK;
904
905 if (bp_params->flags.USE_PCIE_AS_SOURCE_FOR_DPREFCLK)
906 params.param.dceclkflag |=
907 DCE_CLOCK_FLAG_PLL_REFCLK_SRC_PCIE;
908
909 if (bp_params->flags.USE_XTALIN_AS_SOURCE_FOR_DPREFCLK)
910 params.param.dceclkflag |=
911 DCE_CLOCK_FLAG_PLL_REFCLK_SRC_XTALIN;
912
913 if (bp_params->flags.USE_GENERICA_AS_SOURCE_FOR_DPREFCLK)
914 params.param.dceclkflag |=
915 DCE_CLOCK_FLAG_PLL_REFCLK_SRC_GENERICA;
916 } else
917
918
919
920
921 params.param.dceclk_10khz = cpu_to_le32(
922 bp_params->target_clock_frequency / 10);
923 DC_LOG_BIOS("%s:target_clock_frequency = %d"\
924 "clock_type = %d \n", __func__,\
925 bp_params->target_clock_frequency,\
926 bp_params->clock_type);
927
928 if (EXEC_BIOS_CMD_TABLE(setdceclock, params)) {
929
930 bp_params->target_clock_frequency = le32_to_cpu(
931 params.param.dceclk_10khz) * 10;
932 result = BP_RESULT_OK;
933 }
934
935 return result;
936}
937
938
939
940
941
942
943
944
945
946
947static unsigned int get_smu_clock_info_v3_1(struct bios_parser *bp, uint8_t id);
948
949static void init_get_smu_clock_info(struct bios_parser *bp)
950{
951
952 bp->cmd_tbl.get_smu_clock_info = get_smu_clock_info_v3_1;
953
954}
955
956static unsigned int get_smu_clock_info_v3_1(struct bios_parser *bp, uint8_t id)
957{
958 struct atom_get_smu_clock_info_parameters_v3_1 smu_input = {0};
959 struct atom_get_smu_clock_info_output_parameters_v3_1 smu_output;
960
961 smu_input.command = GET_SMU_CLOCK_INFO_V3_1_GET_PLLVCO_FREQ;
962 smu_input.syspll_id = id;
963
964
965 if (EXEC_BIOS_CMD_TABLE(getsmuclockinfo, smu_input)) {
966 memmove(&smu_output, &smu_input, sizeof(
967 struct atom_get_smu_clock_info_parameters_v3_1));
968 return smu_output.atom_smu_outputclkfreq.syspllvcofreq_10khz;
969 }
970
971 return 0;
972}
973
974
975
976
977
978
979
980
981
982static enum bp_result enable_lvtma_control(
983 struct bios_parser *bp,
984 uint8_t uc_pwr_on,
985 uint8_t panel_instance);
986
987static void init_enable_lvtma_control(struct bios_parser *bp)
988{
989
990 bp->cmd_tbl.enable_lvtma_control = enable_lvtma_control;
991
992}
993
994static void enable_lvtma_control_dmcub(
995 struct dc_dmub_srv *dmcub,
996 uint8_t uc_pwr_on,
997 uint8_t panel_instance)
998{
999
1000 union dmub_rb_cmd cmd;
1001
1002 memset(&cmd, 0, sizeof(cmd));
1003
1004 cmd.lvtma_control.header.type = DMUB_CMD__VBIOS;
1005 cmd.lvtma_control.header.sub_type =
1006 DMUB_CMD__VBIOS_LVTMA_CONTROL;
1007 cmd.lvtma_control.data.uc_pwr_action =
1008 uc_pwr_on;
1009 cmd.lvtma_control.data.panel_inst =
1010 panel_instance;
1011 dc_dmub_srv_cmd_queue(dmcub, &cmd);
1012 dc_dmub_srv_cmd_execute(dmcub);
1013 dc_dmub_srv_wait_idle(dmcub);
1014
1015}
1016
1017static enum bp_result enable_lvtma_control(
1018 struct bios_parser *bp,
1019 uint8_t uc_pwr_on,
1020 uint8_t panel_instance)
1021{
1022 enum bp_result result = BP_RESULT_FAILURE;
1023
1024 if (bp->base.ctx->dc->ctx->dmub_srv &&
1025 bp->base.ctx->dc->debug.dmub_command_table) {
1026 enable_lvtma_control_dmcub(bp->base.ctx->dmub_srv,
1027 uc_pwr_on,
1028 panel_instance);
1029 return BP_RESULT_OK;
1030 }
1031 return result;
1032}
1033
1034void dal_firmware_parser_init_cmd_tbl(struct bios_parser *bp)
1035{
1036 init_dig_encoder_control(bp);
1037 init_transmitter_control(bp);
1038 init_set_pixel_clock(bp);
1039
1040 init_set_crtc_timing(bp);
1041
1042 init_enable_crtc(bp);
1043
1044 init_external_encoder_control(bp);
1045 init_enable_disp_power_gating(bp);
1046 init_set_dce_clock(bp);
1047 init_get_smu_clock_info(bp);
1048
1049 init_enable_lvtma_control(bp);
1050}
1051