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 | bool dal_bios_parser_init_cmd_tbl_helper( |
35 | const struct command_table_helper **h, |
36 | enum dce_version dce) |
37 | { |
38 | switch (dce) { |
39 | #if defined(CONFIG_DRM_AMD_DC_SI) |
40 | case DCE_VERSION_6_0: |
41 | case DCE_VERSION_6_1: |
42 | case DCE_VERSION_6_4: |
43 | *h = dal_cmd_tbl_helper_dce60_get_table(); |
44 | return true; |
45 | #endif |
46 | |
47 | case DCE_VERSION_8_0: |
48 | case DCE_VERSION_8_1: |
49 | case DCE_VERSION_8_3: |
50 | *h = dal_cmd_tbl_helper_dce80_get_table(); |
51 | return true; |
52 | |
53 | case DCE_VERSION_10_0: |
54 | *h = dal_cmd_tbl_helper_dce110_get_table(); |
55 | return true; |
56 | |
57 | case DCE_VERSION_11_0: |
58 | *h = dal_cmd_tbl_helper_dce110_get_table(); |
59 | return true; |
60 | |
61 | case DCE_VERSION_11_2: |
62 | case DCE_VERSION_11_22: |
63 | *h = dal_cmd_tbl_helper_dce112_get_table(); |
64 | return true; |
65 | |
66 | default: |
67 | /* Unsupported DCE */ |
68 | BREAK_TO_DEBUGGER(); |
69 | return false; |
70 | } |
71 | } |
72 | |
73 | /* real implementations */ |
74 | |
75 | bool dal_cmd_table_helper_controller_id_to_atom( |
76 | enum controller_id id, |
77 | uint8_t *atom_id) |
78 | { |
79 | if (atom_id == NULL) { |
80 | BREAK_TO_DEBUGGER(); |
81 | return false; |
82 | } |
83 | |
84 | switch (id) { |
85 | case CONTROLLER_ID_D0: |
86 | *atom_id = ATOM_CRTC1; |
87 | return true; |
88 | case CONTROLLER_ID_D1: |
89 | *atom_id = ATOM_CRTC2; |
90 | return true; |
91 | case CONTROLLER_ID_D2: |
92 | *atom_id = ATOM_CRTC3; |
93 | return true; |
94 | case CONTROLLER_ID_D3: |
95 | *atom_id = ATOM_CRTC4; |
96 | return true; |
97 | case CONTROLLER_ID_D4: |
98 | *atom_id = ATOM_CRTC5; |
99 | return true; |
100 | case CONTROLLER_ID_D5: |
101 | *atom_id = ATOM_CRTC6; |
102 | return true; |
103 | case CONTROLLER_ID_UNDERLAY0: |
104 | *atom_id = ATOM_UNDERLAY_PIPE0; |
105 | return true; |
106 | case CONTROLLER_ID_UNDEFINED: |
107 | *atom_id = ATOM_CRTC_INVALID; |
108 | return true; |
109 | default: |
110 | /* Wrong controller id */ |
111 | BREAK_TO_DEBUGGER(); |
112 | return false; |
113 | } |
114 | } |
115 | |
116 | /** |
117 | * dal_cmd_table_helper_transmitter_bp_to_atom - Translate the Transmitter to the |
118 | * corresponding ATOM BIOS value |
119 | * @t: transmitter |
120 | * returns: output digitalTransmitter |
121 | * // =00: Digital Transmitter1 ( UNIPHY linkAB ) |
122 | * // =01: Digital Transmitter2 ( UNIPHY linkCD ) |
123 | * // =02: Digital Transmitter3 ( UNIPHY linkEF ) |
124 | */ |
125 | uint8_t dal_cmd_table_helper_transmitter_bp_to_atom( |
126 | enum transmitter t) |
127 | { |
128 | switch (t) { |
129 | case TRANSMITTER_UNIPHY_A: |
130 | case TRANSMITTER_UNIPHY_B: |
131 | case TRANSMITTER_TRAVIS_LCD: |
132 | return 0; |
133 | case TRANSMITTER_UNIPHY_C: |
134 | case TRANSMITTER_UNIPHY_D: |
135 | return 1; |
136 | case TRANSMITTER_UNIPHY_E: |
137 | case TRANSMITTER_UNIPHY_F: |
138 | return 2; |
139 | default: |
140 | /* Invalid Transmitter Type! */ |
141 | BREAK_TO_DEBUGGER(); |
142 | return 0; |
143 | } |
144 | } |
145 | |
146 | uint32_t dal_cmd_table_helper_encoder_mode_bp_to_atom( |
147 | enum signal_type s, |
148 | bool enable_dp_audio) |
149 | { |
150 | switch (s) { |
151 | case SIGNAL_TYPE_DVI_SINGLE_LINK: |
152 | case SIGNAL_TYPE_DVI_DUAL_LINK: |
153 | return ATOM_ENCODER_MODE_DVI; |
154 | case SIGNAL_TYPE_HDMI_TYPE_A: |
155 | return ATOM_ENCODER_MODE_HDMI; |
156 | case SIGNAL_TYPE_LVDS: |
157 | return ATOM_ENCODER_MODE_LVDS; |
158 | case SIGNAL_TYPE_EDP: |
159 | case SIGNAL_TYPE_DISPLAY_PORT_MST: |
160 | case SIGNAL_TYPE_DISPLAY_PORT: |
161 | case SIGNAL_TYPE_VIRTUAL: |
162 | if (enable_dp_audio) |
163 | return ATOM_ENCODER_MODE_DP_AUDIO; |
164 | else |
165 | return ATOM_ENCODER_MODE_DP; |
166 | case SIGNAL_TYPE_RGB: |
167 | return ATOM_ENCODER_MODE_CRT; |
168 | default: |
169 | return ATOM_ENCODER_MODE_CRT; |
170 | } |
171 | } |
172 | |
173 | void dal_cmd_table_helper_assign_control_parameter( |
174 | const struct command_table_helper *h, |
175 | struct bp_encoder_control *control, |
176 | DIG_ENCODER_CONTROL_PARAMETERS_V2 *ctrl_param) |
177 | { |
178 | /* there are three transmitter blocks, each one has two links 4-lanes |
179 | * each, A+B, C+D, E+F, Uniphy A, C and E are enumerated as link 0 in |
180 | * each transmitter block B, D and F as link 1, third transmitter block |
181 | * has non splitable links (UniphyE and UniphyF can not be configured |
182 | * separately to drive two different streams) |
183 | */ |
184 | if ((control->transmitter == TRANSMITTER_UNIPHY_B) || |
185 | (control->transmitter == TRANSMITTER_UNIPHY_D) || |
186 | (control->transmitter == TRANSMITTER_UNIPHY_F)) { |
187 | /* Bit2: Link Select |
188 | * =0: PHY linkA/C/E |
189 | * =1: PHY linkB/D/F |
190 | */ |
191 | ctrl_param->acConfig.ucLinkSel = 1; |
192 | } |
193 | |
194 | /* Bit[4:3]: Transmitter Selection |
195 | * =00: Digital Transmitter1 ( UNIPHY linkAB ) |
196 | * =01: Digital Transmitter2 ( UNIPHY linkCD ) |
197 | * =02: Digital Transmitter3 ( UNIPHY linkEF ) |
198 | * =03: Reserved |
199 | */ |
200 | ctrl_param->acConfig.ucTransmitterSel = |
201 | (uint8_t)(h->transmitter_bp_to_atom(control->transmitter)); |
202 | |
203 | /* We need to convert from KHz units into 10KHz units */ |
204 | ctrl_param->ucAction = h->encoder_action_to_atom(control->action); |
205 | ctrl_param->usPixelClock = cpu_to_le16((uint16_t)(control->pixel_clock / 10)); |
206 | ctrl_param->ucEncoderMode = |
207 | (uint8_t)(h->encoder_mode_bp_to_atom( |
208 | control->signal, control->enable_dp_audio)); |
209 | ctrl_param->ucLaneNum = (uint8_t)(control->lanes_number); |
210 | } |
211 | |
212 | bool dal_cmd_table_helper_clock_source_id_to_ref_clk_src( |
213 | enum clock_source_id id, |
214 | uint32_t *ref_clk_src_id) |
215 | { |
216 | if (ref_clk_src_id == NULL) { |
217 | BREAK_TO_DEBUGGER(); |
218 | return false; |
219 | } |
220 | |
221 | switch (id) { |
222 | case CLOCK_SOURCE_ID_PLL1: |
223 | *ref_clk_src_id = ENCODER_REFCLK_SRC_P1PLL; |
224 | return true; |
225 | case CLOCK_SOURCE_ID_PLL2: |
226 | *ref_clk_src_id = ENCODER_REFCLK_SRC_P2PLL; |
227 | return true; |
228 | case CLOCK_SOURCE_ID_DCPLL: |
229 | *ref_clk_src_id = ENCODER_REFCLK_SRC_DCPLL; |
230 | return true; |
231 | case CLOCK_SOURCE_ID_EXTERNAL: |
232 | *ref_clk_src_id = ENCODER_REFCLK_SRC_EXTCLK; |
233 | return true; |
234 | case CLOCK_SOURCE_ID_UNDEFINED: |
235 | *ref_clk_src_id = ENCODER_REFCLK_SRC_INVALID; |
236 | return true; |
237 | default: |
238 | /* Unsupported clock source id */ |
239 | BREAK_TO_DEBUGGER(); |
240 | return false; |
241 | } |
242 | } |
243 | |
244 | uint8_t dal_cmd_table_helper_encoder_id_to_atom( |
245 | enum encoder_id id) |
246 | { |
247 | switch (id) { |
248 | case ENCODER_ID_INTERNAL_LVDS: |
249 | return ENCODER_OBJECT_ID_INTERNAL_LVDS; |
250 | case ENCODER_ID_INTERNAL_TMDS1: |
251 | return ENCODER_OBJECT_ID_INTERNAL_TMDS1; |
252 | case ENCODER_ID_INTERNAL_TMDS2: |
253 | return ENCODER_OBJECT_ID_INTERNAL_TMDS2; |
254 | case ENCODER_ID_INTERNAL_DAC1: |
255 | return ENCODER_OBJECT_ID_INTERNAL_DAC1; |
256 | case ENCODER_ID_INTERNAL_DAC2: |
257 | return ENCODER_OBJECT_ID_INTERNAL_DAC2; |
258 | case ENCODER_ID_INTERNAL_LVTM1: |
259 | return ENCODER_OBJECT_ID_INTERNAL_LVTM1; |
260 | case ENCODER_ID_INTERNAL_HDMI: |
261 | return ENCODER_OBJECT_ID_HDMI_INTERNAL; |
262 | case ENCODER_ID_EXTERNAL_TRAVIS: |
263 | return ENCODER_OBJECT_ID_TRAVIS; |
264 | case ENCODER_ID_EXTERNAL_NUTMEG: |
265 | return ENCODER_OBJECT_ID_NUTMEG; |
266 | case ENCODER_ID_INTERNAL_KLDSCP_TMDS1: |
267 | return ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1; |
268 | case ENCODER_ID_INTERNAL_KLDSCP_DAC1: |
269 | return ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1; |
270 | case ENCODER_ID_INTERNAL_KLDSCP_DAC2: |
271 | return ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2; |
272 | case ENCODER_ID_EXTERNAL_MVPU_FPGA: |
273 | return ENCODER_OBJECT_ID_MVPU_FPGA; |
274 | case ENCODER_ID_INTERNAL_DDI: |
275 | return ENCODER_OBJECT_ID_INTERNAL_DDI; |
276 | case ENCODER_ID_INTERNAL_UNIPHY: |
277 | return ENCODER_OBJECT_ID_INTERNAL_UNIPHY; |
278 | case ENCODER_ID_INTERNAL_KLDSCP_LVTMA: |
279 | return ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA; |
280 | case ENCODER_ID_INTERNAL_UNIPHY1: |
281 | return ENCODER_OBJECT_ID_INTERNAL_UNIPHY1; |
282 | case ENCODER_ID_INTERNAL_UNIPHY2: |
283 | return ENCODER_OBJECT_ID_INTERNAL_UNIPHY2; |
284 | case ENCODER_ID_INTERNAL_UNIPHY3: |
285 | return ENCODER_OBJECT_ID_INTERNAL_UNIPHY3; |
286 | case ENCODER_ID_INTERNAL_WIRELESS: |
287 | return ENCODER_OBJECT_ID_INTERNAL_VCE; |
288 | case ENCODER_ID_UNKNOWN: |
289 | return ENCODER_OBJECT_ID_NONE; |
290 | default: |
291 | /* Invalid encoder id */ |
292 | BREAK_TO_DEBUGGER(); |
293 | return ENCODER_OBJECT_ID_NONE; |
294 | } |
295 | } |
296 | |