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 "atom.h"
29
30#include "include/bios_parser_types.h"
31
32#include "../command_table_helper2.h"
33
34static uint8_t phy_id_to_atom(enum transmitter t)
35{
36	uint8_t atom_phy_id;
37
38	switch (t) {
39	case TRANSMITTER_UNIPHY_A:
40		atom_phy_id = ATOM_PHY_ID_UNIPHYA;
41		break;
42	case TRANSMITTER_UNIPHY_B:
43		atom_phy_id = ATOM_PHY_ID_UNIPHYB;
44		break;
45	case TRANSMITTER_UNIPHY_C:
46		atom_phy_id = ATOM_PHY_ID_UNIPHYC;
47		break;
48	case TRANSMITTER_UNIPHY_D:
49		atom_phy_id = ATOM_PHY_ID_UNIPHYD;
50		break;
51	case TRANSMITTER_UNIPHY_E:
52		atom_phy_id = ATOM_PHY_ID_UNIPHYE;
53		break;
54	case TRANSMITTER_UNIPHY_F:
55		atom_phy_id = ATOM_PHY_ID_UNIPHYF;
56		break;
57	case TRANSMITTER_UNIPHY_G:
58		atom_phy_id = ATOM_PHY_ID_UNIPHYG;
59		break;
60	default:
61		atom_phy_id = ATOM_PHY_ID_UNIPHYA;
62		break;
63	}
64	return atom_phy_id;
65}
66
67static uint8_t signal_type_to_atom_dig_mode(enum signal_type s)
68{
69	uint8_t atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V6_DP;
70
71	switch (s) {
72	case SIGNAL_TYPE_DISPLAY_PORT:
73	case SIGNAL_TYPE_EDP:
74		atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V6_DP;
75		break;
76	case SIGNAL_TYPE_DVI_SINGLE_LINK:
77	case SIGNAL_TYPE_DVI_DUAL_LINK:
78		atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V6_DVI;
79		break;
80	case SIGNAL_TYPE_HDMI_TYPE_A:
81		atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V6_HDMI;
82		break;
83	case SIGNAL_TYPE_DISPLAY_PORT_MST:
84		atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V6_DP_MST;
85		break;
86	default:
87		atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V6_DVI;
88		break;
89	}
90
91	return atom_dig_mode;
92}
93
94static uint8_t clock_source_id_to_atom_phy_clk_src_id(
95		enum clock_source_id id)
96{
97	uint8_t atom_phy_clk_src_id = 0;
98
99	switch (id) {
100	case CLOCK_SOURCE_ID_PLL0:
101		atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P0PLL;
102		break;
103	case CLOCK_SOURCE_ID_PLL1:
104		atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P1PLL;
105		break;
106	case CLOCK_SOURCE_ID_PLL2:
107		atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P2PLL;
108		break;
109	case CLOCK_SOURCE_ID_EXTERNAL:
110		atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_REFCLK_SRC_EXT;
111		break;
112	default:
113		atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P1PLL;
114		break;
115	}
116
117	return atom_phy_clk_src_id >> 2;
118}
119
120static uint8_t hpd_sel_to_atom(enum hpd_source_id id)
121{
122	uint8_t atom_hpd_sel = 0;
123
124	switch (id) {
125	case HPD_SOURCEID1:
126		atom_hpd_sel = ATOM_TRANSMITTER_V6_HPD1_SEL;
127		break;
128	case HPD_SOURCEID2:
129		atom_hpd_sel = ATOM_TRANSMITTER_V6_HPD2_SEL;
130		break;
131	case HPD_SOURCEID3:
132		atom_hpd_sel = ATOM_TRANSMITTER_V6_HPD3_SEL;
133		break;
134	case HPD_SOURCEID4:
135		atom_hpd_sel = ATOM_TRANSMITTER_V6_HPD4_SEL;
136		break;
137	case HPD_SOURCEID5:
138		atom_hpd_sel = ATOM_TRANSMITTER_V6_HPD5_SEL;
139		break;
140	case HPD_SOURCEID6:
141		atom_hpd_sel = ATOM_TRANSMITTER_V6_HPD6_SEL;
142		break;
143	case HPD_SOURCEID_UNKNOWN:
144	default:
145		atom_hpd_sel = 0;
146		break;
147	}
148	return atom_hpd_sel;
149}
150
151static uint8_t dig_encoder_sel_to_atom(enum engine_id id)
152{
153	/* On any ASIC after DCE80, we manually program the DIG_FE
154	 * selection (see connect_dig_be_to_fe function of the link
155	 * encoder), so translation should always return 0 (no FE).
156	 */
157
158	return 0;
159}
160
161static bool clock_source_id_to_atom(
162	enum clock_source_id id,
163	uint32_t *atom_pll_id)
164{
165	bool result = true;
166
167	if (atom_pll_id != NULL)
168		switch (id) {
169		case CLOCK_SOURCE_COMBO_PHY_PLL0:
170			*atom_pll_id = ATOM_COMBOPHY_PLL0;
171			break;
172		case CLOCK_SOURCE_COMBO_PHY_PLL1:
173			*atom_pll_id = ATOM_COMBOPHY_PLL1;
174			break;
175		case CLOCK_SOURCE_COMBO_PHY_PLL2:
176			*atom_pll_id = ATOM_COMBOPHY_PLL2;
177			break;
178		case CLOCK_SOURCE_COMBO_PHY_PLL3:
179			*atom_pll_id = ATOM_COMBOPHY_PLL3;
180			break;
181		case CLOCK_SOURCE_COMBO_PHY_PLL4:
182			*atom_pll_id = ATOM_COMBOPHY_PLL4;
183			break;
184		case CLOCK_SOURCE_COMBO_PHY_PLL5:
185			*atom_pll_id = ATOM_COMBOPHY_PLL5;
186			break;
187		case CLOCK_SOURCE_COMBO_DISPLAY_PLL0:
188			*atom_pll_id = ATOM_PPLL0;
189			break;
190		case CLOCK_SOURCE_ID_DFS:
191			*atom_pll_id = ATOM_GCK_DFS;
192			break;
193		case CLOCK_SOURCE_ID_VCE:
194			*atom_pll_id = ATOM_DP_DTO;
195			break;
196		case CLOCK_SOURCE_ID_DP_DTO:
197			*atom_pll_id = ATOM_DP_DTO;
198			break;
199		case CLOCK_SOURCE_ID_UNDEFINED:
200			/* Should not happen */
201			*atom_pll_id = ATOM_PPLL_INVALID;
202			result = false;
203			break;
204		default:
205			result = false;
206			break;
207		}
208
209	return result;
210}
211
212static bool engine_bp_to_atom(enum engine_id id, uint32_t *atom_engine_id)
213{
214	bool result = false;
215
216	if (atom_engine_id != NULL)
217		switch (id) {
218		case ENGINE_ID_DIGA:
219			*atom_engine_id = ASIC_INT_DIG1_ENCODER_ID;
220			result = true;
221			break;
222		case ENGINE_ID_DIGB:
223			*atom_engine_id = ASIC_INT_DIG2_ENCODER_ID;
224			result = true;
225			break;
226		case ENGINE_ID_DIGC:
227			*atom_engine_id = ASIC_INT_DIG3_ENCODER_ID;
228			result = true;
229			break;
230		case ENGINE_ID_DIGD:
231			*atom_engine_id = ASIC_INT_DIG4_ENCODER_ID;
232			result = true;
233			break;
234		case ENGINE_ID_DIGE:
235			*atom_engine_id = ASIC_INT_DIG5_ENCODER_ID;
236			result = true;
237			break;
238		case ENGINE_ID_DIGF:
239			*atom_engine_id = ASIC_INT_DIG6_ENCODER_ID;
240			result = true;
241			break;
242		case ENGINE_ID_DIGG:
243			*atom_engine_id = ASIC_INT_DIG7_ENCODER_ID;
244			result = true;
245			break;
246		case ENGINE_ID_DACA:
247			*atom_engine_id = ASIC_INT_DAC1_ENCODER_ID;
248			result = true;
249			break;
250		default:
251			break;
252		}
253
254	return result;
255}
256
257static uint8_t encoder_action_to_atom(enum bp_encoder_control_action action)
258{
259	uint8_t atom_action = 0;
260
261	switch (action) {
262	case ENCODER_CONTROL_ENABLE:
263		atom_action = ATOM_ENABLE;
264		break;
265	case ENCODER_CONTROL_DISABLE:
266		atom_action = ATOM_DISABLE;
267		break;
268	case ENCODER_CONTROL_SETUP:
269		atom_action = ATOM_ENCODER_CMD_STREAM_SETUP;
270		break;
271	case ENCODER_CONTROL_INIT:
272		atom_action = ATOM_ENCODER_INIT;
273		break;
274	default:
275		BREAK_TO_DEBUGGER(); /* Unhandle action in driver.!! */
276		break;
277	}
278
279	return atom_action;
280}
281
282static uint8_t disp_power_gating_action_to_atom(
283	enum bp_pipe_control_action action)
284{
285	uint8_t atom_pipe_action = 0;
286
287	switch (action) {
288	case ASIC_PIPE_DISABLE:
289		atom_pipe_action = ATOM_DISABLE;
290		break;
291	case ASIC_PIPE_ENABLE:
292		atom_pipe_action = ATOM_ENABLE;
293		break;
294	case ASIC_PIPE_INIT:
295		atom_pipe_action = ATOM_INIT;
296		break;
297	default:
298		ASSERT_CRITICAL(false); /* Unhandle action in driver! */
299		break;
300	}
301
302	return atom_pipe_action;
303}
304
305static bool dc_clock_type_to_atom(
306		enum bp_dce_clock_type id,
307		uint32_t *atom_clock_type)
308{
309	bool retCode = true;
310
311	if (atom_clock_type != NULL) {
312		switch (id) {
313		case DCECLOCK_TYPE_DISPLAY_CLOCK:
314			*atom_clock_type = DCE_CLOCK_TYPE_DISPCLK;
315			break;
316
317		case DCECLOCK_TYPE_DPREFCLK:
318			*atom_clock_type = DCE_CLOCK_TYPE_DPREFCLK;
319			break;
320
321		default:
322			ASSERT_CRITICAL(false); /* Unhandle action in driver! */
323			break;
324		}
325	}
326
327	return retCode;
328}
329
330static uint8_t transmitter_color_depth_to_atom(enum transmitter_color_depth id)
331{
332	uint8_t atomColorDepth = 0;
333
334	switch (id) {
335	case TRANSMITTER_COLOR_DEPTH_24:
336		atomColorDepth = PIXEL_CLOCK_V7_DEEPCOLOR_RATIO_DIS;
337		break;
338	case TRANSMITTER_COLOR_DEPTH_30:
339		atomColorDepth = PIXEL_CLOCK_V7_DEEPCOLOR_RATIO_5_4;
340		break;
341	case TRANSMITTER_COLOR_DEPTH_36:
342		atomColorDepth = PIXEL_CLOCK_V7_DEEPCOLOR_RATIO_3_2;
343		break;
344	case TRANSMITTER_COLOR_DEPTH_48:
345		atomColorDepth = PIXEL_CLOCK_V7_DEEPCOLOR_RATIO_2_1;
346		break;
347	default:
348		ASSERT_CRITICAL(false); /* Unhandle action in driver! */
349		break;
350	}
351
352	return atomColorDepth;
353}
354
355/* function table */
356static const struct command_table_helper command_table_helper_funcs = {
357	.controller_id_to_atom = dal_cmd_table_helper_controller_id_to_atom2,
358	.encoder_action_to_atom = encoder_action_to_atom,
359	.engine_bp_to_atom = engine_bp_to_atom,
360	.clock_source_id_to_atom = clock_source_id_to_atom,
361	.clock_source_id_to_atom_phy_clk_src_id =
362			clock_source_id_to_atom_phy_clk_src_id,
363	.signal_type_to_atom_dig_mode = signal_type_to_atom_dig_mode,
364	.hpd_sel_to_atom = hpd_sel_to_atom,
365	.dig_encoder_sel_to_atom = dig_encoder_sel_to_atom,
366	.phy_id_to_atom = phy_id_to_atom,
367	.disp_power_gating_action_to_atom = disp_power_gating_action_to_atom,
368	.clock_source_id_to_ref_clk_src = NULL,
369	.transmitter_bp_to_atom = NULL,
370	.encoder_id_to_atom = dal_cmd_table_helper_encoder_id_to_atom2,
371	.encoder_mode_bp_to_atom =
372			dal_cmd_table_helper_encoder_mode_bp_to_atom2,
373	.dc_clock_type_to_atom = dc_clock_type_to_atom,
374	.transmitter_color_depth_to_atom = transmitter_color_depth_to_atom,
375};
376
377/*
378 * dal_cmd_tbl_helper_dce110_get_table
379 *
380 * @brief
381 * Initialize command table helper functions
382 *
383 * @param
384 * const struct command_table_helper **h - [out] struct of functions
385 *
386 */
387const struct command_table_helper *dal_cmd_tbl_helper_dce112_get_table2(void)
388{
389	return &command_table_helper_funcs;
390}
391