]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - drivers/gpu/drm/amd/display/dc/bios/command_table2.c
amdgpu/dc: fix indentation warning from smatch.
[mirror_ubuntu-bionic-kernel.git] / drivers / gpu / drm / amd / display / dc / bios / command_table2.c
CommitLineData
ae79c310
HW
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
28#include "ObjectID.h"
29#include "atomfirmware.h"
ae79c310
HW
30
31#include "include/bios_parser_interface.h"
32
33#include "command_table2.h"
34#include "command_table_helper2.h"
35#include "bios_parser_helper.h"
36#include "bios_parser_types_internal2.h"
37
38#define GET_INDEX_INTO_MASTER_TABLE(MasterOrData, FieldName)\
39 (((char *)(&((\
40 struct atom_master_list_of_##MasterOrData##_functions_v2_1 *)0)\
41 ->FieldName)-(char *)0)/sizeof(uint16_t))
42
43#define EXEC_BIOS_CMD_TABLE(fname, params)\
44 (cgs_atom_exec_cmd_table(bp->base.ctx->cgs_device, \
45 GET_INDEX_INTO_MASTER_TABLE(command, fname), \
46 &params) == 0)
47
48#define BIOS_CMD_TABLE_REVISION(fname, frev, crev)\
49 cgs_atom_get_cmd_table_revs(bp->base.ctx->cgs_device, \
50 GET_INDEX_INTO_MASTER_TABLE(command, fname), &frev, &crev)
51
52#define BIOS_CMD_TABLE_PARA_REVISION(fname)\
53 bios_cmd_table_para_revision(bp->base.ctx->cgs_device, \
54 GET_INDEX_INTO_MASTER_TABLE(command, fname))
55
56static void init_dig_encoder_control(struct bios_parser *bp);
57static void init_transmitter_control(struct bios_parser *bp);
58static void init_set_pixel_clock(struct bios_parser *bp);
59
60static void init_set_crtc_timing(struct bios_parser *bp);
61
62static void init_select_crtc_source(struct bios_parser *bp);
63static void init_enable_crtc(struct bios_parser *bp);
64
65static void init_external_encoder_control(struct bios_parser *bp);
66static void init_enable_disp_power_gating(struct bios_parser *bp);
67static void init_set_dce_clock(struct bios_parser *bp);
68static void init_get_smu_clock_info(struct bios_parser *bp);
69
70void dal_firmware_parser_init_cmd_tbl(struct bios_parser *bp)
71{
72 init_dig_encoder_control(bp);
73 init_transmitter_control(bp);
74 init_set_pixel_clock(bp);
75
76 init_set_crtc_timing(bp);
77
78 init_select_crtc_source(bp);
79 init_enable_crtc(bp);
80
81 init_external_encoder_control(bp);
82 init_enable_disp_power_gating(bp);
83 init_set_dce_clock(bp);
84 init_get_smu_clock_info(bp);
85}
86
87static uint32_t bios_cmd_table_para_revision(void *cgs_device,
88 uint32_t index)
89{
90 uint8_t frev, crev;
91
92 if (cgs_atom_get_cmd_table_revs(cgs_device,
93 index,
94 &frev, &crev) != 0)
95 return 0;
96 return crev;
97}
98
99/******************************************************************************
100 ******************************************************************************
101 **
102 ** D I G E N C O D E R C O N T R O L
103 **
104 ******************************************************************************
105 *****************************************************************************/
106
107static enum bp_result encoder_control_digx_v1_5(
108 struct bios_parser *bp,
109 struct bp_encoder_control *cntl);
110
111static void init_dig_encoder_control(struct bios_parser *bp)
112{
113 uint32_t version =
114 BIOS_CMD_TABLE_PARA_REVISION(digxencodercontrol);
115
116 switch (version) {
117 case 5:
118 bp->cmd_tbl.dig_encoder_control = encoder_control_digx_v1_5;
119 break;
120 default:
121 bp->cmd_tbl.dig_encoder_control = NULL;
122 break;
123 }
124}
125
126static enum bp_result encoder_control_digx_v1_5(
127 struct bios_parser *bp,
128 struct bp_encoder_control *cntl)
129{
130 enum bp_result result = BP_RESULT_FAILURE;
131 struct dig_encoder_stream_setup_parameters_v1_5 params = {0};
132
133 params.digid = (uint8_t)(cntl->engine_id);
134 params.action = bp->cmd_helper->encoder_action_to_atom(cntl->action);
135
136 params.pclk_10khz = cntl->pixel_clock / 10;
137 params.digmode =
138 (uint8_t)(bp->cmd_helper->encoder_mode_bp_to_atom(
139 cntl->signal,
140 cntl->enable_dp_audio));
141 params.lanenum = (uint8_t)(cntl->lanes_number);
142
143 switch (cntl->color_depth) {
144 case COLOR_DEPTH_888:
145 params.bitpercolor = PANEL_8BIT_PER_COLOR;
146 break;
147 case COLOR_DEPTH_101010:
148 params.bitpercolor = PANEL_10BIT_PER_COLOR;
149 break;
150 case COLOR_DEPTH_121212:
151 params.bitpercolor = PANEL_12BIT_PER_COLOR;
152 break;
153 case COLOR_DEPTH_161616:
154 params.bitpercolor = PANEL_16BIT_PER_COLOR;
155 break;
156 default:
157 break;
158 }
159
160 if (cntl->signal == SIGNAL_TYPE_HDMI_TYPE_A)
161 switch (cntl->color_depth) {
162 case COLOR_DEPTH_101010:
163 params.pclk_10khz =
164 (params.pclk_10khz * 30) / 24;
165 break;
166 case COLOR_DEPTH_121212:
167 params.pclk_10khz =
168 (params.pclk_10khz * 36) / 24;
169 break;
170 case COLOR_DEPTH_161616:
171 params.pclk_10khz =
172 (params.pclk_10khz * 48) / 24;
173 break;
174 default:
175 break;
176 }
177
178 if (EXEC_BIOS_CMD_TABLE(digxencodercontrol, params))
179 result = BP_RESULT_OK;
180
181 return result;
182}
183
184/*****************************************************************************
185 ******************************************************************************
186 **
187 ** TRANSMITTER CONTROL
188 **
189 ******************************************************************************
190 *****************************************************************************/
191
192static enum bp_result transmitter_control_v1_6(
193 struct bios_parser *bp,
194 struct bp_transmitter_control *cntl);
195
196static void init_transmitter_control(struct bios_parser *bp)
197{
198 uint8_t frev;
199 uint8_t crev;
200
201 if (BIOS_CMD_TABLE_REVISION(dig1transmittercontrol, frev, crev) != 0)
202 BREAK_TO_DEBUGGER();
203 switch (crev) {
204 case 6:
205 bp->cmd_tbl.transmitter_control = transmitter_control_v1_6;
206 break;
207 default:
208 bp->cmd_tbl.transmitter_control = NULL;
209 break;
210 }
211}
212
213static enum bp_result transmitter_control_v1_6(
214 struct bios_parser *bp,
215 struct bp_transmitter_control *cntl)
216{
217 enum bp_result result = BP_RESULT_FAILURE;
218 const struct command_table_helper *cmd = bp->cmd_helper;
219 struct dig_transmitter_control_ps_allocation_v1_6 ps = { { 0 } };
220
221 ps.param.phyid = cmd->phy_id_to_atom(cntl->transmitter);
222 ps.param.action = (uint8_t)cntl->action;
223
224 if (cntl->action == TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS)
225 ps.param.mode_laneset.dplaneset = (uint8_t)cntl->lane_settings;
226 else
227 ps.param.mode_laneset.digmode =
228 cmd->signal_type_to_atom_dig_mode(cntl->signal);
229
230 ps.param.lanenum = (uint8_t)cntl->lanes_number;
231 ps.param.hpdsel = cmd->hpd_sel_to_atom(cntl->hpd_sel);
232 ps.param.digfe_sel = cmd->dig_encoder_sel_to_atom(cntl->engine_id);
233 ps.param.connobj_id = (uint8_t)cntl->connector_obj_id.id;
234 ps.param.symclk_10khz = cntl->pixel_clock/10;
235
236
237 if (cntl->action == TRANSMITTER_CONTROL_ENABLE ||
238 cntl->action == TRANSMITTER_CONTROL_ACTIAVATE ||
239 cntl->action == TRANSMITTER_CONTROL_DEACTIVATE) {
7fc6ff77
JL
240 dm_logger_write(bp->base.ctx->logger, LOG_BIOS,\
241 "%s:ps.param.symclk_10khz = %d\n",\
ae79c310
HW
242 __func__, ps.param.symclk_10khz);
243 }
244
245
246/*color_depth not used any more, driver has deep color factor in the Phyclk*/
247 if (EXEC_BIOS_CMD_TABLE(dig1transmittercontrol, ps))
248 result = BP_RESULT_OK;
249 return result;
250}
251
252/******************************************************************************
253 ******************************************************************************
254 **
255 ** SET PIXEL CLOCK
256 **
257 ******************************************************************************
258 *****************************************************************************/
259
260static enum bp_result set_pixel_clock_v7(
261 struct bios_parser *bp,
262 struct bp_pixel_clock_parameters *bp_params);
263
264static void init_set_pixel_clock(struct bios_parser *bp)
265{
266 switch (BIOS_CMD_TABLE_PARA_REVISION(setpixelclock)) {
267 case 7:
268 bp->cmd_tbl.set_pixel_clock = set_pixel_clock_v7;
269 break;
270 default:
271 bp->cmd_tbl.set_pixel_clock = NULL;
272 break;
273 }
274}
275
276
277
278static enum bp_result set_pixel_clock_v7(
279 struct bios_parser *bp,
280 struct bp_pixel_clock_parameters *bp_params)
281{
282 enum bp_result result = BP_RESULT_FAILURE;
283 struct set_pixel_clock_parameter_v1_7 clk;
284 uint8_t controller_id;
285 uint32_t pll_id;
286
287 memset(&clk, 0, sizeof(clk));
288
289 if (bp->cmd_helper->clock_source_id_to_atom(bp_params->pll_id, &pll_id)
290 && bp->cmd_helper->controller_id_to_atom(bp_params->
291 controller_id, &controller_id)) {
292 /* Note: VBIOS still wants to use ucCRTC name which is now
293 * 1 byte in ULONG
294 *typedef struct _CRTC_PIXEL_CLOCK_FREQ
295 *{
296 * target the pixel clock to drive the CRTC timing.
297 * ULONG ulPixelClock:24;
298 * 0 means disable PPLL/DCPLL. Expanded to 24 bits comparing to
299 * previous version.
300 * ATOM_CRTC1~6, indicate the CRTC controller to
301 * ULONG ucCRTC:8;
302 * drive the pixel clock. not used for DCPLL case.
303 *}CRTC_PIXEL_CLOCK_FREQ;
304 *union
305 *{
306 * pixel clock and CRTC id frequency
307 * CRTC_PIXEL_CLOCK_FREQ ulCrtcPclkFreq;
308 * ULONG ulDispEngClkFreq; dispclk frequency
309 *};
310 */
311 clk.crtc_id = controller_id;
312 clk.pll_id = (uint8_t) pll_id;
313 clk.encoderobjid =
314 bp->cmd_helper->encoder_id_to_atom(
315 dal_graphics_object_id_get_encoder_id(
316 bp_params->encoder_object_id));
317
318 clk.encoder_mode = (uint8_t) bp->
319 cmd_helper->encoder_mode_bp_to_atom(
320 bp_params->signal_type, false);
321
322 /* We need to convert from KHz units into 10KHz units */
323 clk.pixclk_100hz = cpu_to_le32(bp_params->target_pixel_clock *
324 10);
325
326 clk.deep_color_ratio =
327 (uint8_t) bp->cmd_helper->
328 transmitter_color_depth_to_atom(
329 bp_params->color_depth);
7fc6ff77
JL
330 dm_logger_write(bp->base.ctx->logger, LOG_BIOS,\
331 "%s:program display clock = %d"\
ae79c310
HW
332 "colorDepth = %d\n", __func__,\
333 bp_params->target_pixel_clock, bp_params->color_depth);
334
335 if (bp_params->flags.FORCE_PROGRAMMING_OF_PLL)
336 clk.miscinfo |= PIXEL_CLOCK_V7_MISC_FORCE_PROG_PPLL;
337
338 if (bp_params->flags.PROGRAM_PHY_PLL_ONLY)
339 clk.miscinfo |= PIXEL_CLOCK_V7_MISC_PROG_PHYPLL;
340
341 if (bp_params->flags.SUPPORT_YUV_420)
342 clk.miscinfo |= PIXEL_CLOCK_V7_MISC_YUV420_MODE;
343
344 if (bp_params->flags.SET_XTALIN_REF_SRC)
345 clk.miscinfo |= PIXEL_CLOCK_V7_MISC_REF_DIV_SRC_XTALIN;
346
347 if (bp_params->flags.SET_GENLOCK_REF_DIV_SRC)
348 clk.miscinfo |= PIXEL_CLOCK_V7_MISC_REF_DIV_SRC_GENLK;
349
350 if (bp_params->signal_type == SIGNAL_TYPE_DVI_DUAL_LINK)
351 clk.miscinfo |= PIXEL_CLOCK_V7_MISC_DVI_DUALLINK_EN;
352
353 if (EXEC_BIOS_CMD_TABLE(setpixelclock, clk))
354 result = BP_RESULT_OK;
355 }
356 return result;
357}
358
359/******************************************************************************
360 ******************************************************************************
361 **
362 ** SET CRTC TIMING
363 **
364 ******************************************************************************
365 *****************************************************************************/
366
367static enum bp_result set_crtc_using_dtd_timing_v3(
368 struct bios_parser *bp,
369 struct bp_hw_crtc_timing_parameters *bp_params);
370
371static void init_set_crtc_timing(struct bios_parser *bp)
372{
373 uint32_t dtd_version =
374 BIOS_CMD_TABLE_PARA_REVISION(setcrtc_usingdtdtiming);
375
bf5563ed
DA
376 switch (dtd_version) {
377 case 3:
378 bp->cmd_tbl.set_crtc_timing =
379 set_crtc_using_dtd_timing_v3;
380 break;
381 default:
382 bp->cmd_tbl.set_crtc_timing = NULL;
383 break;
384 }
ae79c310
HW
385}
386
387static enum bp_result set_crtc_using_dtd_timing_v3(
388 struct bios_parser *bp,
389 struct bp_hw_crtc_timing_parameters *bp_params)
390{
391 enum bp_result result = BP_RESULT_FAILURE;
392 struct set_crtc_using_dtd_timing_parameters params = {0};
393 uint8_t atom_controller_id;
394
395 if (bp->cmd_helper->controller_id_to_atom(
396 bp_params->controller_id, &atom_controller_id))
397 params.crtc_id = atom_controller_id;
398
399 /* bios usH_Size wants h addressable size */
400 params.h_size = cpu_to_le16((uint16_t)bp_params->h_addressable);
401 /* bios usH_Blanking_Time wants borders included in blanking */
402 params.h_blanking_time =
403 cpu_to_le16((uint16_t)(bp_params->h_total -
404 bp_params->h_addressable));
405 /* bios usV_Size wants v addressable size */
406 params.v_size = cpu_to_le16((uint16_t)bp_params->v_addressable);
407 /* bios usV_Blanking_Time wants borders included in blanking */
408 params.v_blanking_time =
409 cpu_to_le16((uint16_t)(bp_params->v_total -
410 bp_params->v_addressable));
411 /* bios usHSyncOffset is the offset from the end of h addressable,
412 * our horizontalSyncStart is the offset from the beginning
413 * of h addressable
414 */
415 params.h_syncoffset =
416 cpu_to_le16((uint16_t)(bp_params->h_sync_start -
417 bp_params->h_addressable));
418 params.h_syncwidth = cpu_to_le16((uint16_t)bp_params->h_sync_width);
419 /* bios usHSyncOffset is the offset from the end of v addressable,
420 * our verticalSyncStart is the offset from the beginning of
421 * v addressable
422 */
423 params.v_syncoffset =
424 cpu_to_le16((uint16_t)(bp_params->v_sync_start -
425 bp_params->v_addressable));
426 params.v_syncwidth = cpu_to_le16((uint16_t)bp_params->v_sync_width);
427
428 /* we assume that overscan from original timing does not get bigger
429 * than 255
430 * we will program all the borders in the Set CRTC Overscan call below
431 */
432
433 if (bp_params->flags.HSYNC_POSITIVE_POLARITY == 0)
434 params.modemiscinfo =
435 cpu_to_le16(le16_to_cpu(params.modemiscinfo) |
436 ATOM_HSYNC_POLARITY);
437
438 if (bp_params->flags.VSYNC_POSITIVE_POLARITY == 0)
439 params.modemiscinfo =
440 cpu_to_le16(le16_to_cpu(params.modemiscinfo) |
441 ATOM_VSYNC_POLARITY);
442
443 if (bp_params->flags.INTERLACE) {
444 params.modemiscinfo =
445 cpu_to_le16(le16_to_cpu(params.modemiscinfo) |
446 ATOM_INTERLACE);
447
448 /* original DAL code has this condition to apply this
449 * for non-TV/CV only
450 * due to complex MV testing for possible impact
451 * if ( pACParameters->signal != SignalType_YPbPr &&
452 * pACParameters->signal != SignalType_Composite &&
453 * pACParameters->signal != SignalType_SVideo)
454 */
455 {
456 /* HW will deduct 0.5 line from 2nd feild.
457 * i.e. for 1080i, it is 2 lines for 1st field,
458 * 2.5 lines for the 2nd feild. we need input as 5
459 * instead of 4.
460 * but it is 4 either from Edid data (spec CEA 861)
461 * or CEA timing table.
462 */
463 params.v_syncoffset =
464 cpu_to_le16(le16_to_cpu(params.v_syncoffset) +
465 1);
466
467 }
468 }
469
470 if (bp_params->flags.HORZ_COUNT_BY_TWO)
471 params.modemiscinfo =
472 cpu_to_le16(le16_to_cpu(params.modemiscinfo) |
473 0x100); /* ATOM_DOUBLE_CLOCK_MODE */
474
475 if (EXEC_BIOS_CMD_TABLE(setcrtc_usingdtdtiming, params))
476 result = BP_RESULT_OK;
477
478 return result;
479}
480
481/******************************************************************************
482 ******************************************************************************
483 **
484 ** SELECT CRTC SOURCE
485 **
486 ******************************************************************************
487 *****************************************************************************/
488
489
490static enum bp_result select_crtc_source_v3(
491 struct bios_parser *bp,
492 struct bp_crtc_source_select *bp_params);
493
494static void init_select_crtc_source(struct bios_parser *bp)
495{
496 switch (BIOS_CMD_TABLE_PARA_REVISION(selectcrtc_source)) {
497 case 3:
498 bp->cmd_tbl.select_crtc_source = select_crtc_source_v3;
499 break;
500 default:
501 bp->cmd_tbl.select_crtc_source = NULL;
502 break;
503 }
504}
505
506
507static enum bp_result select_crtc_source_v3(
508 struct bios_parser *bp,
509 struct bp_crtc_source_select *bp_params)
510{
511 bool result = BP_RESULT_FAILURE;
512 struct select_crtc_source_parameters_v2_3 params;
513 uint8_t atom_controller_id;
514 uint32_t atom_engine_id;
515 enum signal_type s = bp_params->signal;
516
517 memset(&params, 0, sizeof(params));
518
519 if (bp->cmd_helper->controller_id_to_atom(bp_params->controller_id,
520 &atom_controller_id))
521 params.crtc_id = atom_controller_id;
522 else
523 return result;
524
525 if (bp->cmd_helper->engine_bp_to_atom(bp_params->engine_id,
526 &atom_engine_id))
527 params.encoder_id = (uint8_t)atom_engine_id;
528 else
529 return result;
530
531 if (s == SIGNAL_TYPE_EDP ||
532 (s == SIGNAL_TYPE_DISPLAY_PORT && bp_params->sink_signal ==
533 SIGNAL_TYPE_LVDS))
534 s = SIGNAL_TYPE_LVDS;
535
536 params.encode_mode =
537 bp->cmd_helper->encoder_mode_bp_to_atom(
538 s, bp_params->enable_dp_audio);
539 /* Needed for VBIOS Random Spatial Dithering feature */
540 params.dst_bpc = (uint8_t)(bp_params->display_output_bit_depth);
541
542 if (EXEC_BIOS_CMD_TABLE(selectcrtc_source, params))
543 result = BP_RESULT_OK;
544
545 return result;
546}
547
548/******************************************************************************
549 ******************************************************************************
550 **
551 ** ENABLE CRTC
552 **
553 ******************************************************************************
554 *****************************************************************************/
555
556static enum bp_result enable_crtc_v1(
557 struct bios_parser *bp,
558 enum controller_id controller_id,
559 bool enable);
560
561static void init_enable_crtc(struct bios_parser *bp)
562{
563 switch (BIOS_CMD_TABLE_PARA_REVISION(enablecrtc)) {
564 case 1:
565 bp->cmd_tbl.enable_crtc = enable_crtc_v1;
566 break;
567 default:
568 bp->cmd_tbl.enable_crtc = NULL;
569 break;
570 }
571}
572
573static enum bp_result enable_crtc_v1(
574 struct bios_parser *bp,
575 enum controller_id controller_id,
576 bool enable)
577{
578 bool result = BP_RESULT_FAILURE;
579 struct enable_crtc_parameters params = {0};
580 uint8_t id;
581
582 if (bp->cmd_helper->controller_id_to_atom(controller_id, &id))
583 params.crtc_id = id;
584 else
585 return BP_RESULT_BADINPUT;
586
587 if (enable)
588 params.enable = ATOM_ENABLE;
589 else
590 params.enable = ATOM_DISABLE;
591
592 if (EXEC_BIOS_CMD_TABLE(enablecrtc, params))
593 result = BP_RESULT_OK;
594
595 return result;
596}
597
598/******************************************************************************
599 ******************************************************************************
600 **
601 ** DISPLAY PLL
602 **
603 ******************************************************************************
604 *****************************************************************************/
605
606
607
608/******************************************************************************
609 ******************************************************************************
610 **
611 ** EXTERNAL ENCODER CONTROL
612 **
613 ******************************************************************************
614 *****************************************************************************/
615
616static enum bp_result external_encoder_control_v3(
617 struct bios_parser *bp,
618 struct bp_external_encoder_control *cntl);
619
620static void init_external_encoder_control(
621 struct bios_parser *bp)
622{
623 switch (BIOS_CMD_TABLE_PARA_REVISION(externalencodercontrol)) {
624 case 3:
625 bp->cmd_tbl.external_encoder_control =
626 external_encoder_control_v3;
627 break;
628 default:
629 bp->cmd_tbl.external_encoder_control = NULL;
630 break;
631 }
632}
633
634static enum bp_result external_encoder_control_v3(
635 struct bios_parser *bp,
636 struct bp_external_encoder_control *cntl)
637{
638 /* TODO */
639 return BP_RESULT_OK;
640}
641
642/******************************************************************************
643 ******************************************************************************
644 **
645 ** ENABLE DISPLAY POWER GATING
646 **
647 ******************************************************************************
648 *****************************************************************************/
649
650static enum bp_result enable_disp_power_gating_v2_1(
651 struct bios_parser *bp,
652 enum controller_id crtc_id,
653 enum bp_pipe_control_action action);
654
655static void init_enable_disp_power_gating(
656 struct bios_parser *bp)
657{
658 switch (BIOS_CMD_TABLE_PARA_REVISION(enabledisppowergating)) {
659 case 1:
660 bp->cmd_tbl.enable_disp_power_gating =
661 enable_disp_power_gating_v2_1;
662 break;
663 default:
664 bp->cmd_tbl.enable_disp_power_gating = NULL;
665 break;
666 }
667}
668
669static enum bp_result enable_disp_power_gating_v2_1(
670 struct bios_parser *bp,
671 enum controller_id crtc_id,
672 enum bp_pipe_control_action action)
673{
674 enum bp_result result = BP_RESULT_FAILURE;
675
676
677 struct enable_disp_power_gating_ps_allocation ps = { { 0 } };
678 uint8_t atom_crtc_id;
679
680 if (bp->cmd_helper->controller_id_to_atom(crtc_id, &atom_crtc_id))
681 ps.param.disp_pipe_id = atom_crtc_id;
682 else
683 return BP_RESULT_BADINPUT;
684
685 ps.param.enable =
686 bp->cmd_helper->disp_power_gating_action_to_atom(action);
687
688 if (EXEC_BIOS_CMD_TABLE(enabledisppowergating, ps.param))
689 result = BP_RESULT_OK;
690
691 return result;
692}
693
694/******************************************************************************
695*******************************************************************************
696 **
697 ** SET DCE CLOCK
698 **
699*******************************************************************************
700*******************************************************************************/
701
702static enum bp_result set_dce_clock_v2_1(
703 struct bios_parser *bp,
704 struct bp_set_dce_clock_parameters *bp_params);
705
706static void init_set_dce_clock(struct bios_parser *bp)
707{
708 switch (BIOS_CMD_TABLE_PARA_REVISION(setdceclock)) {
709 case 1:
710 bp->cmd_tbl.set_dce_clock = set_dce_clock_v2_1;
711 break;
712 default:
713 bp->cmd_tbl.set_dce_clock = NULL;
714 break;
715 }
716}
717
718static enum bp_result set_dce_clock_v2_1(
719 struct bios_parser *bp,
720 struct bp_set_dce_clock_parameters *bp_params)
721{
722 enum bp_result result = BP_RESULT_FAILURE;
723
724 struct set_dce_clock_ps_allocation_v2_1 params;
725 uint32_t atom_pll_id;
726 uint32_t atom_clock_type;
727 const struct command_table_helper *cmd = bp->cmd_helper;
728
729 memset(&params, 0, sizeof(params));
730
731 if (!cmd->clock_source_id_to_atom(bp_params->pll_id, &atom_pll_id) ||
732 !cmd->dc_clock_type_to_atom(bp_params->clock_type,
733 &atom_clock_type))
734 return BP_RESULT_BADINPUT;
735
736 params.param.dceclksrc = atom_pll_id;
737 params.param.dceclktype = atom_clock_type;
738
739 if (bp_params->clock_type == DCECLOCK_TYPE_DPREFCLK) {
740 if (bp_params->flags.USE_GENLOCK_AS_SOURCE_FOR_DPREFCLK)
741 params.param.dceclkflag |=
742 DCE_CLOCK_FLAG_PLL_REFCLK_SRC_GENLK;
743
744 if (bp_params->flags.USE_PCIE_AS_SOURCE_FOR_DPREFCLK)
745 params.param.dceclkflag |=
746 DCE_CLOCK_FLAG_PLL_REFCLK_SRC_PCIE;
747
748 if (bp_params->flags.USE_XTALIN_AS_SOURCE_FOR_DPREFCLK)
749 params.param.dceclkflag |=
750 DCE_CLOCK_FLAG_PLL_REFCLK_SRC_XTALIN;
751
752 if (bp_params->flags.USE_GENERICA_AS_SOURCE_FOR_DPREFCLK)
753 params.param.dceclkflag |=
754 DCE_CLOCK_FLAG_PLL_REFCLK_SRC_GENERICA;
755 } else
756 /* only program clock frequency if display clock is used;
757 * VBIOS will program DPREFCLK
758 * We need to convert from KHz units into 10KHz units
759 */
760 params.param.dceclk_10khz = cpu_to_le32(
761 bp_params->target_clock_frequency / 10);
7fc6ff77
JL
762 dm_logger_write(bp->base.ctx->logger, LOG_BIOS,
763 "%s:target_clock_frequency = %d"\
ae79c310
HW
764 "clock_type = %d \n", __func__,\
765 bp_params->target_clock_frequency,\
766 bp_params->clock_type);
767
768 if (EXEC_BIOS_CMD_TABLE(setdceclock, params)) {
769 /* Convert from 10KHz units back to KHz */
770 bp_params->target_clock_frequency = le32_to_cpu(
771 params.param.dceclk_10khz) * 10;
772 result = BP_RESULT_OK;
773 }
774
775 return result;
776}
777
778
779/******************************************************************************
780 ******************************************************************************
781 **
782 ** GET SMU CLOCK INFO
783 **
784 ******************************************************************************
785 *****************************************************************************/
786
787static unsigned int get_smu_clock_info_v3_1(struct bios_parser *bp);
788
789static void init_get_smu_clock_info(struct bios_parser *bp)
790{
791 /* TODO add switch for table vrsion */
792 bp->cmd_tbl.get_smu_clock_info = get_smu_clock_info_v3_1;
793
794}
795
796static unsigned int get_smu_clock_info_v3_1(struct bios_parser *bp)
797{
798 struct atom_get_smu_clock_info_parameters_v3_1 smu_input = {0};
799 struct atom_get_smu_clock_info_output_parameters_v3_1 smu_output;
800
801 smu_input.command = GET_SMU_CLOCK_INFO_V3_1_GET_PLLVCO_FREQ;
802
803 /* Get Specific Clock */
804 if (EXEC_BIOS_CMD_TABLE(getsmuclockinfo, smu_input)) {
805 memmove(&smu_output, &smu_input, sizeof(
806 struct atom_get_smu_clock_info_parameters_v3_1));
807 return smu_output.atom_smu_outputclkfreq.syspllvcofreq_10khz;
808 }
809
810 return 0;
811}
812