xref: /netbsd-src/sys/external/bsd/drm2/dist/drm/amd/display/dc/bios/amdgpu_command_table2.c (revision 41ec02673d281bbb3d38e6c78504ce6e30c228c1)
1 /*	$NetBSD: amdgpu_command_table2.c,v 1.2 2021/12/18 23:45:00 riastradh Exp $	*/
2 
3 /*
4  * Copyright 2012-15 Advanced Micro Devices, Inc.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22  * OTHER DEALINGS IN THE SOFTWARE.
23  *
24  * Authors: AMD
25  *
26  */
27 
28 #include <sys/cdefs.h>
29 __KERNEL_RCSID(0, "$NetBSD: amdgpu_command_table2.c,v 1.2 2021/12/18 23:45:00 riastradh Exp $");
30 
31 #include "dm_services.h"
32 
33 #include "ObjectID.h"
34 
35 #include "atomfirmware.h"
36 #include "atom.h"
37 #include "include/bios_parser_interface.h"
38 
39 #include "command_table2.h"
40 #include "command_table_helper2.h"
41 #include "bios_parser_helper.h"
42 #include "bios_parser_types_internal2.h"
43 #include "amdgpu.h"
44 
45 #include "dc_dmub_srv.h"
46 #include "dc.h"
47 
48 #define DC_LOGGER \
49 	bp->base.ctx->logger
50 
51 #define GET_INDEX_INTO_MASTER_TABLE(MasterOrData, FieldName)\
52 	(((char *)(&((\
53 		struct atom_master_list_of_##MasterOrData##_functions_v2_1 *)0)\
54 		->FieldName)-(char *)0)/sizeof(uint16_t))
55 
56 #define EXEC_BIOS_CMD_TABLE(fname, params)\
57 	(amdgpu_atom_execute_table(((struct amdgpu_device *)bp->base.ctx->driver_context)->mode_info.atom_context, \
58 		GET_INDEX_INTO_MASTER_TABLE(command, fname), \
59 		(uint32_t *)&params) == 0)
60 
61 #define BIOS_CMD_TABLE_REVISION(fname, frev, crev)\
62 	amdgpu_atom_parse_cmd_header(((struct amdgpu_device *)bp->base.ctx->driver_context)->mode_info.atom_context, \
63 		GET_INDEX_INTO_MASTER_TABLE(command, fname), &frev, &crev)
64 
65 #define BIOS_CMD_TABLE_PARA_REVISION(fname)\
66 	bios_cmd_table_para_revision(bp->base.ctx->driver_context, \
67 			GET_INDEX_INTO_MASTER_TABLE(command, fname))
68 
69 
70 
bios_cmd_table_para_revision(void * dev,uint32_t index)71 static uint32_t bios_cmd_table_para_revision(void *dev,
72 					     uint32_t index)
73 {
74 	struct amdgpu_device *adev = dev;
75 	uint8_t frev, crev;
76 
77 	if (amdgpu_atom_parse_cmd_header(adev->mode_info.atom_context,
78 					index,
79 					&frev, &crev))
80 		return crev;
81 	else
82 		return 0;
83 }
84 
85 /******************************************************************************
86  ******************************************************************************
87  **
88  **                  D I G E N C O D E R C O N T R O L
89  **
90  ******************************************************************************
91  *****************************************************************************/
92 
93 static enum bp_result encoder_control_digx_v1_5(
94 	struct bios_parser *bp,
95 	struct bp_encoder_control *cntl);
96 
97 static enum bp_result encoder_control_fallback(
98 	struct bios_parser *bp,
99 	struct bp_encoder_control *cntl);
100 
init_dig_encoder_control(struct bios_parser * bp)101 static void init_dig_encoder_control(struct bios_parser *bp)
102 {
103 	uint32_t version =
104 		BIOS_CMD_TABLE_PARA_REVISION(digxencodercontrol);
105 
106 	switch (version) {
107 	case 5:
108 		bp->cmd_tbl.dig_encoder_control = encoder_control_digx_v1_5;
109 		break;
110 	default:
111 		dm_output_to_console("Don't have dig_encoder_control for v%d\n", version);
112 		bp->cmd_tbl.dig_encoder_control = encoder_control_fallback;
113 		break;
114 	}
115 }
116 
encoder_control_dmcub(struct dc_dmub_srv * dmcub,struct dig_encoder_stream_setup_parameters_v1_5 * dig)117 static void encoder_control_dmcub(
118 		struct dc_dmub_srv *dmcub,
119 		struct dig_encoder_stream_setup_parameters_v1_5 *dig)
120 {
121 	struct dmub_rb_cmd_digx_encoder_control encoder_control = { 0 };
122 
123 	encoder_control.header.type = DMUB_CMD__VBIOS;
124 	encoder_control.header.sub_type = DMUB_CMD__VBIOS_DIGX_ENCODER_CONTROL;
125 	encoder_control.encoder_control.dig.stream_param = *dig;
126 
127 	dc_dmub_srv_cmd_queue(dmcub, &encoder_control.header);
128 	dc_dmub_srv_cmd_execute(dmcub);
129 	dc_dmub_srv_wait_idle(dmcub);
130 }
131 
encoder_control_digx_v1_5(struct bios_parser * bp,struct bp_encoder_control * cntl)132 static enum bp_result encoder_control_digx_v1_5(
133 	struct bios_parser *bp,
134 	struct bp_encoder_control *cntl)
135 {
136 	enum bp_result result = BP_RESULT_FAILURE;
137 	struct dig_encoder_stream_setup_parameters_v1_5 params = {0};
138 
139 	params.digid = (uint8_t)(cntl->engine_id);
140 	params.action = bp->cmd_helper->encoder_action_to_atom(cntl->action);
141 
142 	params.pclk_10khz = cntl->pixel_clock / 10;
143 	params.digmode =
144 			(uint8_t)(bp->cmd_helper->encoder_mode_bp_to_atom(
145 					cntl->signal,
146 					cntl->enable_dp_audio));
147 	params.lanenum = (uint8_t)(cntl->lanes_number);
148 
149 	switch (cntl->color_depth) {
150 	case COLOR_DEPTH_888:
151 		params.bitpercolor = PANEL_8BIT_PER_COLOR;
152 		break;
153 	case COLOR_DEPTH_101010:
154 		params.bitpercolor = PANEL_10BIT_PER_COLOR;
155 		break;
156 	case COLOR_DEPTH_121212:
157 		params.bitpercolor = PANEL_12BIT_PER_COLOR;
158 		break;
159 	case COLOR_DEPTH_161616:
160 		params.bitpercolor = PANEL_16BIT_PER_COLOR;
161 		break;
162 	default:
163 		break;
164 	}
165 
166 	if (cntl->signal == SIGNAL_TYPE_HDMI_TYPE_A)
167 		switch (cntl->color_depth) {
168 		case COLOR_DEPTH_101010:
169 			params.pclk_10khz =
170 				(params.pclk_10khz * 30) / 24;
171 			break;
172 		case COLOR_DEPTH_121212:
173 			params.pclk_10khz =
174 				(params.pclk_10khz * 36) / 24;
175 			break;
176 		case COLOR_DEPTH_161616:
177 			params.pclk_10khz =
178 				(params.pclk_10khz * 48) / 24;
179 			break;
180 		default:
181 			break;
182 		}
183 
184 	if (bp->base.ctx->dc->ctx->dmub_srv &&
185 	    bp->base.ctx->dc->debug.dmub_command_table) {
186 		encoder_control_dmcub(bp->base.ctx->dmub_srv, &params);
187 		return BP_RESULT_OK;
188 	}
189 
190 	if (EXEC_BIOS_CMD_TABLE(digxencodercontrol, params))
191 		result = BP_RESULT_OK;
192 
193 	return result;
194 }
195 
encoder_control_fallback(struct bios_parser * bp,struct bp_encoder_control * cntl)196 static enum bp_result encoder_control_fallback(
197 	struct bios_parser *bp,
198 	struct bp_encoder_control *cntl)
199 {
200 	if (bp->base.ctx->dc->ctx->dmub_srv &&
201 	    bp->base.ctx->dc->debug.dmub_command_table) {
202 		return encoder_control_digx_v1_5(bp, cntl);
203 	}
204 
205 	return BP_RESULT_FAILURE;
206 }
207 
208 /*****************************************************************************
209  ******************************************************************************
210  **
211  **                  TRANSMITTER CONTROL
212  **
213  ******************************************************************************
214  *****************************************************************************/
215 
216 static enum bp_result transmitter_control_v1_6(
217 	struct bios_parser *bp,
218 	struct bp_transmitter_control *cntl);
219 
220 static enum bp_result transmitter_control_fallback(
221 	struct bios_parser *bp,
222 	struct bp_transmitter_control *cntl);
223 
init_transmitter_control(struct bios_parser * bp)224 static void init_transmitter_control(struct bios_parser *bp)
225 {
226 	uint8_t frev;
227 	uint8_t crev;
228 
229 	if (BIOS_CMD_TABLE_REVISION(dig1transmittercontrol, frev, crev) == false)
230 		BREAK_TO_DEBUGGER();
231 	switch (crev) {
232 	case 6:
233 		bp->cmd_tbl.transmitter_control = transmitter_control_v1_6;
234 		break;
235 	default:
236 		dm_output_to_console("Don't have transmitter_control for v%d\n", crev);
237 		bp->cmd_tbl.transmitter_control = transmitter_control_fallback;
238 		break;
239 	}
240 }
241 
transmitter_control_dmcub(struct dc_dmub_srv * dmcub,struct dig_transmitter_control_parameters_v1_6 * dig)242 static void transmitter_control_dmcub(
243 		struct dc_dmub_srv *dmcub,
244 		struct dig_transmitter_control_parameters_v1_6 *dig)
245 {
246 	struct dmub_rb_cmd_dig1_transmitter_control transmitter_control;
247 
248 	transmitter_control.header.type = DMUB_CMD__VBIOS;
249 	transmitter_control.header.sub_type =
250 		DMUB_CMD__VBIOS_DIG1_TRANSMITTER_CONTROL;
251 	transmitter_control.transmitter_control.dig = *dig;
252 
253 	dc_dmub_srv_cmd_queue(dmcub, &transmitter_control.header);
254 	dc_dmub_srv_cmd_execute(dmcub);
255 	dc_dmub_srv_wait_idle(dmcub);
256 }
257 
transmitter_control_v1_6(struct bios_parser * bp,struct bp_transmitter_control * cntl)258 static enum bp_result transmitter_control_v1_6(
259 	struct bios_parser *bp,
260 	struct bp_transmitter_control *cntl)
261 {
262 	enum bp_result result = BP_RESULT_FAILURE;
263 	const struct command_table_helper *cmd = bp->cmd_helper;
264 	struct dig_transmitter_control_ps_allocation_v1_6 ps = { { 0 } };
265 
266 	ps.param.phyid = cmd->phy_id_to_atom(cntl->transmitter);
267 	ps.param.action = (uint8_t)cntl->action;
268 
269 	if (cntl->action == TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS)
270 		ps.param.mode_laneset.dplaneset = (uint8_t)cntl->lane_settings;
271 	else
272 		ps.param.mode_laneset.digmode =
273 				cmd->signal_type_to_atom_dig_mode(cntl->signal);
274 
275 	ps.param.lanenum = (uint8_t)cntl->lanes_number;
276 	ps.param.hpdsel = cmd->hpd_sel_to_atom(cntl->hpd_sel);
277 	ps.param.digfe_sel = cmd->dig_encoder_sel_to_atom(cntl->engine_id);
278 	ps.param.connobj_id = (uint8_t)cntl->connector_obj_id.id;
279 	ps.param.symclk_10khz = cntl->pixel_clock/10;
280 
281 
282 	if (cntl->action == TRANSMITTER_CONTROL_ENABLE ||
283 		cntl->action == TRANSMITTER_CONTROL_ACTIAVATE ||
284 		cntl->action == TRANSMITTER_CONTROL_DEACTIVATE) {
285 		DC_LOG_BIOS("%s:ps.param.symclk_10khz = %d\n",\
286 		__func__, ps.param.symclk_10khz);
287 	}
288 
289 	if (bp->base.ctx->dc->ctx->dmub_srv &&
290 	    bp->base.ctx->dc->debug.dmub_command_table) {
291 		transmitter_control_dmcub(bp->base.ctx->dmub_srv, &ps.param);
292 		return BP_RESULT_OK;
293 	}
294 
295 /*color_depth not used any more, driver has deep color factor in the Phyclk*/
296 	if (EXEC_BIOS_CMD_TABLE(dig1transmittercontrol, ps))
297 		result = BP_RESULT_OK;
298 	return result;
299 }
300 
transmitter_control_fallback(struct bios_parser * bp,struct bp_transmitter_control * cntl)301 static enum bp_result transmitter_control_fallback(
302 	struct bios_parser *bp,
303 	struct bp_transmitter_control *cntl)
304 {
305 	if (bp->base.ctx->dc->ctx->dmub_srv &&
306 	    bp->base.ctx->dc->debug.dmub_command_table) {
307 		return transmitter_control_v1_6(bp, cntl);
308 	}
309 
310 	return BP_RESULT_FAILURE;
311 }
312 
313 /******************************************************************************
314  ******************************************************************************
315  **
316  **                  SET PIXEL CLOCK
317  **
318  ******************************************************************************
319  *****************************************************************************/
320 
321 static enum bp_result set_pixel_clock_v7(
322 	struct bios_parser *bp,
323 	struct bp_pixel_clock_parameters *bp_params);
324 
325 static enum bp_result set_pixel_clock_fallback(
326 	struct bios_parser *bp,
327 	struct bp_pixel_clock_parameters *bp_params);
328 
init_set_pixel_clock(struct bios_parser * bp)329 static void init_set_pixel_clock(struct bios_parser *bp)
330 {
331 	switch (BIOS_CMD_TABLE_PARA_REVISION(setpixelclock)) {
332 	case 7:
333 		bp->cmd_tbl.set_pixel_clock = set_pixel_clock_v7;
334 		break;
335 	default:
336 		dm_output_to_console("Don't have set_pixel_clock for v%d\n",
337 			 BIOS_CMD_TABLE_PARA_REVISION(setpixelclock));
338 		bp->cmd_tbl.set_pixel_clock = set_pixel_clock_fallback;
339 		break;
340 	}
341 }
342 
set_pixel_clock_dmcub(struct dc_dmub_srv * dmcub,struct set_pixel_clock_parameter_v1_7 * clk)343 static void set_pixel_clock_dmcub(
344 		struct dc_dmub_srv *dmcub,
345 		struct set_pixel_clock_parameter_v1_7 *clk)
346 {
347 	struct dmub_rb_cmd_set_pixel_clock pixel_clock = { 0 };
348 
349 	pixel_clock.header.type = DMUB_CMD__VBIOS;
350 	pixel_clock.header.sub_type = DMUB_CMD__VBIOS_SET_PIXEL_CLOCK;
351 	pixel_clock.pixel_clock.clk = *clk;
352 
353 	dc_dmub_srv_cmd_queue(dmcub, &pixel_clock.header);
354 	dc_dmub_srv_cmd_execute(dmcub);
355 	dc_dmub_srv_wait_idle(dmcub);
356 }
357 
set_pixel_clock_v7(struct bios_parser * bp,struct bp_pixel_clock_parameters * bp_params)358 static enum bp_result set_pixel_clock_v7(
359 	struct bios_parser *bp,
360 	struct bp_pixel_clock_parameters *bp_params)
361 {
362 	enum bp_result result = BP_RESULT_FAILURE;
363 	struct set_pixel_clock_parameter_v1_7 clk;
364 	uint8_t controller_id;
365 	uint32_t pll_id;
366 
367 	memset(&clk, 0, sizeof(clk));
368 
369 	if (bp->cmd_helper->clock_source_id_to_atom(bp_params->pll_id, &pll_id)
370 			&& bp->cmd_helper->controller_id_to_atom(bp_params->
371 					controller_id, &controller_id)) {
372 		/* Note: VBIOS still wants to use ucCRTC name which is now
373 		 * 1 byte in ULONG
374 		 *typedef struct _CRTC_PIXEL_CLOCK_FREQ
375 		 *{
376 		 * target the pixel clock to drive the CRTC timing.
377 		 * ULONG ulPixelClock:24;
378 		 * 0 means disable PPLL/DCPLL. Expanded to 24 bits comparing to
379 		 * previous version.
380 		 * ATOM_CRTC1~6, indicate the CRTC controller to
381 		 * ULONG ucCRTC:8;
382 		 * drive the pixel clock. not used for DCPLL case.
383 		 *}CRTC_PIXEL_CLOCK_FREQ;
384 		 *union
385 		 *{
386 		 * pixel clock and CRTC id frequency
387 		 * CRTC_PIXEL_CLOCK_FREQ ulCrtcPclkFreq;
388 		 * ULONG ulDispEngClkFreq; dispclk frequency
389 		 *};
390 		 */
391 		clk.crtc_id = controller_id;
392 		clk.pll_id = (uint8_t) pll_id;
393 		clk.encoderobjid =
394 			bp->cmd_helper->encoder_id_to_atom(
395 				dal_graphics_object_id_get_encoder_id(
396 					bp_params->encoder_object_id));
397 
398 		clk.encoder_mode = (uint8_t) bp->
399 			cmd_helper->encoder_mode_bp_to_atom(
400 				bp_params->signal_type, false);
401 
402 		clk.pixclk_100hz = cpu_to_le32(bp_params->target_pixel_clock_100hz);
403 
404 		clk.deep_color_ratio =
405 			(uint8_t) bp->cmd_helper->
406 				transmitter_color_depth_to_atom(
407 					bp_params->color_depth);
408 
409 		DC_LOG_BIOS("%s:program display clock = %d, tg = %d, pll = %d, "\
410 				"colorDepth = %d\n", __func__,
411 				bp_params->target_pixel_clock_100hz, (int)controller_id,
412 				pll_id, bp_params->color_depth);
413 
414 		if (bp_params->flags.FORCE_PROGRAMMING_OF_PLL)
415 			clk.miscinfo |= PIXEL_CLOCK_V7_MISC_FORCE_PROG_PPLL;
416 
417 		if (bp_params->flags.PROGRAM_PHY_PLL_ONLY)
418 			clk.miscinfo |= PIXEL_CLOCK_V7_MISC_PROG_PHYPLL;
419 
420 		if (bp_params->flags.SUPPORT_YUV_420)
421 			clk.miscinfo |= PIXEL_CLOCK_V7_MISC_YUV420_MODE;
422 
423 		if (bp_params->flags.SET_XTALIN_REF_SRC)
424 			clk.miscinfo |= PIXEL_CLOCK_V7_MISC_REF_DIV_SRC_XTALIN;
425 
426 		if (bp_params->flags.SET_GENLOCK_REF_DIV_SRC)
427 			clk.miscinfo |= PIXEL_CLOCK_V7_MISC_REF_DIV_SRC_GENLK;
428 
429 		if (bp_params->signal_type == SIGNAL_TYPE_DVI_DUAL_LINK)
430 			clk.miscinfo |= PIXEL_CLOCK_V7_MISC_DVI_DUALLINK_EN;
431 
432 		if (bp->base.ctx->dc->ctx->dmub_srv &&
433 		    bp->base.ctx->dc->debug.dmub_command_table) {
434 			set_pixel_clock_dmcub(bp->base.ctx->dmub_srv, &clk);
435 			return BP_RESULT_OK;
436 		}
437 
438 		if (EXEC_BIOS_CMD_TABLE(setpixelclock, clk))
439 			result = BP_RESULT_OK;
440 	}
441 	return result;
442 }
443 
set_pixel_clock_fallback(struct bios_parser * bp,struct bp_pixel_clock_parameters * bp_params)444 static enum bp_result set_pixel_clock_fallback(
445 	struct bios_parser *bp,
446 	struct bp_pixel_clock_parameters *bp_params)
447 {
448 	if (bp->base.ctx->dc->ctx->dmub_srv &&
449 	    bp->base.ctx->dc->debug.dmub_command_table) {
450 		return set_pixel_clock_v7(bp, bp_params);
451 	}
452 
453 	return BP_RESULT_FAILURE;
454 }
455 
456 /******************************************************************************
457  ******************************************************************************
458  **
459  **                  SET CRTC TIMING
460  **
461  ******************************************************************************
462  *****************************************************************************/
463 
464 static enum bp_result set_crtc_using_dtd_timing_v3(
465 	struct bios_parser *bp,
466 	struct bp_hw_crtc_timing_parameters *bp_params);
467 
init_set_crtc_timing(struct bios_parser * bp)468 static void init_set_crtc_timing(struct bios_parser *bp)
469 {
470 	uint32_t dtd_version =
471 			BIOS_CMD_TABLE_PARA_REVISION(setcrtc_usingdtdtiming);
472 
473 	switch (dtd_version) {
474 	case 3:
475 		bp->cmd_tbl.set_crtc_timing =
476 			set_crtc_using_dtd_timing_v3;
477 		break;
478 	default:
479 		dm_output_to_console("Don't have set_crtc_timing for v%d\n", dtd_version);
480 		bp->cmd_tbl.set_crtc_timing = NULL;
481 		break;
482 	}
483 }
484 
set_crtc_using_dtd_timing_v3(struct bios_parser * bp,struct bp_hw_crtc_timing_parameters * bp_params)485 static enum bp_result set_crtc_using_dtd_timing_v3(
486 	struct bios_parser *bp,
487 	struct bp_hw_crtc_timing_parameters *bp_params)
488 {
489 	enum bp_result result = BP_RESULT_FAILURE;
490 	struct set_crtc_using_dtd_timing_parameters params = {0};
491 	uint8_t atom_controller_id;
492 
493 	if (bp->cmd_helper->controller_id_to_atom(
494 			bp_params->controller_id, &atom_controller_id))
495 		params.crtc_id = atom_controller_id;
496 
497 	/* bios usH_Size wants h addressable size */
498 	params.h_size = cpu_to_le16((uint16_t)bp_params->h_addressable);
499 	/* bios usH_Blanking_Time wants borders included in blanking */
500 	params.h_blanking_time =
501 			cpu_to_le16((uint16_t)(bp_params->h_total -
502 					bp_params->h_addressable));
503 	/* bios usV_Size wants v addressable size */
504 	params.v_size = cpu_to_le16((uint16_t)bp_params->v_addressable);
505 	/* bios usV_Blanking_Time wants borders included in blanking */
506 	params.v_blanking_time =
507 			cpu_to_le16((uint16_t)(bp_params->v_total -
508 					bp_params->v_addressable));
509 	/* bios usHSyncOffset is the offset from the end of h addressable,
510 	 * our horizontalSyncStart is the offset from the beginning
511 	 * of h addressable
512 	 */
513 	params.h_syncoffset =
514 			cpu_to_le16((uint16_t)(bp_params->h_sync_start -
515 					bp_params->h_addressable));
516 	params.h_syncwidth = cpu_to_le16((uint16_t)bp_params->h_sync_width);
517 	/* bios usHSyncOffset is the offset from the end of v addressable,
518 	 * our verticalSyncStart is the offset from the beginning of
519 	 * v addressable
520 	 */
521 	params.v_syncoffset =
522 			cpu_to_le16((uint16_t)(bp_params->v_sync_start -
523 					bp_params->v_addressable));
524 	params.v_syncwidth = cpu_to_le16((uint16_t)bp_params->v_sync_width);
525 
526 	/* we assume that overscan from original timing does not get bigger
527 	 * than 255
528 	 * we will program all the borders in the Set CRTC Overscan call below
529 	 */
530 
531 	if (bp_params->flags.HSYNC_POSITIVE_POLARITY == 0)
532 		params.modemiscinfo =
533 				cpu_to_le16(le16_to_cpu(params.modemiscinfo) |
534 						ATOM_HSYNC_POLARITY);
535 
536 	if (bp_params->flags.VSYNC_POSITIVE_POLARITY == 0)
537 		params.modemiscinfo =
538 				cpu_to_le16(le16_to_cpu(params.modemiscinfo) |
539 						ATOM_VSYNC_POLARITY);
540 
541 	if (bp_params->flags.INTERLACE)	{
542 		params.modemiscinfo =
543 				cpu_to_le16(le16_to_cpu(params.modemiscinfo) |
544 						ATOM_INTERLACE);
545 
546 		/* original DAL code has this condition to apply this
547 		 * for non-TV/CV only
548 		 * due to complex MV testing for possible impact
549 		 * if ( pACParameters->signal != SignalType_YPbPr &&
550 		 *  pACParameters->signal != SignalType_Composite &&
551 		 *  pACParameters->signal != SignalType_SVideo)
552 		 */
553 		{
554 			/* HW will deduct 0.5 line from 2nd feild.
555 			 * i.e. for 1080i, it is 2 lines for 1st field,
556 			 * 2.5 lines for the 2nd feild. we need input as 5
557 			 * instead of 4.
558 			 * but it is 4 either from Edid data (spec CEA 861)
559 			 * or CEA timing table.
560 			 */
561 			params.v_syncoffset =
562 				cpu_to_le16(le16_to_cpu(params.v_syncoffset) +
563 						1);
564 
565 		}
566 	}
567 
568 	if (bp_params->flags.HORZ_COUNT_BY_TWO)
569 		params.modemiscinfo =
570 			cpu_to_le16(le16_to_cpu(params.modemiscinfo) |
571 					0x100); /* ATOM_DOUBLE_CLOCK_MODE */
572 
573 	if (EXEC_BIOS_CMD_TABLE(setcrtc_usingdtdtiming, params))
574 		result = BP_RESULT_OK;
575 
576 	return result;
577 }
578 
579 /******************************************************************************
580  ******************************************************************************
581  **
582  **                  ENABLE CRTC
583  **
584  ******************************************************************************
585  *****************************************************************************/
586 
587 static enum bp_result enable_crtc_v1(
588 	struct bios_parser *bp,
589 	enum controller_id controller_id,
590 	bool enable);
591 
init_enable_crtc(struct bios_parser * bp)592 static void init_enable_crtc(struct bios_parser *bp)
593 {
594 	switch (BIOS_CMD_TABLE_PARA_REVISION(enablecrtc)) {
595 	case 1:
596 		bp->cmd_tbl.enable_crtc = enable_crtc_v1;
597 		break;
598 	default:
599 		dm_output_to_console("Don't have enable_crtc for v%d\n",
600 			 BIOS_CMD_TABLE_PARA_REVISION(enablecrtc));
601 		bp->cmd_tbl.enable_crtc = NULL;
602 		break;
603 	}
604 }
605 
enable_crtc_v1(struct bios_parser * bp,enum controller_id controller_id,bool enable)606 static enum bp_result enable_crtc_v1(
607 	struct bios_parser *bp,
608 	enum controller_id controller_id,
609 	bool enable)
610 {
611 	bool result = BP_RESULT_FAILURE;
612 	struct enable_crtc_parameters params = {0};
613 	uint8_t id;
614 
615 	if (bp->cmd_helper->controller_id_to_atom(controller_id, &id))
616 		params.crtc_id = id;
617 	else
618 		return BP_RESULT_BADINPUT;
619 
620 	if (enable)
621 		params.enable = ATOM_ENABLE;
622 	else
623 		params.enable = ATOM_DISABLE;
624 
625 	if (EXEC_BIOS_CMD_TABLE(enablecrtc, params))
626 		result = BP_RESULT_OK;
627 
628 	return result;
629 }
630 
631 /******************************************************************************
632  ******************************************************************************
633  **
634  **                  DISPLAY PLL
635  **
636  ******************************************************************************
637  *****************************************************************************/
638 
639 
640 
641 /******************************************************************************
642  ******************************************************************************
643  **
644  **                  EXTERNAL ENCODER CONTROL
645  **
646  ******************************************************************************
647  *****************************************************************************/
648 
649 static enum bp_result external_encoder_control_v3(
650 	struct bios_parser *bp,
651 	struct bp_external_encoder_control *cntl);
652 
init_external_encoder_control(struct bios_parser * bp)653 static void init_external_encoder_control(
654 	struct bios_parser *bp)
655 {
656 	switch (BIOS_CMD_TABLE_PARA_REVISION(externalencodercontrol)) {
657 	case 3:
658 		bp->cmd_tbl.external_encoder_control =
659 				external_encoder_control_v3;
660 		break;
661 	default:
662 		bp->cmd_tbl.external_encoder_control = NULL;
663 		break;
664 	}
665 }
666 
external_encoder_control_v3(struct bios_parser * bp,struct bp_external_encoder_control * cntl)667 static enum bp_result external_encoder_control_v3(
668 	struct bios_parser *bp,
669 	struct bp_external_encoder_control *cntl)
670 {
671 	/* TODO */
672 	return BP_RESULT_OK;
673 }
674 
675 /******************************************************************************
676  ******************************************************************************
677  **
678  **                  ENABLE DISPLAY POWER GATING
679  **
680  ******************************************************************************
681  *****************************************************************************/
682 
683 static enum bp_result enable_disp_power_gating_v2_1(
684 	struct bios_parser *bp,
685 	enum controller_id crtc_id,
686 	enum bp_pipe_control_action action);
687 
688 static enum bp_result enable_disp_power_gating_fallback(
689 	struct bios_parser *bp,
690 	enum controller_id crtc_id,
691 	enum bp_pipe_control_action action);
692 
init_enable_disp_power_gating(struct bios_parser * bp)693 static void init_enable_disp_power_gating(
694 	struct bios_parser *bp)
695 {
696 	switch (BIOS_CMD_TABLE_PARA_REVISION(enabledisppowergating)) {
697 	case 1:
698 		bp->cmd_tbl.enable_disp_power_gating =
699 				enable_disp_power_gating_v2_1;
700 		break;
701 	default:
702 		dm_output_to_console("Don't enable_disp_power_gating enable_crtc for v%d\n",
703 			 BIOS_CMD_TABLE_PARA_REVISION(enabledisppowergating));
704 		bp->cmd_tbl.enable_disp_power_gating = enable_disp_power_gating_fallback;
705 		break;
706 	}
707 }
708 
enable_disp_power_gating_dmcub(struct dc_dmub_srv * dmcub,struct enable_disp_power_gating_parameters_v2_1 * pwr)709 static void enable_disp_power_gating_dmcub(
710 	struct dc_dmub_srv *dmcub,
711 	struct enable_disp_power_gating_parameters_v2_1 *pwr)
712 {
713 	struct dmub_rb_cmd_enable_disp_power_gating power_gating;
714 
715 	power_gating.header.type = DMUB_CMD__VBIOS;
716 	power_gating.header.sub_type = DMUB_CMD__VBIOS_ENABLE_DISP_POWER_GATING;
717 	power_gating.power_gating.pwr = *pwr;
718 
719 	dc_dmub_srv_cmd_queue(dmcub, &power_gating.header);
720 	dc_dmub_srv_cmd_execute(dmcub);
721 	dc_dmub_srv_wait_idle(dmcub);
722 }
723 
enable_disp_power_gating_v2_1(struct bios_parser * bp,enum controller_id crtc_id,enum bp_pipe_control_action action)724 static enum bp_result enable_disp_power_gating_v2_1(
725 	struct bios_parser *bp,
726 	enum controller_id crtc_id,
727 	enum bp_pipe_control_action action)
728 {
729 	enum bp_result result = BP_RESULT_FAILURE;
730 
731 
732 	struct enable_disp_power_gating_ps_allocation ps = { { 0 } };
733 	uint8_t atom_crtc_id;
734 
735 	if (bp->cmd_helper->controller_id_to_atom(crtc_id, &atom_crtc_id))
736 		ps.param.disp_pipe_id = atom_crtc_id;
737 	else
738 		return BP_RESULT_BADINPUT;
739 
740 	ps.param.enable =
741 		bp->cmd_helper->disp_power_gating_action_to_atom(action);
742 
743 	if (bp->base.ctx->dc->ctx->dmub_srv &&
744 	    bp->base.ctx->dc->debug.dmub_command_table) {
745 		enable_disp_power_gating_dmcub(bp->base.ctx->dmub_srv,
746 					       &ps.param);
747 		return BP_RESULT_OK;
748 	}
749 
750 	if (EXEC_BIOS_CMD_TABLE(enabledisppowergating, ps.param))
751 		result = BP_RESULT_OK;
752 
753 	return result;
754 }
755 
enable_disp_power_gating_fallback(struct bios_parser * bp,enum controller_id crtc_id,enum bp_pipe_control_action action)756 static enum bp_result enable_disp_power_gating_fallback(
757 	struct bios_parser *bp,
758 	enum controller_id crtc_id,
759 	enum bp_pipe_control_action action)
760 {
761 	if (bp->base.ctx->dc->ctx->dmub_srv &&
762 	    bp->base.ctx->dc->debug.dmub_command_table) {
763 		return enable_disp_power_gating_v2_1(bp, crtc_id, action);
764 	}
765 
766 	return BP_RESULT_FAILURE;
767 }
768 
769 /******************************************************************************
770 *******************************************************************************
771  **
772  **                  SET DCE CLOCK
773  **
774 *******************************************************************************
775 *******************************************************************************/
776 
777 static enum bp_result set_dce_clock_v2_1(
778 	struct bios_parser *bp,
779 	struct bp_set_dce_clock_parameters *bp_params);
780 
init_set_dce_clock(struct bios_parser * bp)781 static void init_set_dce_clock(struct bios_parser *bp)
782 {
783 	switch (BIOS_CMD_TABLE_PARA_REVISION(setdceclock)) {
784 	case 1:
785 		bp->cmd_tbl.set_dce_clock = set_dce_clock_v2_1;
786 		break;
787 	default:
788 		dm_output_to_console("Don't have set_dce_clock for v%d\n",
789 			 BIOS_CMD_TABLE_PARA_REVISION(setdceclock));
790 		bp->cmd_tbl.set_dce_clock = NULL;
791 		break;
792 	}
793 }
794 
set_dce_clock_v2_1(struct bios_parser * bp,struct bp_set_dce_clock_parameters * bp_params)795 static enum bp_result set_dce_clock_v2_1(
796 	struct bios_parser *bp,
797 	struct bp_set_dce_clock_parameters *bp_params)
798 {
799 	enum bp_result result = BP_RESULT_FAILURE;
800 
801 	struct set_dce_clock_ps_allocation_v2_1 params;
802 	uint32_t atom_pll_id;
803 	uint32_t atom_clock_type;
804 	const struct command_table_helper *cmd = bp->cmd_helper;
805 
806 	memset(&params, 0, sizeof(params));
807 
808 	if (!cmd->clock_source_id_to_atom(bp_params->pll_id, &atom_pll_id) ||
809 			!cmd->dc_clock_type_to_atom(bp_params->clock_type,
810 					&atom_clock_type))
811 		return BP_RESULT_BADINPUT;
812 
813 	params.param.dceclksrc  = atom_pll_id;
814 	params.param.dceclktype = atom_clock_type;
815 
816 	if (bp_params->clock_type == DCECLOCK_TYPE_DPREFCLK) {
817 		if (bp_params->flags.USE_GENLOCK_AS_SOURCE_FOR_DPREFCLK)
818 			params.param.dceclkflag |=
819 					DCE_CLOCK_FLAG_PLL_REFCLK_SRC_GENLK;
820 
821 		if (bp_params->flags.USE_PCIE_AS_SOURCE_FOR_DPREFCLK)
822 			params.param.dceclkflag |=
823 					DCE_CLOCK_FLAG_PLL_REFCLK_SRC_PCIE;
824 
825 		if (bp_params->flags.USE_XTALIN_AS_SOURCE_FOR_DPREFCLK)
826 			params.param.dceclkflag |=
827 					DCE_CLOCK_FLAG_PLL_REFCLK_SRC_XTALIN;
828 
829 		if (bp_params->flags.USE_GENERICA_AS_SOURCE_FOR_DPREFCLK)
830 			params.param.dceclkflag |=
831 					DCE_CLOCK_FLAG_PLL_REFCLK_SRC_GENERICA;
832 	} else
833 		/* only program clock frequency if display clock is used;
834 		 * VBIOS will program DPREFCLK
835 		 * We need to convert from KHz units into 10KHz units
836 		 */
837 		params.param.dceclk_10khz = cpu_to_le32(
838 				bp_params->target_clock_frequency / 10);
839 	DC_LOG_BIOS("%s:target_clock_frequency = %d"\
840 			"clock_type = %d \n", __func__,\
841 			bp_params->target_clock_frequency,\
842 			bp_params->clock_type);
843 
844 	if (EXEC_BIOS_CMD_TABLE(setdceclock, params)) {
845 		/* Convert from 10KHz units back to KHz */
846 		bp_params->target_clock_frequency = le32_to_cpu(
847 				params.param.dceclk_10khz) * 10;
848 		result = BP_RESULT_OK;
849 	}
850 
851 	return result;
852 }
853 
854 
855 /******************************************************************************
856  ******************************************************************************
857  **
858  **                  GET SMU CLOCK INFO
859  **
860  ******************************************************************************
861  *****************************************************************************/
862 
863 static unsigned int get_smu_clock_info_v3_1(struct bios_parser *bp, uint8_t id);
864 
init_get_smu_clock_info(struct bios_parser * bp)865 static void init_get_smu_clock_info(struct bios_parser *bp)
866 {
867 	/* TODO add switch for table vrsion */
868 	bp->cmd_tbl.get_smu_clock_info = get_smu_clock_info_v3_1;
869 
870 }
871 
get_smu_clock_info_v3_1(struct bios_parser * bp,uint8_t id)872 static unsigned int get_smu_clock_info_v3_1(struct bios_parser *bp, uint8_t id)
873 {
874 	struct atom_get_smu_clock_info_parameters_v3_1 smu_input = {0};
875 	struct atom_get_smu_clock_info_output_parameters_v3_1 smu_output;
876 
877 	smu_input.command = GET_SMU_CLOCK_INFO_V3_1_GET_PLLVCO_FREQ;
878 	smu_input.syspll_id = id;
879 
880 	/* Get Specific Clock */
881 	if (EXEC_BIOS_CMD_TABLE(getsmuclockinfo, smu_input)) {
882 		memmove(&smu_output, &smu_input, sizeof(
883 			struct atom_get_smu_clock_info_parameters_v3_1));
884 		return smu_output.atom_smu_outputclkfreq.syspllvcofreq_10khz;
885 	}
886 
887 	return 0;
888 }
889 
dal_firmware_parser_init_cmd_tbl(struct bios_parser * bp)890 void dal_firmware_parser_init_cmd_tbl(struct bios_parser *bp)
891 {
892 	init_dig_encoder_control(bp);
893 	init_transmitter_control(bp);
894 	init_set_pixel_clock(bp);
895 
896 	init_set_crtc_timing(bp);
897 
898 	init_enable_crtc(bp);
899 
900 	init_external_encoder_control(bp);
901 	init_enable_disp_power_gating(bp);
902 	init_set_dce_clock(bp);
903 	init_get_smu_clock_info(bp);
904 
905 }
906