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_helper.h" |
33 | |
34 | static 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 | |
67 | static 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 | |
94 | static 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 | |
120 | static 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 | |
151 | static 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 | |
161 | static 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 | |
212 | static 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 | |
257 | static 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 | |
282 | static 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 | |
305 | static 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 | |
330 | static 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 */ |
356 | static const struct command_table_helper command_table_helper_funcs = { |
357 | .controller_id_to_atom = dal_cmd_table_helper_controller_id_to_atom, |
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 | .assign_control_parameter = NULL, |
369 | .clock_source_id_to_ref_clk_src = NULL, |
370 | .transmitter_bp_to_atom = NULL, |
371 | .encoder_id_to_atom = dal_cmd_table_helper_encoder_id_to_atom, |
372 | .encoder_mode_bp_to_atom = dal_cmd_table_helper_encoder_mode_bp_to_atom, |
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 | */ |
387 | const struct command_table_helper *dal_cmd_tbl_helper_dce112_get_table(void) |
388 | { |
389 | return &command_table_helper_funcs; |
390 | } |
391 | |