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