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
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
bios_cmd_table_para_revision(void * dev,uint32_t index)66 static 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 ** D I G E N C O D E R C O N T R O L
84 **
85 ******************************************************************************
86 *****************************************************************************/
87
88 static enum bp_result encoder_control_digx_v1_5(
89 struct bios_parser *bp,
90 struct bp_encoder_control *cntl);
91
92 static enum bp_result encoder_control_fallback(
93 struct bios_parser *bp,
94 struct bp_encoder_control *cntl);
95
init_dig_encoder_control(struct bios_parser * bp)96 static 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
encoder_control_dmcub(struct dc_dmub_srv * dmcub,struct dig_encoder_stream_setup_parameters_v1_5 * dig)112 static 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
encoder_control_digx_v1_5(struct bios_parser * bp,struct bp_encoder_control * cntl)133 static 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
encoder_control_fallback(struct bios_parser * bp,struct bp_encoder_control * cntl)197 static 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 ** TRANSMITTER CONTROL
213 **
214 ******************************************************************************
215 *****************************************************************************/
216
217 static enum bp_result transmitter_control_v1_6(
218 struct bios_parser *bp,
219 struct bp_transmitter_control *cntl);
220
221 static enum bp_result transmitter_control_v1_7(
222 struct bios_parser *bp,
223 struct bp_transmitter_control *cntl);
224
225 static enum bp_result transmitter_control_fallback(
226 struct bios_parser *bp,
227 struct bp_transmitter_control *cntl);
228
init_transmitter_control(struct bios_parser * bp)229 static 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
transmitter_control_dmcub(struct dc_dmub_srv * dmcub,struct dig_transmitter_control_parameters_v1_6 * dig)250 static 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
transmitter_control_v1_6(struct bios_parser * bp,struct bp_transmitter_control * cntl)271 static 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 /*color_depth not used any more, driver has deep color factor in the Phyclk*/
309 if (EXEC_BIOS_CMD_TABLE(dig1transmittercontrol, ps))
310 result = BP_RESULT_OK;
311 return result;
312 }
313
transmitter_control_dmcub_v1_7(struct dc_dmub_srv * dmcub,struct dmub_dig_transmitter_control_data_v1_7 * dig)314 static 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
transmitter_control_v1_7(struct bios_parser * bp,struct bp_transmitter_control * cntl)335 static 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 /*color_depth not used any more, driver has deep color factor in the Phyclk*/
372 if (EXEC_BIOS_CMD_TABLE(dig1transmittercontrol, dig_v1_7))
373 result = BP_RESULT_OK;
374 return result;
375 }
376
transmitter_control_fallback(struct bios_parser * bp,struct bp_transmitter_control * cntl)377 static 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 ** SET PIXEL CLOCK
393 **
394 ******************************************************************************
395 *****************************************************************************/
396
397 static enum bp_result set_pixel_clock_v7(
398 struct bios_parser *bp,
399 struct bp_pixel_clock_parameters *bp_params);
400
401 static enum bp_result set_pixel_clock_fallback(
402 struct bios_parser *bp,
403 struct bp_pixel_clock_parameters *bp_params);
404
init_set_pixel_clock(struct bios_parser * bp)405 static 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
set_pixel_clock_dmcub(struct dc_dmub_srv * dmcub,struct set_pixel_clock_parameter_v1_7 * clk)419 static 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
set_pixel_clock_v7(struct bios_parser * bp,struct bp_pixel_clock_parameters * bp_params)439 static 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 /* Note: VBIOS still wants to use ucCRTC name which is now
454 * 1 byte in ULONG
455 *typedef struct _CRTC_PIXEL_CLOCK_FREQ
456 *{
457 * target the pixel clock to drive the CRTC timing.
458 * ULONG ulPixelClock:24;
459 * 0 means disable PPLL/DCPLL. Expanded to 24 bits comparing to
460 * previous version.
461 * ATOM_CRTC1~6, indicate the CRTC controller to
462 * ULONG ucCRTC:8;
463 * drive the pixel clock. not used for DCPLL case.
464 *}CRTC_PIXEL_CLOCK_FREQ;
465 *union
466 *{
467 * pixel clock and CRTC id frequency
468 * CRTC_PIXEL_CLOCK_FREQ ulCrtcPclkFreq;
469 * ULONG ulDispEngClkFreq; dispclk frequency
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
set_pixel_clock_fallback(struct bios_parser * bp,struct bp_pixel_clock_parameters * bp_params)525 static 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 ** SET CRTC TIMING
541 **
542 ******************************************************************************
543 *****************************************************************************/
544
545 static enum bp_result set_crtc_using_dtd_timing_v3(
546 struct bios_parser *bp,
547 struct bp_hw_crtc_timing_parameters *bp_params);
548
init_set_crtc_timing(struct bios_parser * bp)549 static 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
set_crtc_using_dtd_timing_v3(struct bios_parser * bp,struct bp_hw_crtc_timing_parameters * bp_params)566 static 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 /* bios usH_Size wants h addressable size */
579 params.h_size = cpu_to_le16((uint16_t)bp_params->h_addressable);
580 /* bios usH_Blanking_Time wants borders included in blanking */
581 params.h_blanking_time =
582 cpu_to_le16((uint16_t)(bp_params->h_total -
583 bp_params->h_addressable));
584 /* bios usV_Size wants v addressable size */
585 params.v_size = cpu_to_le16((uint16_t)bp_params->v_addressable);
586 /* bios usV_Blanking_Time wants borders included in blanking */
587 params.v_blanking_time =
588 cpu_to_le16((uint16_t)(bp_params->v_total -
589 bp_params->v_addressable));
590 /* bios usHSyncOffset is the offset from the end of h addressable,
591 * our horizontalSyncStart is the offset from the beginning
592 * of h addressable
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 /* bios usHSyncOffset is the offset from the end of v addressable,
599 * our verticalSyncStart is the offset from the beginning of
600 * v addressable
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 /* we assume that overscan from original timing does not get bigger
608 * than 255
609 * we will program all the borders in the Set CRTC Overscan call below
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 /* original DAL code has this condition to apply this
628 * for non-TV/CV only
629 * due to complex MV testing for possible impact
630 * if ( pACParameters->signal != SignalType_YPbPr &&
631 * pACParameters->signal != SignalType_Composite &&
632 * pACParameters->signal != SignalType_SVideo)
633 */
634 {
635 /* HW will deduct 0.5 line from 2nd feild.
636 * i.e. for 1080i, it is 2 lines for 1st field,
637 * 2.5 lines for the 2nd feild. we need input as 5
638 * instead of 4.
639 * but it is 4 either from Edid data (spec CEA 861)
640 * or CEA timing table.
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); /* ATOM_DOUBLE_CLOCK_MODE */
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 ** ENABLE CRTC
661 **
662 ******************************************************************************
663 *****************************************************************************/
664
665 static enum bp_result enable_crtc_v1(
666 struct bios_parser *bp,
667 enum controller_id controller_id,
668 bool enable);
669
init_enable_crtc(struct bios_parser * bp)670 static 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
enable_crtc_v1(struct bios_parser * bp,enum controller_id controller_id,bool enable)684 static 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 ** DISPLAY PLL
713 **
714 ******************************************************************************
715 *****************************************************************************/
716
717
718
719 /******************************************************************************
720 ******************************************************************************
721 **
722 ** EXTERNAL ENCODER CONTROL
723 **
724 ******************************************************************************
725 *****************************************************************************/
726
727 static enum bp_result external_encoder_control_v3(
728 struct bios_parser *bp,
729 struct bp_external_encoder_control *cntl);
730
init_external_encoder_control(struct bios_parser * bp)731 static 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
external_encoder_control_v3(struct bios_parser * bp,struct bp_external_encoder_control * cntl)745 static enum bp_result external_encoder_control_v3(
746 struct bios_parser *bp,
747 struct bp_external_encoder_control *cntl)
748 {
749 /* TODO */
750 return BP_RESULT_OK;
751 }
752
753 /******************************************************************************
754 ******************************************************************************
755 **
756 ** ENABLE DISPLAY POWER GATING
757 **
758 ******************************************************************************
759 *****************************************************************************/
760
761 static 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
766 static 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
init_enable_disp_power_gating(struct bios_parser * bp)771 static 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
enable_disp_power_gating_dmcub(struct dc_dmub_srv * dmcub,struct enable_disp_power_gating_parameters_v2_1 * pwr)787 static 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
enable_disp_power_gating_v2_1(struct bios_parser * bp,enum controller_id crtc_id,enum bp_pipe_control_action action)808 static 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
enable_disp_power_gating_fallback(struct bios_parser * bp,enum controller_id crtc_id,enum bp_pipe_control_action action)840 static 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 ** SET DCE CLOCK
857 **
858 *******************************************************************************
859 *******************************************************************************/
860
861 static enum bp_result set_dce_clock_v2_1(
862 struct bios_parser *bp,
863 struct bp_set_dce_clock_parameters *bp_params);
864
init_set_dce_clock(struct bios_parser * bp)865 static 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
set_dce_clock_v2_1(struct bios_parser * bp,struct bp_set_dce_clock_parameters * bp_params)879 static 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 /* only program clock frequency if display clock is used;
918 * VBIOS will program DPREFCLK
919 * We need to convert from KHz units into 10KHz units
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 /* Convert from 10KHz units back to KHz */
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 ** GET SMU CLOCK INFO
943 **
944 ******************************************************************************
945 *****************************************************************************/
946
947 static unsigned int get_smu_clock_info_v3_1(struct bios_parser *bp, uint8_t id);
948
init_get_smu_clock_info(struct bios_parser * bp)949 static void init_get_smu_clock_info(struct bios_parser *bp)
950 {
951 /* TODO add switch for table vrsion */
952 bp->cmd_tbl.get_smu_clock_info = get_smu_clock_info_v3_1;
953
954 }
955
get_smu_clock_info_v3_1(struct bios_parser * bp,uint8_t id)956 static 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 /* Get Specific Clock */
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 ** LVTMA CONTROL
978 **
979 ******************************************************************************
980 *****************************************************************************/
981
982 static enum bp_result enable_lvtma_control(
983 struct bios_parser *bp,
984 uint8_t uc_pwr_on,
985 uint8_t panel_instance);
986
init_enable_lvtma_control(struct bios_parser * bp)987 static void init_enable_lvtma_control(struct bios_parser *bp)
988 {
989 /* TODO add switch for table vrsion */
990 bp->cmd_tbl.enable_lvtma_control = enable_lvtma_control;
991
992 }
993
enable_lvtma_control_dmcub(struct dc_dmub_srv * dmcub,uint8_t uc_pwr_on,uint8_t panel_instance)994 static 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
enable_lvtma_control(struct bios_parser * bp,uint8_t uc_pwr_on,uint8_t panel_instance)1017 static 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
dal_firmware_parser_init_cmd_tbl(struct bios_parser * bp)1034 void 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