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