treewide: remove redundant IS_ERR() before error code check
[linux/fpc-iii.git] / drivers / gpu / drm / amd / display / dc / bios / command_table2.c
blob2cb7a4288cb7840d943606254d7800294a52ea8a
1 /*
2 * Copyright 2012-15 Advanced Micro Devices, Inc.
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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.
22 * Authors: AMD
26 #include "dm_services.h"
28 #include "ObjectID.h"
30 #include "atomfirmware.h"
31 #include "atom.h"
32 #include "include/bios_parser_interface.h"
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"
40 #include "dc_dmub_srv.h"
41 #include "dc.h"
43 #define DC_LOGGER \
44 bp->base.ctx->logger
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))
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 *)&params) == 0)
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)
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))
66 static uint32_t bios_cmd_table_para_revision(void *dev,
67 uint32_t index)
69 struct amdgpu_device *adev = dev;
70 uint8_t frev, crev;
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;
80 /******************************************************************************
81 ******************************************************************************
83 ** D I G E N C O D E R C O N T R O L
85 ******************************************************************************
86 *****************************************************************************/
88 static enum bp_result encoder_control_digx_v1_5(
89 struct bios_parser *bp,
90 struct bp_encoder_control *cntl);
92 static void init_dig_encoder_control(struct bios_parser *bp)
94 uint32_t version =
95 BIOS_CMD_TABLE_PARA_REVISION(digxencodercontrol);
97 switch (version) {
98 case 5:
99 bp->cmd_tbl.dig_encoder_control = encoder_control_digx_v1_5;
100 break;
101 default:
102 dm_output_to_console("Don't have dig_encoder_control for v%d\n", version);
103 bp->cmd_tbl.dig_encoder_control = NULL;
104 break;
108 static void encoder_control_dmcub(
109 struct dc_dmub_srv *dmcub,
110 struct dig_encoder_stream_setup_parameters_v1_5 *dig)
112 struct dmub_rb_cmd_digx_encoder_control encoder_control = { 0 };
114 encoder_control.header.type = DMUB_CMD__VBIOS;
115 encoder_control.header.sub_type = DMUB_CMD__VBIOS_DIGX_ENCODER_CONTROL;
116 encoder_control.encoder_control.dig.stream_param = *dig;
118 dc_dmub_srv_cmd_queue(dmcub, &encoder_control.header);
119 dc_dmub_srv_cmd_execute(dmcub);
120 dc_dmub_srv_wait_idle(dmcub);
123 static enum bp_result encoder_control_digx_v1_5(
124 struct bios_parser *bp,
125 struct bp_encoder_control *cntl)
127 enum bp_result result = BP_RESULT_FAILURE;
128 struct dig_encoder_stream_setup_parameters_v1_5 params = {0};
130 params.digid = (uint8_t)(cntl->engine_id);
131 params.action = bp->cmd_helper->encoder_action_to_atom(cntl->action);
133 params.pclk_10khz = cntl->pixel_clock / 10;
134 params.digmode =
135 (uint8_t)(bp->cmd_helper->encoder_mode_bp_to_atom(
136 cntl->signal,
137 cntl->enable_dp_audio));
138 params.lanenum = (uint8_t)(cntl->lanes_number);
140 switch (cntl->color_depth) {
141 case COLOR_DEPTH_888:
142 params.bitpercolor = PANEL_8BIT_PER_COLOR;
143 break;
144 case COLOR_DEPTH_101010:
145 params.bitpercolor = PANEL_10BIT_PER_COLOR;
146 break;
147 case COLOR_DEPTH_121212:
148 params.bitpercolor = PANEL_12BIT_PER_COLOR;
149 break;
150 case COLOR_DEPTH_161616:
151 params.bitpercolor = PANEL_16BIT_PER_COLOR;
152 break;
153 default:
154 break;
157 if (cntl->signal == SIGNAL_TYPE_HDMI_TYPE_A)
158 switch (cntl->color_depth) {
159 case COLOR_DEPTH_101010:
160 params.pclk_10khz =
161 (params.pclk_10khz * 30) / 24;
162 break;
163 case COLOR_DEPTH_121212:
164 params.pclk_10khz =
165 (params.pclk_10khz * 36) / 24;
166 break;
167 case COLOR_DEPTH_161616:
168 params.pclk_10khz =
169 (params.pclk_10khz * 48) / 24;
170 break;
171 default:
172 break;
175 if (bp->base.ctx->dc->ctx->dmub_srv &&
176 bp->base.ctx->dc->debug.dmub_command_table) {
177 encoder_control_dmcub(bp->base.ctx->dmub_srv, &params);
178 return BP_RESULT_OK;
181 if (EXEC_BIOS_CMD_TABLE(digxencodercontrol, params))
182 result = BP_RESULT_OK;
184 return result;
187 /*****************************************************************************
188 ******************************************************************************
190 ** TRANSMITTER CONTROL
192 ******************************************************************************
193 *****************************************************************************/
195 static enum bp_result transmitter_control_v1_6(
196 struct bios_parser *bp,
197 struct bp_transmitter_control *cntl);
199 static void init_transmitter_control(struct bios_parser *bp)
201 uint8_t frev;
202 uint8_t crev;
204 if (BIOS_CMD_TABLE_REVISION(dig1transmittercontrol, frev, crev) == false)
205 BREAK_TO_DEBUGGER();
206 switch (crev) {
207 case 6:
208 bp->cmd_tbl.transmitter_control = transmitter_control_v1_6;
209 break;
210 default:
211 dm_output_to_console("Don't have transmitter_control for v%d\n", crev);
212 bp->cmd_tbl.transmitter_control = NULL;
213 break;
217 static void transmitter_control_dmcub(
218 struct dc_dmub_srv *dmcub,
219 struct dig_transmitter_control_parameters_v1_6 *dig)
221 struct dmub_rb_cmd_dig1_transmitter_control transmitter_control;
223 transmitter_control.header.type = DMUB_CMD__VBIOS;
224 transmitter_control.header.sub_type =
225 DMUB_CMD__VBIOS_DIG1_TRANSMITTER_CONTROL;
226 transmitter_control.transmitter_control.dig = *dig;
228 dc_dmub_srv_cmd_queue(dmcub, &transmitter_control.header);
229 dc_dmub_srv_cmd_execute(dmcub);
230 dc_dmub_srv_wait_idle(dmcub);
233 static enum bp_result transmitter_control_v1_6(
234 struct bios_parser *bp,
235 struct bp_transmitter_control *cntl)
237 enum bp_result result = BP_RESULT_FAILURE;
238 const struct command_table_helper *cmd = bp->cmd_helper;
239 struct dig_transmitter_control_ps_allocation_v1_6 ps = { { 0 } };
241 ps.param.phyid = cmd->phy_id_to_atom(cntl->transmitter);
242 ps.param.action = (uint8_t)cntl->action;
244 if (cntl->action == TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS)
245 ps.param.mode_laneset.dplaneset = (uint8_t)cntl->lane_settings;
246 else
247 ps.param.mode_laneset.digmode =
248 cmd->signal_type_to_atom_dig_mode(cntl->signal);
250 ps.param.lanenum = (uint8_t)cntl->lanes_number;
251 ps.param.hpdsel = cmd->hpd_sel_to_atom(cntl->hpd_sel);
252 ps.param.digfe_sel = cmd->dig_encoder_sel_to_atom(cntl->engine_id);
253 ps.param.connobj_id = (uint8_t)cntl->connector_obj_id.id;
254 ps.param.symclk_10khz = cntl->pixel_clock/10;
257 if (cntl->action == TRANSMITTER_CONTROL_ENABLE ||
258 cntl->action == TRANSMITTER_CONTROL_ACTIAVATE ||
259 cntl->action == TRANSMITTER_CONTROL_DEACTIVATE) {
260 DC_LOG_BIOS("%s:ps.param.symclk_10khz = %d\n",\
261 __func__, ps.param.symclk_10khz);
264 if (bp->base.ctx->dc->ctx->dmub_srv &&
265 bp->base.ctx->dc->debug.dmub_command_table) {
266 transmitter_control_dmcub(bp->base.ctx->dmub_srv, &ps.param);
267 return BP_RESULT_OK;
270 /*color_depth not used any more, driver has deep color factor in the Phyclk*/
271 if (EXEC_BIOS_CMD_TABLE(dig1transmittercontrol, ps))
272 result = BP_RESULT_OK;
273 return result;
276 /******************************************************************************
277 ******************************************************************************
279 ** SET PIXEL CLOCK
281 ******************************************************************************
282 *****************************************************************************/
284 static enum bp_result set_pixel_clock_v7(
285 struct bios_parser *bp,
286 struct bp_pixel_clock_parameters *bp_params);
288 static void init_set_pixel_clock(struct bios_parser *bp)
290 switch (BIOS_CMD_TABLE_PARA_REVISION(setpixelclock)) {
291 case 7:
292 bp->cmd_tbl.set_pixel_clock = set_pixel_clock_v7;
293 break;
294 default:
295 dm_output_to_console("Don't have set_pixel_clock for v%d\n",
296 BIOS_CMD_TABLE_PARA_REVISION(setpixelclock));
297 bp->cmd_tbl.set_pixel_clock = NULL;
298 break;
302 static void set_pixel_clock_dmcub(
303 struct dc_dmub_srv *dmcub,
304 struct set_pixel_clock_parameter_v1_7 *clk)
306 struct dmub_rb_cmd_set_pixel_clock pixel_clock = { 0 };
308 pixel_clock.header.type = DMUB_CMD__VBIOS;
309 pixel_clock.header.sub_type = DMUB_CMD__VBIOS_SET_PIXEL_CLOCK;
310 pixel_clock.pixel_clock.clk = *clk;
312 dc_dmub_srv_cmd_queue(dmcub, &pixel_clock.header);
313 dc_dmub_srv_cmd_execute(dmcub);
314 dc_dmub_srv_wait_idle(dmcub);
317 static enum bp_result set_pixel_clock_v7(
318 struct bios_parser *bp,
319 struct bp_pixel_clock_parameters *bp_params)
321 enum bp_result result = BP_RESULT_FAILURE;
322 struct set_pixel_clock_parameter_v1_7 clk;
323 uint8_t controller_id;
324 uint32_t pll_id;
326 memset(&clk, 0, sizeof(clk));
328 if (bp->cmd_helper->clock_source_id_to_atom(bp_params->pll_id, &pll_id)
329 && bp->cmd_helper->controller_id_to_atom(bp_params->
330 controller_id, &controller_id)) {
331 /* Note: VBIOS still wants to use ucCRTC name which is now
332 * 1 byte in ULONG
333 *typedef struct _CRTC_PIXEL_CLOCK_FREQ
335 * target the pixel clock to drive the CRTC timing.
336 * ULONG ulPixelClock:24;
337 * 0 means disable PPLL/DCPLL. Expanded to 24 bits comparing to
338 * previous version.
339 * ATOM_CRTC1~6, indicate the CRTC controller to
340 * ULONG ucCRTC:8;
341 * drive the pixel clock. not used for DCPLL case.
342 *}CRTC_PIXEL_CLOCK_FREQ;
343 *union
345 * pixel clock and CRTC id frequency
346 * CRTC_PIXEL_CLOCK_FREQ ulCrtcPclkFreq;
347 * ULONG ulDispEngClkFreq; dispclk frequency
350 clk.crtc_id = controller_id;
351 clk.pll_id = (uint8_t) pll_id;
352 clk.encoderobjid =
353 bp->cmd_helper->encoder_id_to_atom(
354 dal_graphics_object_id_get_encoder_id(
355 bp_params->encoder_object_id));
357 clk.encoder_mode = (uint8_t) bp->
358 cmd_helper->encoder_mode_bp_to_atom(
359 bp_params->signal_type, false);
361 clk.pixclk_100hz = cpu_to_le32(bp_params->target_pixel_clock_100hz);
363 clk.deep_color_ratio =
364 (uint8_t) bp->cmd_helper->
365 transmitter_color_depth_to_atom(
366 bp_params->color_depth);
368 DC_LOG_BIOS("%s:program display clock = %d, tg = %d, pll = %d, "\
369 "colorDepth = %d\n", __func__,
370 bp_params->target_pixel_clock_100hz, (int)controller_id,
371 pll_id, bp_params->color_depth);
373 if (bp_params->flags.FORCE_PROGRAMMING_OF_PLL)
374 clk.miscinfo |= PIXEL_CLOCK_V7_MISC_FORCE_PROG_PPLL;
376 if (bp_params->flags.PROGRAM_PHY_PLL_ONLY)
377 clk.miscinfo |= PIXEL_CLOCK_V7_MISC_PROG_PHYPLL;
379 if (bp_params->flags.SUPPORT_YUV_420)
380 clk.miscinfo |= PIXEL_CLOCK_V7_MISC_YUV420_MODE;
382 if (bp_params->flags.SET_XTALIN_REF_SRC)
383 clk.miscinfo |= PIXEL_CLOCK_V7_MISC_REF_DIV_SRC_XTALIN;
385 if (bp_params->flags.SET_GENLOCK_REF_DIV_SRC)
386 clk.miscinfo |= PIXEL_CLOCK_V7_MISC_REF_DIV_SRC_GENLK;
388 if (bp_params->signal_type == SIGNAL_TYPE_DVI_DUAL_LINK)
389 clk.miscinfo |= PIXEL_CLOCK_V7_MISC_DVI_DUALLINK_EN;
391 if (bp->base.ctx->dc->ctx->dmub_srv &&
392 bp->base.ctx->dc->debug.dmub_command_table) {
393 set_pixel_clock_dmcub(bp->base.ctx->dmub_srv, &clk);
394 return BP_RESULT_OK;
397 if (EXEC_BIOS_CMD_TABLE(setpixelclock, clk))
398 result = BP_RESULT_OK;
400 return result;
403 /******************************************************************************
404 ******************************************************************************
406 ** SET CRTC TIMING
408 ******************************************************************************
409 *****************************************************************************/
411 static enum bp_result set_crtc_using_dtd_timing_v3(
412 struct bios_parser *bp,
413 struct bp_hw_crtc_timing_parameters *bp_params);
415 static void init_set_crtc_timing(struct bios_parser *bp)
417 uint32_t dtd_version =
418 BIOS_CMD_TABLE_PARA_REVISION(setcrtc_usingdtdtiming);
420 switch (dtd_version) {
421 case 3:
422 bp->cmd_tbl.set_crtc_timing =
423 set_crtc_using_dtd_timing_v3;
424 break;
425 default:
426 dm_output_to_console("Don't have set_crtc_timing for v%d\n", dtd_version);
427 bp->cmd_tbl.set_crtc_timing = NULL;
428 break;
432 static enum bp_result set_crtc_using_dtd_timing_v3(
433 struct bios_parser *bp,
434 struct bp_hw_crtc_timing_parameters *bp_params)
436 enum bp_result result = BP_RESULT_FAILURE;
437 struct set_crtc_using_dtd_timing_parameters params = {0};
438 uint8_t atom_controller_id;
440 if (bp->cmd_helper->controller_id_to_atom(
441 bp_params->controller_id, &atom_controller_id))
442 params.crtc_id = atom_controller_id;
444 /* bios usH_Size wants h addressable size */
445 params.h_size = cpu_to_le16((uint16_t)bp_params->h_addressable);
446 /* bios usH_Blanking_Time wants borders included in blanking */
447 params.h_blanking_time =
448 cpu_to_le16((uint16_t)(bp_params->h_total -
449 bp_params->h_addressable));
450 /* bios usV_Size wants v addressable size */
451 params.v_size = cpu_to_le16((uint16_t)bp_params->v_addressable);
452 /* bios usV_Blanking_Time wants borders included in blanking */
453 params.v_blanking_time =
454 cpu_to_le16((uint16_t)(bp_params->v_total -
455 bp_params->v_addressable));
456 /* bios usHSyncOffset is the offset from the end of h addressable,
457 * our horizontalSyncStart is the offset from the beginning
458 * of h addressable
460 params.h_syncoffset =
461 cpu_to_le16((uint16_t)(bp_params->h_sync_start -
462 bp_params->h_addressable));
463 params.h_syncwidth = cpu_to_le16((uint16_t)bp_params->h_sync_width);
464 /* bios usHSyncOffset is the offset from the end of v addressable,
465 * our verticalSyncStart is the offset from the beginning of
466 * v addressable
468 params.v_syncoffset =
469 cpu_to_le16((uint16_t)(bp_params->v_sync_start -
470 bp_params->v_addressable));
471 params.v_syncwidth = cpu_to_le16((uint16_t)bp_params->v_sync_width);
473 /* we assume that overscan from original timing does not get bigger
474 * than 255
475 * we will program all the borders in the Set CRTC Overscan call below
478 if (bp_params->flags.HSYNC_POSITIVE_POLARITY == 0)
479 params.modemiscinfo =
480 cpu_to_le16(le16_to_cpu(params.modemiscinfo) |
481 ATOM_HSYNC_POLARITY);
483 if (bp_params->flags.VSYNC_POSITIVE_POLARITY == 0)
484 params.modemiscinfo =
485 cpu_to_le16(le16_to_cpu(params.modemiscinfo) |
486 ATOM_VSYNC_POLARITY);
488 if (bp_params->flags.INTERLACE) {
489 params.modemiscinfo =
490 cpu_to_le16(le16_to_cpu(params.modemiscinfo) |
491 ATOM_INTERLACE);
493 /* original DAL code has this condition to apply this
494 * for non-TV/CV only
495 * due to complex MV testing for possible impact
496 * if ( pACParameters->signal != SignalType_YPbPr &&
497 * pACParameters->signal != SignalType_Composite &&
498 * pACParameters->signal != SignalType_SVideo)
501 /* HW will deduct 0.5 line from 2nd feild.
502 * i.e. for 1080i, it is 2 lines for 1st field,
503 * 2.5 lines for the 2nd feild. we need input as 5
504 * instead of 4.
505 * but it is 4 either from Edid data (spec CEA 861)
506 * or CEA timing table.
508 params.v_syncoffset =
509 cpu_to_le16(le16_to_cpu(params.v_syncoffset) +
515 if (bp_params->flags.HORZ_COUNT_BY_TWO)
516 params.modemiscinfo =
517 cpu_to_le16(le16_to_cpu(params.modemiscinfo) |
518 0x100); /* ATOM_DOUBLE_CLOCK_MODE */
520 if (EXEC_BIOS_CMD_TABLE(setcrtc_usingdtdtiming, params))
521 result = BP_RESULT_OK;
523 return result;
526 /******************************************************************************
527 ******************************************************************************
529 ** ENABLE CRTC
531 ******************************************************************************
532 *****************************************************************************/
534 static enum bp_result enable_crtc_v1(
535 struct bios_parser *bp,
536 enum controller_id controller_id,
537 bool enable);
539 static void init_enable_crtc(struct bios_parser *bp)
541 switch (BIOS_CMD_TABLE_PARA_REVISION(enablecrtc)) {
542 case 1:
543 bp->cmd_tbl.enable_crtc = enable_crtc_v1;
544 break;
545 default:
546 dm_output_to_console("Don't have enable_crtc for v%d\n",
547 BIOS_CMD_TABLE_PARA_REVISION(enablecrtc));
548 bp->cmd_tbl.enable_crtc = NULL;
549 break;
553 static enum bp_result enable_crtc_v1(
554 struct bios_parser *bp,
555 enum controller_id controller_id,
556 bool enable)
558 bool result = BP_RESULT_FAILURE;
559 struct enable_crtc_parameters params = {0};
560 uint8_t id;
562 if (bp->cmd_helper->controller_id_to_atom(controller_id, &id))
563 params.crtc_id = id;
564 else
565 return BP_RESULT_BADINPUT;
567 if (enable)
568 params.enable = ATOM_ENABLE;
569 else
570 params.enable = ATOM_DISABLE;
572 if (EXEC_BIOS_CMD_TABLE(enablecrtc, params))
573 result = BP_RESULT_OK;
575 return result;
578 /******************************************************************************
579 ******************************************************************************
581 ** DISPLAY PLL
583 ******************************************************************************
584 *****************************************************************************/
588 /******************************************************************************
589 ******************************************************************************
591 ** EXTERNAL ENCODER CONTROL
593 ******************************************************************************
594 *****************************************************************************/
596 static enum bp_result external_encoder_control_v3(
597 struct bios_parser *bp,
598 struct bp_external_encoder_control *cntl);
600 static void init_external_encoder_control(
601 struct bios_parser *bp)
603 switch (BIOS_CMD_TABLE_PARA_REVISION(externalencodercontrol)) {
604 case 3:
605 bp->cmd_tbl.external_encoder_control =
606 external_encoder_control_v3;
607 break;
608 default:
609 bp->cmd_tbl.external_encoder_control = NULL;
610 break;
614 static enum bp_result external_encoder_control_v3(
615 struct bios_parser *bp,
616 struct bp_external_encoder_control *cntl)
618 /* TODO */
619 return BP_RESULT_OK;
622 /******************************************************************************
623 ******************************************************************************
625 ** ENABLE DISPLAY POWER GATING
627 ******************************************************************************
628 *****************************************************************************/
630 static enum bp_result enable_disp_power_gating_v2_1(
631 struct bios_parser *bp,
632 enum controller_id crtc_id,
633 enum bp_pipe_control_action action);
635 static void init_enable_disp_power_gating(
636 struct bios_parser *bp)
638 switch (BIOS_CMD_TABLE_PARA_REVISION(enabledisppowergating)) {
639 case 1:
640 bp->cmd_tbl.enable_disp_power_gating =
641 enable_disp_power_gating_v2_1;
642 break;
643 default:
644 dm_output_to_console("Don't enable_disp_power_gating enable_crtc for v%d\n",
645 BIOS_CMD_TABLE_PARA_REVISION(enabledisppowergating));
646 bp->cmd_tbl.enable_disp_power_gating = NULL;
647 break;
651 static void enable_disp_power_gating_dmcub(
652 struct dc_dmub_srv *dmcub,
653 struct enable_disp_power_gating_parameters_v2_1 *pwr)
655 struct dmub_rb_cmd_enable_disp_power_gating power_gating;
657 power_gating.header.type = DMUB_CMD__VBIOS;
658 power_gating.header.sub_type = DMUB_CMD__VBIOS_ENABLE_DISP_POWER_GATING;
659 power_gating.power_gating.pwr = *pwr;
661 dc_dmub_srv_cmd_queue(dmcub, &power_gating.header);
662 dc_dmub_srv_cmd_execute(dmcub);
663 dc_dmub_srv_wait_idle(dmcub);
666 static enum bp_result enable_disp_power_gating_v2_1(
667 struct bios_parser *bp,
668 enum controller_id crtc_id,
669 enum bp_pipe_control_action action)
671 enum bp_result result = BP_RESULT_FAILURE;
674 struct enable_disp_power_gating_ps_allocation ps = { { 0 } };
675 uint8_t atom_crtc_id;
677 if (bp->cmd_helper->controller_id_to_atom(crtc_id, &atom_crtc_id))
678 ps.param.disp_pipe_id = atom_crtc_id;
679 else
680 return BP_RESULT_BADINPUT;
682 ps.param.enable =
683 bp->cmd_helper->disp_power_gating_action_to_atom(action);
685 if (bp->base.ctx->dc->ctx->dmub_srv &&
686 bp->base.ctx->dc->debug.dmub_command_table) {
687 enable_disp_power_gating_dmcub(bp->base.ctx->dmub_srv,
688 &ps.param);
689 return BP_RESULT_OK;
692 if (EXEC_BIOS_CMD_TABLE(enabledisppowergating, ps.param))
693 result = BP_RESULT_OK;
695 return result;
698 /******************************************************************************
699 *******************************************************************************
701 ** SET DCE CLOCK
703 *******************************************************************************
704 *******************************************************************************/
706 static enum bp_result set_dce_clock_v2_1(
707 struct bios_parser *bp,
708 struct bp_set_dce_clock_parameters *bp_params);
710 static void init_set_dce_clock(struct bios_parser *bp)
712 switch (BIOS_CMD_TABLE_PARA_REVISION(setdceclock)) {
713 case 1:
714 bp->cmd_tbl.set_dce_clock = set_dce_clock_v2_1;
715 break;
716 default:
717 dm_output_to_console("Don't have set_dce_clock for v%d\n",
718 BIOS_CMD_TABLE_PARA_REVISION(setdceclock));
719 bp->cmd_tbl.set_dce_clock = NULL;
720 break;
724 static enum bp_result set_dce_clock_v2_1(
725 struct bios_parser *bp,
726 struct bp_set_dce_clock_parameters *bp_params)
728 enum bp_result result = BP_RESULT_FAILURE;
730 struct set_dce_clock_ps_allocation_v2_1 params;
731 uint32_t atom_pll_id;
732 uint32_t atom_clock_type;
733 const struct command_table_helper *cmd = bp->cmd_helper;
735 memset(&params, 0, sizeof(params));
737 if (!cmd->clock_source_id_to_atom(bp_params->pll_id, &atom_pll_id) ||
738 !cmd->dc_clock_type_to_atom(bp_params->clock_type,
739 &atom_clock_type))
740 return BP_RESULT_BADINPUT;
742 params.param.dceclksrc = atom_pll_id;
743 params.param.dceclktype = atom_clock_type;
745 if (bp_params->clock_type == DCECLOCK_TYPE_DPREFCLK) {
746 if (bp_params->flags.USE_GENLOCK_AS_SOURCE_FOR_DPREFCLK)
747 params.param.dceclkflag |=
748 DCE_CLOCK_FLAG_PLL_REFCLK_SRC_GENLK;
750 if (bp_params->flags.USE_PCIE_AS_SOURCE_FOR_DPREFCLK)
751 params.param.dceclkflag |=
752 DCE_CLOCK_FLAG_PLL_REFCLK_SRC_PCIE;
754 if (bp_params->flags.USE_XTALIN_AS_SOURCE_FOR_DPREFCLK)
755 params.param.dceclkflag |=
756 DCE_CLOCK_FLAG_PLL_REFCLK_SRC_XTALIN;
758 if (bp_params->flags.USE_GENERICA_AS_SOURCE_FOR_DPREFCLK)
759 params.param.dceclkflag |=
760 DCE_CLOCK_FLAG_PLL_REFCLK_SRC_GENERICA;
761 } else
762 /* only program clock frequency if display clock is used;
763 * VBIOS will program DPREFCLK
764 * We need to convert from KHz units into 10KHz units
766 params.param.dceclk_10khz = cpu_to_le32(
767 bp_params->target_clock_frequency / 10);
768 DC_LOG_BIOS("%s:target_clock_frequency = %d"\
769 "clock_type = %d \n", __func__,\
770 bp_params->target_clock_frequency,\
771 bp_params->clock_type);
773 if (EXEC_BIOS_CMD_TABLE(setdceclock, params)) {
774 /* Convert from 10KHz units back to KHz */
775 bp_params->target_clock_frequency = le32_to_cpu(
776 params.param.dceclk_10khz) * 10;
777 result = BP_RESULT_OK;
780 return result;
784 /******************************************************************************
785 ******************************************************************************
787 ** GET SMU CLOCK INFO
789 ******************************************************************************
790 *****************************************************************************/
792 static unsigned int get_smu_clock_info_v3_1(struct bios_parser *bp, uint8_t id);
794 static void init_get_smu_clock_info(struct bios_parser *bp)
796 /* TODO add switch for table vrsion */
797 bp->cmd_tbl.get_smu_clock_info = get_smu_clock_info_v3_1;
801 static unsigned int get_smu_clock_info_v3_1(struct bios_parser *bp, uint8_t id)
803 struct atom_get_smu_clock_info_parameters_v3_1 smu_input = {0};
804 struct atom_get_smu_clock_info_output_parameters_v3_1 smu_output;
806 smu_input.command = GET_SMU_CLOCK_INFO_V3_1_GET_PLLVCO_FREQ;
807 smu_input.syspll_id = id;
809 /* Get Specific Clock */
810 if (EXEC_BIOS_CMD_TABLE(getsmuclockinfo, smu_input)) {
811 memmove(&smu_output, &smu_input, sizeof(
812 struct atom_get_smu_clock_info_parameters_v3_1));
813 return smu_output.atom_smu_outputclkfreq.syspllvcofreq_10khz;
816 return 0;
819 void dal_firmware_parser_init_cmd_tbl(struct bios_parser *bp)
821 init_dig_encoder_control(bp);
822 init_transmitter_control(bp);
823 init_set_pixel_clock(bp);
825 init_set_crtc_timing(bp);
827 init_enable_crtc(bp);
829 init_external_encoder_control(bp);
830 init_enable_disp_power_gating(bp);
831 init_set_dce_clock(bp);
832 init_get_smu_clock_info(bp);