Branch data Line data Source code
1 : : /*
2 : : * Copyright © 2012 Intel Corporation
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 (including the next
12 : : * paragraph) shall be included in all copies or substantial portions of the
13 : : * Software.
14 : : *
15 : : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 : : * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 : : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 : : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 : : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 : : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 : : * IN THE SOFTWARE.
22 : : *
23 : : * Authors:
24 : : * Eugeni Dodonov <eugeni.dodonov@intel.com>
25 : : *
26 : : */
27 : :
28 : : #include <drm/drm_scdc_helper.h>
29 : :
30 : : #include "i915_drv.h"
31 : : #include "intel_audio.h"
32 : : #include "intel_combo_phy.h"
33 : : #include "intel_connector.h"
34 : : #include "intel_ddi.h"
35 : : #include "intel_display_types.h"
36 : : #include "intel_dp.h"
37 : : #include "intel_dp_mst.h"
38 : : #include "intel_dp_link_training.h"
39 : : #include "intel_dpio_phy.h"
40 : : #include "intel_dsi.h"
41 : : #include "intel_fifo_underrun.h"
42 : : #include "intel_gmbus.h"
43 : : #include "intel_hdcp.h"
44 : : #include "intel_hdmi.h"
45 : : #include "intel_hotplug.h"
46 : : #include "intel_lspcon.h"
47 : : #include "intel_panel.h"
48 : : #include "intel_psr.h"
49 : : #include "intel_sprite.h"
50 : : #include "intel_tc.h"
51 : : #include "intel_vdsc.h"
52 : :
53 : : struct ddi_buf_trans {
54 : : u32 trans1; /* balance leg enable, de-emph level */
55 : : u32 trans2; /* vref sel, vswing */
56 : : u8 i_boost; /* SKL: I_boost; valid: 0x0, 0x1, 0x3, 0x7 */
57 : : };
58 : :
59 : : static const u8 index_to_dp_signal_levels[] = {
60 : : [0] = DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_0,
61 : : [1] = DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_1,
62 : : [2] = DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_2,
63 : : [3] = DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_3,
64 : : [4] = DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_0,
65 : : [5] = DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_1,
66 : : [6] = DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_2,
67 : : [7] = DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_0,
68 : : [8] = DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_1,
69 : : [9] = DP_TRAIN_VOLTAGE_SWING_LEVEL_3 | DP_TRAIN_PRE_EMPH_LEVEL_0,
70 : : };
71 : :
72 : : /* HDMI/DVI modes ignore everything but the last 2 items. So we share
73 : : * them for both DP and FDI transports, allowing those ports to
74 : : * automatically adapt to HDMI connections as well
75 : : */
76 : : static const struct ddi_buf_trans hsw_ddi_translations_dp[] = {
77 : : { 0x00FFFFFF, 0x0006000E, 0x0 },
78 : : { 0x00D75FFF, 0x0005000A, 0x0 },
79 : : { 0x00C30FFF, 0x00040006, 0x0 },
80 : : { 0x80AAAFFF, 0x000B0000, 0x0 },
81 : : { 0x00FFFFFF, 0x0005000A, 0x0 },
82 : : { 0x00D75FFF, 0x000C0004, 0x0 },
83 : : { 0x80C30FFF, 0x000B0000, 0x0 },
84 : : { 0x00FFFFFF, 0x00040006, 0x0 },
85 : : { 0x80D75FFF, 0x000B0000, 0x0 },
86 : : };
87 : :
88 : : static const struct ddi_buf_trans hsw_ddi_translations_fdi[] = {
89 : : { 0x00FFFFFF, 0x0007000E, 0x0 },
90 : : { 0x00D75FFF, 0x000F000A, 0x0 },
91 : : { 0x00C30FFF, 0x00060006, 0x0 },
92 : : { 0x00AAAFFF, 0x001E0000, 0x0 },
93 : : { 0x00FFFFFF, 0x000F000A, 0x0 },
94 : : { 0x00D75FFF, 0x00160004, 0x0 },
95 : : { 0x00C30FFF, 0x001E0000, 0x0 },
96 : : { 0x00FFFFFF, 0x00060006, 0x0 },
97 : : { 0x00D75FFF, 0x001E0000, 0x0 },
98 : : };
99 : :
100 : : static const struct ddi_buf_trans hsw_ddi_translations_hdmi[] = {
101 : : /* Idx NT mV d T mV d db */
102 : : { 0x00FFFFFF, 0x0006000E, 0x0 },/* 0: 400 400 0 */
103 : : { 0x00E79FFF, 0x000E000C, 0x0 },/* 1: 400 500 2 */
104 : : { 0x00D75FFF, 0x0005000A, 0x0 },/* 2: 400 600 3.5 */
105 : : { 0x00FFFFFF, 0x0005000A, 0x0 },/* 3: 600 600 0 */
106 : : { 0x00E79FFF, 0x001D0007, 0x0 },/* 4: 600 750 2 */
107 : : { 0x00D75FFF, 0x000C0004, 0x0 },/* 5: 600 900 3.5 */
108 : : { 0x00FFFFFF, 0x00040006, 0x0 },/* 6: 800 800 0 */
109 : : { 0x80E79FFF, 0x00030002, 0x0 },/* 7: 800 1000 2 */
110 : : { 0x00FFFFFF, 0x00140005, 0x0 },/* 8: 850 850 0 */
111 : : { 0x00FFFFFF, 0x000C0004, 0x0 },/* 9: 900 900 0 */
112 : : { 0x00FFFFFF, 0x001C0003, 0x0 },/* 10: 950 950 0 */
113 : : { 0x80FFFFFF, 0x00030002, 0x0 },/* 11: 1000 1000 0 */
114 : : };
115 : :
116 : : static const struct ddi_buf_trans bdw_ddi_translations_edp[] = {
117 : : { 0x00FFFFFF, 0x00000012, 0x0 },
118 : : { 0x00EBAFFF, 0x00020011, 0x0 },
119 : : { 0x00C71FFF, 0x0006000F, 0x0 },
120 : : { 0x00AAAFFF, 0x000E000A, 0x0 },
121 : : { 0x00FFFFFF, 0x00020011, 0x0 },
122 : : { 0x00DB6FFF, 0x0005000F, 0x0 },
123 : : { 0x00BEEFFF, 0x000A000C, 0x0 },
124 : : { 0x00FFFFFF, 0x0005000F, 0x0 },
125 : : { 0x00DB6FFF, 0x000A000C, 0x0 },
126 : : };
127 : :
128 : : static const struct ddi_buf_trans bdw_ddi_translations_dp[] = {
129 : : { 0x00FFFFFF, 0x0007000E, 0x0 },
130 : : { 0x00D75FFF, 0x000E000A, 0x0 },
131 : : { 0x00BEFFFF, 0x00140006, 0x0 },
132 : : { 0x80B2CFFF, 0x001B0002, 0x0 },
133 : : { 0x00FFFFFF, 0x000E000A, 0x0 },
134 : : { 0x00DB6FFF, 0x00160005, 0x0 },
135 : : { 0x80C71FFF, 0x001A0002, 0x0 },
136 : : { 0x00F7DFFF, 0x00180004, 0x0 },
137 : : { 0x80D75FFF, 0x001B0002, 0x0 },
138 : : };
139 : :
140 : : static const struct ddi_buf_trans bdw_ddi_translations_fdi[] = {
141 : : { 0x00FFFFFF, 0x0001000E, 0x0 },
142 : : { 0x00D75FFF, 0x0004000A, 0x0 },
143 : : { 0x00C30FFF, 0x00070006, 0x0 },
144 : : { 0x00AAAFFF, 0x000C0000, 0x0 },
145 : : { 0x00FFFFFF, 0x0004000A, 0x0 },
146 : : { 0x00D75FFF, 0x00090004, 0x0 },
147 : : { 0x00C30FFF, 0x000C0000, 0x0 },
148 : : { 0x00FFFFFF, 0x00070006, 0x0 },
149 : : { 0x00D75FFF, 0x000C0000, 0x0 },
150 : : };
151 : :
152 : : static const struct ddi_buf_trans bdw_ddi_translations_hdmi[] = {
153 : : /* Idx NT mV d T mV df db */
154 : : { 0x00FFFFFF, 0x0007000E, 0x0 },/* 0: 400 400 0 */
155 : : { 0x00D75FFF, 0x000E000A, 0x0 },/* 1: 400 600 3.5 */
156 : : { 0x00BEFFFF, 0x00140006, 0x0 },/* 2: 400 800 6 */
157 : : { 0x00FFFFFF, 0x0009000D, 0x0 },/* 3: 450 450 0 */
158 : : { 0x00FFFFFF, 0x000E000A, 0x0 },/* 4: 600 600 0 */
159 : : { 0x00D7FFFF, 0x00140006, 0x0 },/* 5: 600 800 2.5 */
160 : : { 0x80CB2FFF, 0x001B0002, 0x0 },/* 6: 600 1000 4.5 */
161 : : { 0x00FFFFFF, 0x00140006, 0x0 },/* 7: 800 800 0 */
162 : : { 0x80E79FFF, 0x001B0002, 0x0 },/* 8: 800 1000 2 */
163 : : { 0x80FFFFFF, 0x001B0002, 0x0 },/* 9: 1000 1000 0 */
164 : : };
165 : :
166 : : /* Skylake H and S */
167 : : static const struct ddi_buf_trans skl_ddi_translations_dp[] = {
168 : : { 0x00002016, 0x000000A0, 0x0 },
169 : : { 0x00005012, 0x0000009B, 0x0 },
170 : : { 0x00007011, 0x00000088, 0x0 },
171 : : { 0x80009010, 0x000000C0, 0x1 },
172 : : { 0x00002016, 0x0000009B, 0x0 },
173 : : { 0x00005012, 0x00000088, 0x0 },
174 : : { 0x80007011, 0x000000C0, 0x1 },
175 : : { 0x00002016, 0x000000DF, 0x0 },
176 : : { 0x80005012, 0x000000C0, 0x1 },
177 : : };
178 : :
179 : : /* Skylake U */
180 : : static const struct ddi_buf_trans skl_u_ddi_translations_dp[] = {
181 : : { 0x0000201B, 0x000000A2, 0x0 },
182 : : { 0x00005012, 0x00000088, 0x0 },
183 : : { 0x80007011, 0x000000CD, 0x1 },
184 : : { 0x80009010, 0x000000C0, 0x1 },
185 : : { 0x0000201B, 0x0000009D, 0x0 },
186 : : { 0x80005012, 0x000000C0, 0x1 },
187 : : { 0x80007011, 0x000000C0, 0x1 },
188 : : { 0x00002016, 0x00000088, 0x0 },
189 : : { 0x80005012, 0x000000C0, 0x1 },
190 : : };
191 : :
192 : : /* Skylake Y */
193 : : static const struct ddi_buf_trans skl_y_ddi_translations_dp[] = {
194 : : { 0x00000018, 0x000000A2, 0x0 },
195 : : { 0x00005012, 0x00000088, 0x0 },
196 : : { 0x80007011, 0x000000CD, 0x3 },
197 : : { 0x80009010, 0x000000C0, 0x3 },
198 : : { 0x00000018, 0x0000009D, 0x0 },
199 : : { 0x80005012, 0x000000C0, 0x3 },
200 : : { 0x80007011, 0x000000C0, 0x3 },
201 : : { 0x00000018, 0x00000088, 0x0 },
202 : : { 0x80005012, 0x000000C0, 0x3 },
203 : : };
204 : :
205 : : /* Kabylake H and S */
206 : : static const struct ddi_buf_trans kbl_ddi_translations_dp[] = {
207 : : { 0x00002016, 0x000000A0, 0x0 },
208 : : { 0x00005012, 0x0000009B, 0x0 },
209 : : { 0x00007011, 0x00000088, 0x0 },
210 : : { 0x80009010, 0x000000C0, 0x1 },
211 : : { 0x00002016, 0x0000009B, 0x0 },
212 : : { 0x00005012, 0x00000088, 0x0 },
213 : : { 0x80007011, 0x000000C0, 0x1 },
214 : : { 0x00002016, 0x00000097, 0x0 },
215 : : { 0x80005012, 0x000000C0, 0x1 },
216 : : };
217 : :
218 : : /* Kabylake U */
219 : : static const struct ddi_buf_trans kbl_u_ddi_translations_dp[] = {
220 : : { 0x0000201B, 0x000000A1, 0x0 },
221 : : { 0x00005012, 0x00000088, 0x0 },
222 : : { 0x80007011, 0x000000CD, 0x3 },
223 : : { 0x80009010, 0x000000C0, 0x3 },
224 : : { 0x0000201B, 0x0000009D, 0x0 },
225 : : { 0x80005012, 0x000000C0, 0x3 },
226 : : { 0x80007011, 0x000000C0, 0x3 },
227 : : { 0x00002016, 0x0000004F, 0x0 },
228 : : { 0x80005012, 0x000000C0, 0x3 },
229 : : };
230 : :
231 : : /* Kabylake Y */
232 : : static const struct ddi_buf_trans kbl_y_ddi_translations_dp[] = {
233 : : { 0x00001017, 0x000000A1, 0x0 },
234 : : { 0x00005012, 0x00000088, 0x0 },
235 : : { 0x80007011, 0x000000CD, 0x3 },
236 : : { 0x8000800F, 0x000000C0, 0x3 },
237 : : { 0x00001017, 0x0000009D, 0x0 },
238 : : { 0x80005012, 0x000000C0, 0x3 },
239 : : { 0x80007011, 0x000000C0, 0x3 },
240 : : { 0x00001017, 0x0000004C, 0x0 },
241 : : { 0x80005012, 0x000000C0, 0x3 },
242 : : };
243 : :
244 : : /*
245 : : * Skylake/Kabylake H and S
246 : : * eDP 1.4 low vswing translation parameters
247 : : */
248 : : static const struct ddi_buf_trans skl_ddi_translations_edp[] = {
249 : : { 0x00000018, 0x000000A8, 0x0 },
250 : : { 0x00004013, 0x000000A9, 0x0 },
251 : : { 0x00007011, 0x000000A2, 0x0 },
252 : : { 0x00009010, 0x0000009C, 0x0 },
253 : : { 0x00000018, 0x000000A9, 0x0 },
254 : : { 0x00006013, 0x000000A2, 0x0 },
255 : : { 0x00007011, 0x000000A6, 0x0 },
256 : : { 0x00000018, 0x000000AB, 0x0 },
257 : : { 0x00007013, 0x0000009F, 0x0 },
258 : : { 0x00000018, 0x000000DF, 0x0 },
259 : : };
260 : :
261 : : /*
262 : : * Skylake/Kabylake U
263 : : * eDP 1.4 low vswing translation parameters
264 : : */
265 : : static const struct ddi_buf_trans skl_u_ddi_translations_edp[] = {
266 : : { 0x00000018, 0x000000A8, 0x0 },
267 : : { 0x00004013, 0x000000A9, 0x0 },
268 : : { 0x00007011, 0x000000A2, 0x0 },
269 : : { 0x00009010, 0x0000009C, 0x0 },
270 : : { 0x00000018, 0x000000A9, 0x0 },
271 : : { 0x00006013, 0x000000A2, 0x0 },
272 : : { 0x00007011, 0x000000A6, 0x0 },
273 : : { 0x00002016, 0x000000AB, 0x0 },
274 : : { 0x00005013, 0x0000009F, 0x0 },
275 : : { 0x00000018, 0x000000DF, 0x0 },
276 : : };
277 : :
278 : : /*
279 : : * Skylake/Kabylake Y
280 : : * eDP 1.4 low vswing translation parameters
281 : : */
282 : : static const struct ddi_buf_trans skl_y_ddi_translations_edp[] = {
283 : : { 0x00000018, 0x000000A8, 0x0 },
284 : : { 0x00004013, 0x000000AB, 0x0 },
285 : : { 0x00007011, 0x000000A4, 0x0 },
286 : : { 0x00009010, 0x000000DF, 0x0 },
287 : : { 0x00000018, 0x000000AA, 0x0 },
288 : : { 0x00006013, 0x000000A4, 0x0 },
289 : : { 0x00007011, 0x0000009D, 0x0 },
290 : : { 0x00000018, 0x000000A0, 0x0 },
291 : : { 0x00006012, 0x000000DF, 0x0 },
292 : : { 0x00000018, 0x0000008A, 0x0 },
293 : : };
294 : :
295 : : /* Skylake/Kabylake U, H and S */
296 : : static const struct ddi_buf_trans skl_ddi_translations_hdmi[] = {
297 : : { 0x00000018, 0x000000AC, 0x0 },
298 : : { 0x00005012, 0x0000009D, 0x0 },
299 : : { 0x00007011, 0x00000088, 0x0 },
300 : : { 0x00000018, 0x000000A1, 0x0 },
301 : : { 0x00000018, 0x00000098, 0x0 },
302 : : { 0x00004013, 0x00000088, 0x0 },
303 : : { 0x80006012, 0x000000CD, 0x1 },
304 : : { 0x00000018, 0x000000DF, 0x0 },
305 : : { 0x80003015, 0x000000CD, 0x1 }, /* Default */
306 : : { 0x80003015, 0x000000C0, 0x1 },
307 : : { 0x80000018, 0x000000C0, 0x1 },
308 : : };
309 : :
310 : : /* Skylake/Kabylake Y */
311 : : static const struct ddi_buf_trans skl_y_ddi_translations_hdmi[] = {
312 : : { 0x00000018, 0x000000A1, 0x0 },
313 : : { 0x00005012, 0x000000DF, 0x0 },
314 : : { 0x80007011, 0x000000CB, 0x3 },
315 : : { 0x00000018, 0x000000A4, 0x0 },
316 : : { 0x00000018, 0x0000009D, 0x0 },
317 : : { 0x00004013, 0x00000080, 0x0 },
318 : : { 0x80006013, 0x000000C0, 0x3 },
319 : : { 0x00000018, 0x0000008A, 0x0 },
320 : : { 0x80003015, 0x000000C0, 0x3 }, /* Default */
321 : : { 0x80003015, 0x000000C0, 0x3 },
322 : : { 0x80000018, 0x000000C0, 0x3 },
323 : : };
324 : :
325 : : struct bxt_ddi_buf_trans {
326 : : u8 margin; /* swing value */
327 : : u8 scale; /* scale value */
328 : : u8 enable; /* scale enable */
329 : : u8 deemphasis;
330 : : };
331 : :
332 : : static const struct bxt_ddi_buf_trans bxt_ddi_translations_dp[] = {
333 : : /* Idx NT mV diff db */
334 : : { 52, 0x9A, 0, 128, }, /* 0: 400 0 */
335 : : { 78, 0x9A, 0, 85, }, /* 1: 400 3.5 */
336 : : { 104, 0x9A, 0, 64, }, /* 2: 400 6 */
337 : : { 154, 0x9A, 0, 43, }, /* 3: 400 9.5 */
338 : : { 77, 0x9A, 0, 128, }, /* 4: 600 0 */
339 : : { 116, 0x9A, 0, 85, }, /* 5: 600 3.5 */
340 : : { 154, 0x9A, 0, 64, }, /* 6: 600 6 */
341 : : { 102, 0x9A, 0, 128, }, /* 7: 800 0 */
342 : : { 154, 0x9A, 0, 85, }, /* 8: 800 3.5 */
343 : : { 154, 0x9A, 1, 128, }, /* 9: 1200 0 */
344 : : };
345 : :
346 : : static const struct bxt_ddi_buf_trans bxt_ddi_translations_edp[] = {
347 : : /* Idx NT mV diff db */
348 : : { 26, 0, 0, 128, }, /* 0: 200 0 */
349 : : { 38, 0, 0, 112, }, /* 1: 200 1.5 */
350 : : { 48, 0, 0, 96, }, /* 2: 200 4 */
351 : : { 54, 0, 0, 69, }, /* 3: 200 6 */
352 : : { 32, 0, 0, 128, }, /* 4: 250 0 */
353 : : { 48, 0, 0, 104, }, /* 5: 250 1.5 */
354 : : { 54, 0, 0, 85, }, /* 6: 250 4 */
355 : : { 43, 0, 0, 128, }, /* 7: 300 0 */
356 : : { 54, 0, 0, 101, }, /* 8: 300 1.5 */
357 : : { 48, 0, 0, 128, }, /* 9: 300 0 */
358 : : };
359 : :
360 : : /* BSpec has 2 recommended values - entries 0 and 8.
361 : : * Using the entry with higher vswing.
362 : : */
363 : : static const struct bxt_ddi_buf_trans bxt_ddi_translations_hdmi[] = {
364 : : /* Idx NT mV diff db */
365 : : { 52, 0x9A, 0, 128, }, /* 0: 400 0 */
366 : : { 52, 0x9A, 0, 85, }, /* 1: 400 3.5 */
367 : : { 52, 0x9A, 0, 64, }, /* 2: 400 6 */
368 : : { 42, 0x9A, 0, 43, }, /* 3: 400 9.5 */
369 : : { 77, 0x9A, 0, 128, }, /* 4: 600 0 */
370 : : { 77, 0x9A, 0, 85, }, /* 5: 600 3.5 */
371 : : { 77, 0x9A, 0, 64, }, /* 6: 600 6 */
372 : : { 102, 0x9A, 0, 128, }, /* 7: 800 0 */
373 : : { 102, 0x9A, 0, 85, }, /* 8: 800 3.5 */
374 : : { 154, 0x9A, 1, 128, }, /* 9: 1200 0 */
375 : : };
376 : :
377 : : struct cnl_ddi_buf_trans {
378 : : u8 dw2_swing_sel;
379 : : u8 dw7_n_scalar;
380 : : u8 dw4_cursor_coeff;
381 : : u8 dw4_post_cursor_2;
382 : : u8 dw4_post_cursor_1;
383 : : };
384 : :
385 : : /* Voltage Swing Programming for VccIO 0.85V for DP */
386 : : static const struct cnl_ddi_buf_trans cnl_ddi_translations_dp_0_85V[] = {
387 : : /* NT mV Trans mV db */
388 : : { 0xA, 0x5D, 0x3F, 0x00, 0x00 }, /* 350 350 0.0 */
389 : : { 0xA, 0x6A, 0x38, 0x00, 0x07 }, /* 350 500 3.1 */
390 : : { 0xB, 0x7A, 0x32, 0x00, 0x0D }, /* 350 700 6.0 */
391 : : { 0x6, 0x7C, 0x2D, 0x00, 0x12 }, /* 350 900 8.2 */
392 : : { 0xA, 0x69, 0x3F, 0x00, 0x00 }, /* 500 500 0.0 */
393 : : { 0xB, 0x7A, 0x36, 0x00, 0x09 }, /* 500 700 2.9 */
394 : : { 0x6, 0x7C, 0x30, 0x00, 0x0F }, /* 500 900 5.1 */
395 : : { 0xB, 0x7D, 0x3C, 0x00, 0x03 }, /* 650 725 0.9 */
396 : : { 0x6, 0x7C, 0x34, 0x00, 0x0B }, /* 600 900 3.5 */
397 : : { 0x6, 0x7B, 0x3F, 0x00, 0x00 }, /* 900 900 0.0 */
398 : : };
399 : :
400 : : /* Voltage Swing Programming for VccIO 0.85V for HDMI */
401 : : static const struct cnl_ddi_buf_trans cnl_ddi_translations_hdmi_0_85V[] = {
402 : : /* NT mV Trans mV db */
403 : : { 0xA, 0x60, 0x3F, 0x00, 0x00 }, /* 450 450 0.0 */
404 : : { 0xB, 0x73, 0x36, 0x00, 0x09 }, /* 450 650 3.2 */
405 : : { 0x6, 0x7F, 0x31, 0x00, 0x0E }, /* 450 850 5.5 */
406 : : { 0xB, 0x73, 0x3F, 0x00, 0x00 }, /* 650 650 0.0 */
407 : : { 0x6, 0x7F, 0x37, 0x00, 0x08 }, /* 650 850 2.3 */
408 : : { 0x6, 0x7F, 0x3F, 0x00, 0x00 }, /* 850 850 0.0 */
409 : : { 0x6, 0x7F, 0x35, 0x00, 0x0A }, /* 600 850 3.0 */
410 : : };
411 : :
412 : : /* Voltage Swing Programming for VccIO 0.85V for eDP */
413 : : static const struct cnl_ddi_buf_trans cnl_ddi_translations_edp_0_85V[] = {
414 : : /* NT mV Trans mV db */
415 : : { 0xA, 0x66, 0x3A, 0x00, 0x05 }, /* 384 500 2.3 */
416 : : { 0x0, 0x7F, 0x38, 0x00, 0x07 }, /* 153 200 2.3 */
417 : : { 0x8, 0x7F, 0x38, 0x00, 0x07 }, /* 192 250 2.3 */
418 : : { 0x1, 0x7F, 0x38, 0x00, 0x07 }, /* 230 300 2.3 */
419 : : { 0x9, 0x7F, 0x38, 0x00, 0x07 }, /* 269 350 2.3 */
420 : : { 0xA, 0x66, 0x3C, 0x00, 0x03 }, /* 446 500 1.0 */
421 : : { 0xB, 0x70, 0x3C, 0x00, 0x03 }, /* 460 600 2.3 */
422 : : { 0xC, 0x75, 0x3C, 0x00, 0x03 }, /* 537 700 2.3 */
423 : : { 0x2, 0x7F, 0x3F, 0x00, 0x00 }, /* 400 400 0.0 */
424 : : };
425 : :
426 : : /* Voltage Swing Programming for VccIO 0.95V for DP */
427 : : static const struct cnl_ddi_buf_trans cnl_ddi_translations_dp_0_95V[] = {
428 : : /* NT mV Trans mV db */
429 : : { 0xA, 0x5D, 0x3F, 0x00, 0x00 }, /* 350 350 0.0 */
430 : : { 0xA, 0x6A, 0x38, 0x00, 0x07 }, /* 350 500 3.1 */
431 : : { 0xB, 0x7A, 0x32, 0x00, 0x0D }, /* 350 700 6.0 */
432 : : { 0x6, 0x7C, 0x2D, 0x00, 0x12 }, /* 350 900 8.2 */
433 : : { 0xA, 0x69, 0x3F, 0x00, 0x00 }, /* 500 500 0.0 */
434 : : { 0xB, 0x7A, 0x36, 0x00, 0x09 }, /* 500 700 2.9 */
435 : : { 0x6, 0x7C, 0x30, 0x00, 0x0F }, /* 500 900 5.1 */
436 : : { 0xB, 0x7D, 0x3C, 0x00, 0x03 }, /* 650 725 0.9 */
437 : : { 0x6, 0x7C, 0x34, 0x00, 0x0B }, /* 600 900 3.5 */
438 : : { 0x6, 0x7B, 0x3F, 0x00, 0x00 }, /* 900 900 0.0 */
439 : : };
440 : :
441 : : /* Voltage Swing Programming for VccIO 0.95V for HDMI */
442 : : static const struct cnl_ddi_buf_trans cnl_ddi_translations_hdmi_0_95V[] = {
443 : : /* NT mV Trans mV db */
444 : : { 0xA, 0x5C, 0x3F, 0x00, 0x00 }, /* 400 400 0.0 */
445 : : { 0xB, 0x69, 0x37, 0x00, 0x08 }, /* 400 600 3.5 */
446 : : { 0x5, 0x76, 0x31, 0x00, 0x0E }, /* 400 800 6.0 */
447 : : { 0xA, 0x5E, 0x3F, 0x00, 0x00 }, /* 450 450 0.0 */
448 : : { 0xB, 0x69, 0x3F, 0x00, 0x00 }, /* 600 600 0.0 */
449 : : { 0xB, 0x79, 0x35, 0x00, 0x0A }, /* 600 850 3.0 */
450 : : { 0x6, 0x7D, 0x32, 0x00, 0x0D }, /* 600 1000 4.4 */
451 : : { 0x5, 0x76, 0x3F, 0x00, 0x00 }, /* 800 800 0.0 */
452 : : { 0x6, 0x7D, 0x39, 0x00, 0x06 }, /* 800 1000 1.9 */
453 : : { 0x6, 0x7F, 0x39, 0x00, 0x06 }, /* 850 1050 1.8 */
454 : : { 0x6, 0x7F, 0x3F, 0x00, 0x00 }, /* 1050 1050 0.0 */
455 : : };
456 : :
457 : : /* Voltage Swing Programming for VccIO 0.95V for eDP */
458 : : static const struct cnl_ddi_buf_trans cnl_ddi_translations_edp_0_95V[] = {
459 : : /* NT mV Trans mV db */
460 : : { 0xA, 0x61, 0x3A, 0x00, 0x05 }, /* 384 500 2.3 */
461 : : { 0x0, 0x7F, 0x38, 0x00, 0x07 }, /* 153 200 2.3 */
462 : : { 0x8, 0x7F, 0x38, 0x00, 0x07 }, /* 192 250 2.3 */
463 : : { 0x1, 0x7F, 0x38, 0x00, 0x07 }, /* 230 300 2.3 */
464 : : { 0x9, 0x7F, 0x38, 0x00, 0x07 }, /* 269 350 2.3 */
465 : : { 0xA, 0x61, 0x3C, 0x00, 0x03 }, /* 446 500 1.0 */
466 : : { 0xB, 0x68, 0x39, 0x00, 0x06 }, /* 460 600 2.3 */
467 : : { 0xC, 0x6E, 0x39, 0x00, 0x06 }, /* 537 700 2.3 */
468 : : { 0x4, 0x7F, 0x3A, 0x00, 0x05 }, /* 460 600 2.3 */
469 : : { 0x2, 0x7F, 0x3F, 0x00, 0x00 }, /* 400 400 0.0 */
470 : : };
471 : :
472 : : /* Voltage Swing Programming for VccIO 1.05V for DP */
473 : : static const struct cnl_ddi_buf_trans cnl_ddi_translations_dp_1_05V[] = {
474 : : /* NT mV Trans mV db */
475 : : { 0xA, 0x58, 0x3F, 0x00, 0x00 }, /* 400 400 0.0 */
476 : : { 0xB, 0x64, 0x37, 0x00, 0x08 }, /* 400 600 3.5 */
477 : : { 0x5, 0x70, 0x31, 0x00, 0x0E }, /* 400 800 6.0 */
478 : : { 0x6, 0x7F, 0x2C, 0x00, 0x13 }, /* 400 1050 8.4 */
479 : : { 0xB, 0x64, 0x3F, 0x00, 0x00 }, /* 600 600 0.0 */
480 : : { 0x5, 0x73, 0x35, 0x00, 0x0A }, /* 600 850 3.0 */
481 : : { 0x6, 0x7F, 0x30, 0x00, 0x0F }, /* 550 1050 5.6 */
482 : : { 0x5, 0x76, 0x3E, 0x00, 0x01 }, /* 850 900 0.5 */
483 : : { 0x6, 0x7F, 0x36, 0x00, 0x09 }, /* 750 1050 2.9 */
484 : : { 0x6, 0x7F, 0x3F, 0x00, 0x00 }, /* 1050 1050 0.0 */
485 : : };
486 : :
487 : : /* Voltage Swing Programming for VccIO 1.05V for HDMI */
488 : : static const struct cnl_ddi_buf_trans cnl_ddi_translations_hdmi_1_05V[] = {
489 : : /* NT mV Trans mV db */
490 : : { 0xA, 0x58, 0x3F, 0x00, 0x00 }, /* 400 400 0.0 */
491 : : { 0xB, 0x64, 0x37, 0x00, 0x08 }, /* 400 600 3.5 */
492 : : { 0x5, 0x70, 0x31, 0x00, 0x0E }, /* 400 800 6.0 */
493 : : { 0xA, 0x5B, 0x3F, 0x00, 0x00 }, /* 450 450 0.0 */
494 : : { 0xB, 0x64, 0x3F, 0x00, 0x00 }, /* 600 600 0.0 */
495 : : { 0x5, 0x73, 0x35, 0x00, 0x0A }, /* 600 850 3.0 */
496 : : { 0x6, 0x7C, 0x32, 0x00, 0x0D }, /* 600 1000 4.4 */
497 : : { 0x5, 0x70, 0x3F, 0x00, 0x00 }, /* 800 800 0.0 */
498 : : { 0x6, 0x7C, 0x39, 0x00, 0x06 }, /* 800 1000 1.9 */
499 : : { 0x6, 0x7F, 0x39, 0x00, 0x06 }, /* 850 1050 1.8 */
500 : : { 0x6, 0x7F, 0x3F, 0x00, 0x00 }, /* 1050 1050 0.0 */
501 : : };
502 : :
503 : : /* Voltage Swing Programming for VccIO 1.05V for eDP */
504 : : static const struct cnl_ddi_buf_trans cnl_ddi_translations_edp_1_05V[] = {
505 : : /* NT mV Trans mV db */
506 : : { 0xA, 0x5E, 0x3A, 0x00, 0x05 }, /* 384 500 2.3 */
507 : : { 0x0, 0x7F, 0x38, 0x00, 0x07 }, /* 153 200 2.3 */
508 : : { 0x8, 0x7F, 0x38, 0x00, 0x07 }, /* 192 250 2.3 */
509 : : { 0x1, 0x7F, 0x38, 0x00, 0x07 }, /* 230 300 2.3 */
510 : : { 0x9, 0x7F, 0x38, 0x00, 0x07 }, /* 269 350 2.3 */
511 : : { 0xA, 0x5E, 0x3C, 0x00, 0x03 }, /* 446 500 1.0 */
512 : : { 0xB, 0x64, 0x39, 0x00, 0x06 }, /* 460 600 2.3 */
513 : : { 0xE, 0x6A, 0x39, 0x00, 0x06 }, /* 537 700 2.3 */
514 : : { 0x2, 0x7F, 0x3F, 0x00, 0x00 }, /* 400 400 0.0 */
515 : : };
516 : :
517 : : /* icl_combo_phy_ddi_translations */
518 : : static const struct cnl_ddi_buf_trans icl_combo_phy_ddi_translations_dp_hbr2[] = {
519 : : /* NT mV Trans mV db */
520 : : { 0xA, 0x35, 0x3F, 0x00, 0x00 }, /* 350 350 0.0 */
521 : : { 0xA, 0x4F, 0x37, 0x00, 0x08 }, /* 350 500 3.1 */
522 : : { 0xC, 0x71, 0x2F, 0x00, 0x10 }, /* 350 700 6.0 */
523 : : { 0x6, 0x7F, 0x2B, 0x00, 0x14 }, /* 350 900 8.2 */
524 : : { 0xA, 0x4C, 0x3F, 0x00, 0x00 }, /* 500 500 0.0 */
525 : : { 0xC, 0x73, 0x34, 0x00, 0x0B }, /* 500 700 2.9 */
526 : : { 0x6, 0x7F, 0x2F, 0x00, 0x10 }, /* 500 900 5.1 */
527 : : { 0xC, 0x6C, 0x3C, 0x00, 0x03 }, /* 650 700 0.6 */
528 : : { 0x6, 0x7F, 0x35, 0x00, 0x0A }, /* 600 900 3.5 */
529 : : { 0x6, 0x7F, 0x3F, 0x00, 0x00 }, /* 900 900 0.0 */
530 : : };
531 : :
532 : : static const struct cnl_ddi_buf_trans icl_combo_phy_ddi_translations_edp_hbr2[] = {
533 : : /* NT mV Trans mV db */
534 : : { 0x0, 0x7F, 0x3F, 0x00, 0x00 }, /* 200 200 0.0 */
535 : : { 0x8, 0x7F, 0x38, 0x00, 0x07 }, /* 200 250 1.9 */
536 : : { 0x1, 0x7F, 0x33, 0x00, 0x0C }, /* 200 300 3.5 */
537 : : { 0x9, 0x7F, 0x31, 0x00, 0x0E }, /* 200 350 4.9 */
538 : : { 0x8, 0x7F, 0x3F, 0x00, 0x00 }, /* 250 250 0.0 */
539 : : { 0x1, 0x7F, 0x38, 0x00, 0x07 }, /* 250 300 1.6 */
540 : : { 0x9, 0x7F, 0x35, 0x00, 0x0A }, /* 250 350 2.9 */
541 : : { 0x1, 0x7F, 0x3F, 0x00, 0x00 }, /* 300 300 0.0 */
542 : : { 0x9, 0x7F, 0x38, 0x00, 0x07 }, /* 300 350 1.3 */
543 : : { 0x9, 0x7F, 0x3F, 0x00, 0x00 }, /* 350 350 0.0 */
544 : : };
545 : :
546 : : static const struct cnl_ddi_buf_trans icl_combo_phy_ddi_translations_edp_hbr3[] = {
547 : : /* NT mV Trans mV db */
548 : : { 0xA, 0x35, 0x3F, 0x00, 0x00 }, /* 350 350 0.0 */
549 : : { 0xA, 0x4F, 0x37, 0x00, 0x08 }, /* 350 500 3.1 */
550 : : { 0xC, 0x71, 0x2F, 0x00, 0x10 }, /* 350 700 6.0 */
551 : : { 0x6, 0x7F, 0x2B, 0x00, 0x14 }, /* 350 900 8.2 */
552 : : { 0xA, 0x4C, 0x3F, 0x00, 0x00 }, /* 500 500 0.0 */
553 : : { 0xC, 0x73, 0x34, 0x00, 0x0B }, /* 500 700 2.9 */
554 : : { 0x6, 0x7F, 0x2F, 0x00, 0x10 }, /* 500 900 5.1 */
555 : : { 0xC, 0x6C, 0x3C, 0x00, 0x03 }, /* 650 700 0.6 */
556 : : { 0x6, 0x7F, 0x35, 0x00, 0x0A }, /* 600 900 3.5 */
557 : : { 0x6, 0x7F, 0x3F, 0x00, 0x00 }, /* 900 900 0.0 */
558 : : };
559 : :
560 : : static const struct cnl_ddi_buf_trans icl_combo_phy_ddi_translations_hdmi[] = {
561 : : /* NT mV Trans mV db */
562 : : { 0xA, 0x60, 0x3F, 0x00, 0x00 }, /* 450 450 0.0 */
563 : : { 0xB, 0x73, 0x36, 0x00, 0x09 }, /* 450 650 3.2 */
564 : : { 0x6, 0x7F, 0x31, 0x00, 0x0E }, /* 450 850 5.5 */
565 : : { 0xB, 0x73, 0x3F, 0x00, 0x00 }, /* 650 650 0.0 ALS */
566 : : { 0x6, 0x7F, 0x37, 0x00, 0x08 }, /* 650 850 2.3 */
567 : : { 0x6, 0x7F, 0x3F, 0x00, 0x00 }, /* 850 850 0.0 */
568 : : { 0x6, 0x7F, 0x35, 0x00, 0x0A }, /* 600 850 3.0 */
569 : : };
570 : :
571 : : struct icl_mg_phy_ddi_buf_trans {
572 : : u32 cri_txdeemph_override_5_0;
573 : : u32 cri_txdeemph_override_11_6;
574 : : u32 cri_txdeemph_override_17_12;
575 : : };
576 : :
577 : : static const struct icl_mg_phy_ddi_buf_trans icl_mg_phy_ddi_translations[] = {
578 : : /* Voltage swing pre-emphasis */
579 : : { 0x0, 0x1B, 0x00 }, /* 0 0 */
580 : : { 0x0, 0x23, 0x08 }, /* 0 1 */
581 : : { 0x0, 0x2D, 0x12 }, /* 0 2 */
582 : : { 0x0, 0x00, 0x00 }, /* 0 3 */
583 : : { 0x0, 0x23, 0x00 }, /* 1 0 */
584 : : { 0x0, 0x2B, 0x09 }, /* 1 1 */
585 : : { 0x0, 0x2E, 0x11 }, /* 1 2 */
586 : : { 0x0, 0x2F, 0x00 }, /* 2 0 */
587 : : { 0x0, 0x33, 0x0C }, /* 2 1 */
588 : : { 0x0, 0x00, 0x00 }, /* 3 0 */
589 : : };
590 : :
591 : : struct tgl_dkl_phy_ddi_buf_trans {
592 : : u32 dkl_vswing_control;
593 : : u32 dkl_preshoot_control;
594 : : u32 dkl_de_emphasis_control;
595 : : };
596 : :
597 : : static const struct tgl_dkl_phy_ddi_buf_trans tgl_dkl_phy_dp_ddi_trans[] = {
598 : : /* VS pre-emp Non-trans mV Pre-emph dB */
599 : : { 0x7, 0x0, 0x00 }, /* 0 0 400mV 0 dB */
600 : : { 0x5, 0x0, 0x03 }, /* 0 1 400mV 3.5 dB */
601 : : { 0x2, 0x0, 0x0b }, /* 0 2 400mV 6 dB */
602 : : { 0x0, 0x0, 0x19 }, /* 0 3 400mV 9.5 dB */
603 : : { 0x5, 0x0, 0x00 }, /* 1 0 600mV 0 dB */
604 : : { 0x2, 0x0, 0x03 }, /* 1 1 600mV 3.5 dB */
605 : : { 0x0, 0x0, 0x14 }, /* 1 2 600mV 6 dB */
606 : : { 0x2, 0x0, 0x00 }, /* 2 0 800mV 0 dB */
607 : : { 0x0, 0x0, 0x0B }, /* 2 1 800mV 3.5 dB */
608 : : { 0x0, 0x0, 0x00 }, /* 3 0 1200mV 0 dB HDMI default */
609 : : };
610 : :
611 : : static const struct tgl_dkl_phy_ddi_buf_trans tgl_dkl_phy_hdmi_ddi_trans[] = {
612 : : /* HDMI Preset VS Pre-emph */
613 : : { 0x7, 0x0, 0x0 }, /* 1 400mV 0dB */
614 : : { 0x6, 0x0, 0x0 }, /* 2 500mV 0dB */
615 : : { 0x4, 0x0, 0x0 }, /* 3 650mV 0dB */
616 : : { 0x2, 0x0, 0x0 }, /* 4 800mV 0dB */
617 : : { 0x0, 0x0, 0x0 }, /* 5 1000mV 0dB */
618 : : { 0x0, 0x0, 0x5 }, /* 6 Full -1.5 dB */
619 : : { 0x0, 0x0, 0x6 }, /* 7 Full -1.8 dB */
620 : : { 0x0, 0x0, 0x7 }, /* 8 Full -2 dB */
621 : : { 0x0, 0x0, 0x8 }, /* 9 Full -2.5 dB */
622 : : { 0x0, 0x0, 0xA }, /* 10 Full -3 dB */
623 : : };
624 : :
625 : : static const struct ddi_buf_trans *
626 : 0 : bdw_get_buf_trans_edp(struct drm_i915_private *dev_priv, int *n_entries)
627 : : {
628 : 0 : if (dev_priv->vbt.edp.low_vswing) {
629 : 0 : *n_entries = ARRAY_SIZE(bdw_ddi_translations_edp);
630 : 0 : return bdw_ddi_translations_edp;
631 : : } else {
632 : 0 : *n_entries = ARRAY_SIZE(bdw_ddi_translations_dp);
633 : 0 : return bdw_ddi_translations_dp;
634 : : }
635 : : }
636 : :
637 : : static const struct ddi_buf_trans *
638 : 0 : skl_get_buf_trans_dp(struct drm_i915_private *dev_priv, int *n_entries)
639 : : {
640 : 0 : if (IS_SKL_ULX(dev_priv)) {
641 : 0 : *n_entries = ARRAY_SIZE(skl_y_ddi_translations_dp);
642 : 0 : return skl_y_ddi_translations_dp;
643 [ # # # # ]: 0 : } else if (IS_SKL_ULT(dev_priv)) {
644 : 0 : *n_entries = ARRAY_SIZE(skl_u_ddi_translations_dp);
645 : 0 : return skl_u_ddi_translations_dp;
646 : : } else {
647 : 0 : *n_entries = ARRAY_SIZE(skl_ddi_translations_dp);
648 : 0 : return skl_ddi_translations_dp;
649 : : }
650 : : }
651 : :
652 : : static const struct ddi_buf_trans *
653 : 0 : kbl_get_buf_trans_dp(struct drm_i915_private *dev_priv, int *n_entries)
654 : : {
655 [ # # # # ]: 0 : if (IS_KBL_ULX(dev_priv) || IS_CFL_ULX(dev_priv)) {
656 : 0 : *n_entries = ARRAY_SIZE(kbl_y_ddi_translations_dp);
657 : 0 : return kbl_y_ddi_translations_dp;
658 [ # # # # : 0 : } else if (IS_KBL_ULT(dev_priv) || IS_CFL_ULT(dev_priv)) {
# # # # ]
659 : 0 : *n_entries = ARRAY_SIZE(kbl_u_ddi_translations_dp);
660 : 0 : return kbl_u_ddi_translations_dp;
661 : : } else {
662 : 0 : *n_entries = ARRAY_SIZE(kbl_ddi_translations_dp);
663 : 0 : return kbl_ddi_translations_dp;
664 : : }
665 : : }
666 : :
667 : : static const struct ddi_buf_trans *
668 : 0 : skl_get_buf_trans_edp(struct drm_i915_private *dev_priv, int *n_entries)
669 : : {
670 [ # # ]: 0 : if (dev_priv->vbt.edp.low_vswing) {
671 [ # # # # : 0 : if (IS_SKL_ULX(dev_priv) || IS_KBL_ULX(dev_priv) ||
# # ]
672 : : IS_CFL_ULX(dev_priv)) {
673 : 0 : *n_entries = ARRAY_SIZE(skl_y_ddi_translations_edp);
674 : 0 : return skl_y_ddi_translations_edp;
675 [ # # # # : 0 : } else if (IS_SKL_ULT(dev_priv) || IS_KBL_ULT(dev_priv) ||
# # ]
676 : : IS_CFL_ULT(dev_priv)) {
677 : 0 : *n_entries = ARRAY_SIZE(skl_u_ddi_translations_edp);
678 : 0 : return skl_u_ddi_translations_edp;
679 : : } else {
680 : 0 : *n_entries = ARRAY_SIZE(skl_ddi_translations_edp);
681 : 0 : return skl_ddi_translations_edp;
682 : : }
683 : : }
684 : :
685 [ # # # # ]: 0 : if (IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv))
686 [ # # ]: 0 : return kbl_get_buf_trans_dp(dev_priv, n_entries);
687 : : else
688 [ # # ]: 0 : return skl_get_buf_trans_dp(dev_priv, n_entries);
689 : : }
690 : :
691 : : static const struct ddi_buf_trans *
692 : 0 : skl_get_buf_trans_hdmi(struct drm_i915_private *dev_priv, int *n_entries)
693 : : {
694 [ # # # # ]: 0 : if (IS_SKL_ULX(dev_priv) || IS_KBL_ULX(dev_priv) ||
695 : : IS_CFL_ULX(dev_priv)) {
696 : 0 : *n_entries = ARRAY_SIZE(skl_y_ddi_translations_hdmi);
697 : 0 : return skl_y_ddi_translations_hdmi;
698 : : } else {
699 : 0 : *n_entries = ARRAY_SIZE(skl_ddi_translations_hdmi);
700 : 0 : return skl_ddi_translations_hdmi;
701 : : }
702 : : }
703 : :
704 : 0 : static int skl_buf_trans_num_entries(enum port port, int n_entries)
705 : : {
706 : : /* Only DDIA and DDIE can select the 10th register with DP */
707 : 0 : if (port == PORT_A || port == PORT_E)
708 : 0 : return min(n_entries, 10);
709 : : else
710 : 0 : return min(n_entries, 9);
711 : : }
712 : :
713 : : static const struct ddi_buf_trans *
714 : 0 : intel_ddi_get_buf_trans_dp(struct drm_i915_private *dev_priv,
715 : : enum port port, int *n_entries)
716 : : {
717 [ # # # # ]: 0 : if (IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv)) {
718 [ # # ]: 0 : const struct ddi_buf_trans *ddi_translations =
719 : : kbl_get_buf_trans_dp(dev_priv, n_entries);
720 [ # # ]: 0 : *n_entries = skl_buf_trans_num_entries(port, *n_entries);
721 : 0 : return ddi_translations;
722 [ # # ]: 0 : } else if (IS_SKYLAKE(dev_priv)) {
723 [ # # ]: 0 : const struct ddi_buf_trans *ddi_translations =
724 : : skl_get_buf_trans_dp(dev_priv, n_entries);
725 [ # # ]: 0 : *n_entries = skl_buf_trans_num_entries(port, *n_entries);
726 : 0 : return ddi_translations;
727 [ # # ]: 0 : } else if (IS_BROADWELL(dev_priv)) {
728 : 0 : *n_entries = ARRAY_SIZE(bdw_ddi_translations_dp);
729 : 0 : return bdw_ddi_translations_dp;
730 [ # # ]: 0 : } else if (IS_HASWELL(dev_priv)) {
731 : 0 : *n_entries = ARRAY_SIZE(hsw_ddi_translations_dp);
732 : 0 : return hsw_ddi_translations_dp;
733 : : }
734 : :
735 : 0 : *n_entries = 0;
736 : 0 : return NULL;
737 : : }
738 : :
739 : : static const struct ddi_buf_trans *
740 : 0 : intel_ddi_get_buf_trans_edp(struct drm_i915_private *dev_priv,
741 : : enum port port, int *n_entries)
742 : : {
743 [ # # # # ]: 0 : if (IS_GEN9_BC(dev_priv)) {
744 : 0 : const struct ddi_buf_trans *ddi_translations =
745 : 0 : skl_get_buf_trans_edp(dev_priv, n_entries);
746 [ # # ]: 0 : *n_entries = skl_buf_trans_num_entries(port, *n_entries);
747 : 0 : return ddi_translations;
748 [ # # ]: 0 : } else if (IS_BROADWELL(dev_priv)) {
749 [ # # ]: 0 : return bdw_get_buf_trans_edp(dev_priv, n_entries);
750 [ # # ]: 0 : } else if (IS_HASWELL(dev_priv)) {
751 : 0 : *n_entries = ARRAY_SIZE(hsw_ddi_translations_dp);
752 : 0 : return hsw_ddi_translations_dp;
753 : : }
754 : :
755 : 0 : *n_entries = 0;
756 : 0 : return NULL;
757 : : }
758 : :
759 : : static const struct ddi_buf_trans *
760 : : intel_ddi_get_buf_trans_fdi(struct drm_i915_private *dev_priv,
761 : : int *n_entries)
762 : : {
763 : : if (IS_BROADWELL(dev_priv)) {
764 : : *n_entries = ARRAY_SIZE(bdw_ddi_translations_fdi);
765 : : return bdw_ddi_translations_fdi;
766 : : } else if (IS_HASWELL(dev_priv)) {
767 : : *n_entries = ARRAY_SIZE(hsw_ddi_translations_fdi);
768 : : return hsw_ddi_translations_fdi;
769 : : }
770 : :
771 : : *n_entries = 0;
772 : : return NULL;
773 : : }
774 : :
775 : : static const struct ddi_buf_trans *
776 : 0 : intel_ddi_get_buf_trans_hdmi(struct drm_i915_private *dev_priv,
777 : : int *n_entries)
778 : : {
779 [ # # # # ]: 0 : if (IS_GEN9_BC(dev_priv)) {
780 [ # # ]: 0 : return skl_get_buf_trans_hdmi(dev_priv, n_entries);
781 [ # # ]: 0 : } else if (IS_BROADWELL(dev_priv)) {
782 : 0 : *n_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
783 : 0 : return bdw_ddi_translations_hdmi;
784 [ # # ]: 0 : } else if (IS_HASWELL(dev_priv)) {
785 : 0 : *n_entries = ARRAY_SIZE(hsw_ddi_translations_hdmi);
786 : 0 : return hsw_ddi_translations_hdmi;
787 : : }
788 : :
789 : 0 : *n_entries = 0;
790 : 0 : return NULL;
791 : : }
792 : :
793 : : static const struct bxt_ddi_buf_trans *
794 : 0 : bxt_get_buf_trans_dp(struct drm_i915_private *dev_priv, int *n_entries)
795 : : {
796 : 0 : *n_entries = ARRAY_SIZE(bxt_ddi_translations_dp);
797 : 0 : return bxt_ddi_translations_dp;
798 : : }
799 : :
800 : : static const struct bxt_ddi_buf_trans *
801 : 0 : bxt_get_buf_trans_edp(struct drm_i915_private *dev_priv, int *n_entries)
802 : : {
803 : 0 : if (dev_priv->vbt.edp.low_vswing) {
804 : 0 : *n_entries = ARRAY_SIZE(bxt_ddi_translations_edp);
805 : 0 : return bxt_ddi_translations_edp;
806 : : }
807 : :
808 : 0 : return bxt_get_buf_trans_dp(dev_priv, n_entries);
809 : : }
810 : :
811 : : static const struct bxt_ddi_buf_trans *
812 : 0 : bxt_get_buf_trans_hdmi(struct drm_i915_private *dev_priv, int *n_entries)
813 : : {
814 : 0 : *n_entries = ARRAY_SIZE(bxt_ddi_translations_hdmi);
815 : 0 : return bxt_ddi_translations_hdmi;
816 : : }
817 : :
818 : : static const struct cnl_ddi_buf_trans *
819 : 0 : cnl_get_buf_trans_hdmi(struct drm_i915_private *dev_priv, int *n_entries)
820 : : {
821 : 0 : u32 voltage = I915_READ(CNL_PORT_COMP_DW3) & VOLTAGE_INFO_MASK;
822 : :
823 [ # # ]: 0 : if (voltage == VOLTAGE_INFO_0_85V) {
824 : 0 : *n_entries = ARRAY_SIZE(cnl_ddi_translations_hdmi_0_85V);
825 : 0 : return cnl_ddi_translations_hdmi_0_85V;
826 [ # # ]: 0 : } else if (voltage == VOLTAGE_INFO_0_95V) {
827 : 0 : *n_entries = ARRAY_SIZE(cnl_ddi_translations_hdmi_0_95V);
828 : 0 : return cnl_ddi_translations_hdmi_0_95V;
829 [ # # ]: 0 : } else if (voltage == VOLTAGE_INFO_1_05V) {
830 : 0 : *n_entries = ARRAY_SIZE(cnl_ddi_translations_hdmi_1_05V);
831 : 0 : return cnl_ddi_translations_hdmi_1_05V;
832 : : } else {
833 : 0 : *n_entries = 1; /* shut up gcc */
834 : 0 : MISSING_CASE(voltage);
835 : : }
836 : 0 : return NULL;
837 : : }
838 : :
839 : : static const struct cnl_ddi_buf_trans *
840 : 0 : cnl_get_buf_trans_dp(struct drm_i915_private *dev_priv, int *n_entries)
841 : : {
842 : 0 : u32 voltage = I915_READ(CNL_PORT_COMP_DW3) & VOLTAGE_INFO_MASK;
843 : :
844 [ # # ]: 0 : if (voltage == VOLTAGE_INFO_0_85V) {
845 : 0 : *n_entries = ARRAY_SIZE(cnl_ddi_translations_dp_0_85V);
846 : 0 : return cnl_ddi_translations_dp_0_85V;
847 [ # # ]: 0 : } else if (voltage == VOLTAGE_INFO_0_95V) {
848 : 0 : *n_entries = ARRAY_SIZE(cnl_ddi_translations_dp_0_95V);
849 : 0 : return cnl_ddi_translations_dp_0_95V;
850 [ # # ]: 0 : } else if (voltage == VOLTAGE_INFO_1_05V) {
851 : 0 : *n_entries = ARRAY_SIZE(cnl_ddi_translations_dp_1_05V);
852 : 0 : return cnl_ddi_translations_dp_1_05V;
853 : : } else {
854 : 0 : *n_entries = 1; /* shut up gcc */
855 : 0 : MISSING_CASE(voltage);
856 : : }
857 : 0 : return NULL;
858 : : }
859 : :
860 : : static const struct cnl_ddi_buf_trans *
861 : 0 : cnl_get_buf_trans_edp(struct drm_i915_private *dev_priv, int *n_entries)
862 : : {
863 : 0 : u32 voltage = I915_READ(CNL_PORT_COMP_DW3) & VOLTAGE_INFO_MASK;
864 : :
865 [ # # ]: 0 : if (dev_priv->vbt.edp.low_vswing) {
866 [ # # ]: 0 : if (voltage == VOLTAGE_INFO_0_85V) {
867 : 0 : *n_entries = ARRAY_SIZE(cnl_ddi_translations_edp_0_85V);
868 : 0 : return cnl_ddi_translations_edp_0_85V;
869 [ # # ]: 0 : } else if (voltage == VOLTAGE_INFO_0_95V) {
870 : 0 : *n_entries = ARRAY_SIZE(cnl_ddi_translations_edp_0_95V);
871 : 0 : return cnl_ddi_translations_edp_0_95V;
872 [ # # ]: 0 : } else if (voltage == VOLTAGE_INFO_1_05V) {
873 : 0 : *n_entries = ARRAY_SIZE(cnl_ddi_translations_edp_1_05V);
874 : 0 : return cnl_ddi_translations_edp_1_05V;
875 : : } else {
876 : 0 : *n_entries = 1; /* shut up gcc */
877 : 0 : MISSING_CASE(voltage);
878 : : }
879 : 0 : return NULL;
880 : : } else {
881 : 0 : return cnl_get_buf_trans_dp(dev_priv, n_entries);
882 : : }
883 : : }
884 : :
885 : : static const struct cnl_ddi_buf_trans *
886 : 0 : icl_get_combo_buf_trans(struct drm_i915_private *dev_priv, int type, int rate,
887 : : int *n_entries)
888 : : {
889 : 0 : if (type == INTEL_OUTPUT_HDMI) {
890 : 0 : *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_hdmi);
891 : 0 : return icl_combo_phy_ddi_translations_hdmi;
892 [ # # # # : 0 : } else if (rate > 540000 && type == INTEL_OUTPUT_EDP) {
# # ]
893 : 0 : *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_hbr3);
894 : 0 : return icl_combo_phy_ddi_translations_edp_hbr3;
895 [ # # # # : 0 : } else if (type == INTEL_OUTPUT_EDP && dev_priv->vbt.edp.low_vswing) {
# # # # #
# # # ]
896 : 0 : *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_hbr2);
897 : 0 : return icl_combo_phy_ddi_translations_edp_hbr2;
898 : : }
899 : :
900 : 0 : *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_dp_hbr2);
901 : 0 : return icl_combo_phy_ddi_translations_dp_hbr2;
902 : : }
903 : :
904 : 0 : static int intel_ddi_hdmi_level(struct drm_i915_private *dev_priv, enum port port)
905 : : {
906 : 0 : struct ddi_vbt_port_info *port_info = &dev_priv->vbt.ddi_port_info[port];
907 : 0 : int n_entries, level, default_entry;
908 : 0 : enum phy phy = intel_port_to_phy(dev_priv, port);
909 : :
910 [ # # ]: 0 : if (INTEL_GEN(dev_priv) >= 12) {
911 [ # # ]: 0 : if (intel_phy_is_combo(dev_priv, phy))
912 : 0 : icl_get_combo_buf_trans(dev_priv, INTEL_OUTPUT_HDMI,
913 : : 0, &n_entries);
914 : : else
915 : 0 : n_entries = ARRAY_SIZE(tgl_dkl_phy_hdmi_ddi_trans);
916 : 0 : default_entry = n_entries - 1;
917 [ # # ]: 0 : } else if (INTEL_GEN(dev_priv) == 11) {
918 [ # # ]: 0 : if (intel_phy_is_combo(dev_priv, phy))
919 : 0 : icl_get_combo_buf_trans(dev_priv, INTEL_OUTPUT_HDMI,
920 : : 0, &n_entries);
921 : : else
922 : 0 : n_entries = ARRAY_SIZE(icl_mg_phy_ddi_translations);
923 : 0 : default_entry = n_entries - 1;
924 [ # # ]: 0 : } else if (IS_CANNONLAKE(dev_priv)) {
925 : 0 : cnl_get_buf_trans_hdmi(dev_priv, &n_entries);
926 : 0 : default_entry = n_entries - 1;
927 [ # # # # ]: 0 : } else if (IS_GEN9_LP(dev_priv)) {
928 : 0 : bxt_get_buf_trans_hdmi(dev_priv, &n_entries);
929 : 0 : default_entry = n_entries - 1;
930 [ # # # # ]: 0 : } else if (IS_GEN9_BC(dev_priv)) {
931 : 0 : intel_ddi_get_buf_trans_hdmi(dev_priv, &n_entries);
932 : 0 : default_entry = 8;
933 [ # # ]: 0 : } else if (IS_BROADWELL(dev_priv)) {
934 : 0 : intel_ddi_get_buf_trans_hdmi(dev_priv, &n_entries);
935 : 0 : default_entry = 7;
936 [ # # ]: 0 : } else if (IS_HASWELL(dev_priv)) {
937 : 0 : intel_ddi_get_buf_trans_hdmi(dev_priv, &n_entries);
938 : 0 : default_entry = 6;
939 : : } else {
940 : 0 : WARN(1, "ddi translation table missing\n");
941 : 0 : return 0;
942 : : }
943 : :
944 [ # # # # : 0 : if (WARN_ON_ONCE(n_entries == 0))
# # ]
945 : : return 0;
946 : :
947 [ # # ]: 0 : if (port_info->hdmi_level_shift_set)
948 : 0 : level = port_info->hdmi_level_shift;
949 : : else
950 : : level = default_entry;
951 : :
952 [ # # # # : 0 : if (WARN_ON_ONCE(level >= n_entries))
# # ]
953 : 0 : level = n_entries - 1;
954 : :
955 : : return level;
956 : : }
957 : :
958 : : /*
959 : : * Starting with Haswell, DDI port buffers must be programmed with correct
960 : : * values in advance. This function programs the correct values for
961 : : * DP/eDP/FDI use cases.
962 : : */
963 : : static void intel_prepare_dp_ddi_buffers(struct intel_encoder *encoder,
964 : : const struct intel_crtc_state *crtc_state)
965 : : {
966 : : struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
967 : : u32 iboost_bit = 0;
968 : : int i, n_entries;
969 : : enum port port = encoder->port;
970 : : const struct ddi_buf_trans *ddi_translations;
971 : :
972 : : if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_ANALOG))
973 : : ddi_translations = intel_ddi_get_buf_trans_fdi(dev_priv,
974 : : &n_entries);
975 : : else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
976 : : ddi_translations = intel_ddi_get_buf_trans_edp(dev_priv, port,
977 : : &n_entries);
978 : : else
979 : : ddi_translations = intel_ddi_get_buf_trans_dp(dev_priv, port,
980 : : &n_entries);
981 : :
982 : : /* If we're boosting the current, set bit 31 of trans1 */
983 : : if (IS_GEN9_BC(dev_priv) &&
984 : : dev_priv->vbt.ddi_port_info[port].dp_boost_level)
985 : : iboost_bit = DDI_BUF_BALANCE_LEG_ENABLE;
986 : :
987 : : for (i = 0; i < n_entries; i++) {
988 : : I915_WRITE(DDI_BUF_TRANS_LO(port, i),
989 : : ddi_translations[i].trans1 | iboost_bit);
990 : : I915_WRITE(DDI_BUF_TRANS_HI(port, i),
991 : : ddi_translations[i].trans2);
992 : : }
993 : : }
994 : :
995 : : /*
996 : : * Starting with Haswell, DDI port buffers must be programmed with correct
997 : : * values in advance. This function programs the correct values for
998 : : * HDMI/DVI use cases.
999 : : */
1000 : : static void intel_prepare_hdmi_ddi_buffers(struct intel_encoder *encoder,
1001 : : int level)
1002 : : {
1003 : : struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
1004 : : u32 iboost_bit = 0;
1005 : : int n_entries;
1006 : : enum port port = encoder->port;
1007 : : const struct ddi_buf_trans *ddi_translations;
1008 : :
1009 : : ddi_translations = intel_ddi_get_buf_trans_hdmi(dev_priv, &n_entries);
1010 : :
1011 : : if (WARN_ON_ONCE(!ddi_translations))
1012 : : return;
1013 : : if (WARN_ON_ONCE(level >= n_entries))
1014 : : level = n_entries - 1;
1015 : :
1016 : : /* If we're boosting the current, set bit 31 of trans1 */
1017 : : if (IS_GEN9_BC(dev_priv) &&
1018 : : dev_priv->vbt.ddi_port_info[port].hdmi_boost_level)
1019 : : iboost_bit = DDI_BUF_BALANCE_LEG_ENABLE;
1020 : :
1021 : : /* Entry 9 is for HDMI: */
1022 : : I915_WRITE(DDI_BUF_TRANS_LO(port, 9),
1023 : : ddi_translations[level].trans1 | iboost_bit);
1024 : : I915_WRITE(DDI_BUF_TRANS_HI(port, 9),
1025 : : ddi_translations[level].trans2);
1026 : : }
1027 : :
1028 : 0 : static void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv,
1029 : : enum port port)
1030 : : {
1031 : 0 : i915_reg_t reg = DDI_BUF_CTL(port);
1032 : 0 : int i;
1033 : :
1034 [ # # ]: 0 : for (i = 0; i < 16; i++) {
1035 : 0 : udelay(1);
1036 [ # # ]: 0 : if (I915_READ(reg) & DDI_BUF_IS_IDLE)
1037 : : return;
1038 : : }
1039 : 0 : DRM_ERROR("Timeout waiting for DDI BUF %c idle bit\n", port_name(port));
1040 : : }
1041 : :
1042 : : static u32 hsw_pll_to_ddi_pll_sel(const struct intel_shared_dpll *pll)
1043 : : {
1044 : : switch (pll->info->id) {
1045 : : case DPLL_ID_WRPLL1:
1046 : : return PORT_CLK_SEL_WRPLL1;
1047 : : case DPLL_ID_WRPLL2:
1048 : : return PORT_CLK_SEL_WRPLL2;
1049 : : case DPLL_ID_SPLL:
1050 : : return PORT_CLK_SEL_SPLL;
1051 : : case DPLL_ID_LCPLL_810:
1052 : : return PORT_CLK_SEL_LCPLL_810;
1053 : : case DPLL_ID_LCPLL_1350:
1054 : : return PORT_CLK_SEL_LCPLL_1350;
1055 : : case DPLL_ID_LCPLL_2700:
1056 : : return PORT_CLK_SEL_LCPLL_2700;
1057 : : default:
1058 : : MISSING_CASE(pll->info->id);
1059 : : return PORT_CLK_SEL_NONE;
1060 : : }
1061 : : }
1062 : :
1063 : : static u32 icl_pll_to_ddi_clk_sel(struct intel_encoder *encoder,
1064 : : const struct intel_crtc_state *crtc_state)
1065 : : {
1066 : : const struct intel_shared_dpll *pll = crtc_state->shared_dpll;
1067 : : int clock = crtc_state->port_clock;
1068 : : const enum intel_dpll_id id = pll->info->id;
1069 : :
1070 : : switch (id) {
1071 : : default:
1072 : : /*
1073 : : * DPLL_ID_ICL_DPLL0 and DPLL_ID_ICL_DPLL1 should not be used
1074 : : * here, so do warn if this get passed in
1075 : : */
1076 : : MISSING_CASE(id);
1077 : : return DDI_CLK_SEL_NONE;
1078 : : case DPLL_ID_ICL_TBTPLL:
1079 : : switch (clock) {
1080 : : case 162000:
1081 : : return DDI_CLK_SEL_TBT_162;
1082 : : case 270000:
1083 : : return DDI_CLK_SEL_TBT_270;
1084 : : case 540000:
1085 : : return DDI_CLK_SEL_TBT_540;
1086 : : case 810000:
1087 : : return DDI_CLK_SEL_TBT_810;
1088 : : default:
1089 : : MISSING_CASE(clock);
1090 : : return DDI_CLK_SEL_NONE;
1091 : : }
1092 : : case DPLL_ID_ICL_MGPLL1:
1093 : : case DPLL_ID_ICL_MGPLL2:
1094 : : case DPLL_ID_ICL_MGPLL3:
1095 : : case DPLL_ID_ICL_MGPLL4:
1096 : : case DPLL_ID_TGL_MGPLL5:
1097 : : case DPLL_ID_TGL_MGPLL6:
1098 : : return DDI_CLK_SEL_MG;
1099 : : }
1100 : : }
1101 : :
1102 : : /* Starting with Haswell, different DDI ports can work in FDI mode for
1103 : : * connection to the PCH-located connectors. For this, it is necessary to train
1104 : : * both the DDI port and PCH receiver for the desired DDI buffer settings.
1105 : : *
1106 : : * The recommended port to work in FDI mode is DDI E, which we use here. Also,
1107 : : * please note that when FDI mode is active on DDI E, it shares 2 lines with
1108 : : * DDI A (which is used for eDP)
1109 : : */
1110 : :
1111 : 0 : void hsw_fdi_link_train(struct intel_encoder *encoder,
1112 : : const struct intel_crtc_state *crtc_state)
1113 : : {
1114 : 0 : struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1115 : 0 : struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1116 : 0 : u32 temp, i, rx_ctl_val, ddi_pll_sel;
1117 : :
1118 : 0 : intel_prepare_dp_ddi_buffers(encoder, crtc_state);
1119 : :
1120 : : /* Set the FDI_RX_MISC pwrdn lanes and the 2 workarounds listed at the
1121 : : * mode set "sequence for CRT port" document:
1122 : : * - TP1 to TP2 time with the default value
1123 : : * - FDI delay to 90h
1124 : : *
1125 : : * WaFDIAutoLinkSetTimingOverrride:hsw
1126 : : */
1127 : 0 : I915_WRITE(FDI_RX_MISC(PIPE_A), FDI_RX_PWRDN_LANE1_VAL(2) |
1128 : : FDI_RX_PWRDN_LANE0_VAL(2) |
1129 : : FDI_RX_TP1_TO_TP2_48 | FDI_RX_FDI_DELAY_90);
1130 : :
1131 : : /* Enable the PCH Receiver FDI PLL */
1132 : 0 : rx_ctl_val = dev_priv->fdi_rx_config | FDI_RX_ENHANCE_FRAME_ENABLE |
1133 : 0 : FDI_RX_PLL_ENABLE |
1134 : 0 : FDI_DP_PORT_WIDTH(crtc_state->fdi_lanes);
1135 : 0 : I915_WRITE(FDI_RX_CTL(PIPE_A), rx_ctl_val);
1136 : 0 : POSTING_READ(FDI_RX_CTL(PIPE_A));
1137 : 0 : udelay(220);
1138 : :
1139 : : /* Switch from Rawclk to PCDclk */
1140 : 0 : rx_ctl_val |= FDI_PCDCLK;
1141 : 0 : I915_WRITE(FDI_RX_CTL(PIPE_A), rx_ctl_val);
1142 : :
1143 : : /* Configure Port Clock Select */
1144 : 0 : ddi_pll_sel = hsw_pll_to_ddi_pll_sel(crtc_state->shared_dpll);
1145 : 0 : I915_WRITE(PORT_CLK_SEL(PORT_E), ddi_pll_sel);
1146 [ # # ]: 0 : WARN_ON(ddi_pll_sel != PORT_CLK_SEL_SPLL);
1147 : :
1148 : : /* Start the training iterating through available voltages and emphasis,
1149 : : * testing each value twice. */
1150 : 0 : for (i = 0; i < ARRAY_SIZE(hsw_ddi_translations_fdi) * 2; i++) {
1151 : : /* Configure DP_TP_CTL with auto-training */
1152 : 0 : I915_WRITE(DP_TP_CTL(PORT_E),
1153 : : DP_TP_CTL_FDI_AUTOTRAIN |
1154 : : DP_TP_CTL_ENHANCED_FRAME_ENABLE |
1155 : : DP_TP_CTL_LINK_TRAIN_PAT1 |
1156 : : DP_TP_CTL_ENABLE);
1157 : :
1158 : : /* Configure and enable DDI_BUF_CTL for DDI E with next voltage.
1159 : : * DDI E does not support port reversal, the functionality is
1160 : : * achieved on the PCH side in FDI_RX_CTL, so no need to set the
1161 : : * port reversal bit */
1162 : 0 : I915_WRITE(DDI_BUF_CTL(PORT_E),
1163 : : DDI_BUF_CTL_ENABLE |
1164 : : ((crtc_state->fdi_lanes - 1) << 1) |
1165 : : DDI_BUF_TRANS_SELECT(i / 2));
1166 : 0 : POSTING_READ(DDI_BUF_CTL(PORT_E));
1167 : :
1168 : 0 : udelay(600);
1169 : :
1170 : : /* Program PCH FDI Receiver TU */
1171 : 0 : I915_WRITE(FDI_RX_TUSIZE1(PIPE_A), TU_SIZE(64));
1172 : :
1173 : : /* Enable PCH FDI Receiver with auto-training */
1174 : 0 : rx_ctl_val |= FDI_RX_ENABLE | FDI_LINK_TRAIN_AUTO;
1175 : 0 : I915_WRITE(FDI_RX_CTL(PIPE_A), rx_ctl_val);
1176 : 0 : POSTING_READ(FDI_RX_CTL(PIPE_A));
1177 : :
1178 : : /* Wait for FDI receiver lane calibration */
1179 : 0 : udelay(30);
1180 : :
1181 : : /* Unset FDI_RX_MISC pwrdn lanes */
1182 : 0 : temp = I915_READ(FDI_RX_MISC(PIPE_A));
1183 : 0 : temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
1184 : 0 : I915_WRITE(FDI_RX_MISC(PIPE_A), temp);
1185 : 0 : POSTING_READ(FDI_RX_MISC(PIPE_A));
1186 : :
1187 : : /* Wait for FDI auto training time */
1188 : 0 : udelay(5);
1189 : :
1190 : 0 : temp = I915_READ(DP_TP_STATUS(PORT_E));
1191 : 0 : if (temp & DP_TP_STATUS_AUTOTRAIN_DONE) {
1192 : 0 : DRM_DEBUG_KMS("FDI link training done on step %d\n", i);
1193 : 0 : break;
1194 : : }
1195 : :
1196 : : /*
1197 : : * Leave things enabled even if we failed to train FDI.
1198 : : * Results in less fireworks from the state checker.
1199 : : */
1200 [ # # ]: 0 : if (i == ARRAY_SIZE(hsw_ddi_translations_fdi) * 2 - 1) {
1201 : 0 : DRM_ERROR("FDI link training failed!\n");
1202 : 0 : break;
1203 : : }
1204 : :
1205 : 0 : rx_ctl_val &= ~FDI_RX_ENABLE;
1206 : 0 : I915_WRITE(FDI_RX_CTL(PIPE_A), rx_ctl_val);
1207 : 0 : POSTING_READ(FDI_RX_CTL(PIPE_A));
1208 : :
1209 : 0 : temp = I915_READ(DDI_BUF_CTL(PORT_E));
1210 : 0 : temp &= ~DDI_BUF_CTL_ENABLE;
1211 : 0 : I915_WRITE(DDI_BUF_CTL(PORT_E), temp);
1212 : 0 : POSTING_READ(DDI_BUF_CTL(PORT_E));
1213 : :
1214 : : /* Disable DP_TP_CTL and FDI_RX_CTL and retry */
1215 : 0 : temp = I915_READ(DP_TP_CTL(PORT_E));
1216 : 0 : temp &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
1217 : 0 : temp |= DP_TP_CTL_LINK_TRAIN_PAT1;
1218 : 0 : I915_WRITE(DP_TP_CTL(PORT_E), temp);
1219 : 0 : POSTING_READ(DP_TP_CTL(PORT_E));
1220 : :
1221 : 0 : intel_wait_ddi_buf_idle(dev_priv, PORT_E);
1222 : :
1223 : : /* Reset FDI_RX_MISC pwrdn lanes */
1224 : 0 : temp = I915_READ(FDI_RX_MISC(PIPE_A));
1225 : 0 : temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
1226 : 0 : temp |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2);
1227 : 0 : I915_WRITE(FDI_RX_MISC(PIPE_A), temp);
1228 : 0 : POSTING_READ(FDI_RX_MISC(PIPE_A));
1229 : : }
1230 : :
1231 : : /* Enable normal pixel sending for FDI */
1232 : 0 : I915_WRITE(DP_TP_CTL(PORT_E),
1233 : : DP_TP_CTL_FDI_AUTOTRAIN |
1234 : : DP_TP_CTL_LINK_TRAIN_NORMAL |
1235 : : DP_TP_CTL_ENHANCED_FRAME_ENABLE |
1236 : : DP_TP_CTL_ENABLE);
1237 : 0 : }
1238 : :
1239 : 0 : static void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder)
1240 : : {
1241 [ # # ]: 0 : struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
1242 [ # # ]: 0 : struct intel_digital_port *intel_dig_port =
1243 : : enc_to_dig_port(encoder);
1244 : :
1245 : 0 : intel_dp->DP = intel_dig_port->saved_port_bits |
1246 : 0 : DDI_BUF_CTL_ENABLE | DDI_BUF_TRANS_SELECT(0);
1247 : 0 : intel_dp->DP |= DDI_PORT_WIDTH(intel_dp->lane_count);
1248 : 0 : }
1249 : :
1250 : : static struct intel_encoder *
1251 : 0 : intel_ddi_get_crtc_encoder(struct intel_crtc *crtc)
1252 : : {
1253 : 0 : struct drm_device *dev = crtc->base.dev;
1254 : 0 : struct intel_encoder *encoder, *ret = NULL;
1255 : 0 : int num_encoders = 0;
1256 : :
1257 [ # # # # ]: 0 : for_each_encoder_on_crtc(dev, &crtc->base, encoder) {
1258 : 0 : ret = encoder;
1259 : 0 : num_encoders++;
1260 : : }
1261 : :
1262 [ # # ]: 0 : if (num_encoders != 1)
1263 : 0 : WARN(1, "%d encoders on crtc for pipe %c\n", num_encoders,
1264 : : pipe_name(crtc->pipe));
1265 : :
1266 [ # # ]: 0 : BUG_ON(ret == NULL);
1267 : 0 : return ret;
1268 : : }
1269 : :
1270 : 0 : static int hsw_ddi_calc_wrpll_link(struct drm_i915_private *dev_priv,
1271 : : i915_reg_t reg)
1272 : : {
1273 : 0 : int refclk;
1274 : 0 : int n, p, r;
1275 : 0 : u32 wrpll;
1276 : :
1277 : 0 : wrpll = I915_READ(reg);
1278 [ # # # # ]: 0 : switch (wrpll & WRPLL_REF_MASK) {
1279 : : case WRPLL_REF_SPECIAL_HSW:
1280 : : /*
1281 : : * muxed-SSC for BDW.
1282 : : * non-SSC for non-ULT HSW. Check FUSE_STRAP3
1283 : : * for the non-SSC reference frequency.
1284 : : */
1285 [ # # # # ]: 0 : if (IS_HASWELL(dev_priv) && !IS_HSW_ULT(dev_priv)) {
1286 [ # # ]: 0 : if (I915_READ(FUSE_STRAP3) & HSW_REF_CLK_SELECT)
1287 : : refclk = 24;
1288 : : else
1289 : 0 : refclk = 135;
1290 : : break;
1291 : : }
1292 : : /* fall through */
1293 : : case WRPLL_REF_PCH_SSC:
1294 : : /*
1295 : : * We could calculate spread here, but our checking
1296 : : * code only cares about 5% accuracy, and spread is a max of
1297 : : * 0.5% downspread.
1298 : : */
1299 : : refclk = 135;
1300 : : break;
1301 : : case WRPLL_REF_LCPLL:
1302 : : refclk = 2700;
1303 : : break;
1304 : : default:
1305 : 0 : MISSING_CASE(wrpll);
1306 : 0 : return 0;
1307 : : }
1308 : :
1309 : 0 : r = wrpll & WRPLL_DIVIDER_REF_MASK;
1310 : 0 : p = (wrpll & WRPLL_DIVIDER_POST_MASK) >> WRPLL_DIVIDER_POST_SHIFT;
1311 : 0 : n = (wrpll & WRPLL_DIVIDER_FB_MASK) >> WRPLL_DIVIDER_FB_SHIFT;
1312 : :
1313 : : /* Convert to KHz, p & r have a fixed point portion */
1314 : 0 : return (refclk * n * 100) / (p * r);
1315 : : }
1316 : :
1317 : : static int skl_calc_wrpll_link(const struct intel_dpll_hw_state *pll_state)
1318 : : {
1319 : : u32 p0, p1, p2, dco_freq;
1320 : :
1321 : : p0 = pll_state->cfgcr2 & DPLL_CFGCR2_PDIV_MASK;
1322 : : p2 = pll_state->cfgcr2 & DPLL_CFGCR2_KDIV_MASK;
1323 : :
1324 : : if (pll_state->cfgcr2 & DPLL_CFGCR2_QDIV_MODE(1))
1325 : : p1 = (pll_state->cfgcr2 & DPLL_CFGCR2_QDIV_RATIO_MASK) >> 8;
1326 : : else
1327 : : p1 = 1;
1328 : :
1329 : :
1330 : : switch (p0) {
1331 : : case DPLL_CFGCR2_PDIV_1:
1332 : : p0 = 1;
1333 : : break;
1334 : : case DPLL_CFGCR2_PDIV_2:
1335 : : p0 = 2;
1336 : : break;
1337 : : case DPLL_CFGCR2_PDIV_3:
1338 : : p0 = 3;
1339 : : break;
1340 : : case DPLL_CFGCR2_PDIV_7:
1341 : : p0 = 7;
1342 : : break;
1343 : : }
1344 : :
1345 : : switch (p2) {
1346 : : case DPLL_CFGCR2_KDIV_5:
1347 : : p2 = 5;
1348 : : break;
1349 : : case DPLL_CFGCR2_KDIV_2:
1350 : : p2 = 2;
1351 : : break;
1352 : : case DPLL_CFGCR2_KDIV_3:
1353 : : p2 = 3;
1354 : : break;
1355 : : case DPLL_CFGCR2_KDIV_1:
1356 : : p2 = 1;
1357 : : break;
1358 : : }
1359 : :
1360 : : dco_freq = (pll_state->cfgcr1 & DPLL_CFGCR1_DCO_INTEGER_MASK)
1361 : : * 24 * 1000;
1362 : :
1363 : : dco_freq += (((pll_state->cfgcr1 & DPLL_CFGCR1_DCO_FRACTION_MASK) >> 9)
1364 : : * 24 * 1000) / 0x8000;
1365 : :
1366 : : if (WARN_ON(p0 == 0 || p1 == 0 || p2 == 0))
1367 : : return 0;
1368 : :
1369 : : return dco_freq / (p0 * p1 * p2 * 5);
1370 : : }
1371 : :
1372 : 0 : int cnl_calc_wrpll_link(struct drm_i915_private *dev_priv,
1373 : : struct intel_dpll_hw_state *pll_state)
1374 : : {
1375 : 0 : u32 p0, p1, p2, dco_freq, ref_clock;
1376 : :
1377 : 0 : p0 = pll_state->cfgcr1 & DPLL_CFGCR1_PDIV_MASK;
1378 : 0 : p2 = pll_state->cfgcr1 & DPLL_CFGCR1_KDIV_MASK;
1379 : :
1380 [ # # ]: 0 : if (pll_state->cfgcr1 & DPLL_CFGCR1_QDIV_MODE(1))
1381 : 0 : p1 = (pll_state->cfgcr1 & DPLL_CFGCR1_QDIV_RATIO_MASK) >>
1382 : : DPLL_CFGCR1_QDIV_RATIO_SHIFT;
1383 : : else
1384 : : p1 = 1;
1385 : :
1386 : :
1387 [ # # # # : 0 : switch (p0) {
# ]
1388 : 0 : case DPLL_CFGCR1_PDIV_2:
1389 : 0 : p0 = 2;
1390 : 0 : break;
1391 : 0 : case DPLL_CFGCR1_PDIV_3:
1392 : 0 : p0 = 3;
1393 : 0 : break;
1394 : 0 : case DPLL_CFGCR1_PDIV_5:
1395 : 0 : p0 = 5;
1396 : 0 : break;
1397 : 0 : case DPLL_CFGCR1_PDIV_7:
1398 : 0 : p0 = 7;
1399 : 0 : break;
1400 : : }
1401 : :
1402 [ # # # # ]: 0 : switch (p2) {
1403 : 0 : case DPLL_CFGCR1_KDIV_1:
1404 : 0 : p2 = 1;
1405 : 0 : break;
1406 : 0 : case DPLL_CFGCR1_KDIV_2:
1407 : 0 : p2 = 2;
1408 : 0 : break;
1409 : 0 : case DPLL_CFGCR1_KDIV_3:
1410 : 0 : p2 = 3;
1411 : 0 : break;
1412 : : }
1413 : :
1414 : 0 : ref_clock = cnl_hdmi_pll_ref_clock(dev_priv);
1415 : :
1416 : 0 : dco_freq = (pll_state->cfgcr0 & DPLL_CFGCR0_DCO_INTEGER_MASK)
1417 : : * ref_clock;
1418 : :
1419 : 0 : dco_freq += (((pll_state->cfgcr0 & DPLL_CFGCR0_DCO_FRACTION_MASK) >>
1420 : 0 : DPLL_CFGCR0_DCO_FRACTION_SHIFT) * ref_clock) / 0x8000;
1421 : :
1422 [ # # # # : 0 : if (WARN_ON(p0 == 0 || p1 == 0 || p2 == 0))
# # # # ]
1423 : : return 0;
1424 : :
1425 : 0 : return dco_freq / (p0 * p1 * p2 * 5);
1426 : : }
1427 : :
1428 : 0 : static int icl_calc_tbt_pll_link(struct drm_i915_private *dev_priv,
1429 : : enum port port)
1430 : : {
1431 : 0 : u32 val = I915_READ(DDI_CLK_SEL(port)) & DDI_CLK_SEL_MASK;
1432 : :
1433 [ # # # # : 0 : switch (val) {
# # ]
1434 : : case DDI_CLK_SEL_NONE:
1435 : : return 0;
1436 : 0 : case DDI_CLK_SEL_TBT_162:
1437 : 0 : return 162000;
1438 : 0 : case DDI_CLK_SEL_TBT_270:
1439 : 0 : return 270000;
1440 : 0 : case DDI_CLK_SEL_TBT_540:
1441 : 0 : return 540000;
1442 : 0 : case DDI_CLK_SEL_TBT_810:
1443 : 0 : return 810000;
1444 : : default:
1445 : 0 : MISSING_CASE(val);
1446 : 0 : return 0;
1447 : : }
1448 : : }
1449 : :
1450 : : static int icl_calc_mg_pll_link(struct drm_i915_private *dev_priv,
1451 : : const struct intel_dpll_hw_state *pll_state)
1452 : : {
1453 : : u32 m1, m2_int, m2_frac, div1, div2, ref_clock;
1454 : : u64 tmp;
1455 : :
1456 : : ref_clock = dev_priv->cdclk.hw.ref;
1457 : :
1458 : : if (INTEL_GEN(dev_priv) >= 12) {
1459 : : m1 = pll_state->mg_pll_div0 & DKL_PLL_DIV0_FBPREDIV_MASK;
1460 : : m1 = m1 >> DKL_PLL_DIV0_FBPREDIV_SHIFT;
1461 : : m2_int = pll_state->mg_pll_div0 & DKL_PLL_DIV0_FBDIV_INT_MASK;
1462 : :
1463 : : if (pll_state->mg_pll_bias & DKL_PLL_BIAS_FRAC_EN_H) {
1464 : : m2_frac = pll_state->mg_pll_bias &
1465 : : DKL_PLL_BIAS_FBDIV_FRAC_MASK;
1466 : : m2_frac = m2_frac >> DKL_PLL_BIAS_FBDIV_SHIFT;
1467 : : } else {
1468 : : m2_frac = 0;
1469 : : }
1470 : : } else {
1471 : : m1 = pll_state->mg_pll_div1 & MG_PLL_DIV1_FBPREDIV_MASK;
1472 : : m2_int = pll_state->mg_pll_div0 & MG_PLL_DIV0_FBDIV_INT_MASK;
1473 : :
1474 : : if (pll_state->mg_pll_div0 & MG_PLL_DIV0_FRACNEN_H) {
1475 : : m2_frac = pll_state->mg_pll_div0 &
1476 : : MG_PLL_DIV0_FBDIV_FRAC_MASK;
1477 : : m2_frac = m2_frac >> MG_PLL_DIV0_FBDIV_FRAC_SHIFT;
1478 : : } else {
1479 : : m2_frac = 0;
1480 : : }
1481 : : }
1482 : :
1483 : : switch (pll_state->mg_clktop2_hsclkctl &
1484 : : MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_MASK) {
1485 : : case MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_2:
1486 : : div1 = 2;
1487 : : break;
1488 : : case MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_3:
1489 : : div1 = 3;
1490 : : break;
1491 : : case MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_5:
1492 : : div1 = 5;
1493 : : break;
1494 : : case MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_7:
1495 : : div1 = 7;
1496 : : break;
1497 : : default:
1498 : : MISSING_CASE(pll_state->mg_clktop2_hsclkctl);
1499 : : return 0;
1500 : : }
1501 : :
1502 : : div2 = (pll_state->mg_clktop2_hsclkctl &
1503 : : MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO_MASK) >>
1504 : : MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO_SHIFT;
1505 : :
1506 : : /* div2 value of 0 is same as 1 means no div */
1507 : : if (div2 == 0)
1508 : : div2 = 1;
1509 : :
1510 : : /*
1511 : : * Adjust the original formula to delay the division by 2^22 in order to
1512 : : * minimize possible rounding errors.
1513 : : */
1514 : : tmp = (u64)m1 * m2_int * ref_clock +
1515 : : (((u64)m1 * m2_frac * ref_clock) >> 22);
1516 : : tmp = div_u64(tmp, 5 * div1 * div2);
1517 : :
1518 : : return tmp;
1519 : : }
1520 : :
1521 : 0 : static void ddi_dotclock_get(struct intel_crtc_state *pipe_config)
1522 : : {
1523 : 0 : int dotclock;
1524 : :
1525 [ # # ]: 0 : if (pipe_config->has_pch_encoder)
1526 : 0 : dotclock = intel_dotclock_calculate(pipe_config->port_clock,
1527 : 0 : &pipe_config->fdi_m_n);
1528 [ # # ]: 0 : else if (intel_crtc_has_dp_encoder(pipe_config))
1529 : 0 : dotclock = intel_dotclock_calculate(pipe_config->port_clock,
1530 : 0 : &pipe_config->dp_m_n);
1531 [ # # # # ]: 0 : else if (pipe_config->has_hdmi_sink && pipe_config->pipe_bpp > 24)
1532 : 0 : dotclock = pipe_config->port_clock * 24 / pipe_config->pipe_bpp;
1533 : : else
1534 : 0 : dotclock = pipe_config->port_clock;
1535 : :
1536 [ # # # # ]: 0 : if (pipe_config->output_format == INTEL_OUTPUT_FORMAT_YCBCR420 &&
1537 [ # # ]: 0 : !intel_crtc_has_dp_encoder(pipe_config))
1538 : 0 : dotclock *= 2;
1539 : :
1540 [ # # ]: 0 : if (pipe_config->pixel_multiplier)
1541 : 0 : dotclock /= pipe_config->pixel_multiplier;
1542 : :
1543 : 0 : pipe_config->hw.adjusted_mode.crtc_clock = dotclock;
1544 : 0 : }
1545 : :
1546 : : static void icl_ddi_clock_get(struct intel_encoder *encoder,
1547 : : struct intel_crtc_state *pipe_config)
1548 : : {
1549 : : struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
1550 : : struct intel_dpll_hw_state *pll_state = &pipe_config->dpll_hw_state;
1551 : : enum port port = encoder->port;
1552 : : enum phy phy = intel_port_to_phy(dev_priv, port);
1553 : : int link_clock;
1554 : :
1555 : : if (intel_phy_is_combo(dev_priv, phy)) {
1556 : : link_clock = cnl_calc_wrpll_link(dev_priv, pll_state);
1557 : : } else {
1558 : : enum intel_dpll_id pll_id = intel_get_shared_dpll_id(dev_priv,
1559 : : pipe_config->shared_dpll);
1560 : :
1561 : : if (pll_id == DPLL_ID_ICL_TBTPLL)
1562 : : link_clock = icl_calc_tbt_pll_link(dev_priv, port);
1563 : : else
1564 : : link_clock = icl_calc_mg_pll_link(dev_priv, pll_state);
1565 : : }
1566 : :
1567 : : pipe_config->port_clock = link_clock;
1568 : :
1569 : : ddi_dotclock_get(pipe_config);
1570 : : }
1571 : :
1572 : : static void cnl_ddi_clock_get(struct intel_encoder *encoder,
1573 : : struct intel_crtc_state *pipe_config)
1574 : : {
1575 : : struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
1576 : : struct intel_dpll_hw_state *pll_state = &pipe_config->dpll_hw_state;
1577 : : int link_clock;
1578 : :
1579 : : if (pll_state->cfgcr0 & DPLL_CFGCR0_HDMI_MODE) {
1580 : : link_clock = cnl_calc_wrpll_link(dev_priv, pll_state);
1581 : : } else {
1582 : : link_clock = pll_state->cfgcr0 & DPLL_CFGCR0_LINK_RATE_MASK;
1583 : :
1584 : : switch (link_clock) {
1585 : : case DPLL_CFGCR0_LINK_RATE_810:
1586 : : link_clock = 81000;
1587 : : break;
1588 : : case DPLL_CFGCR0_LINK_RATE_1080:
1589 : : link_clock = 108000;
1590 : : break;
1591 : : case DPLL_CFGCR0_LINK_RATE_1350:
1592 : : link_clock = 135000;
1593 : : break;
1594 : : case DPLL_CFGCR0_LINK_RATE_1620:
1595 : : link_clock = 162000;
1596 : : break;
1597 : : case DPLL_CFGCR0_LINK_RATE_2160:
1598 : : link_clock = 216000;
1599 : : break;
1600 : : case DPLL_CFGCR0_LINK_RATE_2700:
1601 : : link_clock = 270000;
1602 : : break;
1603 : : case DPLL_CFGCR0_LINK_RATE_3240:
1604 : : link_clock = 324000;
1605 : : break;
1606 : : case DPLL_CFGCR0_LINK_RATE_4050:
1607 : : link_clock = 405000;
1608 : : break;
1609 : : default:
1610 : : WARN(1, "Unsupported link rate\n");
1611 : : break;
1612 : : }
1613 : : link_clock *= 2;
1614 : : }
1615 : :
1616 : : pipe_config->port_clock = link_clock;
1617 : :
1618 : : ddi_dotclock_get(pipe_config);
1619 : : }
1620 : :
1621 : : static void skl_ddi_clock_get(struct intel_encoder *encoder,
1622 : : struct intel_crtc_state *pipe_config)
1623 : : {
1624 : : struct intel_dpll_hw_state *pll_state = &pipe_config->dpll_hw_state;
1625 : : int link_clock;
1626 : :
1627 : : /*
1628 : : * ctrl1 register is already shifted for each pll, just use 0 to get
1629 : : * the internal shift for each field
1630 : : */
1631 : : if (pll_state->ctrl1 & DPLL_CTRL1_HDMI_MODE(0)) {
1632 : : link_clock = skl_calc_wrpll_link(pll_state);
1633 : : } else {
1634 : : link_clock = pll_state->ctrl1 & DPLL_CTRL1_LINK_RATE_MASK(0);
1635 : : link_clock >>= DPLL_CTRL1_LINK_RATE_SHIFT(0);
1636 : :
1637 : : switch (link_clock) {
1638 : : case DPLL_CTRL1_LINK_RATE_810:
1639 : : link_clock = 81000;
1640 : : break;
1641 : : case DPLL_CTRL1_LINK_RATE_1080:
1642 : : link_clock = 108000;
1643 : : break;
1644 : : case DPLL_CTRL1_LINK_RATE_1350:
1645 : : link_clock = 135000;
1646 : : break;
1647 : : case DPLL_CTRL1_LINK_RATE_1620:
1648 : : link_clock = 162000;
1649 : : break;
1650 : : case DPLL_CTRL1_LINK_RATE_2160:
1651 : : link_clock = 216000;
1652 : : break;
1653 : : case DPLL_CTRL1_LINK_RATE_2700:
1654 : : link_clock = 270000;
1655 : : break;
1656 : : default:
1657 : : WARN(1, "Unsupported link rate\n");
1658 : : break;
1659 : : }
1660 : : link_clock *= 2;
1661 : : }
1662 : :
1663 : : pipe_config->port_clock = link_clock;
1664 : :
1665 : : ddi_dotclock_get(pipe_config);
1666 : : }
1667 : :
1668 : : static void hsw_ddi_clock_get(struct intel_encoder *encoder,
1669 : : struct intel_crtc_state *pipe_config)
1670 : : {
1671 : : struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
1672 : : int link_clock = 0;
1673 : : u32 val, pll;
1674 : :
1675 : : val = hsw_pll_to_ddi_pll_sel(pipe_config->shared_dpll);
1676 : : switch (val & PORT_CLK_SEL_MASK) {
1677 : : case PORT_CLK_SEL_LCPLL_810:
1678 : : link_clock = 81000;
1679 : : break;
1680 : : case PORT_CLK_SEL_LCPLL_1350:
1681 : : link_clock = 135000;
1682 : : break;
1683 : : case PORT_CLK_SEL_LCPLL_2700:
1684 : : link_clock = 270000;
1685 : : break;
1686 : : case PORT_CLK_SEL_WRPLL1:
1687 : : link_clock = hsw_ddi_calc_wrpll_link(dev_priv, WRPLL_CTL(0));
1688 : : break;
1689 : : case PORT_CLK_SEL_WRPLL2:
1690 : : link_clock = hsw_ddi_calc_wrpll_link(dev_priv, WRPLL_CTL(1));
1691 : : break;
1692 : : case PORT_CLK_SEL_SPLL:
1693 : : pll = I915_READ(SPLL_CTL) & SPLL_FREQ_MASK;
1694 : : if (pll == SPLL_FREQ_810MHz)
1695 : : link_clock = 81000;
1696 : : else if (pll == SPLL_FREQ_1350MHz)
1697 : : link_clock = 135000;
1698 : : else if (pll == SPLL_FREQ_2700MHz)
1699 : : link_clock = 270000;
1700 : : else {
1701 : : WARN(1, "bad spll freq\n");
1702 : : return;
1703 : : }
1704 : : break;
1705 : : default:
1706 : : WARN(1, "bad port clock sel\n");
1707 : : return;
1708 : : }
1709 : :
1710 : : pipe_config->port_clock = link_clock * 2;
1711 : :
1712 : : ddi_dotclock_get(pipe_config);
1713 : : }
1714 : :
1715 : 0 : static int bxt_calc_pll_link(const struct intel_dpll_hw_state *pll_state)
1716 : : {
1717 : 0 : struct dpll clock;
1718 : :
1719 : 0 : clock.m1 = 2;
1720 : 0 : clock.m2 = (pll_state->pll0 & PORT_PLL_M2_MASK) << 22;
1721 [ # # ]: 0 : if (pll_state->pll3 & PORT_PLL_M2_FRAC_ENABLE)
1722 : 0 : clock.m2 |= pll_state->pll2 & PORT_PLL_M2_FRAC_MASK;
1723 : 0 : clock.n = (pll_state->pll1 & PORT_PLL_N_MASK) >> PORT_PLL_N_SHIFT;
1724 : 0 : clock.p1 = (pll_state->ebb0 & PORT_PLL_P1_MASK) >> PORT_PLL_P1_SHIFT;
1725 : 0 : clock.p2 = (pll_state->ebb0 & PORT_PLL_P2_MASK) >> PORT_PLL_P2_SHIFT;
1726 : :
1727 : 0 : return chv_calc_dpll_params(100000, &clock);
1728 : : }
1729 : :
1730 : 0 : static void bxt_ddi_clock_get(struct intel_encoder *encoder,
1731 : : struct intel_crtc_state *pipe_config)
1732 : : {
1733 : 0 : pipe_config->port_clock =
1734 : 0 : bxt_calc_pll_link(&pipe_config->dpll_hw_state);
1735 : :
1736 : 0 : ddi_dotclock_get(pipe_config);
1737 : 0 : }
1738 : :
1739 : 0 : static void intel_ddi_clock_get(struct intel_encoder *encoder,
1740 : : struct intel_crtc_state *pipe_config)
1741 : : {
1742 [ # # ]: 0 : struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
1743 : :
1744 [ # # ]: 0 : if (INTEL_GEN(dev_priv) >= 11)
1745 : 0 : icl_ddi_clock_get(encoder, pipe_config);
1746 [ # # ]: 0 : else if (IS_CANNONLAKE(dev_priv))
1747 : 0 : cnl_ddi_clock_get(encoder, pipe_config);
1748 [ # # # # ]: 0 : else if (IS_GEN9_LP(dev_priv))
1749 : 0 : bxt_ddi_clock_get(encoder, pipe_config);
1750 [ # # # # ]: 0 : else if (IS_GEN9_BC(dev_priv))
1751 : 0 : skl_ddi_clock_get(encoder, pipe_config);
1752 [ # # ]: 0 : else if (INTEL_GEN(dev_priv) <= 8)
1753 : 0 : hsw_ddi_clock_get(encoder, pipe_config);
1754 : 0 : }
1755 : :
1756 : 0 : void intel_ddi_set_dp_msa(const struct intel_crtc_state *crtc_state,
1757 : : const struct drm_connector_state *conn_state)
1758 : : {
1759 : 0 : struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1760 [ # # ]: 0 : struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1761 : 0 : enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
1762 : 0 : u32 temp;
1763 : :
1764 [ # # ]: 0 : if (!intel_crtc_has_dp_encoder(crtc_state))
1765 : : return;
1766 : :
1767 [ # # ]: 0 : WARN_ON(transcoder_is_dsi(cpu_transcoder));
1768 : :
1769 : 0 : temp = DP_MSA_MISC_SYNC_CLOCK;
1770 : :
1771 [ # # # # : 0 : switch (crtc_state->pipe_bpp) {
# ]
1772 : : case 18:
1773 : : temp |= DP_MSA_MISC_6_BPC;
1774 : : break;
1775 : 0 : case 24:
1776 : 0 : temp |= DP_MSA_MISC_8_BPC;
1777 : 0 : break;
1778 : 0 : case 30:
1779 : 0 : temp |= DP_MSA_MISC_10_BPC;
1780 : 0 : break;
1781 : 0 : case 36:
1782 : 0 : temp |= DP_MSA_MISC_12_BPC;
1783 : 0 : break;
1784 : : default:
1785 : 0 : MISSING_CASE(crtc_state->pipe_bpp);
1786 : 0 : break;
1787 : : }
1788 : :
1789 : : /* nonsense combination */
1790 [ # # # # : 0 : WARN_ON(crtc_state->limited_color_range &&
# # ]
1791 : : crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB);
1792 : :
1793 [ # # ]: 0 : if (crtc_state->limited_color_range)
1794 : 0 : temp |= DP_MSA_MISC_COLOR_CEA_RGB;
1795 : :
1796 : : /*
1797 : : * As per DP 1.2 spec section 2.3.4.3 while sending
1798 : : * YCBCR 444 signals we should program MSA MISC1/0 fields with
1799 : : * colorspace information.
1800 : : */
1801 [ # # ]: 0 : if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR444)
1802 : 0 : temp |= DP_MSA_MISC_COLOR_YCBCR_444_BT709;
1803 : :
1804 : : /*
1805 : : * As per DP 1.4a spec section 2.2.4.3 [MSA Field for Indication
1806 : : * of Color Encoding Format and Content Color Gamut] while sending
1807 : : * YCBCR 420, HDR BT.2020 signals we should program MSA MISC1 fields
1808 : : * which indicate VSC SDP for the Pixel Encoding/Colorimetry Format.
1809 : : */
1810 [ # # ]: 0 : if (intel_dp_needs_vsc_sdp(crtc_state, conn_state))
1811 : 0 : temp |= DP_MSA_MISC_COLOR_VSC_SDP;
1812 : :
1813 : 0 : I915_WRITE(TRANS_MSA_MISC(cpu_transcoder), temp);
1814 : : }
1815 : :
1816 : : /*
1817 : : * Returns the TRANS_DDI_FUNC_CTL value based on CRTC state.
1818 : : *
1819 : : * Only intended to be used by intel_ddi_enable_transcoder_func() and
1820 : : * intel_ddi_config_transcoder_func().
1821 : : */
1822 : : static u32
1823 : 0 : intel_ddi_transcoder_func_reg_val_get(const struct intel_crtc_state *crtc_state)
1824 : : {
1825 : 0 : struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1826 : 0 : struct intel_encoder *encoder = intel_ddi_get_crtc_encoder(crtc);
1827 [ # # ]: 0 : struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1828 : 0 : enum pipe pipe = crtc->pipe;
1829 : 0 : enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
1830 : 0 : enum port port = encoder->port;
1831 : 0 : u32 temp;
1832 : :
1833 : : /* Enable TRANS_DDI_FUNC_CTL for the pipe to work in HDMI mode */
1834 : 0 : temp = TRANS_DDI_FUNC_ENABLE;
1835 [ # # ]: 0 : if (INTEL_GEN(dev_priv) >= 12)
1836 : 0 : temp |= TGL_TRANS_DDI_SELECT_PORT(port);
1837 : : else
1838 : 0 : temp |= TRANS_DDI_SELECT_PORT(port);
1839 : :
1840 [ # # # # : 0 : switch (crtc_state->pipe_bpp) {
# ]
1841 : 0 : case 18:
1842 : 0 : temp |= TRANS_DDI_BPC_6;
1843 : 0 : break;
1844 : : case 24:
1845 : : temp |= TRANS_DDI_BPC_8;
1846 : : break;
1847 : 0 : case 30:
1848 : 0 : temp |= TRANS_DDI_BPC_10;
1849 : 0 : break;
1850 : 0 : case 36:
1851 : 0 : temp |= TRANS_DDI_BPC_12;
1852 : 0 : break;
1853 : 0 : default:
1854 : 0 : BUG();
1855 : : }
1856 : :
1857 [ # # ]: 0 : if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_PVSYNC)
1858 : 0 : temp |= TRANS_DDI_PVSYNC;
1859 [ # # ]: 0 : if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_PHSYNC)
1860 : 0 : temp |= TRANS_DDI_PHSYNC;
1861 : :
1862 [ # # ]: 0 : if (cpu_transcoder == TRANSCODER_EDP) {
1863 [ # # # # ]: 0 : switch (pipe) {
1864 : 0 : case PIPE_A:
1865 : : /* On Haswell, can only use the always-on power well for
1866 : : * eDP when not using the panel fitter, and when not
1867 : : * using motion blur mitigation (which we don't
1868 : : * support). */
1869 [ # # ]: 0 : if (crtc_state->pch_pfit.force_thru)
1870 : 0 : temp |= TRANS_DDI_EDP_INPUT_A_ONOFF;
1871 : : else
1872 : : temp |= TRANS_DDI_EDP_INPUT_A_ON;
1873 : : break;
1874 : 0 : case PIPE_B:
1875 : 0 : temp |= TRANS_DDI_EDP_INPUT_B_ONOFF;
1876 : 0 : break;
1877 : 0 : case PIPE_C:
1878 : 0 : temp |= TRANS_DDI_EDP_INPUT_C_ONOFF;
1879 : 0 : break;
1880 : 0 : default:
1881 : 0 : BUG();
1882 : 0 : break;
1883 : : }
1884 : 0 : }
1885 : :
1886 [ # # ]: 0 : if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) {
1887 [ # # ]: 0 : if (crtc_state->has_hdmi_sink)
1888 : : temp |= TRANS_DDI_MODE_SELECT_HDMI;
1889 : : else
1890 : 0 : temp |= TRANS_DDI_MODE_SELECT_DVI;
1891 : :
1892 [ # # ]: 0 : if (crtc_state->hdmi_scrambling)
1893 : 0 : temp |= TRANS_DDI_HDMI_SCRAMBLING;
1894 [ # # ]: 0 : if (crtc_state->hdmi_high_tmds_clock_ratio)
1895 : 0 : temp |= TRANS_DDI_HIGH_TMDS_CHAR_RATE;
1896 [ # # ]: 0 : } else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_ANALOG)) {
1897 : 0 : temp |= TRANS_DDI_MODE_SELECT_FDI;
1898 : 0 : temp |= (crtc_state->fdi_lanes - 1) << 1;
1899 [ # # ]: 0 : } else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST)) {
1900 : 0 : temp |= TRANS_DDI_MODE_SELECT_DP_MST;
1901 : 0 : temp |= DDI_PORT_WIDTH(crtc_state->lane_count);
1902 : :
1903 [ # # ]: 0 : if (INTEL_GEN(dev_priv) >= 12) {
1904 : 0 : enum transcoder master;
1905 : :
1906 : 0 : master = crtc_state->mst_master_transcoder;
1907 [ # # ]: 0 : WARN_ON(master == INVALID_TRANSCODER);
1908 : 0 : temp |= TRANS_DDI_MST_TRANSPORT_SELECT(master);
1909 : : }
1910 : : } else {
1911 : 0 : temp |= TRANS_DDI_MODE_SELECT_DP_SST;
1912 : 0 : temp |= DDI_PORT_WIDTH(crtc_state->lane_count);
1913 : : }
1914 : :
1915 : 0 : return temp;
1916 : : }
1917 : :
1918 : 0 : void intel_ddi_enable_transcoder_func(const struct intel_crtc_state *crtc_state)
1919 : : {
1920 : 0 : struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1921 : 0 : struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1922 : 0 : enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
1923 : 0 : u32 temp;
1924 : :
1925 : 0 : temp = intel_ddi_transcoder_func_reg_val_get(crtc_state);
1926 [ # # ]: 0 : if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST))
1927 : 0 : temp |= TRANS_DDI_DP_VC_PAYLOAD_ALLOC;
1928 : 0 : I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp);
1929 : 0 : }
1930 : :
1931 : : /*
1932 : : * Same as intel_ddi_enable_transcoder_func(), but it does not set the enable
1933 : : * bit.
1934 : : */
1935 : : static void
1936 : 0 : intel_ddi_config_transcoder_func(const struct intel_crtc_state *crtc_state)
1937 : : {
1938 : 0 : struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1939 : 0 : struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1940 : 0 : enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
1941 : 0 : u32 temp;
1942 : :
1943 : 0 : temp = intel_ddi_transcoder_func_reg_val_get(crtc_state);
1944 : 0 : temp &= ~TRANS_DDI_FUNC_ENABLE;
1945 : 0 : I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp);
1946 : 0 : }
1947 : :
1948 : 0 : void intel_ddi_disable_transcoder_func(const struct intel_crtc_state *crtc_state)
1949 : : {
1950 : 0 : struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1951 : 0 : struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1952 : 0 : enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
1953 : 0 : u32 val;
1954 : :
1955 : 0 : val = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
1956 : 0 : val &= ~TRANS_DDI_FUNC_ENABLE;
1957 : :
1958 [ # # ]: 0 : if (INTEL_GEN(dev_priv) >= 12) {
1959 [ # # ]: 0 : if (!intel_dp_mst_is_master_trans(crtc_state))
1960 : 0 : val &= ~TGL_TRANS_DDI_PORT_MASK;
1961 : : } else {
1962 : 0 : val &= ~TRANS_DDI_PORT_MASK;
1963 : : }
1964 : 0 : I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), val);
1965 : :
1966 [ # # # # ]: 0 : if (dev_priv->quirks & QUIRK_INCREASE_DDI_DISABLED_TIME &&
1967 [ # # ]: 0 : intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) {
1968 : 0 : DRM_DEBUG_KMS("Quirk Increase DDI disabled time\n");
1969 : : /* Quirk time at 100ms for reliable operation */
1970 : 0 : msleep(100);
1971 : : }
1972 : 0 : }
1973 : :
1974 : 0 : int intel_ddi_toggle_hdcp_signalling(struct intel_encoder *intel_encoder,
1975 : : bool enable)
1976 : : {
1977 : 0 : struct drm_device *dev = intel_encoder->base.dev;
1978 : 0 : struct drm_i915_private *dev_priv = to_i915(dev);
1979 : 0 : intel_wakeref_t wakeref;
1980 : 0 : enum pipe pipe = 0;
1981 : 0 : int ret = 0;
1982 : 0 : u32 tmp;
1983 : :
1984 : 0 : wakeref = intel_display_power_get_if_enabled(dev_priv,
1985 : : intel_encoder->power_domain);
1986 [ # # # # ]: 0 : if (WARN_ON(!wakeref))
1987 : : return -ENXIO;
1988 : :
1989 [ # # # # ]: 0 : if (WARN_ON(!intel_encoder->get_hw_state(intel_encoder, &pipe))) {
1990 : 0 : ret = -EIO;
1991 : 0 : goto out;
1992 : : }
1993 : :
1994 : 0 : tmp = I915_READ(TRANS_DDI_FUNC_CTL(pipe));
1995 [ # # ]: 0 : if (enable)
1996 : 0 : tmp |= TRANS_DDI_HDCP_SIGNALLING;
1997 : : else
1998 : 0 : tmp &= ~TRANS_DDI_HDCP_SIGNALLING;
1999 : 0 : I915_WRITE(TRANS_DDI_FUNC_CTL(pipe), tmp);
2000 : 0 : out:
2001 : 0 : intel_display_power_put(dev_priv, intel_encoder->power_domain, wakeref);
2002 : 0 : return ret;
2003 : : }
2004 : :
2005 : 0 : bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector)
2006 : : {
2007 : 0 : struct drm_device *dev = intel_connector->base.dev;
2008 : 0 : struct drm_i915_private *dev_priv = to_i915(dev);
2009 : 0 : struct intel_encoder *encoder = intel_connector->encoder;
2010 : 0 : int type = intel_connector->base.connector_type;
2011 : 0 : enum port port = encoder->port;
2012 : 0 : enum transcoder cpu_transcoder;
2013 : 0 : intel_wakeref_t wakeref;
2014 : 0 : enum pipe pipe = 0;
2015 : 0 : u32 tmp;
2016 : 0 : bool ret;
2017 : :
2018 : 0 : wakeref = intel_display_power_get_if_enabled(dev_priv,
2019 : : encoder->power_domain);
2020 [ # # ]: 0 : if (!wakeref)
2021 : : return false;
2022 : :
2023 [ # # ]: 0 : if (!encoder->get_hw_state(encoder, &pipe)) {
2024 : 0 : ret = false;
2025 : 0 : goto out;
2026 : : }
2027 : :
2028 [ # # # # ]: 0 : if (HAS_TRANSCODER_EDP(dev_priv) && port == PORT_A)
2029 : : cpu_transcoder = TRANSCODER_EDP;
2030 : : else
2031 : 0 : cpu_transcoder = (enum transcoder) pipe;
2032 : :
2033 : 0 : tmp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
2034 : :
2035 [ # # # # ]: 0 : switch (tmp & TRANS_DDI_MODE_SELECT_MASK) {
2036 : 0 : case TRANS_DDI_MODE_SELECT_HDMI:
2037 : : case TRANS_DDI_MODE_SELECT_DVI:
2038 : 0 : ret = type == DRM_MODE_CONNECTOR_HDMIA;
2039 : 0 : break;
2040 : :
2041 : 0 : case TRANS_DDI_MODE_SELECT_DP_SST:
2042 : 0 : ret = type == DRM_MODE_CONNECTOR_eDP ||
2043 : 0 : type == DRM_MODE_CONNECTOR_DisplayPort;
2044 : 0 : break;
2045 : :
2046 : : case TRANS_DDI_MODE_SELECT_DP_MST:
2047 : : /* if the transcoder is in MST state then
2048 : : * connector isn't connected */
2049 : : ret = false;
2050 : : break;
2051 : :
2052 : 0 : case TRANS_DDI_MODE_SELECT_FDI:
2053 : 0 : ret = type == DRM_MODE_CONNECTOR_VGA;
2054 : 0 : break;
2055 : :
2056 : : default:
2057 : : ret = false;
2058 : : break;
2059 : : }
2060 : :
2061 : 0 : out:
2062 : 0 : intel_display_power_put(dev_priv, encoder->power_domain, wakeref);
2063 : :
2064 : 0 : return ret;
2065 : : }
2066 : :
2067 : 0 : static void intel_ddi_get_encoder_pipes(struct intel_encoder *encoder,
2068 : : u8 *pipe_mask, bool *is_dp_mst)
2069 : : {
2070 : 0 : struct drm_device *dev = encoder->base.dev;
2071 : 0 : struct drm_i915_private *dev_priv = to_i915(dev);
2072 : 0 : enum port port = encoder->port;
2073 : 0 : intel_wakeref_t wakeref;
2074 : 0 : enum pipe p;
2075 : 0 : u32 tmp;
2076 : 0 : u8 mst_pipe_mask;
2077 : :
2078 : 0 : *pipe_mask = 0;
2079 : 0 : *is_dp_mst = false;
2080 : :
2081 : 0 : wakeref = intel_display_power_get_if_enabled(dev_priv,
2082 : : encoder->power_domain);
2083 [ # # ]: 0 : if (!wakeref)
2084 : : return;
2085 : :
2086 : 0 : tmp = I915_READ(DDI_BUF_CTL(port));
2087 [ # # ]: 0 : if (!(tmp & DDI_BUF_CTL_ENABLE))
2088 : 0 : goto out;
2089 : :
2090 [ # # # # ]: 0 : if (HAS_TRANSCODER_EDP(dev_priv) && port == PORT_A) {
2091 : 0 : tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP));
2092 : :
2093 [ # # # # ]: 0 : switch (tmp & TRANS_DDI_EDP_INPUT_MASK) {
2094 : : default:
2095 : 0 : MISSING_CASE(tmp & TRANS_DDI_EDP_INPUT_MASK);
2096 : : /* fallthrough */
2097 : 0 : case TRANS_DDI_EDP_INPUT_A_ON:
2098 : : case TRANS_DDI_EDP_INPUT_A_ONOFF:
2099 : 0 : *pipe_mask = BIT(PIPE_A);
2100 : 0 : break;
2101 : 0 : case TRANS_DDI_EDP_INPUT_B_ONOFF:
2102 : 0 : *pipe_mask = BIT(PIPE_B);
2103 : 0 : break;
2104 : 0 : case TRANS_DDI_EDP_INPUT_C_ONOFF:
2105 : 0 : *pipe_mask = BIT(PIPE_C);
2106 : 0 : break;
2107 : : }
2108 : :
2109 : 0 : goto out;
2110 : : }
2111 : :
2112 : : mst_pipe_mask = 0;
2113 [ # # # # ]: 0 : for_each_pipe(dev_priv, p) {
2114 : 0 : enum transcoder cpu_transcoder = (enum transcoder)p;
2115 : 0 : unsigned int port_mask, ddi_select;
2116 : 0 : intel_wakeref_t trans_wakeref;
2117 : :
2118 [ # # ]: 0 : trans_wakeref = intel_display_power_get_if_enabled(dev_priv,
2119 : 0 : POWER_DOMAIN_TRANSCODER(cpu_transcoder));
2120 [ # # ]: 0 : if (!trans_wakeref)
2121 : 0 : continue;
2122 : :
2123 [ # # ]: 0 : if (INTEL_GEN(dev_priv) >= 12) {
2124 : 0 : port_mask = TGL_TRANS_DDI_PORT_MASK;
2125 : 0 : ddi_select = TGL_TRANS_DDI_SELECT_PORT(port);
2126 : : } else {
2127 : 0 : port_mask = TRANS_DDI_PORT_MASK;
2128 : 0 : ddi_select = TRANS_DDI_SELECT_PORT(port);
2129 : : }
2130 : :
2131 : 0 : tmp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
2132 : 0 : intel_display_power_put(dev_priv, POWER_DOMAIN_TRANSCODER(cpu_transcoder),
2133 : : trans_wakeref);
2134 : :
2135 [ # # ]: 0 : if ((tmp & port_mask) != ddi_select)
2136 : 0 : continue;
2137 : :
2138 [ # # ]: 0 : if ((tmp & TRANS_DDI_MODE_SELECT_MASK) ==
2139 : : TRANS_DDI_MODE_SELECT_DP_MST)
2140 : 0 : mst_pipe_mask |= BIT(p);
2141 : :
2142 : 0 : *pipe_mask |= BIT(p);
2143 : : }
2144 : :
2145 [ # # ]: 0 : if (!*pipe_mask)
2146 : 0 : DRM_DEBUG_KMS("No pipe for [ENCODER:%d:%s] found\n",
2147 : : encoder->base.base.id, encoder->base.name);
2148 : :
2149 [ # # # # : 0 : if (!mst_pipe_mask && hweight8(*pipe_mask) > 1) {
# # ]
2150 : 0 : DRM_DEBUG_KMS("Multiple pipes for [ENCODER:%d:%s] (pipe_mask %02x)\n",
2151 : : encoder->base.base.id, encoder->base.name,
2152 : : *pipe_mask);
2153 : 0 : *pipe_mask = BIT(ffs(*pipe_mask) - 1);
2154 : : }
2155 : :
2156 [ # # # # ]: 0 : if (mst_pipe_mask && mst_pipe_mask != *pipe_mask)
2157 : 0 : DRM_DEBUG_KMS("Conflicting MST and non-MST state for [ENCODER:%d:%s] (pipe_mask %02x mst_pipe_mask %02x)\n",
2158 : : encoder->base.base.id, encoder->base.name,
2159 : : *pipe_mask, mst_pipe_mask);
2160 : : else
2161 : 0 : *is_dp_mst = mst_pipe_mask;
2162 : :
2163 : 0 : out:
2164 [ # # # # : 0 : if (*pipe_mask && IS_GEN9_LP(dev_priv)) {
# # ]
2165 : 0 : tmp = I915_READ(BXT_PHY_CTL(port));
2166 [ # # ]: 0 : if ((tmp & (BXT_PHY_CMNLANE_POWERDOWN_ACK |
2167 : : BXT_PHY_LANE_POWERDOWN_ACK |
2168 : : BXT_PHY_LANE_ENABLED)) != BXT_PHY_LANE_ENABLED)
2169 : 0 : DRM_ERROR("[ENCODER:%d:%s] enabled but PHY powered down? "
2170 : : "(PHY_CTL %08x)\n", encoder->base.base.id,
2171 : : encoder->base.name, tmp);
2172 : : }
2173 : :
2174 : 0 : intel_display_power_put(dev_priv, encoder->power_domain, wakeref);
2175 : : }
2176 : :
2177 : 0 : bool intel_ddi_get_hw_state(struct intel_encoder *encoder,
2178 : : enum pipe *pipe)
2179 : : {
2180 : 0 : u8 pipe_mask;
2181 : 0 : bool is_mst;
2182 : :
2183 : 0 : intel_ddi_get_encoder_pipes(encoder, &pipe_mask, &is_mst);
2184 : :
2185 [ # # # # ]: 0 : if (is_mst || !pipe_mask)
2186 : : return false;
2187 : :
2188 : 0 : *pipe = ffs(pipe_mask) - 1;
2189 : :
2190 : 0 : return true;
2191 : : }
2192 : :
2193 : : static inline enum intel_display_power_domain
2194 : 0 : intel_ddi_main_link_aux_domain(struct intel_digital_port *dig_port)
2195 : : {
2196 : : /* CNL+ HW requires corresponding AUX IOs to be powered up for PSR with
2197 : : * DC states enabled at the same time, while for driver initiated AUX
2198 : : * transfers we need the same AUX IOs to be powered but with DC states
2199 : : * disabled. Accordingly use the AUX power domain here which leaves DC
2200 : : * states enabled.
2201 : : * However, for non-A AUX ports the corresponding non-EDP transcoders
2202 : : * would have already enabled power well 2 and DC_OFF. This means we can
2203 : : * acquire a wider POWER_DOMAIN_AUX_{B,C,D,F} reference instead of a
2204 : : * specific AUX_IO reference without powering up any extra wells.
2205 : : * Note that PSR is enabled only on Port A even though this function
2206 : : * returns the correct domain for other ports too.
2207 : : */
2208 : 0 : return dig_port->aux_ch == AUX_CH_A ? POWER_DOMAIN_AUX_IO_A :
2209 : 0 : intel_aux_power_domain(dig_port);
2210 : : }
2211 : :
2212 : 0 : static void intel_ddi_get_power_domains(struct intel_encoder *encoder,
2213 : : struct intel_crtc_state *crtc_state)
2214 : : {
2215 : 0 : struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
2216 : 0 : struct intel_digital_port *dig_port;
2217 : 0 : enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
2218 : :
2219 : : /*
2220 : : * TODO: Add support for MST encoders. Atm, the following should never
2221 : : * happen since fake-MST encoders don't set their get_power_domains()
2222 : : * hook.
2223 : : */
2224 [ # # # # ]: 0 : if (WARN_ON(intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST)))
2225 : : return;
2226 : :
2227 [ # # ]: 0 : dig_port = enc_to_dig_port(encoder);
2228 : 0 : intel_display_power_get(dev_priv, dig_port->ddi_io_power_domain);
2229 : :
2230 : : /*
2231 : : * AUX power is only needed for (e)DP mode, and for HDMI mode on TC
2232 : : * ports.
2233 : : */
2234 [ # # # # ]: 0 : if (intel_crtc_has_dp_encoder(crtc_state) ||
2235 : 0 : intel_phy_is_tc(dev_priv, phy))
2236 [ # # ]: 0 : intel_display_power_get(dev_priv,
2237 : : intel_ddi_main_link_aux_domain(dig_port));
2238 : :
2239 : : /*
2240 : : * VDSC power is needed when DSC is enabled
2241 : : */
2242 [ # # ]: 0 : if (crtc_state->dsc.compression_enable)
2243 : 0 : intel_display_power_get(dev_priv,
2244 : : intel_dsc_power_domain(crtc_state));
2245 : : }
2246 : :
2247 : 0 : void intel_ddi_enable_pipe_clock(const struct intel_crtc_state *crtc_state)
2248 : : {
2249 : 0 : struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
2250 : 0 : struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
2251 : 0 : struct intel_encoder *encoder = intel_ddi_get_crtc_encoder(crtc);
2252 : 0 : enum port port = encoder->port;
2253 : 0 : enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
2254 : :
2255 [ # # ]: 0 : if (cpu_transcoder != TRANSCODER_EDP) {
2256 [ # # ]: 0 : if (INTEL_GEN(dev_priv) >= 12)
2257 : 0 : I915_WRITE(TRANS_CLK_SEL(cpu_transcoder),
2258 : : TGL_TRANS_CLK_SEL_PORT(port));
2259 : : else
2260 : 0 : I915_WRITE(TRANS_CLK_SEL(cpu_transcoder),
2261 : : TRANS_CLK_SEL_PORT(port));
2262 : : }
2263 : 0 : }
2264 : :
2265 : 0 : void intel_ddi_disable_pipe_clock(const struct intel_crtc_state *crtc_state)
2266 : : {
2267 [ # # ]: 0 : struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
2268 : 0 : enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
2269 : :
2270 [ # # ]: 0 : if (cpu_transcoder != TRANSCODER_EDP) {
2271 [ # # ]: 0 : if (INTEL_GEN(dev_priv) >= 12)
2272 : 0 : I915_WRITE(TRANS_CLK_SEL(cpu_transcoder),
2273 : : TGL_TRANS_CLK_SEL_DISABLED);
2274 : : else
2275 : 0 : I915_WRITE(TRANS_CLK_SEL(cpu_transcoder),
2276 : : TRANS_CLK_SEL_DISABLED);
2277 : : }
2278 : 0 : }
2279 : :
2280 : 0 : static void _skl_ddi_set_iboost(struct drm_i915_private *dev_priv,
2281 : : enum port port, u8 iboost)
2282 : : {
2283 : 0 : u32 tmp;
2284 : :
2285 : 0 : tmp = I915_READ(DISPIO_CR_TX_BMU_CR0);
2286 : 0 : tmp &= ~(BALANCE_LEG_MASK(port) | BALANCE_LEG_DISABLE(port));
2287 [ # # ]: 0 : if (iboost)
2288 : 0 : tmp |= iboost << BALANCE_LEG_SHIFT(port);
2289 : : else
2290 : 0 : tmp |= BALANCE_LEG_DISABLE(port);
2291 : 0 : I915_WRITE(DISPIO_CR_TX_BMU_CR0, tmp);
2292 : 0 : }
2293 : :
2294 : 0 : static void skl_ddi_set_iboost(struct intel_encoder *encoder,
2295 : : int level, enum intel_output_type type)
2296 : : {
2297 [ # # ]: 0 : struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
2298 [ # # ]: 0 : struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
2299 : 0 : enum port port = encoder->port;
2300 : 0 : u8 iboost;
2301 : :
2302 [ # # ]: 0 : if (type == INTEL_OUTPUT_HDMI)
2303 : 0 : iboost = dev_priv->vbt.ddi_port_info[port].hdmi_boost_level;
2304 : : else
2305 : 0 : iboost = dev_priv->vbt.ddi_port_info[port].dp_boost_level;
2306 : :
2307 [ # # ]: 0 : if (iboost == 0) {
2308 : 0 : const struct ddi_buf_trans *ddi_translations;
2309 : 0 : int n_entries;
2310 : :
2311 [ # # ]: 0 : if (type == INTEL_OUTPUT_HDMI)
2312 : 0 : ddi_translations = intel_ddi_get_buf_trans_hdmi(dev_priv, &n_entries);
2313 [ # # ]: 0 : else if (type == INTEL_OUTPUT_EDP)
2314 : 0 : ddi_translations = intel_ddi_get_buf_trans_edp(dev_priv, port, &n_entries);
2315 : : else
2316 : 0 : ddi_translations = intel_ddi_get_buf_trans_dp(dev_priv, port, &n_entries);
2317 : :
2318 [ # # # # : 0 : if (WARN_ON_ONCE(!ddi_translations))
# # ]
2319 : 0 : return;
2320 [ # # # # : 0 : if (WARN_ON_ONCE(level >= n_entries))
# # ]
2321 : 0 : level = n_entries - 1;
2322 : :
2323 : 0 : iboost = ddi_translations[level].i_boost;
2324 : : }
2325 : :
2326 : : /* Make sure that the requested I_boost is valid */
2327 [ # # # # ]: 0 : if (iboost && iboost != 0x1 && iboost != 0x3 && iboost != 0x7) {
2328 : 0 : DRM_ERROR("Invalid I_boost value %u\n", iboost);
2329 : 0 : return;
2330 : : }
2331 : :
2332 : 0 : _skl_ddi_set_iboost(dev_priv, port, iboost);
2333 : :
2334 [ # # # # ]: 0 : if (port == PORT_A && intel_dig_port->max_lanes == 4)
2335 : 0 : _skl_ddi_set_iboost(dev_priv, PORT_E, iboost);
2336 : : }
2337 : :
2338 : : static void bxt_ddi_vswing_sequence(struct intel_encoder *encoder,
2339 : : int level, enum intel_output_type type)
2340 : : {
2341 : : struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
2342 : : const struct bxt_ddi_buf_trans *ddi_translations;
2343 : : enum port port = encoder->port;
2344 : : int n_entries;
2345 : :
2346 : : if (type == INTEL_OUTPUT_HDMI)
2347 : : ddi_translations = bxt_get_buf_trans_hdmi(dev_priv, &n_entries);
2348 : : else if (type == INTEL_OUTPUT_EDP)
2349 : : ddi_translations = bxt_get_buf_trans_edp(dev_priv, &n_entries);
2350 : : else
2351 : : ddi_translations = bxt_get_buf_trans_dp(dev_priv, &n_entries);
2352 : :
2353 : : if (WARN_ON_ONCE(!ddi_translations))
2354 : : return;
2355 : : if (WARN_ON_ONCE(level >= n_entries))
2356 : : level = n_entries - 1;
2357 : :
2358 : : bxt_ddi_phy_set_signal_level(dev_priv, port,
2359 : : ddi_translations[level].margin,
2360 : : ddi_translations[level].scale,
2361 : : ddi_translations[level].enable,
2362 : : ddi_translations[level].deemphasis);
2363 : : }
2364 : :
2365 : 0 : u8 intel_ddi_dp_voltage_max(struct intel_encoder *encoder)
2366 : : {
2367 [ # # ]: 0 : struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
2368 [ # # ]: 0 : struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
2369 : 0 : enum port port = encoder->port;
2370 : 0 : enum phy phy = intel_port_to_phy(dev_priv, port);
2371 : 0 : int n_entries;
2372 : :
2373 [ # # ]: 0 : if (INTEL_GEN(dev_priv) >= 12) {
2374 [ # # ]: 0 : if (intel_phy_is_combo(dev_priv, phy))
2375 [ # # ]: 0 : icl_get_combo_buf_trans(dev_priv, encoder->type,
2376 : : intel_dp->link_rate, &n_entries);
2377 : : else
2378 : 0 : n_entries = ARRAY_SIZE(tgl_dkl_phy_dp_ddi_trans);
2379 [ # # ]: 0 : } else if (INTEL_GEN(dev_priv) == 11) {
2380 [ # # ]: 0 : if (intel_phy_is_combo(dev_priv, phy))
2381 [ # # ]: 0 : icl_get_combo_buf_trans(dev_priv, encoder->type,
2382 : : intel_dp->link_rate, &n_entries);
2383 : : else
2384 : 0 : n_entries = ARRAY_SIZE(icl_mg_phy_ddi_translations);
2385 [ # # ]: 0 : } else if (IS_CANNONLAKE(dev_priv)) {
2386 [ # # ]: 0 : if (encoder->type == INTEL_OUTPUT_EDP)
2387 : 0 : cnl_get_buf_trans_edp(dev_priv, &n_entries);
2388 : : else
2389 : 0 : cnl_get_buf_trans_dp(dev_priv, &n_entries);
2390 [ # # # # ]: 0 : } else if (IS_GEN9_LP(dev_priv)) {
2391 [ # # ]: 0 : if (encoder->type == INTEL_OUTPUT_EDP)
2392 [ # # ]: 0 : bxt_get_buf_trans_edp(dev_priv, &n_entries);
2393 : : else
2394 : 0 : bxt_get_buf_trans_dp(dev_priv, &n_entries);
2395 : : } else {
2396 [ # # ]: 0 : if (encoder->type == INTEL_OUTPUT_EDP)
2397 : 0 : intel_ddi_get_buf_trans_edp(dev_priv, port, &n_entries);
2398 : : else
2399 : 0 : intel_ddi_get_buf_trans_dp(dev_priv, port, &n_entries);
2400 : : }
2401 : :
2402 [ # # # # ]: 0 : if (WARN_ON(n_entries < 1))
2403 : 0 : n_entries = 1;
2404 [ # # # # ]: 0 : if (WARN_ON(n_entries > ARRAY_SIZE(index_to_dp_signal_levels)))
2405 : 0 : n_entries = ARRAY_SIZE(index_to_dp_signal_levels);
2406 : :
2407 : 0 : return index_to_dp_signal_levels[n_entries - 1] &
2408 : : DP_TRAIN_VOLTAGE_SWING_MASK;
2409 : : }
2410 : :
2411 : : /*
2412 : : * We assume that the full set of pre-emphasis values can be
2413 : : * used on all DDI platforms. Should that change we need to
2414 : : * rethink this code.
2415 : : */
2416 : 0 : u8 intel_ddi_dp_pre_emphasis_max(struct intel_encoder *encoder, u8 voltage_swing)
2417 : : {
2418 [ # # ]: 0 : switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
2419 : : case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
2420 : : return DP_TRAIN_PRE_EMPH_LEVEL_3;
2421 : : case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
2422 : : return DP_TRAIN_PRE_EMPH_LEVEL_2;
2423 : : case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
2424 : : return DP_TRAIN_PRE_EMPH_LEVEL_1;
2425 : : case DP_TRAIN_VOLTAGE_SWING_LEVEL_3:
2426 : : default:
2427 : : return DP_TRAIN_PRE_EMPH_LEVEL_0;
2428 : : }
2429 : : }
2430 : :
2431 : : static void cnl_ddi_vswing_program(struct intel_encoder *encoder,
2432 : : int level, enum intel_output_type type)
2433 : : {
2434 : : struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
2435 : : const struct cnl_ddi_buf_trans *ddi_translations;
2436 : : enum port port = encoder->port;
2437 : : int n_entries, ln;
2438 : : u32 val;
2439 : :
2440 : : if (type == INTEL_OUTPUT_HDMI)
2441 : : ddi_translations = cnl_get_buf_trans_hdmi(dev_priv, &n_entries);
2442 : : else if (type == INTEL_OUTPUT_EDP)
2443 : : ddi_translations = cnl_get_buf_trans_edp(dev_priv, &n_entries);
2444 : : else
2445 : : ddi_translations = cnl_get_buf_trans_dp(dev_priv, &n_entries);
2446 : :
2447 : : if (WARN_ON_ONCE(!ddi_translations))
2448 : : return;
2449 : : if (WARN_ON_ONCE(level >= n_entries))
2450 : : level = n_entries - 1;
2451 : :
2452 : : /* Set PORT_TX_DW5 Scaling Mode Sel to 010b. */
2453 : : val = I915_READ(CNL_PORT_TX_DW5_LN0(port));
2454 : : val &= ~SCALING_MODE_SEL_MASK;
2455 : : val |= SCALING_MODE_SEL(2);
2456 : : I915_WRITE(CNL_PORT_TX_DW5_GRP(port), val);
2457 : :
2458 : : /* Program PORT_TX_DW2 */
2459 : : val = I915_READ(CNL_PORT_TX_DW2_LN0(port));
2460 : : val &= ~(SWING_SEL_LOWER_MASK | SWING_SEL_UPPER_MASK |
2461 : : RCOMP_SCALAR_MASK);
2462 : : val |= SWING_SEL_UPPER(ddi_translations[level].dw2_swing_sel);
2463 : : val |= SWING_SEL_LOWER(ddi_translations[level].dw2_swing_sel);
2464 : : /* Rcomp scalar is fixed as 0x98 for every table entry */
2465 : : val |= RCOMP_SCALAR(0x98);
2466 : : I915_WRITE(CNL_PORT_TX_DW2_GRP(port), val);
2467 : :
2468 : : /* Program PORT_TX_DW4 */
2469 : : /* We cannot write to GRP. It would overrite individual loadgen */
2470 : : for (ln = 0; ln < 4; ln++) {
2471 : : val = I915_READ(CNL_PORT_TX_DW4_LN(ln, port));
2472 : : val &= ~(POST_CURSOR_1_MASK | POST_CURSOR_2_MASK |
2473 : : CURSOR_COEFF_MASK);
2474 : : val |= POST_CURSOR_1(ddi_translations[level].dw4_post_cursor_1);
2475 : : val |= POST_CURSOR_2(ddi_translations[level].dw4_post_cursor_2);
2476 : : val |= CURSOR_COEFF(ddi_translations[level].dw4_cursor_coeff);
2477 : : I915_WRITE(CNL_PORT_TX_DW4_LN(ln, port), val);
2478 : : }
2479 : :
2480 : : /* Program PORT_TX_DW5 */
2481 : : /* All DW5 values are fixed for every table entry */
2482 : : val = I915_READ(CNL_PORT_TX_DW5_LN0(port));
2483 : : val &= ~RTERM_SELECT_MASK;
2484 : : val |= RTERM_SELECT(6);
2485 : : val |= TAP3_DISABLE;
2486 : : I915_WRITE(CNL_PORT_TX_DW5_GRP(port), val);
2487 : :
2488 : : /* Program PORT_TX_DW7 */
2489 : : val = I915_READ(CNL_PORT_TX_DW7_LN0(port));
2490 : : val &= ~N_SCALAR_MASK;
2491 : : val |= N_SCALAR(ddi_translations[level].dw7_n_scalar);
2492 : : I915_WRITE(CNL_PORT_TX_DW7_GRP(port), val);
2493 : : }
2494 : :
2495 : 0 : static void cnl_ddi_vswing_sequence(struct intel_encoder *encoder,
2496 : : int level, enum intel_output_type type)
2497 : : {
2498 [ # # ]: 0 : struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
2499 : 0 : enum port port = encoder->port;
2500 : 0 : int width, rate, ln;
2501 : 0 : u32 val;
2502 : :
2503 [ # # ]: 0 : if (type == INTEL_OUTPUT_HDMI) {
2504 : : width = 4;
2505 : : rate = 0; /* Rate is always < than 6GHz for HDMI */
2506 : : } else {
2507 [ # # ]: 0 : struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
2508 : :
2509 : 0 : width = intel_dp->lane_count;
2510 : 0 : rate = intel_dp->link_rate;
2511 : : }
2512 : :
2513 : : /*
2514 : : * 1. If port type is eDP or DP,
2515 : : * set PORT_PCS_DW1 cmnkeeper_enable to 1b,
2516 : : * else clear to 0b.
2517 : : */
2518 : 0 : val = I915_READ(CNL_PORT_PCS_DW1_LN0(port));
2519 [ # # ]: 0 : if (type != INTEL_OUTPUT_HDMI)
2520 : 0 : val |= COMMON_KEEPER_EN;
2521 : : else
2522 : 0 : val &= ~COMMON_KEEPER_EN;
2523 : 0 : I915_WRITE(CNL_PORT_PCS_DW1_GRP(port), val);
2524 : :
2525 : : /* 2. Program loadgen select */
2526 : : /*
2527 : : * Program PORT_TX_DW4_LN depending on Bit rate and used lanes
2528 : : * <= 6 GHz and 4 lanes (LN0=0, LN1=1, LN2=1, LN3=1)
2529 : : * <= 6 GHz and 1,2 lanes (LN0=0, LN1=1, LN2=1, LN3=0)
2530 : : * > 6 GHz (LN0=0, LN1=0, LN2=0, LN3=0)
2531 : : */
2532 [ # # ]: 0 : for (ln = 0; ln <= 3; ln++) {
2533 : 0 : val = I915_READ(CNL_PORT_TX_DW4_LN(ln, port));
2534 : 0 : val &= ~LOADGEN_SELECT;
2535 : :
2536 [ # # # # ]: 0 : if ((rate <= 600000 && width == 4 && ln >= 1) ||
2537 [ # # # # ]: 0 : (rate <= 600000 && width < 4 && (ln == 1 || ln == 2))) {
2538 : 0 : val |= LOADGEN_SELECT;
2539 : : }
2540 : 0 : I915_WRITE(CNL_PORT_TX_DW4_LN(ln, port), val);
2541 : : }
2542 : :
2543 : : /* 3. Set PORT_CL_DW5 SUS Clock Config to 11b */
2544 : 0 : val = I915_READ(CNL_PORT_CL1CM_DW5);
2545 : 0 : val |= SUS_CLOCK_CONFIG;
2546 : 0 : I915_WRITE(CNL_PORT_CL1CM_DW5, val);
2547 : :
2548 : : /* 4. Clear training enable to change swing values */
2549 : 0 : val = I915_READ(CNL_PORT_TX_DW5_LN0(port));
2550 : 0 : val &= ~TX_TRAINING_EN;
2551 : 0 : I915_WRITE(CNL_PORT_TX_DW5_GRP(port), val);
2552 : :
2553 : : /* 5. Program swing and de-emphasis */
2554 : 0 : cnl_ddi_vswing_program(encoder, level, type);
2555 : :
2556 : : /* 6. Set training enable to trigger update */
2557 : 0 : val = I915_READ(CNL_PORT_TX_DW5_LN0(port));
2558 : 0 : val |= TX_TRAINING_EN;
2559 : 0 : I915_WRITE(CNL_PORT_TX_DW5_GRP(port), val);
2560 : 0 : }
2561 : :
2562 : 0 : static void icl_ddi_combo_vswing_program(struct drm_i915_private *dev_priv,
2563 : : u32 level, enum phy phy, int type,
2564 : : int rate)
2565 : : {
2566 : 0 : const struct cnl_ddi_buf_trans *ddi_translations = NULL;
2567 : 0 : u32 n_entries, val;
2568 : 0 : int ln;
2569 : :
2570 [ # # ]: 0 : ddi_translations = icl_get_combo_buf_trans(dev_priv, type, rate,
2571 : : &n_entries);
2572 : 0 : if (!ddi_translations)
2573 : : return;
2574 : :
2575 [ # # ]: 0 : if (level >= n_entries) {
2576 : 0 : DRM_DEBUG_KMS("DDI translation not found for level %d. Using %d instead.", level, n_entries - 1);
2577 : 0 : level = n_entries - 1;
2578 : : }
2579 : :
2580 : : /* Set PORT_TX_DW5 */
2581 : 0 : val = I915_READ(ICL_PORT_TX_DW5_LN0(phy));
2582 : 0 : val &= ~(SCALING_MODE_SEL_MASK | RTERM_SELECT_MASK |
2583 : : TAP2_DISABLE | TAP3_DISABLE);
2584 : 0 : val |= SCALING_MODE_SEL(0x2);
2585 : 0 : val |= RTERM_SELECT(0x6);
2586 : 0 : val |= TAP3_DISABLE;
2587 : 0 : I915_WRITE(ICL_PORT_TX_DW5_GRP(phy), val);
2588 : :
2589 : : /* Program PORT_TX_DW2 */
2590 : 0 : val = I915_READ(ICL_PORT_TX_DW2_LN0(phy));
2591 : 0 : val &= ~(SWING_SEL_LOWER_MASK | SWING_SEL_UPPER_MASK |
2592 : : RCOMP_SCALAR_MASK);
2593 : 0 : val |= SWING_SEL_UPPER(ddi_translations[level].dw2_swing_sel);
2594 : 0 : val |= SWING_SEL_LOWER(ddi_translations[level].dw2_swing_sel);
2595 : : /* Program Rcomp scalar for every table entry */
2596 : 0 : val |= RCOMP_SCALAR(0x98);
2597 : 0 : I915_WRITE(ICL_PORT_TX_DW2_GRP(phy), val);
2598 : :
2599 : : /* Program PORT_TX_DW4 */
2600 : : /* We cannot write to GRP. It would overwrite individual loadgen. */
2601 [ # # ]: 0 : for (ln = 0; ln <= 3; ln++) {
2602 : 0 : val = I915_READ(ICL_PORT_TX_DW4_LN(ln, phy));
2603 : 0 : val &= ~(POST_CURSOR_1_MASK | POST_CURSOR_2_MASK |
2604 : : CURSOR_COEFF_MASK);
2605 : 0 : val |= POST_CURSOR_1(ddi_translations[level].dw4_post_cursor_1);
2606 : 0 : val |= POST_CURSOR_2(ddi_translations[level].dw4_post_cursor_2);
2607 : 0 : val |= CURSOR_COEFF(ddi_translations[level].dw4_cursor_coeff);
2608 : 0 : I915_WRITE(ICL_PORT_TX_DW4_LN(ln, phy), val);
2609 : : }
2610 : :
2611 : : /* Program PORT_TX_DW7 */
2612 : 0 : val = I915_READ(ICL_PORT_TX_DW7_LN0(phy));
2613 : 0 : val &= ~N_SCALAR_MASK;
2614 : 0 : val |= N_SCALAR(ddi_translations[level].dw7_n_scalar);
2615 : 0 : I915_WRITE(ICL_PORT_TX_DW7_GRP(phy), val);
2616 : : }
2617 : :
2618 : 0 : static void icl_combo_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
2619 : : u32 level,
2620 : : enum intel_output_type type)
2621 : : {
2622 : 0 : struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
2623 : 0 : enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
2624 : 0 : int width = 0;
2625 : 0 : int rate = 0;
2626 : 0 : u32 val;
2627 : 0 : int ln = 0;
2628 : :
2629 [ # # ]: 0 : if (type == INTEL_OUTPUT_HDMI) {
2630 : : width = 4;
2631 : : /* Rate is always < than 6GHz for HDMI */
2632 : : } else {
2633 [ # # ]: 0 : struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
2634 : :
2635 : 0 : width = intel_dp->lane_count;
2636 : 0 : rate = intel_dp->link_rate;
2637 : : }
2638 : :
2639 : : /*
2640 : : * 1. If port type is eDP or DP,
2641 : : * set PORT_PCS_DW1 cmnkeeper_enable to 1b,
2642 : : * else clear to 0b.
2643 : : */
2644 : 0 : val = I915_READ(ICL_PORT_PCS_DW1_LN0(phy));
2645 [ # # ]: 0 : if (type == INTEL_OUTPUT_HDMI)
2646 : 0 : val &= ~COMMON_KEEPER_EN;
2647 : : else
2648 : 0 : val |= COMMON_KEEPER_EN;
2649 : 0 : I915_WRITE(ICL_PORT_PCS_DW1_GRP(phy), val);
2650 : :
2651 : : /* 2. Program loadgen select */
2652 : : /*
2653 : : * Program PORT_TX_DW4_LN depending on Bit rate and used lanes
2654 : : * <= 6 GHz and 4 lanes (LN0=0, LN1=1, LN2=1, LN3=1)
2655 : : * <= 6 GHz and 1,2 lanes (LN0=0, LN1=1, LN2=1, LN3=0)
2656 : : * > 6 GHz (LN0=0, LN1=0, LN2=0, LN3=0)
2657 : : */
2658 [ # # ]: 0 : for (ln = 0; ln <= 3; ln++) {
2659 : 0 : val = I915_READ(ICL_PORT_TX_DW4_LN(ln, phy));
2660 : 0 : val &= ~LOADGEN_SELECT;
2661 : :
2662 [ # # # # ]: 0 : if ((rate <= 600000 && width == 4 && ln >= 1) ||
2663 [ # # # # ]: 0 : (rate <= 600000 && width < 4 && (ln == 1 || ln == 2))) {
2664 : 0 : val |= LOADGEN_SELECT;
2665 : : }
2666 : 0 : I915_WRITE(ICL_PORT_TX_DW4_LN(ln, phy), val);
2667 : : }
2668 : :
2669 : : /* 3. Set PORT_CL_DW5 SUS Clock Config to 11b */
2670 : 0 : val = I915_READ(ICL_PORT_CL_DW5(phy));
2671 : 0 : val |= SUS_CLOCK_CONFIG;
2672 : 0 : I915_WRITE(ICL_PORT_CL_DW5(phy), val);
2673 : :
2674 : : /* 4. Clear training enable to change swing values */
2675 : 0 : val = I915_READ(ICL_PORT_TX_DW5_LN0(phy));
2676 : 0 : val &= ~TX_TRAINING_EN;
2677 : 0 : I915_WRITE(ICL_PORT_TX_DW5_GRP(phy), val);
2678 : :
2679 : : /* 5. Program swing and de-emphasis */
2680 : 0 : icl_ddi_combo_vswing_program(dev_priv, level, phy, type, rate);
2681 : :
2682 : : /* 6. Set training enable to trigger update */
2683 : 0 : val = I915_READ(ICL_PORT_TX_DW5_LN0(phy));
2684 : 0 : val |= TX_TRAINING_EN;
2685 : 0 : I915_WRITE(ICL_PORT_TX_DW5_GRP(phy), val);
2686 : 0 : }
2687 : :
2688 : : static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
2689 : : int link_clock,
2690 : : u32 level)
2691 : : {
2692 : : struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
2693 : : enum tc_port tc_port = intel_port_to_tc(dev_priv, encoder->port);
2694 : : const struct icl_mg_phy_ddi_buf_trans *ddi_translations;
2695 : : u32 n_entries, val;
2696 : : int ln;
2697 : :
2698 : : n_entries = ARRAY_SIZE(icl_mg_phy_ddi_translations);
2699 : : ddi_translations = icl_mg_phy_ddi_translations;
2700 : : /* The table does not have values for level 3 and level 9. */
2701 : : if (level >= n_entries || level == 3 || level == 9) {
2702 : : DRM_DEBUG_KMS("DDI translation not found for level %d. Using %d instead.",
2703 : : level, n_entries - 2);
2704 : : level = n_entries - 2;
2705 : : }
2706 : :
2707 : : /* Set MG_TX_LINK_PARAMS cri_use_fs32 to 0. */
2708 : : for (ln = 0; ln < 2; ln++) {
2709 : : val = I915_READ(MG_TX1_LINK_PARAMS(ln, tc_port));
2710 : : val &= ~CRI_USE_FS32;
2711 : : I915_WRITE(MG_TX1_LINK_PARAMS(ln, tc_port), val);
2712 : :
2713 : : val = I915_READ(MG_TX2_LINK_PARAMS(ln, tc_port));
2714 : : val &= ~CRI_USE_FS32;
2715 : : I915_WRITE(MG_TX2_LINK_PARAMS(ln, tc_port), val);
2716 : : }
2717 : :
2718 : : /* Program MG_TX_SWINGCTRL with values from vswing table */
2719 : : for (ln = 0; ln < 2; ln++) {
2720 : : val = I915_READ(MG_TX1_SWINGCTRL(ln, tc_port));
2721 : : val &= ~CRI_TXDEEMPH_OVERRIDE_17_12_MASK;
2722 : : val |= CRI_TXDEEMPH_OVERRIDE_17_12(
2723 : : ddi_translations[level].cri_txdeemph_override_17_12);
2724 : : I915_WRITE(MG_TX1_SWINGCTRL(ln, tc_port), val);
2725 : :
2726 : : val = I915_READ(MG_TX2_SWINGCTRL(ln, tc_port));
2727 : : val &= ~CRI_TXDEEMPH_OVERRIDE_17_12_MASK;
2728 : : val |= CRI_TXDEEMPH_OVERRIDE_17_12(
2729 : : ddi_translations[level].cri_txdeemph_override_17_12);
2730 : : I915_WRITE(MG_TX2_SWINGCTRL(ln, tc_port), val);
2731 : : }
2732 : :
2733 : : /* Program MG_TX_DRVCTRL with values from vswing table */
2734 : : for (ln = 0; ln < 2; ln++) {
2735 : : val = I915_READ(MG_TX1_DRVCTRL(ln, tc_port));
2736 : : val &= ~(CRI_TXDEEMPH_OVERRIDE_11_6_MASK |
2737 : : CRI_TXDEEMPH_OVERRIDE_5_0_MASK);
2738 : : val |= CRI_TXDEEMPH_OVERRIDE_5_0(
2739 : : ddi_translations[level].cri_txdeemph_override_5_0) |
2740 : : CRI_TXDEEMPH_OVERRIDE_11_6(
2741 : : ddi_translations[level].cri_txdeemph_override_11_6) |
2742 : : CRI_TXDEEMPH_OVERRIDE_EN;
2743 : : I915_WRITE(MG_TX1_DRVCTRL(ln, tc_port), val);
2744 : :
2745 : : val = I915_READ(MG_TX2_DRVCTRL(ln, tc_port));
2746 : : val &= ~(CRI_TXDEEMPH_OVERRIDE_11_6_MASK |
2747 : : CRI_TXDEEMPH_OVERRIDE_5_0_MASK);
2748 : : val |= CRI_TXDEEMPH_OVERRIDE_5_0(
2749 : : ddi_translations[level].cri_txdeemph_override_5_0) |
2750 : : CRI_TXDEEMPH_OVERRIDE_11_6(
2751 : : ddi_translations[level].cri_txdeemph_override_11_6) |
2752 : : CRI_TXDEEMPH_OVERRIDE_EN;
2753 : : I915_WRITE(MG_TX2_DRVCTRL(ln, tc_port), val);
2754 : :
2755 : : /* FIXME: Program CRI_LOADGEN_SEL after the spec is updated */
2756 : : }
2757 : :
2758 : : /*
2759 : : * Program MG_CLKHUB<LN, port being used> with value from frequency table
2760 : : * In case of Legacy mode on MG PHY, both TX1 and TX2 enabled so use the
2761 : : * values from table for which TX1 and TX2 enabled.
2762 : : */
2763 : : for (ln = 0; ln < 2; ln++) {
2764 : : val = I915_READ(MG_CLKHUB(ln, tc_port));
2765 : : if (link_clock < 300000)
2766 : : val |= CFG_LOW_RATE_LKREN_EN;
2767 : : else
2768 : : val &= ~CFG_LOW_RATE_LKREN_EN;
2769 : : I915_WRITE(MG_CLKHUB(ln, tc_port), val);
2770 : : }
2771 : :
2772 : : /* Program the MG_TX_DCC<LN, port being used> based on the link frequency */
2773 : : for (ln = 0; ln < 2; ln++) {
2774 : : val = I915_READ(MG_TX1_DCC(ln, tc_port));
2775 : : val &= ~CFG_AMI_CK_DIV_OVERRIDE_VAL_MASK;
2776 : : if (link_clock <= 500000) {
2777 : : val &= ~CFG_AMI_CK_DIV_OVERRIDE_EN;
2778 : : } else {
2779 : : val |= CFG_AMI_CK_DIV_OVERRIDE_EN |
2780 : : CFG_AMI_CK_DIV_OVERRIDE_VAL(1);
2781 : : }
2782 : : I915_WRITE(MG_TX1_DCC(ln, tc_port), val);
2783 : :
2784 : : val = I915_READ(MG_TX2_DCC(ln, tc_port));
2785 : : val &= ~CFG_AMI_CK_DIV_OVERRIDE_VAL_MASK;
2786 : : if (link_clock <= 500000) {
2787 : : val &= ~CFG_AMI_CK_DIV_OVERRIDE_EN;
2788 : : } else {
2789 : : val |= CFG_AMI_CK_DIV_OVERRIDE_EN |
2790 : : CFG_AMI_CK_DIV_OVERRIDE_VAL(1);
2791 : : }
2792 : : I915_WRITE(MG_TX2_DCC(ln, tc_port), val);
2793 : : }
2794 : :
2795 : : /* Program MG_TX_PISO_READLOAD with values from vswing table */
2796 : : for (ln = 0; ln < 2; ln++) {
2797 : : val = I915_READ(MG_TX1_PISO_READLOAD(ln, tc_port));
2798 : : val |= CRI_CALCINIT;
2799 : : I915_WRITE(MG_TX1_PISO_READLOAD(ln, tc_port), val);
2800 : :
2801 : : val = I915_READ(MG_TX2_PISO_READLOAD(ln, tc_port));
2802 : : val |= CRI_CALCINIT;
2803 : : I915_WRITE(MG_TX2_PISO_READLOAD(ln, tc_port), val);
2804 : : }
2805 : : }
2806 : :
2807 : 0 : static void icl_ddi_vswing_sequence(struct intel_encoder *encoder,
2808 : : int link_clock,
2809 : : u32 level,
2810 : : enum intel_output_type type)
2811 : : {
2812 : 0 : struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
2813 : 0 : enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
2814 : :
2815 [ # # ]: 0 : if (intel_phy_is_combo(dev_priv, phy))
2816 : 0 : icl_combo_phy_ddi_vswing_sequence(encoder, level, type);
2817 : : else
2818 : 0 : icl_mg_phy_ddi_vswing_sequence(encoder, link_clock, level);
2819 : 0 : }
2820 : :
2821 : : static void
2822 : : tgl_dkl_phy_ddi_vswing_sequence(struct intel_encoder *encoder, int link_clock,
2823 : : u32 level)
2824 : : {
2825 : : struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
2826 : : enum tc_port tc_port = intel_port_to_tc(dev_priv, encoder->port);
2827 : : const struct tgl_dkl_phy_ddi_buf_trans *ddi_translations;
2828 : : u32 n_entries, val, ln, dpcnt_mask, dpcnt_val;
2829 : :
2830 : : if (encoder->type == INTEL_OUTPUT_HDMI) {
2831 : : n_entries = ARRAY_SIZE(tgl_dkl_phy_hdmi_ddi_trans);
2832 : : ddi_translations = tgl_dkl_phy_hdmi_ddi_trans;
2833 : : } else {
2834 : : n_entries = ARRAY_SIZE(tgl_dkl_phy_dp_ddi_trans);
2835 : : ddi_translations = tgl_dkl_phy_dp_ddi_trans;
2836 : : }
2837 : :
2838 : : if (level >= n_entries)
2839 : : level = n_entries - 1;
2840 : :
2841 : : dpcnt_mask = (DKL_TX_PRESHOOT_COEFF_MASK |
2842 : : DKL_TX_DE_EMPAHSIS_COEFF_MASK |
2843 : : DKL_TX_VSWING_CONTROL_MASK);
2844 : : dpcnt_val = DKL_TX_VSWING_CONTROL(ddi_translations[level].dkl_vswing_control);
2845 : : dpcnt_val |= DKL_TX_DE_EMPHASIS_COEFF(ddi_translations[level].dkl_de_emphasis_control);
2846 : : dpcnt_val |= DKL_TX_PRESHOOT_COEFF(ddi_translations[level].dkl_preshoot_control);
2847 : :
2848 : : for (ln = 0; ln < 2; ln++) {
2849 : : I915_WRITE(HIP_INDEX_REG(tc_port), HIP_INDEX_VAL(tc_port, ln));
2850 : :
2851 : : I915_WRITE(DKL_TX_PMD_LANE_SUS(tc_port), 0);
2852 : :
2853 : : /* All the registers are RMW */
2854 : : val = I915_READ(DKL_TX_DPCNTL0(tc_port));
2855 : : val &= ~dpcnt_mask;
2856 : : val |= dpcnt_val;
2857 : : I915_WRITE(DKL_TX_DPCNTL0(tc_port), val);
2858 : :
2859 : : val = I915_READ(DKL_TX_DPCNTL1(tc_port));
2860 : : val &= ~dpcnt_mask;
2861 : : val |= dpcnt_val;
2862 : : I915_WRITE(DKL_TX_DPCNTL1(tc_port), val);
2863 : :
2864 : : val = I915_READ(DKL_TX_DPCNTL2(tc_port));
2865 : : val &= ~DKL_TX_DP20BITMODE;
2866 : : I915_WRITE(DKL_TX_DPCNTL2(tc_port), val);
2867 : : }
2868 : : }
2869 : :
2870 : : static void tgl_ddi_vswing_sequence(struct intel_encoder *encoder,
2871 : : int link_clock,
2872 : : u32 level,
2873 : : enum intel_output_type type)
2874 : : {
2875 : : struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
2876 : : enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
2877 : :
2878 : : if (intel_phy_is_combo(dev_priv, phy))
2879 : : icl_combo_phy_ddi_vswing_sequence(encoder, level, type);
2880 : : else
2881 : : tgl_dkl_phy_ddi_vswing_sequence(encoder, link_clock, level);
2882 : : }
2883 : :
2884 : 0 : static u32 translate_signal_level(int signal_levels)
2885 : : {
2886 : 0 : int i;
2887 : :
2888 [ # # ]: 0 : for (i = 0; i < ARRAY_SIZE(index_to_dp_signal_levels); i++) {
2889 [ # # ]: 0 : if (index_to_dp_signal_levels[i] == signal_levels)
2890 : 0 : return i;
2891 : : }
2892 : :
2893 : 0 : WARN(1, "Unsupported voltage swing/pre-emphasis level: 0x%x\n",
2894 : : signal_levels);
2895 : :
2896 : 0 : return 0;
2897 : : }
2898 : :
2899 : 0 : static u32 intel_ddi_dp_level(struct intel_dp *intel_dp)
2900 : : {
2901 : 0 : u8 train_set = intel_dp->train_set[0];
2902 : 0 : int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
2903 : : DP_TRAIN_PRE_EMPHASIS_MASK);
2904 : :
2905 : 0 : return translate_signal_level(signal_levels);
2906 : : }
2907 : :
2908 : 0 : u32 bxt_signal_levels(struct intel_dp *intel_dp)
2909 : : {
2910 : 0 : struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
2911 : 0 : struct drm_i915_private *dev_priv = to_i915(dport->base.base.dev);
2912 : 0 : struct intel_encoder *encoder = &dport->base;
2913 : 0 : int level = intel_ddi_dp_level(intel_dp);
2914 : :
2915 [ # # ]: 0 : if (INTEL_GEN(dev_priv) >= 12)
2916 : 0 : tgl_ddi_vswing_sequence(encoder, intel_dp->link_rate,
2917 : : level, encoder->type);
2918 [ # # ]: 0 : else if (INTEL_GEN(dev_priv) >= 11)
2919 : 0 : icl_ddi_vswing_sequence(encoder, intel_dp->link_rate,
2920 : : level, encoder->type);
2921 [ # # ]: 0 : else if (IS_CANNONLAKE(dev_priv))
2922 : 0 : cnl_ddi_vswing_sequence(encoder, level, encoder->type);
2923 : : else
2924 : 0 : bxt_ddi_vswing_sequence(encoder, level, encoder->type);
2925 : :
2926 : 0 : return 0;
2927 : : }
2928 : :
2929 : 0 : u32 ddi_signal_levels(struct intel_dp *intel_dp)
2930 : : {
2931 : 0 : struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
2932 : 0 : struct drm_i915_private *dev_priv = to_i915(dport->base.base.dev);
2933 : 0 : struct intel_encoder *encoder = &dport->base;
2934 : 0 : int level = intel_ddi_dp_level(intel_dp);
2935 : :
2936 [ # # # # ]: 0 : if (IS_GEN9_BC(dev_priv))
2937 : 0 : skl_ddi_set_iboost(encoder, level, encoder->type);
2938 : :
2939 : 0 : return DDI_BUF_TRANS_SELECT(level);
2940 : : }
2941 : :
2942 : : static inline
2943 : 0 : u32 icl_dpclka_cfgcr0_clk_off(struct drm_i915_private *dev_priv,
2944 : : enum phy phy)
2945 : : {
2946 [ # # ]: 0 : if (intel_phy_is_combo(dev_priv, phy)) {
2947 : 0 : return ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy);
2948 [ # # ]: 0 : } else if (intel_phy_is_tc(dev_priv, phy)) {
2949 : 0 : enum tc_port tc_port = intel_port_to_tc(dev_priv,
2950 : : (enum port)phy);
2951 : :
2952 [ # # ]: 0 : return ICL_DPCLKA_CFGCR0_TC_CLK_OFF(tc_port);
2953 : : }
2954 : :
2955 : : return 0;
2956 : : }
2957 : :
2958 : : static void icl_map_plls_to_ports(struct intel_encoder *encoder,
2959 : : const struct intel_crtc_state *crtc_state)
2960 : : {
2961 : : struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
2962 : : struct intel_shared_dpll *pll = crtc_state->shared_dpll;
2963 : : enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
2964 : : u32 val;
2965 : :
2966 : : mutex_lock(&dev_priv->dpll_lock);
2967 : :
2968 : : val = I915_READ(ICL_DPCLKA_CFGCR0);
2969 : : WARN_ON((val & icl_dpclka_cfgcr0_clk_off(dev_priv, phy)) == 0);
2970 : :
2971 : : if (intel_phy_is_combo(dev_priv, phy)) {
2972 : : /*
2973 : : * Even though this register references DDIs, note that we
2974 : : * want to pass the PHY rather than the port (DDI). For
2975 : : * ICL, port=phy in all cases so it doesn't matter, but for
2976 : : * EHL the bspec notes the following:
2977 : : *
2978 : : * "DDID clock tied to DDIA clock, so DPCLKA_CFGCR0 DDIA
2979 : : * Clock Select chooses the PLL for both DDIA and DDID and
2980 : : * drives port A in all cases."
2981 : : */
2982 : : val &= ~ICL_DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(phy);
2983 : : val |= ICL_DPCLKA_CFGCR0_DDI_CLK_SEL(pll->info->id, phy);
2984 : : I915_WRITE(ICL_DPCLKA_CFGCR0, val);
2985 : : POSTING_READ(ICL_DPCLKA_CFGCR0);
2986 : : }
2987 : :
2988 : : val &= ~icl_dpclka_cfgcr0_clk_off(dev_priv, phy);
2989 : : I915_WRITE(ICL_DPCLKA_CFGCR0, val);
2990 : :
2991 : : mutex_unlock(&dev_priv->dpll_lock);
2992 : : }
2993 : :
2994 : : static void icl_unmap_plls_to_ports(struct intel_encoder *encoder)
2995 : : {
2996 : : struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
2997 : : enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
2998 : : u32 val;
2999 : :
3000 : : mutex_lock(&dev_priv->dpll_lock);
3001 : :
3002 : : val = I915_READ(ICL_DPCLKA_CFGCR0);
3003 : : val |= icl_dpclka_cfgcr0_clk_off(dev_priv, phy);
3004 : : I915_WRITE(ICL_DPCLKA_CFGCR0, val);
3005 : :
3006 : : mutex_unlock(&dev_priv->dpll_lock);
3007 : : }
3008 : :
3009 : 0 : static void icl_sanitize_port_clk_off(struct drm_i915_private *dev_priv,
3010 : : u32 port_mask, bool ddi_clk_needed)
3011 : : {
3012 : 0 : enum port port;
3013 : 0 : u32 val;
3014 : :
3015 : 0 : val = I915_READ(ICL_DPCLKA_CFGCR0);
3016 [ # # # # ]: 0 : for_each_port_masked(port, port_mask) {
3017 : 0 : enum phy phy = intel_port_to_phy(dev_priv, port);
3018 : 0 : bool ddi_clk_off = val & icl_dpclka_cfgcr0_clk_off(dev_priv,
3019 : : phy);
3020 : :
3021 [ # # ]: 0 : if (ddi_clk_needed == !ddi_clk_off)
3022 : 0 : continue;
3023 : :
3024 : : /*
3025 : : * Punt on the case now where clock is gated, but it would
3026 : : * be needed by the port. Something else is really broken then.
3027 : : */
3028 [ # # # # ]: 0 : if (WARN_ON(ddi_clk_needed))
3029 : 0 : continue;
3030 : :
3031 : 0 : DRM_NOTE("PHY %c is disabled/in DSI mode with an ungated DDI clock, gate it\n",
3032 : : phy_name(phy));
3033 : 0 : val |= icl_dpclka_cfgcr0_clk_off(dev_priv, phy);
3034 : 0 : I915_WRITE(ICL_DPCLKA_CFGCR0, val);
3035 : : }
3036 : 0 : }
3037 : :
3038 : 0 : void icl_sanitize_encoder_pll_mapping(struct intel_encoder *encoder)
3039 : : {
3040 [ # # ]: 0 : struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
3041 : 0 : u32 port_mask;
3042 : 0 : bool ddi_clk_needed;
3043 : :
3044 : : /*
3045 : : * In case of DP MST, we sanitize the primary encoder only, not the
3046 : : * virtual ones.
3047 : : */
3048 [ # # ]: 0 : if (encoder->type == INTEL_OUTPUT_DP_MST)
3049 : : return;
3050 : :
3051 [ # # # # ]: 0 : if (!encoder->base.crtc && intel_encoder_is_dp(encoder)) {
3052 : 0 : u8 pipe_mask;
3053 : 0 : bool is_mst;
3054 : :
3055 : 0 : intel_ddi_get_encoder_pipes(encoder, &pipe_mask, &is_mst);
3056 : : /*
3057 : : * In the unlikely case that BIOS enables DP in MST mode, just
3058 : : * warn since our MST HW readout is incomplete.
3059 : : */
3060 [ # # # # ]: 0 : if (WARN_ON(is_mst))
3061 : 0 : return;
3062 : : }
3063 : :
3064 : 0 : port_mask = BIT(encoder->port);
3065 : 0 : ddi_clk_needed = encoder->base.crtc;
3066 : :
3067 [ # # ]: 0 : if (encoder->type == INTEL_OUTPUT_DSI) {
3068 : 0 : struct intel_encoder *other_encoder;
3069 : :
3070 : 0 : port_mask = intel_dsi_encoder_ports(encoder);
3071 : : /*
3072 : : * Sanity check that we haven't incorrectly registered another
3073 : : * encoder using any of the ports of this DSI encoder.
3074 : : */
3075 [ # # ]: 0 : for_each_intel_encoder(&dev_priv->drm, other_encoder) {
3076 [ # # ]: 0 : if (other_encoder == encoder)
3077 : 0 : continue;
3078 : :
3079 [ # # # # ]: 0 : if (WARN_ON(port_mask & BIT(other_encoder->port)))
3080 : : return;
3081 : : }
3082 : : /*
3083 : : * For DSI we keep the ddi clocks gated
3084 : : * except during enable/disable sequence.
3085 : : */
3086 : : ddi_clk_needed = false;
3087 : : }
3088 : :
3089 : 0 : icl_sanitize_port_clk_off(dev_priv, port_mask, ddi_clk_needed);
3090 : : }
3091 : :
3092 : : static void intel_ddi_clk_select(struct intel_encoder *encoder,
3093 : : const struct intel_crtc_state *crtc_state)
3094 : : {
3095 : : struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
3096 : : enum port port = encoder->port;
3097 : : enum phy phy = intel_port_to_phy(dev_priv, port);
3098 : : u32 val;
3099 : : const struct intel_shared_dpll *pll = crtc_state->shared_dpll;
3100 : :
3101 : : if (WARN_ON(!pll))
3102 : : return;
3103 : :
3104 : : mutex_lock(&dev_priv->dpll_lock);
3105 : :
3106 : : if (INTEL_GEN(dev_priv) >= 11) {
3107 : : if (!intel_phy_is_combo(dev_priv, phy))
3108 : : I915_WRITE(DDI_CLK_SEL(port),
3109 : : icl_pll_to_ddi_clk_sel(encoder, crtc_state));
3110 : : else if (IS_ELKHARTLAKE(dev_priv) && port >= PORT_C)
3111 : : /*
3112 : : * MG does not exist but the programming is required
3113 : : * to ungate DDIC and DDID
3114 : : */
3115 : : I915_WRITE(DDI_CLK_SEL(port), DDI_CLK_SEL_MG);
3116 : : } else if (IS_CANNONLAKE(dev_priv)) {
3117 : : /* Configure DPCLKA_CFGCR0 to map the DPLL to the DDI. */
3118 : : val = I915_READ(DPCLKA_CFGCR0);
3119 : : val &= ~DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(port);
3120 : : val |= DPCLKA_CFGCR0_DDI_CLK_SEL(pll->info->id, port);
3121 : : I915_WRITE(DPCLKA_CFGCR0, val);
3122 : :
3123 : : /*
3124 : : * Configure DPCLKA_CFGCR0 to turn on the clock for the DDI.
3125 : : * This step and the step before must be done with separate
3126 : : * register writes.
3127 : : */
3128 : : val = I915_READ(DPCLKA_CFGCR0);
3129 : : val &= ~DPCLKA_CFGCR0_DDI_CLK_OFF(port);
3130 : : I915_WRITE(DPCLKA_CFGCR0, val);
3131 : : } else if (IS_GEN9_BC(dev_priv)) {
3132 : : /* DDI -> PLL mapping */
3133 : : val = I915_READ(DPLL_CTRL2);
3134 : :
3135 : : val &= ~(DPLL_CTRL2_DDI_CLK_OFF(port) |
3136 : : DPLL_CTRL2_DDI_CLK_SEL_MASK(port));
3137 : : val |= (DPLL_CTRL2_DDI_CLK_SEL(pll->info->id, port) |
3138 : : DPLL_CTRL2_DDI_SEL_OVERRIDE(port));
3139 : :
3140 : : I915_WRITE(DPLL_CTRL2, val);
3141 : :
3142 : : } else if (INTEL_GEN(dev_priv) < 9) {
3143 : : I915_WRITE(PORT_CLK_SEL(port), hsw_pll_to_ddi_pll_sel(pll));
3144 : : }
3145 : :
3146 : : mutex_unlock(&dev_priv->dpll_lock);
3147 : : }
3148 : :
3149 : : static void intel_ddi_clk_disable(struct intel_encoder *encoder)
3150 : : {
3151 : : struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
3152 : : enum port port = encoder->port;
3153 : : enum phy phy = intel_port_to_phy(dev_priv, port);
3154 : :
3155 : : if (INTEL_GEN(dev_priv) >= 11) {
3156 : : if (!intel_phy_is_combo(dev_priv, phy) ||
3157 : : (IS_ELKHARTLAKE(dev_priv) && port >= PORT_C))
3158 : : I915_WRITE(DDI_CLK_SEL(port), DDI_CLK_SEL_NONE);
3159 : : } else if (IS_CANNONLAKE(dev_priv)) {
3160 : : I915_WRITE(DPCLKA_CFGCR0, I915_READ(DPCLKA_CFGCR0) |
3161 : : DPCLKA_CFGCR0_DDI_CLK_OFF(port));
3162 : : } else if (IS_GEN9_BC(dev_priv)) {
3163 : : I915_WRITE(DPLL_CTRL2, I915_READ(DPLL_CTRL2) |
3164 : : DPLL_CTRL2_DDI_CLK_OFF(port));
3165 : : } else if (INTEL_GEN(dev_priv) < 9) {
3166 : : I915_WRITE(PORT_CLK_SEL(port), PORT_CLK_SEL_NONE);
3167 : : }
3168 : : }
3169 : :
3170 : : static void
3171 : : icl_program_mg_dp_mode(struct intel_digital_port *intel_dig_port,
3172 : : const struct intel_crtc_state *crtc_state)
3173 : : {
3174 : : struct drm_i915_private *dev_priv = to_i915(intel_dig_port->base.base.dev);
3175 : : enum tc_port tc_port = intel_port_to_tc(dev_priv, intel_dig_port->base.port);
3176 : : u32 ln0, ln1, pin_assignment;
3177 : : u8 width;
3178 : :
3179 : : if (intel_dig_port->tc_mode == TC_PORT_TBT_ALT)
3180 : : return;
3181 : :
3182 : : if (INTEL_GEN(dev_priv) >= 12) {
3183 : : I915_WRITE(HIP_INDEX_REG(tc_port), HIP_INDEX_VAL(tc_port, 0x0));
3184 : : ln0 = I915_READ(DKL_DP_MODE(tc_port));
3185 : : I915_WRITE(HIP_INDEX_REG(tc_port), HIP_INDEX_VAL(tc_port, 0x1));
3186 : : ln1 = I915_READ(DKL_DP_MODE(tc_port));
3187 : : } else {
3188 : : ln0 = I915_READ(MG_DP_MODE(0, tc_port));
3189 : : ln1 = I915_READ(MG_DP_MODE(1, tc_port));
3190 : : }
3191 : :
3192 : : ln0 &= ~(MG_DP_MODE_CFG_DP_X1_MODE | MG_DP_MODE_CFG_DP_X1_MODE);
3193 : : ln1 &= ~(MG_DP_MODE_CFG_DP_X1_MODE | MG_DP_MODE_CFG_DP_X2_MODE);
3194 : :
3195 : : /* DPPATC */
3196 : : pin_assignment = intel_tc_port_get_pin_assignment_mask(intel_dig_port);
3197 : : width = crtc_state->lane_count;
3198 : :
3199 : : switch (pin_assignment) {
3200 : : case 0x0:
3201 : : WARN_ON(intel_dig_port->tc_mode != TC_PORT_LEGACY);
3202 : : if (width == 1) {
3203 : : ln1 |= MG_DP_MODE_CFG_DP_X1_MODE;
3204 : : } else {
3205 : : ln0 |= MG_DP_MODE_CFG_DP_X2_MODE;
3206 : : ln1 |= MG_DP_MODE_CFG_DP_X2_MODE;
3207 : : }
3208 : : break;
3209 : : case 0x1:
3210 : : if (width == 4) {
3211 : : ln0 |= MG_DP_MODE_CFG_DP_X2_MODE;
3212 : : ln1 |= MG_DP_MODE_CFG_DP_X2_MODE;
3213 : : }
3214 : : break;
3215 : : case 0x2:
3216 : : if (width == 2) {
3217 : : ln0 |= MG_DP_MODE_CFG_DP_X2_MODE;
3218 : : ln1 |= MG_DP_MODE_CFG_DP_X2_MODE;
3219 : : }
3220 : : break;
3221 : : case 0x3:
3222 : : case 0x5:
3223 : : if (width == 1) {
3224 : : ln0 |= MG_DP_MODE_CFG_DP_X1_MODE;
3225 : : ln1 |= MG_DP_MODE_CFG_DP_X1_MODE;
3226 : : } else {
3227 : : ln0 |= MG_DP_MODE_CFG_DP_X2_MODE;
3228 : : ln1 |= MG_DP_MODE_CFG_DP_X2_MODE;
3229 : : }
3230 : : break;
3231 : : case 0x4:
3232 : : case 0x6:
3233 : : if (width == 1) {
3234 : : ln0 |= MG_DP_MODE_CFG_DP_X1_MODE;
3235 : : ln1 |= MG_DP_MODE_CFG_DP_X1_MODE;
3236 : : } else {
3237 : : ln0 |= MG_DP_MODE_CFG_DP_X2_MODE;
3238 : : ln1 |= MG_DP_MODE_CFG_DP_X2_MODE;
3239 : : }
3240 : : break;
3241 : : default:
3242 : : MISSING_CASE(pin_assignment);
3243 : : }
3244 : :
3245 : : if (INTEL_GEN(dev_priv) >= 12) {
3246 : : I915_WRITE(HIP_INDEX_REG(tc_port), HIP_INDEX_VAL(tc_port, 0x0));
3247 : : I915_WRITE(DKL_DP_MODE(tc_port), ln0);
3248 : : I915_WRITE(HIP_INDEX_REG(tc_port), HIP_INDEX_VAL(tc_port, 0x1));
3249 : : I915_WRITE(DKL_DP_MODE(tc_port), ln1);
3250 : : } else {
3251 : : I915_WRITE(MG_DP_MODE(0, tc_port), ln0);
3252 : : I915_WRITE(MG_DP_MODE(1, tc_port), ln1);
3253 : : }
3254 : : }
3255 : :
3256 : : static void intel_dp_sink_set_fec_ready(struct intel_dp *intel_dp,
3257 : : const struct intel_crtc_state *crtc_state)
3258 : : {
3259 : : if (!crtc_state->fec_enable)
3260 : : return;
3261 : :
3262 : : if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_FEC_CONFIGURATION, DP_FEC_READY) <= 0)
3263 : : DRM_DEBUG_KMS("Failed to set FEC_READY in the sink\n");
3264 : : }
3265 : :
3266 : : static void intel_ddi_enable_fec(struct intel_encoder *encoder,
3267 : : const struct intel_crtc_state *crtc_state)
3268 : : {
3269 : : struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
3270 : : struct intel_dp *intel_dp;
3271 : : u32 val;
3272 : :
3273 : : if (!crtc_state->fec_enable)
3274 : : return;
3275 : :
3276 : : intel_dp = enc_to_intel_dp(encoder);
3277 : : val = I915_READ(intel_dp->regs.dp_tp_ctl);
3278 : : val |= DP_TP_CTL_FEC_ENABLE;
3279 : : I915_WRITE(intel_dp->regs.dp_tp_ctl, val);
3280 : :
3281 : : if (intel_de_wait_for_set(dev_priv, intel_dp->regs.dp_tp_status,
3282 : : DP_TP_STATUS_FEC_ENABLE_LIVE, 1))
3283 : : DRM_ERROR("Timed out waiting for FEC Enable Status\n");
3284 : : }
3285 : :
3286 : : static void intel_ddi_disable_fec_state(struct intel_encoder *encoder,
3287 : : const struct intel_crtc_state *crtc_state)
3288 : : {
3289 : : struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
3290 : : struct intel_dp *intel_dp;
3291 : : u32 val;
3292 : :
3293 : : if (!crtc_state->fec_enable)
3294 : : return;
3295 : :
3296 : : intel_dp = enc_to_intel_dp(encoder);
3297 : : val = I915_READ(intel_dp->regs.dp_tp_ctl);
3298 : : val &= ~DP_TP_CTL_FEC_ENABLE;
3299 : : I915_WRITE(intel_dp->regs.dp_tp_ctl, val);
3300 : : POSTING_READ(intel_dp->regs.dp_tp_ctl);
3301 : : }
3302 : :
3303 : : static void
3304 : 0 : tgl_clear_psr2_transcoder_exitline(const struct intel_crtc_state *cstate)
3305 : : {
3306 [ # # ]: 0 : struct drm_i915_private *dev_priv = to_i915(cstate->uapi.crtc->dev);
3307 : 0 : u32 val;
3308 : :
3309 [ # # ]: 0 : if (!cstate->dc3co_exitline)
3310 : : return;
3311 : :
3312 : 0 : val = I915_READ(EXITLINE(cstate->cpu_transcoder));
3313 : 0 : val &= ~(EXITLINE_MASK | EXITLINE_ENABLE);
3314 : 0 : I915_WRITE(EXITLINE(cstate->cpu_transcoder), val);
3315 : : }
3316 : :
3317 : : static void
3318 : 0 : tgl_set_psr2_transcoder_exitline(const struct intel_crtc_state *cstate)
3319 : : {
3320 : 0 : u32 val, exit_scanlines;
3321 [ # # ]: 0 : struct drm_i915_private *dev_priv = to_i915(cstate->uapi.crtc->dev);
3322 : :
3323 [ # # ]: 0 : if (!cstate->dc3co_exitline)
3324 : : return;
3325 : :
3326 : 0 : exit_scanlines = cstate->dc3co_exitline;
3327 : 0 : exit_scanlines <<= EXITLINE_SHIFT;
3328 : 0 : val = I915_READ(EXITLINE(cstate->cpu_transcoder));
3329 : 0 : val &= ~(EXITLINE_MASK | EXITLINE_ENABLE);
3330 : 0 : val |= exit_scanlines;
3331 : 0 : val |= EXITLINE_ENABLE;
3332 : 0 : I915_WRITE(EXITLINE(cstate->cpu_transcoder), val);
3333 : : }
3334 : :
3335 : : static void tgl_dc3co_exitline_compute_config(struct intel_encoder *encoder,
3336 : : struct intel_crtc_state *cstate)
3337 : : {
3338 : : u32 exit_scanlines;
3339 : : struct drm_i915_private *dev_priv = to_i915(cstate->uapi.crtc->dev);
3340 : : u32 crtc_vdisplay = cstate->hw.adjusted_mode.crtc_vdisplay;
3341 : :
3342 : : cstate->dc3co_exitline = 0;
3343 : :
3344 : : if (!(dev_priv->csr.allowed_dc_mask & DC_STATE_EN_DC3CO))
3345 : : return;
3346 : :
3347 : : /* B.Specs:49196 DC3CO only works with pipeA and DDIA.*/
3348 : : if (to_intel_crtc(cstate->uapi.crtc)->pipe != PIPE_A ||
3349 : : encoder->port != PORT_A)
3350 : : return;
3351 : :
3352 : : if (!cstate->has_psr2 || !cstate->hw.active)
3353 : : return;
3354 : :
3355 : : /*
3356 : : * DC3CO Exit time 200us B.Spec 49196
3357 : : * PSR2 transcoder Early Exit scanlines = ROUNDUP(200 / line time) + 1
3358 : : */
3359 : : exit_scanlines =
3360 : : intel_usecs_to_scanlines(&cstate->hw.adjusted_mode, 200) + 1;
3361 : :
3362 : : if (WARN_ON(exit_scanlines > crtc_vdisplay))
3363 : : return;
3364 : :
3365 : : cstate->dc3co_exitline = crtc_vdisplay - exit_scanlines;
3366 : : DRM_DEBUG_KMS("DC3CO exit scanlines %d\n", cstate->dc3co_exitline);
3367 : : }
3368 : :
3369 : 0 : static void tgl_dc3co_exitline_get_config(struct intel_crtc_state *crtc_state)
3370 : : {
3371 : 0 : u32 val;
3372 [ # # ]: 0 : struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
3373 : :
3374 [ # # ]: 0 : if (INTEL_GEN(dev_priv) < 12)
3375 : : return;
3376 : :
3377 : 0 : val = I915_READ(EXITLINE(crtc_state->cpu_transcoder));
3378 : :
3379 [ # # ]: 0 : if (val & EXITLINE_ENABLE)
3380 : 0 : crtc_state->dc3co_exitline = val & EXITLINE_MASK;
3381 : : }
3382 : :
3383 : : static void tgl_ddi_pre_enable_dp(struct intel_encoder *encoder,
3384 : : const struct intel_crtc_state *crtc_state,
3385 : : const struct drm_connector_state *conn_state)
3386 : : {
3387 : : struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
3388 : : struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
3389 : : enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
3390 : : struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
3391 : : bool is_mst = intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST);
3392 : : int level = intel_ddi_dp_level(intel_dp);
3393 : : enum transcoder transcoder = crtc_state->cpu_transcoder;
3394 : :
3395 : : tgl_set_psr2_transcoder_exitline(crtc_state);
3396 : : intel_dp_set_link_params(intel_dp, crtc_state->port_clock,
3397 : : crtc_state->lane_count, is_mst);
3398 : :
3399 : : intel_dp->regs.dp_tp_ctl = TGL_DP_TP_CTL(transcoder);
3400 : : intel_dp->regs.dp_tp_status = TGL_DP_TP_STATUS(transcoder);
3401 : :
3402 : : /*
3403 : : * 1. Enable Power Wells
3404 : : *
3405 : : * This was handled at the beginning of intel_atomic_commit_tail(),
3406 : : * before we called down into this function.
3407 : : */
3408 : :
3409 : : /* 2. Enable Panel Power if PPS is required */
3410 : : intel_edp_panel_on(intel_dp);
3411 : :
3412 : : /*
3413 : : * 3. For non-TBT Type-C ports, set FIA lane count
3414 : : * (DFLEXDPSP.DPX4TXLATC)
3415 : : *
3416 : : * This was done before tgl_ddi_pre_enable_dp by
3417 : : * hsw_crtc_enable()->intel_encoders_pre_pll_enable().
3418 : : */
3419 : :
3420 : : /*
3421 : : * 4. Enable the port PLL.
3422 : : *
3423 : : * The PLL enabling itself was already done before this function by
3424 : : * hsw_crtc_enable()->intel_enable_shared_dpll(). We need only
3425 : : * configure the PLL to port mapping here.
3426 : : */
3427 : : intel_ddi_clk_select(encoder, crtc_state);
3428 : :
3429 : : /* 5. If IO power is controlled through PWR_WELL_CTL, Enable IO Power */
3430 : : if (!intel_phy_is_tc(dev_priv, phy) ||
3431 : : dig_port->tc_mode != TC_PORT_TBT_ALT)
3432 : : intel_display_power_get(dev_priv,
3433 : : dig_port->ddi_io_power_domain);
3434 : :
3435 : : /* 6. Program DP_MODE */
3436 : : icl_program_mg_dp_mode(dig_port, crtc_state);
3437 : :
3438 : : /*
3439 : : * 7. The rest of the below are substeps under the bspec's "Enable and
3440 : : * Train Display Port" step. Note that steps that are specific to
3441 : : * MST will be handled by intel_mst_pre_enable_dp() before/after it
3442 : : * calls into this function. Also intel_mst_pre_enable_dp() only calls
3443 : : * us when active_mst_links==0, so any steps designated for "single
3444 : : * stream or multi-stream master transcoder" can just be performed
3445 : : * unconditionally here.
3446 : : */
3447 : :
3448 : : /*
3449 : : * 7.a Configure Transcoder Clock Select to direct the Port clock to the
3450 : : * Transcoder.
3451 : : */
3452 : : intel_ddi_enable_pipe_clock(crtc_state);
3453 : :
3454 : : /*
3455 : : * 7.b Configure TRANS_DDI_FUNC_CTL DDI Select, DDI Mode Select & MST
3456 : : * Transport Select
3457 : : */
3458 : : intel_ddi_config_transcoder_func(crtc_state);
3459 : :
3460 : : /*
3461 : : * 7.c Configure & enable DP_TP_CTL with link training pattern 1
3462 : : * selected
3463 : : *
3464 : : * This will be handled by the intel_dp_start_link_train() farther
3465 : : * down this function.
3466 : : */
3467 : :
3468 : : /* 7.e Configure voltage swing and related IO settings */
3469 : : tgl_ddi_vswing_sequence(encoder, crtc_state->port_clock, level,
3470 : : encoder->type);
3471 : :
3472 : : /*
3473 : : * 7.f Combo PHY: Configure PORT_CL_DW10 Static Power Down to power up
3474 : : * the used lanes of the DDI.
3475 : : */
3476 : : if (intel_phy_is_combo(dev_priv, phy)) {
3477 : : bool lane_reversal =
3478 : : dig_port->saved_port_bits & DDI_BUF_PORT_REVERSAL;
3479 : :
3480 : : intel_combo_phy_power_up_lanes(dev_priv, phy, false,
3481 : : crtc_state->lane_count,
3482 : : lane_reversal);
3483 : : }
3484 : :
3485 : : /*
3486 : : * 7.g Configure and enable DDI_BUF_CTL
3487 : : * 7.h Wait for DDI_BUF_CTL DDI Idle Status = 0b (Not Idle), timeout
3488 : : * after 500 us.
3489 : : *
3490 : : * We only configure what the register value will be here. Actual
3491 : : * enabling happens during link training farther down.
3492 : : */
3493 : : intel_ddi_init_dp_buf_reg(encoder);
3494 : :
3495 : : if (!is_mst)
3496 : : intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
3497 : :
3498 : : intel_dp_sink_set_decompression_state(intel_dp, crtc_state, true);
3499 : : /*
3500 : : * DDI FEC: "anticipates enabling FEC encoding sets the FEC_READY bit
3501 : : * in the FEC_CONFIGURATION register to 1 before initiating link
3502 : : * training
3503 : : */
3504 : : intel_dp_sink_set_fec_ready(intel_dp, crtc_state);
3505 : :
3506 : : /*
3507 : : * 7.i Follow DisplayPort specification training sequence (see notes for
3508 : : * failure handling)
3509 : : * 7.j If DisplayPort multi-stream - Set DP_TP_CTL link training to Idle
3510 : : * Pattern, wait for 5 idle patterns (DP_TP_STATUS Min_Idles_Sent)
3511 : : * (timeout after 800 us)
3512 : : */
3513 : : intel_dp_start_link_train(intel_dp);
3514 : :
3515 : : /* 7.k Set DP_TP_CTL link training to Normal */
3516 : : if (!is_trans_port_sync_mode(crtc_state))
3517 : : intel_dp_stop_link_train(intel_dp);
3518 : :
3519 : : /* 7.l Configure and enable FEC if needed */
3520 : : intel_ddi_enable_fec(encoder, crtc_state);
3521 : : intel_dsc_enable(encoder, crtc_state);
3522 : : }
3523 : :
3524 : : static void hsw_ddi_pre_enable_dp(struct intel_encoder *encoder,
3525 : : const struct intel_crtc_state *crtc_state,
3526 : : const struct drm_connector_state *conn_state)
3527 : : {
3528 : : struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
3529 : : struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
3530 : : enum port port = encoder->port;
3531 : : enum phy phy = intel_port_to_phy(dev_priv, port);
3532 : : struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
3533 : : bool is_mst = intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST);
3534 : : int level = intel_ddi_dp_level(intel_dp);
3535 : :
3536 : : if (INTEL_GEN(dev_priv) < 11)
3537 : : WARN_ON(is_mst && (port == PORT_A || port == PORT_E));
3538 : : else
3539 : : WARN_ON(is_mst && port == PORT_A);
3540 : :
3541 : : intel_dp_set_link_params(intel_dp, crtc_state->port_clock,
3542 : : crtc_state->lane_count, is_mst);
3543 : :
3544 : : intel_dp->regs.dp_tp_ctl = DP_TP_CTL(port);
3545 : : intel_dp->regs.dp_tp_status = DP_TP_STATUS(port);
3546 : :
3547 : : intel_edp_panel_on(intel_dp);
3548 : :
3549 : : intel_ddi_clk_select(encoder, crtc_state);
3550 : :
3551 : : if (!intel_phy_is_tc(dev_priv, phy) ||
3552 : : dig_port->tc_mode != TC_PORT_TBT_ALT)
3553 : : intel_display_power_get(dev_priv,
3554 : : dig_port->ddi_io_power_domain);
3555 : :
3556 : : icl_program_mg_dp_mode(dig_port, crtc_state);
3557 : :
3558 : : if (INTEL_GEN(dev_priv) >= 11)
3559 : : icl_ddi_vswing_sequence(encoder, crtc_state->port_clock,
3560 : : level, encoder->type);
3561 : : else if (IS_CANNONLAKE(dev_priv))
3562 : : cnl_ddi_vswing_sequence(encoder, level, encoder->type);
3563 : : else if (IS_GEN9_LP(dev_priv))
3564 : : bxt_ddi_vswing_sequence(encoder, level, encoder->type);
3565 : : else
3566 : : intel_prepare_dp_ddi_buffers(encoder, crtc_state);
3567 : :
3568 : : if (intel_phy_is_combo(dev_priv, phy)) {
3569 : : bool lane_reversal =
3570 : : dig_port->saved_port_bits & DDI_BUF_PORT_REVERSAL;
3571 : :
3572 : : intel_combo_phy_power_up_lanes(dev_priv, phy, false,
3573 : : crtc_state->lane_count,
3574 : : lane_reversal);
3575 : : }
3576 : :
3577 : : intel_ddi_init_dp_buf_reg(encoder);
3578 : : if (!is_mst)
3579 : : intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
3580 : : intel_dp_sink_set_decompression_state(intel_dp, crtc_state,
3581 : : true);
3582 : : intel_dp_sink_set_fec_ready(intel_dp, crtc_state);
3583 : : intel_dp_start_link_train(intel_dp);
3584 : : if ((port != PORT_A || INTEL_GEN(dev_priv) >= 9) &&
3585 : : !is_trans_port_sync_mode(crtc_state))
3586 : : intel_dp_stop_link_train(intel_dp);
3587 : :
3588 : : intel_ddi_enable_fec(encoder, crtc_state);
3589 : :
3590 : : if (!is_mst)
3591 : : intel_ddi_enable_pipe_clock(crtc_state);
3592 : :
3593 : : intel_dsc_enable(encoder, crtc_state);
3594 : : }
3595 : :
3596 : 0 : static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder,
3597 : : const struct intel_crtc_state *crtc_state,
3598 : : const struct drm_connector_state *conn_state)
3599 : : {
3600 [ # # ]: 0 : struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
3601 : :
3602 [ # # ]: 0 : if (INTEL_GEN(dev_priv) >= 12)
3603 : 0 : tgl_ddi_pre_enable_dp(encoder, crtc_state, conn_state);
3604 : : else
3605 : 0 : hsw_ddi_pre_enable_dp(encoder, crtc_state, conn_state);
3606 : :
3607 : : /* MST will call a setting of MSA after an allocating of Virtual Channel
3608 : : * from MST encoder pre_enable callback.
3609 : : */
3610 [ # # ]: 0 : if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST))
3611 : 0 : intel_ddi_set_dp_msa(crtc_state, conn_state);
3612 : 0 : }
3613 : :
3614 : 0 : static void intel_ddi_pre_enable_hdmi(struct intel_encoder *encoder,
3615 : : const struct intel_crtc_state *crtc_state,
3616 : : const struct drm_connector_state *conn_state)
3617 : : {
3618 [ # # ]: 0 : struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
3619 : 0 : struct intel_hdmi *intel_hdmi = &intel_dig_port->hdmi;
3620 : 0 : struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
3621 : 0 : enum port port = encoder->port;
3622 : 0 : int level = intel_ddi_hdmi_level(dev_priv, port);
3623 [ # # ]: 0 : struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
3624 : :
3625 : 0 : intel_dp_dual_mode_set_tmds_output(intel_hdmi, true);
3626 : 0 : intel_ddi_clk_select(encoder, crtc_state);
3627 : :
3628 : 0 : intel_display_power_get(dev_priv, dig_port->ddi_io_power_domain);
3629 : :
3630 : 0 : icl_program_mg_dp_mode(dig_port, crtc_state);
3631 : :
3632 [ # # ]: 0 : if (INTEL_GEN(dev_priv) >= 12)
3633 : 0 : tgl_ddi_vswing_sequence(encoder, crtc_state->port_clock,
3634 : : level, INTEL_OUTPUT_HDMI);
3635 [ # # ]: 0 : else if (INTEL_GEN(dev_priv) == 11)
3636 : 0 : icl_ddi_vswing_sequence(encoder, crtc_state->port_clock,
3637 : : level, INTEL_OUTPUT_HDMI);
3638 [ # # ]: 0 : else if (IS_CANNONLAKE(dev_priv))
3639 : 0 : cnl_ddi_vswing_sequence(encoder, level, INTEL_OUTPUT_HDMI);
3640 [ # # # # ]: 0 : else if (IS_GEN9_LP(dev_priv))
3641 : 0 : bxt_ddi_vswing_sequence(encoder, level, INTEL_OUTPUT_HDMI);
3642 : : else
3643 : 0 : intel_prepare_hdmi_ddi_buffers(encoder, level);
3644 : :
3645 [ # # # # ]: 0 : if (IS_GEN9_BC(dev_priv))
3646 : 0 : skl_ddi_set_iboost(encoder, level, INTEL_OUTPUT_HDMI);
3647 : :
3648 : 0 : intel_ddi_enable_pipe_clock(crtc_state);
3649 : :
3650 : 0 : intel_dig_port->set_infoframes(encoder,
3651 : 0 : crtc_state->has_infoframe,
3652 : : crtc_state, conn_state);
3653 : 0 : }
3654 : :
3655 : 0 : static void intel_ddi_pre_enable(struct intel_encoder *encoder,
3656 : : const struct intel_crtc_state *crtc_state,
3657 : : const struct drm_connector_state *conn_state)
3658 : : {
3659 : 0 : struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
3660 [ # # ]: 0 : struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
3661 : 0 : enum pipe pipe = crtc->pipe;
3662 : :
3663 : : /*
3664 : : * When called from DP MST code:
3665 : : * - conn_state will be NULL
3666 : : * - encoder will be the main encoder (ie. mst->primary)
3667 : : * - the main connector associated with this port
3668 : : * won't be active or linked to a crtc
3669 : : * - crtc_state will be the state of the first stream to
3670 : : * be activated on this port, and it may not be the same
3671 : : * stream that will be deactivated last, but each stream
3672 : : * should have a state that is identical when it comes to
3673 : : * the DP link parameteres
3674 : : */
3675 : :
3676 [ # # ]: 0 : WARN_ON(crtc_state->has_pch_encoder);
3677 : :
3678 [ # # ]: 0 : if (INTEL_GEN(dev_priv) >= 11)
3679 : 0 : icl_map_plls_to_ports(encoder, crtc_state);
3680 : :
3681 : 0 : intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
3682 : :
3683 [ # # ]: 0 : if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) {
3684 : 0 : intel_ddi_pre_enable_hdmi(encoder, crtc_state, conn_state);
3685 : : } else {
3686 [ # # ]: 0 : struct intel_lspcon *lspcon =
3687 : : enc_to_intel_lspcon(encoder);
3688 : :
3689 : 0 : intel_ddi_pre_enable_dp(encoder, crtc_state, conn_state);
3690 [ # # ]: 0 : if (lspcon->active) {
3691 [ # # ]: 0 : struct intel_digital_port *dig_port =
3692 : : enc_to_dig_port(encoder);
3693 : :
3694 : 0 : dig_port->set_infoframes(encoder,
3695 : 0 : crtc_state->has_infoframe,
3696 : : crtc_state, conn_state);
3697 : : }
3698 : : }
3699 : 0 : }
3700 : :
3701 : 0 : static void intel_disable_ddi_buf(struct intel_encoder *encoder,
3702 : : const struct intel_crtc_state *crtc_state)
3703 : : {
3704 : 0 : struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
3705 : 0 : enum port port = encoder->port;
3706 : 0 : bool wait = false;
3707 : 0 : u32 val;
3708 : :
3709 : 0 : val = I915_READ(DDI_BUF_CTL(port));
3710 [ # # ]: 0 : if (val & DDI_BUF_CTL_ENABLE) {
3711 : 0 : val &= ~DDI_BUF_CTL_ENABLE;
3712 : 0 : I915_WRITE(DDI_BUF_CTL(port), val);
3713 : 0 : wait = true;
3714 : : }
3715 : :
3716 [ # # ]: 0 : if (intel_crtc_has_dp_encoder(crtc_state)) {
3717 [ # # ]: 0 : struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
3718 : :
3719 : 0 : val = I915_READ(intel_dp->regs.dp_tp_ctl);
3720 : 0 : val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
3721 : 0 : val |= DP_TP_CTL_LINK_TRAIN_PAT1;
3722 : 0 : I915_WRITE(intel_dp->regs.dp_tp_ctl, val);
3723 : : }
3724 : :
3725 : : /* Disable FEC in DP Sink */
3726 : 0 : intel_ddi_disable_fec_state(encoder, crtc_state);
3727 : :
3728 [ # # ]: 0 : if (wait)
3729 : 0 : intel_wait_ddi_buf_idle(dev_priv, port);
3730 : 0 : }
3731 : :
3732 : : static void intel_ddi_post_disable_dp(struct intel_encoder *encoder,
3733 : : const struct intel_crtc_state *old_crtc_state,
3734 : : const struct drm_connector_state *old_conn_state)
3735 : : {
3736 : : struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
3737 : : struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
3738 : : struct intel_dp *intel_dp = &dig_port->dp;
3739 : : bool is_mst = intel_crtc_has_type(old_crtc_state,
3740 : : INTEL_OUTPUT_DP_MST);
3741 : : enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
3742 : :
3743 : : /*
3744 : : * Power down sink before disabling the port, otherwise we end
3745 : : * up getting interrupts from the sink on detecting link loss.
3746 : : */
3747 : : intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
3748 : :
3749 : : if (INTEL_GEN(dev_priv) >= 12) {
3750 : : if (is_mst) {
3751 : : enum transcoder cpu_transcoder = old_crtc_state->cpu_transcoder;
3752 : : u32 val;
3753 : :
3754 : : val = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
3755 : : val &= ~TGL_TRANS_DDI_PORT_MASK;
3756 : : I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), val);
3757 : : }
3758 : : } else {
3759 : : if (!is_mst)
3760 : : intel_ddi_disable_pipe_clock(old_crtc_state);
3761 : : }
3762 : :
3763 : : intel_disable_ddi_buf(encoder, old_crtc_state);
3764 : :
3765 : : /*
3766 : : * From TGL spec: "If single stream or multi-stream master transcoder:
3767 : : * Configure Transcoder Clock select to direct no clock to the
3768 : : * transcoder"
3769 : : */
3770 : : if (INTEL_GEN(dev_priv) >= 12)
3771 : : intel_ddi_disable_pipe_clock(old_crtc_state);
3772 : :
3773 : : intel_edp_panel_vdd_on(intel_dp);
3774 : : intel_edp_panel_off(intel_dp);
3775 : :
3776 : : if (!intel_phy_is_tc(dev_priv, phy) ||
3777 : : dig_port->tc_mode != TC_PORT_TBT_ALT)
3778 : : intel_display_power_put_unchecked(dev_priv,
3779 : : dig_port->ddi_io_power_domain);
3780 : :
3781 : : intel_ddi_clk_disable(encoder);
3782 : : tgl_clear_psr2_transcoder_exitline(old_crtc_state);
3783 : : }
3784 : :
3785 : 0 : static void intel_ddi_post_disable_hdmi(struct intel_encoder *encoder,
3786 : : const struct intel_crtc_state *old_crtc_state,
3787 : : const struct drm_connector_state *old_conn_state)
3788 : : {
3789 [ # # ]: 0 : struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
3790 [ # # ]: 0 : struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
3791 : 0 : struct intel_hdmi *intel_hdmi = &dig_port->hdmi;
3792 : :
3793 : 0 : dig_port->set_infoframes(encoder, false,
3794 : : old_crtc_state, old_conn_state);
3795 : :
3796 : 0 : intel_ddi_disable_pipe_clock(old_crtc_state);
3797 : :
3798 : 0 : intel_disable_ddi_buf(encoder, old_crtc_state);
3799 : :
3800 : 0 : intel_display_power_put_unchecked(dev_priv,
3801 : : dig_port->ddi_io_power_domain);
3802 : :
3803 : 0 : intel_ddi_clk_disable(encoder);
3804 : :
3805 : 0 : intel_dp_dual_mode_set_tmds_output(intel_hdmi, false);
3806 : 0 : }
3807 : :
3808 : 0 : static void icl_disable_transcoder_port_sync(const struct intel_crtc_state *old_crtc_state)
3809 : : {
3810 : 0 : struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
3811 [ # # ]: 0 : struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
3812 : :
3813 [ # # ]: 0 : if (old_crtc_state->master_transcoder == INVALID_TRANSCODER)
3814 : : return;
3815 : :
3816 [ # # ]: 0 : DRM_DEBUG_KMS("Disabling Transcoder Port Sync on Slave Transcoder %s\n",
3817 : : transcoder_name(old_crtc_state->cpu_transcoder));
3818 : :
3819 : 0 : I915_WRITE(TRANS_DDI_FUNC_CTL2(old_crtc_state->cpu_transcoder), 0);
3820 : : }
3821 : :
3822 : 0 : static void intel_ddi_post_disable(struct intel_encoder *encoder,
3823 : : const struct intel_crtc_state *old_crtc_state,
3824 : : const struct drm_connector_state *old_conn_state)
3825 : : {
3826 [ # # ]: 0 : struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
3827 [ # # ]: 0 : struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
3828 : 0 : enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
3829 : 0 : bool is_tc_port = intel_phy_is_tc(dev_priv, phy);
3830 : :
3831 [ # # ]: 0 : if (!intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_DP_MST)) {
3832 : 0 : intel_crtc_vblank_off(old_crtc_state);
3833 : :
3834 : 0 : intel_disable_pipe(old_crtc_state);
3835 : :
3836 [ # # ]: 0 : if (INTEL_GEN(dev_priv) >= 11)
3837 : 0 : icl_disable_transcoder_port_sync(old_crtc_state);
3838 : :
3839 : 0 : intel_ddi_disable_transcoder_func(old_crtc_state);
3840 : :
3841 : 0 : intel_dsc_disable(old_crtc_state);
3842 : :
3843 [ # # ]: 0 : if (INTEL_GEN(dev_priv) >= 9)
3844 : 0 : skl_scaler_disable(old_crtc_state);
3845 : : else
3846 : 0 : ilk_pfit_disable(old_crtc_state);
3847 : : }
3848 : :
3849 : : /*
3850 : : * When called from DP MST code:
3851 : : * - old_conn_state will be NULL
3852 : : * - encoder will be the main encoder (ie. mst->primary)
3853 : : * - the main connector associated with this port
3854 : : * won't be active or linked to a crtc
3855 : : * - old_crtc_state will be the state of the last stream to
3856 : : * be deactivated on this port, and it may not be the same
3857 : : * stream that was activated last, but each stream
3858 : : * should have a state that is identical when it comes to
3859 : : * the DP link parameteres
3860 : : */
3861 : :
3862 [ # # ]: 0 : if (intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_HDMI))
3863 : 0 : intel_ddi_post_disable_hdmi(encoder,
3864 : : old_crtc_state, old_conn_state);
3865 : : else
3866 : 0 : intel_ddi_post_disable_dp(encoder,
3867 : : old_crtc_state, old_conn_state);
3868 : :
3869 [ # # ]: 0 : if (INTEL_GEN(dev_priv) >= 11)
3870 : 0 : icl_unmap_plls_to_ports(encoder);
3871 : :
3872 [ # # # # ]: 0 : if (intel_crtc_has_dp_encoder(old_crtc_state) || is_tc_port)
3873 [ # # ]: 0 : intel_display_power_put_unchecked(dev_priv,
3874 : : intel_ddi_main_link_aux_domain(dig_port));
3875 : :
3876 [ # # ]: 0 : if (is_tc_port)
3877 : 0 : intel_tc_port_put_link(dig_port);
3878 : 0 : }
3879 : :
3880 : 0 : void intel_ddi_fdi_post_disable(struct intel_encoder *encoder,
3881 : : const struct intel_crtc_state *old_crtc_state,
3882 : : const struct drm_connector_state *old_conn_state)
3883 : : {
3884 : 0 : struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
3885 : 0 : u32 val;
3886 : :
3887 : : /*
3888 : : * Bspec lists this as both step 13 (before DDI_BUF_CTL disable)
3889 : : * and step 18 (after clearing PORT_CLK_SEL). Based on a BUN,
3890 : : * step 13 is the correct place for it. Step 18 is where it was
3891 : : * originally before the BUN.
3892 : : */
3893 : 0 : val = I915_READ(FDI_RX_CTL(PIPE_A));
3894 : 0 : val &= ~FDI_RX_ENABLE;
3895 : 0 : I915_WRITE(FDI_RX_CTL(PIPE_A), val);
3896 : :
3897 : 0 : intel_disable_ddi_buf(encoder, old_crtc_state);
3898 : 0 : intel_ddi_clk_disable(encoder);
3899 : :
3900 : 0 : val = I915_READ(FDI_RX_MISC(PIPE_A));
3901 : 0 : val &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
3902 : 0 : val |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2);
3903 : 0 : I915_WRITE(FDI_RX_MISC(PIPE_A), val);
3904 : :
3905 : 0 : val = I915_READ(FDI_RX_CTL(PIPE_A));
3906 : 0 : val &= ~FDI_PCDCLK;
3907 : 0 : I915_WRITE(FDI_RX_CTL(PIPE_A), val);
3908 : :
3909 : 0 : val = I915_READ(FDI_RX_CTL(PIPE_A));
3910 : 0 : val &= ~FDI_RX_PLL_ENABLE;
3911 : 0 : I915_WRITE(FDI_RX_CTL(PIPE_A), val);
3912 : 0 : }
3913 : :
3914 : 0 : static void intel_enable_ddi_dp(struct intel_encoder *encoder,
3915 : : const struct intel_crtc_state *crtc_state,
3916 : : const struct drm_connector_state *conn_state)
3917 : : {
3918 [ # # ]: 0 : struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
3919 [ # # ]: 0 : struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
3920 : 0 : enum port port = encoder->port;
3921 : :
3922 [ # # # # ]: 0 : if (port == PORT_A && INTEL_GEN(dev_priv) < 9)
3923 : 0 : intel_dp_stop_link_train(intel_dp);
3924 : :
3925 : 0 : intel_edp_backlight_on(crtc_state, conn_state);
3926 : 0 : intel_psr_enable(intel_dp, crtc_state);
3927 : 0 : intel_dp_vsc_enable(intel_dp, crtc_state, conn_state);
3928 : 0 : intel_dp_hdr_metadata_enable(intel_dp, crtc_state, conn_state);
3929 : 0 : intel_edp_drrs_enable(intel_dp, crtc_state);
3930 : :
3931 [ # # ]: 0 : if (crtc_state->has_audio)
3932 : 0 : intel_audio_codec_enable(encoder, crtc_state, conn_state);
3933 : 0 : }
3934 : :
3935 : : static i915_reg_t
3936 : : gen9_chicken_trans_reg_by_port(struct drm_i915_private *dev_priv,
3937 : : enum port port)
3938 : : {
3939 : : static const enum transcoder trans[] = {
3940 : : [PORT_A] = TRANSCODER_EDP,
3941 : : [PORT_B] = TRANSCODER_A,
3942 : : [PORT_C] = TRANSCODER_B,
3943 : : [PORT_D] = TRANSCODER_C,
3944 : : [PORT_E] = TRANSCODER_A,
3945 : : };
3946 : :
3947 : : WARN_ON(INTEL_GEN(dev_priv) < 9);
3948 : :
3949 : : if (WARN_ON(port < PORT_A || port > PORT_E))
3950 : : port = PORT_A;
3951 : :
3952 : : return CHICKEN_TRANS(trans[port]);
3953 : : }
3954 : :
3955 : 0 : static void intel_enable_ddi_hdmi(struct intel_encoder *encoder,
3956 : : const struct intel_crtc_state *crtc_state,
3957 : : const struct drm_connector_state *conn_state)
3958 : : {
3959 [ # # ]: 0 : struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
3960 [ # # ]: 0 : struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
3961 : 0 : struct drm_connector *connector = conn_state->connector;
3962 : 0 : enum port port = encoder->port;
3963 : :
3964 [ # # ]: 0 : if (!intel_hdmi_handle_sink_scrambling(encoder, connector,
3965 : 0 : crtc_state->hdmi_high_tmds_clock_ratio,
3966 : 0 : crtc_state->hdmi_scrambling))
3967 : 0 : DRM_ERROR("[CONNECTOR:%d:%s] Failed to configure sink scrambling/TMDS bit clock ratio\n",
3968 : : connector->base.id, connector->name);
3969 : :
3970 : : /* Display WA #1143: skl,kbl,cfl */
3971 [ # # # # ]: 0 : if (IS_GEN9_BC(dev_priv)) {
3972 : : /*
3973 : : * For some reason these chicken bits have been
3974 : : * stuffed into a transcoder register, event though
3975 : : * the bits affect a specific DDI port rather than
3976 : : * a specific transcoder.
3977 : : */
3978 : 0 : i915_reg_t reg = gen9_chicken_trans_reg_by_port(dev_priv, port);
3979 : 0 : u32 val;
3980 : :
3981 : 0 : val = I915_READ(reg);
3982 : :
3983 [ # # ]: 0 : if (port == PORT_E)
3984 : 0 : val |= DDIE_TRAINING_OVERRIDE_ENABLE |
3985 : : DDIE_TRAINING_OVERRIDE_VALUE;
3986 : : else
3987 : 0 : val |= DDI_TRAINING_OVERRIDE_ENABLE |
3988 : : DDI_TRAINING_OVERRIDE_VALUE;
3989 : :
3990 : 0 : I915_WRITE(reg, val);
3991 : 0 : POSTING_READ(reg);
3992 : :
3993 : 0 : udelay(1);
3994 : :
3995 [ # # ]: 0 : if (port == PORT_E)
3996 : 0 : val &= ~(DDIE_TRAINING_OVERRIDE_ENABLE |
3997 : : DDIE_TRAINING_OVERRIDE_VALUE);
3998 : : else
3999 : 0 : val &= ~(DDI_TRAINING_OVERRIDE_ENABLE |
4000 : : DDI_TRAINING_OVERRIDE_VALUE);
4001 : :
4002 : 0 : I915_WRITE(reg, val);
4003 : : }
4004 : :
4005 : : /* In HDMI/DVI mode, the port width, and swing/emphasis values
4006 : : * are ignored so nothing special needs to be done besides
4007 : : * enabling the port.
4008 : : */
4009 : 0 : I915_WRITE(DDI_BUF_CTL(port),
4010 : : dig_port->saved_port_bits | DDI_BUF_CTL_ENABLE);
4011 : :
4012 [ # # ]: 0 : if (crtc_state->has_audio)
4013 : 0 : intel_audio_codec_enable(encoder, crtc_state, conn_state);
4014 : 0 : }
4015 : :
4016 : 0 : static void intel_enable_ddi(struct intel_encoder *encoder,
4017 : : const struct intel_crtc_state *crtc_state,
4018 : : const struct drm_connector_state *conn_state)
4019 : : {
4020 [ # # ]: 0 : if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
4021 : 0 : intel_enable_ddi_hdmi(encoder, crtc_state, conn_state);
4022 : : else
4023 : 0 : intel_enable_ddi_dp(encoder, crtc_state, conn_state);
4024 : :
4025 : : /* Enable hdcp if it's desired */
4026 [ # # ]: 0 : if (conn_state->content_protection ==
4027 : : DRM_MODE_CONTENT_PROTECTION_DESIRED)
4028 : 0 : intel_hdcp_enable(to_intel_connector(conn_state->connector),
4029 : : crtc_state->cpu_transcoder,
4030 : 0 : (u8)conn_state->hdcp_content_type);
4031 : 0 : }
4032 : :
4033 : 0 : static void intel_disable_ddi_dp(struct intel_encoder *encoder,
4034 : : const struct intel_crtc_state *old_crtc_state,
4035 : : const struct drm_connector_state *old_conn_state)
4036 : : {
4037 [ # # ]: 0 : struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
4038 : :
4039 : 0 : intel_dp->link_trained = false;
4040 : :
4041 [ # # ]: 0 : if (old_crtc_state->has_audio)
4042 : 0 : intel_audio_codec_disable(encoder,
4043 : : old_crtc_state, old_conn_state);
4044 : :
4045 : 0 : intel_edp_drrs_disable(intel_dp, old_crtc_state);
4046 : 0 : intel_psr_disable(intel_dp, old_crtc_state);
4047 : 0 : intel_edp_backlight_off(old_conn_state);
4048 : : /* Disable the decompression in DP Sink */
4049 : 0 : intel_dp_sink_set_decompression_state(intel_dp, old_crtc_state,
4050 : : false);
4051 : 0 : }
4052 : :
4053 : 0 : static void intel_disable_ddi_hdmi(struct intel_encoder *encoder,
4054 : : const struct intel_crtc_state *old_crtc_state,
4055 : : const struct drm_connector_state *old_conn_state)
4056 : : {
4057 : 0 : struct drm_connector *connector = old_conn_state->connector;
4058 : :
4059 [ # # ]: 0 : if (old_crtc_state->has_audio)
4060 : 0 : intel_audio_codec_disable(encoder,
4061 : : old_crtc_state, old_conn_state);
4062 : :
4063 [ # # ]: 0 : if (!intel_hdmi_handle_sink_scrambling(encoder, connector,
4064 : : false, false))
4065 : 0 : DRM_DEBUG_KMS("[CONNECTOR:%d:%s] Failed to reset sink scrambling/TMDS bit clock ratio\n",
4066 : : connector->base.id, connector->name);
4067 : 0 : }
4068 : :
4069 : 0 : static void intel_disable_ddi(struct intel_encoder *encoder,
4070 : : const struct intel_crtc_state *old_crtc_state,
4071 : : const struct drm_connector_state *old_conn_state)
4072 : : {
4073 : 0 : intel_hdcp_disable(to_intel_connector(old_conn_state->connector));
4074 : :
4075 [ # # ]: 0 : if (intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_HDMI))
4076 : 0 : intel_disable_ddi_hdmi(encoder, old_crtc_state, old_conn_state);
4077 : : else
4078 : 0 : intel_disable_ddi_dp(encoder, old_crtc_state, old_conn_state);
4079 : 0 : }
4080 : :
4081 : 0 : static void intel_ddi_update_pipe_dp(struct intel_encoder *encoder,
4082 : : const struct intel_crtc_state *crtc_state,
4083 : : const struct drm_connector_state *conn_state)
4084 : : {
4085 [ # # ]: 0 : struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
4086 : :
4087 : 0 : intel_ddi_set_dp_msa(crtc_state, conn_state);
4088 : :
4089 : 0 : intel_psr_update(intel_dp, crtc_state);
4090 : 0 : intel_edp_drrs_enable(intel_dp, crtc_state);
4091 : :
4092 : 0 : intel_panel_update_backlight(encoder, crtc_state, conn_state);
4093 : 0 : }
4094 : :
4095 : 0 : static void intel_ddi_update_pipe(struct intel_encoder *encoder,
4096 : : const struct intel_crtc_state *crtc_state,
4097 : : const struct drm_connector_state *conn_state)
4098 : : {
4099 : 0 : struct intel_connector *connector =
4100 : 0 : to_intel_connector(conn_state->connector);
4101 : 0 : struct intel_hdcp *hdcp = &connector->hdcp;
4102 : 0 : bool content_protection_type_changed =
4103 [ # # ]: 0 : (conn_state->hdcp_content_type != hdcp->content_type &&
4104 [ # # ]: 0 : conn_state->content_protection !=
4105 : : DRM_MODE_CONTENT_PROTECTION_UNDESIRED);
4106 : :
4107 [ # # ]: 0 : if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
4108 : 0 : intel_ddi_update_pipe_dp(encoder, crtc_state, conn_state);
4109 : :
4110 : : /*
4111 : : * During the HDCP encryption session if Type change is requested,
4112 : : * disable the HDCP and reenable it with new TYPE value.
4113 : : */
4114 [ # # ]: 0 : if (conn_state->content_protection ==
4115 [ # # ]: 0 : DRM_MODE_CONTENT_PROTECTION_UNDESIRED ||
4116 : : content_protection_type_changed)
4117 : 0 : intel_hdcp_disable(connector);
4118 : :
4119 : : /*
4120 : : * Mark the hdcp state as DESIRED after the hdcp disable of type
4121 : : * change procedure.
4122 : : */
4123 [ # # ]: 0 : if (content_protection_type_changed) {
4124 : 0 : mutex_lock(&hdcp->mutex);
4125 : 0 : hdcp->value = DRM_MODE_CONTENT_PROTECTION_DESIRED;
4126 : 0 : schedule_work(&hdcp->prop_work);
4127 : 0 : mutex_unlock(&hdcp->mutex);
4128 : : }
4129 : :
4130 [ # # ]: 0 : if (conn_state->content_protection ==
4131 [ # # ]: 0 : DRM_MODE_CONTENT_PROTECTION_DESIRED ||
4132 : : content_protection_type_changed)
4133 : 0 : intel_hdcp_enable(connector,
4134 : : crtc_state->cpu_transcoder,
4135 : 0 : (u8)conn_state->hdcp_content_type);
4136 : 0 : }
4137 : :
4138 : : static void
4139 : 0 : intel_ddi_update_prepare(struct intel_atomic_state *state,
4140 : : struct intel_encoder *encoder,
4141 : : struct intel_crtc *crtc)
4142 : : {
4143 : 0 : struct intel_crtc_state *crtc_state =
4144 [ # # ]: 0 : crtc ? intel_atomic_get_new_crtc_state(state, crtc) : NULL;
4145 [ # # ]: 0 : int required_lanes = crtc_state ? crtc_state->lane_count : 1;
4146 : :
4147 [ # # # # : 0 : WARN_ON(crtc && crtc->active);
# # ]
4148 : :
4149 [ # # ]: 0 : intel_tc_port_get_link(enc_to_dig_port(encoder),
4150 : : required_lanes);
4151 [ # # # # ]: 0 : if (crtc_state && crtc_state->hw.active)
4152 : 0 : intel_update_active_dpll(state, crtc, encoder);
4153 : 0 : }
4154 : :
4155 : : static void
4156 : 0 : intel_ddi_update_complete(struct intel_atomic_state *state,
4157 : : struct intel_encoder *encoder,
4158 : : struct intel_crtc *crtc)
4159 : : {
4160 [ # # ]: 0 : intel_tc_port_put_link(enc_to_dig_port(encoder));
4161 : 0 : }
4162 : :
4163 : : static void
4164 : 0 : intel_ddi_pre_pll_enable(struct intel_encoder *encoder,
4165 : : const struct intel_crtc_state *crtc_state,
4166 : : const struct drm_connector_state *conn_state)
4167 : : {
4168 [ # # ]: 0 : struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
4169 [ # # ]: 0 : struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
4170 : 0 : enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
4171 : 0 : bool is_tc_port = intel_phy_is_tc(dev_priv, phy);
4172 : :
4173 [ # # ]: 0 : if (is_tc_port)
4174 : 0 : intel_tc_port_get_link(dig_port, crtc_state->lane_count);
4175 : :
4176 [ # # # # ]: 0 : if (intel_crtc_has_dp_encoder(crtc_state) || is_tc_port)
4177 [ # # ]: 0 : intel_display_power_get(dev_priv,
4178 : : intel_ddi_main_link_aux_domain(dig_port));
4179 : :
4180 [ # # # # ]: 0 : if (is_tc_port && dig_port->tc_mode != TC_PORT_TBT_ALT)
4181 : : /*
4182 : : * Program the lane count for static/dynamic connections on
4183 : : * Type-C ports. Skip this step for TBT.
4184 : : */
4185 : 0 : intel_tc_port_set_fia_lane_count(dig_port, crtc_state->lane_count);
4186 [ # # # # ]: 0 : else if (IS_GEN9_LP(dev_priv))
4187 : 0 : bxt_ddi_phy_set_lane_optim_mask(encoder,
4188 : 0 : crtc_state->lane_lat_optim_mask);
4189 : 0 : }
4190 : :
4191 : 0 : static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp)
4192 : : {
4193 : 0 : struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
4194 : 0 : struct drm_i915_private *dev_priv =
4195 : 0 : to_i915(intel_dig_port->base.base.dev);
4196 : 0 : enum port port = intel_dig_port->base.port;
4197 : 0 : u32 dp_tp_ctl, ddi_buf_ctl;
4198 : 0 : bool wait = false;
4199 : :
4200 : 0 : dp_tp_ctl = I915_READ(intel_dp->regs.dp_tp_ctl);
4201 : :
4202 [ # # ]: 0 : if (dp_tp_ctl & DP_TP_CTL_ENABLE) {
4203 : 0 : ddi_buf_ctl = I915_READ(DDI_BUF_CTL(port));
4204 [ # # ]: 0 : if (ddi_buf_ctl & DDI_BUF_CTL_ENABLE) {
4205 : 0 : I915_WRITE(DDI_BUF_CTL(port),
4206 : : ddi_buf_ctl & ~DDI_BUF_CTL_ENABLE);
4207 : 0 : wait = true;
4208 : : }
4209 : :
4210 : 0 : dp_tp_ctl &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
4211 : 0 : dp_tp_ctl |= DP_TP_CTL_LINK_TRAIN_PAT1;
4212 : 0 : I915_WRITE(intel_dp->regs.dp_tp_ctl, dp_tp_ctl);
4213 : 0 : POSTING_READ(intel_dp->regs.dp_tp_ctl);
4214 : :
4215 [ # # ]: 0 : if (wait)
4216 : 0 : intel_wait_ddi_buf_idle(dev_priv, port);
4217 : : }
4218 : :
4219 : 0 : dp_tp_ctl = DP_TP_CTL_ENABLE |
4220 : : DP_TP_CTL_LINK_TRAIN_PAT1 | DP_TP_CTL_SCRAMBLE_DISABLE;
4221 [ # # ]: 0 : if (intel_dp->link_mst)
4222 : : dp_tp_ctl |= DP_TP_CTL_MODE_MST;
4223 : : else {
4224 : 0 : dp_tp_ctl |= DP_TP_CTL_MODE_SST;
4225 [ # # # # ]: 0 : if (drm_dp_enhanced_frame_cap(intel_dp->dpcd))
4226 : 0 : dp_tp_ctl |= DP_TP_CTL_ENHANCED_FRAME_ENABLE;
4227 : : }
4228 : 0 : I915_WRITE(intel_dp->regs.dp_tp_ctl, dp_tp_ctl);
4229 : 0 : POSTING_READ(intel_dp->regs.dp_tp_ctl);
4230 : :
4231 : 0 : intel_dp->DP |= DDI_BUF_CTL_ENABLE;
4232 : 0 : I915_WRITE(DDI_BUF_CTL(port), intel_dp->DP);
4233 : 0 : POSTING_READ(DDI_BUF_CTL(port));
4234 : :
4235 : 0 : udelay(600);
4236 : 0 : }
4237 : :
4238 : 0 : static bool intel_ddi_is_audio_enabled(struct drm_i915_private *dev_priv,
4239 : : enum transcoder cpu_transcoder)
4240 : : {
4241 [ # # ]: 0 : if (cpu_transcoder == TRANSCODER_EDP)
4242 : : return false;
4243 : :
4244 [ # # ]: 0 : if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_AUDIO))
4245 : : return false;
4246 : :
4247 : 0 : return I915_READ(HSW_AUD_PIN_ELD_CP_VLD) &
4248 : 0 : AUDIO_OUTPUT_ENABLE(cpu_transcoder);
4249 : : }
4250 : :
4251 : 0 : void intel_ddi_compute_min_voltage_level(struct drm_i915_private *dev_priv,
4252 : : struct intel_crtc_state *crtc_state)
4253 : : {
4254 [ # # # # ]: 0 : if (IS_ELKHARTLAKE(dev_priv) && crtc_state->port_clock > 594000)
4255 : 0 : crtc_state->min_voltage_level = 3;
4256 [ # # # # ]: 0 : else if (INTEL_GEN(dev_priv) >= 11 && crtc_state->port_clock > 594000)
4257 : 0 : crtc_state->min_voltage_level = 1;
4258 [ # # # # ]: 0 : else if (IS_CANNONLAKE(dev_priv) && crtc_state->port_clock > 594000)
4259 : 0 : crtc_state->min_voltage_level = 2;
4260 : 0 : }
4261 : :
4262 : 0 : void intel_ddi_get_config(struct intel_encoder *encoder,
4263 : : struct intel_crtc_state *pipe_config)
4264 : : {
4265 [ # # ]: 0 : struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
4266 : 0 : struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->uapi.crtc);
4267 : 0 : enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
4268 : 0 : u32 temp, flags = 0;
4269 : :
4270 : : /* XXX: DSI transcoder paranoia */
4271 [ # # # # ]: 0 : if (WARN_ON(transcoder_is_dsi(cpu_transcoder)))
4272 : : return;
4273 : :
4274 : 0 : intel_dsc_get_config(encoder, pipe_config);
4275 : :
4276 : 0 : temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
4277 [ # # ]: 0 : if (temp & TRANS_DDI_PHSYNC)
4278 : : flags |= DRM_MODE_FLAG_PHSYNC;
4279 : : else
4280 : 0 : flags |= DRM_MODE_FLAG_NHSYNC;
4281 [ # # ]: 0 : if (temp & TRANS_DDI_PVSYNC)
4282 : 0 : flags |= DRM_MODE_FLAG_PVSYNC;
4283 : : else
4284 : 0 : flags |= DRM_MODE_FLAG_NVSYNC;
4285 : :
4286 : 0 : pipe_config->hw.adjusted_mode.flags |= flags;
4287 : :
4288 [ # # # # : 0 : switch (temp & TRANS_DDI_BPC_MASK) {
# ]
4289 : 0 : case TRANS_DDI_BPC_6:
4290 : 0 : pipe_config->pipe_bpp = 18;
4291 : 0 : break;
4292 : 0 : case TRANS_DDI_BPC_8:
4293 : 0 : pipe_config->pipe_bpp = 24;
4294 : 0 : break;
4295 : 0 : case TRANS_DDI_BPC_10:
4296 : 0 : pipe_config->pipe_bpp = 30;
4297 : 0 : break;
4298 : 0 : case TRANS_DDI_BPC_12:
4299 : 0 : pipe_config->pipe_bpp = 36;
4300 : 0 : break;
4301 : : default:
4302 : : break;
4303 : : }
4304 : :
4305 [ # # # # : 0 : switch (temp & TRANS_DDI_MODE_SELECT_MASK) {
# # ]
4306 : 0 : case TRANS_DDI_MODE_SELECT_HDMI:
4307 : 0 : pipe_config->has_hdmi_sink = true;
4308 : :
4309 : 0 : pipe_config->infoframes.enable |=
4310 : 0 : intel_hdmi_infoframes_enabled(encoder, pipe_config);
4311 : :
4312 [ # # ]: 0 : if (pipe_config->infoframes.enable)
4313 : 0 : pipe_config->has_infoframe = true;
4314 : :
4315 [ # # ]: 0 : if (temp & TRANS_DDI_HDMI_SCRAMBLING)
4316 : 0 : pipe_config->hdmi_scrambling = true;
4317 [ # # ]: 0 : if (temp & TRANS_DDI_HIGH_TMDS_CHAR_RATE)
4318 : 0 : pipe_config->hdmi_high_tmds_clock_ratio = true;
4319 : : /* fall through */
4320 : : case TRANS_DDI_MODE_SELECT_DVI:
4321 : 0 : pipe_config->output_types |= BIT(INTEL_OUTPUT_HDMI);
4322 : 0 : pipe_config->lane_count = 4;
4323 : 0 : break;
4324 : 0 : case TRANS_DDI_MODE_SELECT_FDI:
4325 : 0 : pipe_config->output_types |= BIT(INTEL_OUTPUT_ANALOG);
4326 : 0 : break;
4327 : 0 : case TRANS_DDI_MODE_SELECT_DP_SST:
4328 [ # # ]: 0 : if (encoder->type == INTEL_OUTPUT_EDP)
4329 : 0 : pipe_config->output_types |= BIT(INTEL_OUTPUT_EDP);
4330 : : else
4331 : 0 : pipe_config->output_types |= BIT(INTEL_OUTPUT_DP);
4332 : 0 : pipe_config->lane_count =
4333 : 0 : ((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1;
4334 : 0 : intel_dp_get_m_n(intel_crtc, pipe_config);
4335 : :
4336 [ # # ]: 0 : if (INTEL_GEN(dev_priv) >= 11) {
4337 : 0 : i915_reg_t dp_tp_ctl;
4338 : :
4339 [ # # ]: 0 : if (IS_GEN(dev_priv, 11))
4340 : 0 : dp_tp_ctl = DP_TP_CTL(encoder->port);
4341 : : else
4342 : 0 : dp_tp_ctl = TGL_DP_TP_CTL(pipe_config->cpu_transcoder);
4343 : :
4344 : 0 : pipe_config->fec_enable =
4345 : 0 : I915_READ(dp_tp_ctl) & DP_TP_CTL_FEC_ENABLE;
4346 : :
4347 : 0 : DRM_DEBUG_KMS("[ENCODER:%d:%s] Fec status: %u\n",
4348 : : encoder->base.base.id, encoder->base.name,
4349 : : pipe_config->fec_enable);
4350 : : }
4351 : :
4352 : : break;
4353 : 0 : case TRANS_DDI_MODE_SELECT_DP_MST:
4354 : 0 : pipe_config->output_types |= BIT(INTEL_OUTPUT_DP_MST);
4355 : 0 : pipe_config->lane_count =
4356 : 0 : ((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1;
4357 : :
4358 [ # # ]: 0 : if (INTEL_GEN(dev_priv) >= 12)
4359 : 0 : pipe_config->mst_master_transcoder =
4360 : 0 : REG_FIELD_GET(TRANS_DDI_MST_TRANSPORT_SELECT_MASK, temp);
4361 : :
4362 : 0 : intel_dp_get_m_n(intel_crtc, pipe_config);
4363 : 0 : break;
4364 : : default:
4365 : : break;
4366 : : }
4367 : :
4368 [ # # ]: 0 : if (encoder->type == INTEL_OUTPUT_EDP)
4369 : 0 : tgl_dc3co_exitline_get_config(pipe_config);
4370 : :
4371 : 0 : pipe_config->has_audio =
4372 : 0 : intel_ddi_is_audio_enabled(dev_priv, cpu_transcoder);
4373 : :
4374 [ # # # # ]: 0 : if (encoder->type == INTEL_OUTPUT_EDP && dev_priv->vbt.edp.bpp &&
4375 [ # # ]: 0 : pipe_config->pipe_bpp > dev_priv->vbt.edp.bpp) {
4376 : : /*
4377 : : * This is a big fat ugly hack.
4378 : : *
4379 : : * Some machines in UEFI boot mode provide us a VBT that has 18
4380 : : * bpp and 1.62 GHz link bandwidth for eDP, which for reasons
4381 : : * unknown we fail to light up. Yet the same BIOS boots up with
4382 : : * 24 bpp and 2.7 GHz link. Use the same bpp as the BIOS uses as
4383 : : * max, not what it tells us to use.
4384 : : *
4385 : : * Note: This will still be broken if the eDP panel is not lit
4386 : : * up by the BIOS, and thus we can't get the mode at module
4387 : : * load.
4388 : : */
4389 : 0 : DRM_DEBUG_KMS("pipe has %d bpp for eDP panel, overriding BIOS-provided max %d bpp\n",
4390 : : pipe_config->pipe_bpp, dev_priv->vbt.edp.bpp);
4391 : 0 : dev_priv->vbt.edp.bpp = pipe_config->pipe_bpp;
4392 : : }
4393 : :
4394 : 0 : intel_ddi_clock_get(encoder, pipe_config);
4395 : :
4396 [ # # # # ]: 0 : if (IS_GEN9_LP(dev_priv))
4397 : 0 : pipe_config->lane_lat_optim_mask =
4398 : 0 : bxt_ddi_phy_get_lane_lat_optim_mask(encoder);
4399 : :
4400 : 0 : intel_ddi_compute_min_voltage_level(dev_priv, pipe_config);
4401 : :
4402 : 0 : intel_hdmi_read_gcp_infoframe(encoder, pipe_config);
4403 : :
4404 : 0 : intel_read_infoframe(encoder, pipe_config,
4405 : : HDMI_INFOFRAME_TYPE_AVI,
4406 : : &pipe_config->infoframes.avi);
4407 : 0 : intel_read_infoframe(encoder, pipe_config,
4408 : : HDMI_INFOFRAME_TYPE_SPD,
4409 : : &pipe_config->infoframes.spd);
4410 : 0 : intel_read_infoframe(encoder, pipe_config,
4411 : : HDMI_INFOFRAME_TYPE_VENDOR,
4412 : : &pipe_config->infoframes.hdmi);
4413 : 0 : intel_read_infoframe(encoder, pipe_config,
4414 : : HDMI_INFOFRAME_TYPE_DRM,
4415 : : &pipe_config->infoframes.drm);
4416 : : }
4417 : :
4418 : : static enum intel_output_type
4419 : 0 : intel_ddi_compute_output_type(struct intel_encoder *encoder,
4420 : : struct intel_crtc_state *crtc_state,
4421 : : struct drm_connector_state *conn_state)
4422 : : {
4423 [ # # # # ]: 0 : switch (conn_state->connector->connector_type) {
4424 : : case DRM_MODE_CONNECTOR_HDMIA:
4425 : : return INTEL_OUTPUT_HDMI;
4426 : 0 : case DRM_MODE_CONNECTOR_eDP:
4427 : 0 : return INTEL_OUTPUT_EDP;
4428 : 0 : case DRM_MODE_CONNECTOR_DisplayPort:
4429 : 0 : return INTEL_OUTPUT_DP;
4430 : : default:
4431 : 0 : MISSING_CASE(conn_state->connector->connector_type);
4432 : 0 : return INTEL_OUTPUT_UNUSED;
4433 : : }
4434 : : }
4435 : :
4436 : 0 : static int intel_ddi_compute_config(struct intel_encoder *encoder,
4437 : : struct intel_crtc_state *pipe_config,
4438 : : struct drm_connector_state *conn_state)
4439 : : {
4440 : 0 : struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
4441 [ # # ]: 0 : struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
4442 : 0 : enum port port = encoder->port;
4443 : 0 : int ret;
4444 : :
4445 [ # # # # ]: 0 : if (HAS_TRANSCODER_EDP(dev_priv) && port == PORT_A)
4446 : 0 : pipe_config->cpu_transcoder = TRANSCODER_EDP;
4447 : :
4448 [ # # ]: 0 : if (intel_crtc_has_type(pipe_config, INTEL_OUTPUT_HDMI)) {
4449 : 0 : ret = intel_hdmi_compute_config(encoder, pipe_config, conn_state);
4450 : : } else {
4451 : 0 : ret = intel_dp_compute_config(encoder, pipe_config, conn_state);
4452 : 0 : tgl_dc3co_exitline_compute_config(encoder, pipe_config);
4453 : : }
4454 : :
4455 [ # # ]: 0 : if (ret)
4456 : : return ret;
4457 : :
4458 [ # # # # ]: 0 : if (IS_HASWELL(dev_priv) && crtc->pipe == PIPE_A &&
4459 [ # # ]: 0 : pipe_config->cpu_transcoder == TRANSCODER_EDP)
4460 : 0 : pipe_config->pch_pfit.force_thru =
4461 [ # # ]: 0 : pipe_config->pch_pfit.enabled ||
4462 [ # # ]: 0 : pipe_config->crc_enabled;
4463 : :
4464 [ # # # # ]: 0 : if (IS_GEN9_LP(dev_priv))
4465 : 0 : pipe_config->lane_lat_optim_mask =
4466 : 0 : bxt_ddi_phy_calc_lane_lat_optim_mask(pipe_config->lane_count);
4467 : :
4468 : 0 : intel_ddi_compute_min_voltage_level(dev_priv, pipe_config);
4469 : :
4470 : 0 : return 0;
4471 : : }
4472 : :
4473 : 0 : static void intel_ddi_encoder_destroy(struct drm_encoder *encoder)
4474 : : {
4475 [ # # ]: 0 : struct intel_digital_port *dig_port = enc_to_dig_port(to_intel_encoder(encoder));
4476 : :
4477 : 0 : intel_dp_encoder_flush_work(encoder);
4478 : :
4479 : 0 : drm_encoder_cleanup(encoder);
4480 : 0 : kfree(dig_port);
4481 : 0 : }
4482 : :
4483 : : static const struct drm_encoder_funcs intel_ddi_funcs = {
4484 : : .reset = intel_dp_encoder_reset,
4485 : : .destroy = intel_ddi_encoder_destroy,
4486 : : };
4487 : :
4488 : : static struct intel_connector *
4489 : 0 : intel_ddi_init_dp_connector(struct intel_digital_port *intel_dig_port)
4490 : : {
4491 : 0 : struct intel_connector *connector;
4492 : 0 : enum port port = intel_dig_port->base.port;
4493 : :
4494 : 0 : connector = intel_connector_alloc();
4495 [ # # ]: 0 : if (!connector)
4496 : : return NULL;
4497 : :
4498 : 0 : intel_dig_port->dp.output_reg = DDI_BUF_CTL(port);
4499 : 0 : intel_dig_port->dp.prepare_link_retrain =
4500 : : intel_ddi_prepare_link_retrain;
4501 : :
4502 [ # # ]: 0 : if (!intel_dp_init_connector(intel_dig_port, connector)) {
4503 : 0 : kfree(connector);
4504 : 0 : return NULL;
4505 : : }
4506 : :
4507 : : return connector;
4508 : : }
4509 : :
4510 : 0 : static int modeset_pipe(struct drm_crtc *crtc,
4511 : : struct drm_modeset_acquire_ctx *ctx)
4512 : : {
4513 : 0 : struct drm_atomic_state *state;
4514 : 0 : struct drm_crtc_state *crtc_state;
4515 : 0 : int ret;
4516 : :
4517 : 0 : state = drm_atomic_state_alloc(crtc->dev);
4518 [ # # ]: 0 : if (!state)
4519 : : return -ENOMEM;
4520 : :
4521 : 0 : state->acquire_ctx = ctx;
4522 : :
4523 : 0 : crtc_state = drm_atomic_get_crtc_state(state, crtc);
4524 [ # # ]: 0 : if (IS_ERR(crtc_state)) {
4525 : 0 : ret = PTR_ERR(crtc_state);
4526 : 0 : goto out;
4527 : : }
4528 : :
4529 : 0 : crtc_state->connectors_changed = true;
4530 : :
4531 : 0 : ret = drm_atomic_commit(state);
4532 : 0 : out:
4533 : 0 : drm_atomic_state_put(state);
4534 : :
4535 : 0 : return ret;
4536 : : }
4537 : :
4538 : 0 : static int intel_hdmi_reset_link(struct intel_encoder *encoder,
4539 : : struct drm_modeset_acquire_ctx *ctx)
4540 : : {
4541 : 0 : struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
4542 : 0 : struct intel_hdmi *hdmi = enc_to_intel_hdmi(encoder);
4543 : 0 : struct intel_connector *connector = hdmi->attached_connector;
4544 : 0 : struct i2c_adapter *adapter =
4545 : 0 : intel_gmbus_get_adapter(dev_priv, hdmi->ddc_bus);
4546 : 0 : struct drm_connector_state *conn_state;
4547 : 0 : struct intel_crtc_state *crtc_state;
4548 : 0 : struct intel_crtc *crtc;
4549 : 0 : u8 config;
4550 : 0 : int ret;
4551 : :
4552 [ # # # # ]: 0 : if (!connector || connector->base.status != connector_status_connected)
4553 : : return 0;
4554 : :
4555 : 0 : ret = drm_modeset_lock(&dev_priv->drm.mode_config.connection_mutex,
4556 : : ctx);
4557 [ # # ]: 0 : if (ret)
4558 : : return ret;
4559 : :
4560 : 0 : conn_state = connector->base.state;
4561 : :
4562 : 0 : crtc = to_intel_crtc(conn_state->crtc);
4563 [ # # ]: 0 : if (!crtc)
4564 : : return 0;
4565 : :
4566 : 0 : ret = drm_modeset_lock(&crtc->base.mutex, ctx);
4567 [ # # ]: 0 : if (ret)
4568 : : return ret;
4569 : :
4570 : 0 : crtc_state = to_intel_crtc_state(crtc->base.state);
4571 : :
4572 [ # # ]: 0 : WARN_ON(!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI));
4573 : :
4574 [ # # ]: 0 : if (!crtc_state->hw.active)
4575 : : return 0;
4576 : :
4577 [ # # ]: 0 : if (!crtc_state->hdmi_high_tmds_clock_ratio &&
4578 [ # # ]: 0 : !crtc_state->hdmi_scrambling)
4579 : : return 0;
4580 : :
4581 [ # # # # ]: 0 : if (conn_state->commit &&
4582 : 0 : !try_wait_for_completion(&conn_state->commit->hw_done))
4583 : : return 0;
4584 : :
4585 : 0 : ret = drm_scdc_readb(adapter, SCDC_TMDS_CONFIG, &config);
4586 [ # # ]: 0 : if (ret < 0) {
4587 : 0 : DRM_ERROR("Failed to read TMDS config: %d\n", ret);
4588 : 0 : return 0;
4589 : : }
4590 : :
4591 : 0 : if (!!(config & SCDC_TMDS_BIT_CLOCK_RATIO_BY_40) ==
4592 [ # # ]: 0 : crtc_state->hdmi_high_tmds_clock_ratio &&
4593 : 0 : !!(config & SCDC_SCRAMBLING_ENABLE) ==
4594 [ # # ]: 0 : crtc_state->hdmi_scrambling)
4595 : : return 0;
4596 : :
4597 : : /*
4598 : : * HDMI 2.0 says that one should not send scrambled data
4599 : : * prior to configuring the sink scrambling, and that
4600 : : * TMDS clock/data transmission should be suspended when
4601 : : * changing the TMDS clock rate in the sink. So let's
4602 : : * just do a full modeset here, even though some sinks
4603 : : * would be perfectly happy if were to just reconfigure
4604 : : * the SCDC settings on the fly.
4605 : : */
4606 : 0 : return modeset_pipe(&crtc->base, ctx);
4607 : : }
4608 : :
4609 : : static enum intel_hotplug_state
4610 : 0 : intel_ddi_hotplug(struct intel_encoder *encoder,
4611 : : struct intel_connector *connector,
4612 : : bool irq_received)
4613 : : {
4614 [ # # ]: 0 : struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
4615 : 0 : struct drm_modeset_acquire_ctx ctx;
4616 : 0 : enum intel_hotplug_state state;
4617 : 0 : int ret;
4618 : :
4619 : 0 : state = intel_encoder_hotplug(encoder, connector, irq_received);
4620 : :
4621 : 0 : drm_modeset_acquire_init(&ctx, 0);
4622 : :
4623 : 0 : for (;;) {
4624 [ # # ]: 0 : if (connector->base.connector_type == DRM_MODE_CONNECTOR_HDMIA)
4625 : 0 : ret = intel_hdmi_reset_link(encoder, &ctx);
4626 : : else
4627 : 0 : ret = intel_dp_retrain_link(encoder, &ctx);
4628 : :
4629 [ # # ]: 0 : if (ret == -EDEADLK) {
4630 : 0 : drm_modeset_backoff(&ctx);
4631 : 0 : continue;
4632 : : }
4633 : :
4634 : 0 : break;
4635 : : }
4636 : :
4637 : 0 : drm_modeset_drop_locks(&ctx);
4638 : 0 : drm_modeset_acquire_fini(&ctx);
4639 [ # # ]: 0 : WARN(ret, "Acquiring modeset locks failed with %i\n", ret);
4640 : :
4641 : : /*
4642 : : * Unpowered type-c dongles can take some time to boot and be
4643 : : * responsible, so here giving some time to those dongles to power up
4644 : : * and then retrying the probe.
4645 : : *
4646 : : * On many platforms the HDMI live state signal is known to be
4647 : : * unreliable, so we can't use it to detect if a sink is connected or
4648 : : * not. Instead we detect if it's connected based on whether we can
4649 : : * read the EDID or not. That in turn has a problem during disconnect,
4650 : : * since the HPD interrupt may be raised before the DDC lines get
4651 : : * disconnected (due to how the required length of DDC vs. HPD
4652 : : * connector pins are specified) and so we'll still be able to get a
4653 : : * valid EDID. To solve this schedule another detection cycle if this
4654 : : * time around we didn't detect any change in the sink's connection
4655 : : * status.
4656 : : */
4657 [ # # ]: 0 : if (state == INTEL_HOTPLUG_UNCHANGED && irq_received &&
4658 [ # # ]: 0 : !dig_port->dp.is_mst)
4659 : 0 : state = INTEL_HOTPLUG_RETRY;
4660 : :
4661 : 0 : return state;
4662 : : }
4663 : :
4664 : : static struct intel_connector *
4665 : 0 : intel_ddi_init_hdmi_connector(struct intel_digital_port *intel_dig_port)
4666 : : {
4667 : 0 : struct intel_connector *connector;
4668 : 0 : enum port port = intel_dig_port->base.port;
4669 : :
4670 : 0 : connector = intel_connector_alloc();
4671 [ # # ]: 0 : if (!connector)
4672 : : return NULL;
4673 : :
4674 : 0 : intel_dig_port->hdmi.hdmi_reg = DDI_BUF_CTL(port);
4675 : 0 : intel_hdmi_init_connector(intel_dig_port, connector);
4676 : :
4677 : 0 : return connector;
4678 : : }
4679 : :
4680 : 0 : static bool intel_ddi_a_force_4_lanes(struct intel_digital_port *dport)
4681 : : {
4682 [ # # ]: 0 : struct drm_i915_private *dev_priv = to_i915(dport->base.base.dev);
4683 : :
4684 [ # # ]: 0 : if (dport->base.port != PORT_A)
4685 : : return false;
4686 : :
4687 [ # # ]: 0 : if (dport->saved_port_bits & DDI_A_4_LANES)
4688 : : return false;
4689 : :
4690 : : /* Broxton/Geminilake: Bspec says that DDI_A_4_LANES is the only
4691 : : * supported configuration
4692 : : */
4693 [ # # # # ]: 0 : if (IS_GEN9_LP(dev_priv))
4694 : : return true;
4695 : :
4696 : : /* Cannonlake: Most of SKUs don't support DDI_E, and the only
4697 : : * one who does also have a full A/E split called
4698 : : * DDI_F what makes DDI_E useless. However for this
4699 : : * case let's trust VBT info.
4700 : : */
4701 [ # # # # ]: 0 : if (IS_CANNONLAKE(dev_priv) &&
4702 : 0 : !intel_bios_is_port_present(dev_priv, PORT_E))
4703 : 0 : return true;
4704 : :
4705 : : return false;
4706 : : }
4707 : :
4708 : : static int
4709 : 0 : intel_ddi_max_lanes(struct intel_digital_port *intel_dport)
4710 : : {
4711 [ # # ]: 0 : struct drm_i915_private *dev_priv = to_i915(intel_dport->base.base.dev);
4712 : 0 : enum port port = intel_dport->base.port;
4713 : 0 : int max_lanes = 4;
4714 : :
4715 [ # # ]: 0 : if (INTEL_GEN(dev_priv) >= 11)
4716 : : return max_lanes;
4717 : :
4718 [ # # ]: 0 : if (port == PORT_A || port == PORT_E) {
4719 [ # # ]: 0 : if (I915_READ(DDI_BUF_CTL(PORT_A)) & DDI_A_4_LANES)
4720 [ # # ]: 0 : max_lanes = port == PORT_A ? 4 : 0;
4721 : : else
4722 : : /* Both A and E share 2 lanes */
4723 : : max_lanes = 2;
4724 : : }
4725 : :
4726 : : /*
4727 : : * Some BIOS might fail to set this bit on port A if eDP
4728 : : * wasn't lit up at boot. Force this bit set when needed
4729 : : * so we use the proper lane count for our calculations.
4730 : : */
4731 [ # # ]: 0 : if (intel_ddi_a_force_4_lanes(intel_dport)) {
4732 : 0 : DRM_DEBUG_KMS("Forcing DDI_A_4_LANES for port A\n");
4733 : 0 : intel_dport->saved_port_bits |= DDI_A_4_LANES;
4734 : 0 : max_lanes = 4;
4735 : : }
4736 : :
4737 : : return max_lanes;
4738 : : }
4739 : :
4740 : 0 : void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
4741 : : {
4742 : 0 : struct ddi_vbt_port_info *port_info =
4743 : : &dev_priv->vbt.ddi_port_info[port];
4744 : 0 : struct intel_digital_port *intel_dig_port;
4745 : 0 : struct intel_encoder *encoder;
4746 : 0 : bool init_hdmi, init_dp, init_lspcon = false;
4747 : 0 : enum phy phy = intel_port_to_phy(dev_priv, port);
4748 : :
4749 : 0 : init_hdmi = port_info->supports_dvi || port_info->supports_hdmi;
4750 : 0 : init_dp = port_info->supports_dp;
4751 : :
4752 [ # # ]: 0 : if (intel_bios_is_lspcon_present(dev_priv, port)) {
4753 : : /*
4754 : : * Lspcon device needs to be driven with DP connector
4755 : : * with special detection sequence. So make sure DP
4756 : : * is initialized before lspcon.
4757 : : */
4758 : 0 : init_dp = true;
4759 : 0 : init_lspcon = true;
4760 : 0 : init_hdmi = false;
4761 : 0 : DRM_DEBUG_KMS("VBT says port %c has lspcon\n", port_name(port));
4762 : : }
4763 : :
4764 [ # # ]: 0 : if (!init_dp && !init_hdmi) {
4765 : 0 : DRM_DEBUG_KMS("VBT says port %c is not DVI/HDMI/DP compatible, respect it\n",
4766 : : port_name(port));
4767 : 0 : return;
4768 : : }
4769 : :
4770 : 0 : intel_dig_port = kzalloc(sizeof(*intel_dig_port), GFP_KERNEL);
4771 [ # # ]: 0 : if (!intel_dig_port)
4772 : : return;
4773 : :
4774 : 0 : encoder = &intel_dig_port->base;
4775 : :
4776 : 0 : drm_encoder_init(&dev_priv->drm, &encoder->base, &intel_ddi_funcs,
4777 : : DRM_MODE_ENCODER_TMDS, "DDI %c", port_name(port));
4778 : :
4779 : 0 : encoder->hotplug = intel_ddi_hotplug;
4780 : 0 : encoder->compute_output_type = intel_ddi_compute_output_type;
4781 : 0 : encoder->compute_config = intel_ddi_compute_config;
4782 : 0 : encoder->enable = intel_enable_ddi;
4783 : 0 : encoder->pre_pll_enable = intel_ddi_pre_pll_enable;
4784 : 0 : encoder->pre_enable = intel_ddi_pre_enable;
4785 : 0 : encoder->disable = intel_disable_ddi;
4786 : 0 : encoder->post_disable = intel_ddi_post_disable;
4787 : 0 : encoder->update_pipe = intel_ddi_update_pipe;
4788 : 0 : encoder->get_hw_state = intel_ddi_get_hw_state;
4789 : 0 : encoder->get_config = intel_ddi_get_config;
4790 : 0 : encoder->suspend = intel_dp_encoder_suspend;
4791 : 0 : encoder->get_power_domains = intel_ddi_get_power_domains;
4792 : :
4793 : 0 : encoder->type = INTEL_OUTPUT_DDI;
4794 : 0 : encoder->power_domain = intel_port_to_power_domain(port);
4795 : 0 : encoder->port = port;
4796 : 0 : encoder->cloneable = 0;
4797 : 0 : encoder->pipe_mask = ~0;
4798 : :
4799 [ # # ]: 0 : if (INTEL_GEN(dev_priv) >= 11)
4800 : 0 : intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) &
4801 : : DDI_BUF_PORT_REVERSAL;
4802 : : else
4803 : 0 : intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) &
4804 : : (DDI_BUF_PORT_REVERSAL | DDI_A_4_LANES);
4805 : :
4806 : 0 : intel_dig_port->dp.output_reg = INVALID_MMIO_REG;
4807 : 0 : intel_dig_port->max_lanes = intel_ddi_max_lanes(intel_dig_port);
4808 : 0 : intel_dig_port->aux_ch = intel_bios_port_aux_ch(dev_priv, port);
4809 : :
4810 [ # # ]: 0 : if (intel_phy_is_tc(dev_priv, phy)) {
4811 : 0 : bool is_legacy = !port_info->supports_typec_usb &&
4812 : : !port_info->supports_tbt;
4813 : :
4814 : 0 : intel_tc_port_init(intel_dig_port, is_legacy);
4815 : :
4816 : 0 : encoder->update_prepare = intel_ddi_update_prepare;
4817 : 0 : encoder->update_complete = intel_ddi_update_complete;
4818 : : }
4819 : :
4820 [ # # ]: 0 : WARN_ON(port > PORT_I);
4821 : 0 : intel_dig_port->ddi_io_power_domain = POWER_DOMAIN_PORT_DDI_A_IO +
4822 : 0 : port - PORT_A;
4823 : :
4824 [ # # ]: 0 : if (init_dp) {
4825 [ # # ]: 0 : if (!intel_ddi_init_dp_connector(intel_dig_port))
4826 : 0 : goto err;
4827 : :
4828 : 0 : intel_dig_port->hpd_pulse = intel_dp_hpd_pulse;
4829 : : }
4830 : :
4831 : : /* In theory we don't need the encoder->type check, but leave it just in
4832 : : * case we have some really bad VBTs... */
4833 [ # # # # ]: 0 : if (encoder->type != INTEL_OUTPUT_EDP && init_hdmi) {
4834 [ # # ]: 0 : if (!intel_ddi_init_hdmi_connector(intel_dig_port))
4835 : 0 : goto err;
4836 : : }
4837 : :
4838 [ # # ]: 0 : if (init_lspcon) {
4839 [ # # ]: 0 : if (lspcon_init(intel_dig_port))
4840 : : /* TODO: handle hdmi info frame part */
4841 : 0 : DRM_DEBUG_KMS("LSPCON init success on port %c\n",
4842 : : port_name(port));
4843 : : else
4844 : : /*
4845 : : * LSPCON init faied, but DP init was success, so
4846 : : * lets try to drive as DP++ port.
4847 : : */
4848 : 0 : DRM_ERROR("LSPCON init failed on port %c\n",
4849 : : port_name(port));
4850 : : }
4851 : :
4852 : 0 : intel_infoframe_init(intel_dig_port);
4853 : :
4854 : 0 : return;
4855 : :
4856 : 0 : err:
4857 : 0 : drm_encoder_cleanup(&encoder->base);
4858 : 0 : kfree(intel_dig_port);
4859 : : }
|