File: | dev/pci/drm/i915/display/intel_dp.c |
Warning: | line 2205, column 27 Value stored to 'i915' during its initialization is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* |
2 | * Copyright © 2008 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 | * Keith Packard <keithp@keithp.com> |
25 | * |
26 | */ |
27 | |
28 | #include <linux/export.h> |
29 | #include <linux/i2c.h> |
30 | #include <linux/notifier.h> |
31 | #include <linux/slab.h> |
32 | #include <linux/string_helpers.h> |
33 | #include <linux/timekeeping.h> |
34 | #include <linux/types.h> |
35 | |
36 | #include <asm/byteorder.h> |
37 | |
38 | #include <drm/display/drm_dp_helper.h> |
39 | #include <drm/display/drm_dsc_helper.h> |
40 | #include <drm/display/drm_hdmi_helper.h> |
41 | #include <drm/drm_atomic_helper.h> |
42 | #include <drm/drm_crtc.h> |
43 | #include <drm/drm_edid.h> |
44 | #include <drm/drm_probe_helper.h> |
45 | |
46 | #include "g4x_dp.h" |
47 | #include "i915_debugfs.h" |
48 | #include "i915_drv.h" |
49 | #include "intel_atomic.h" |
50 | #include "intel_audio.h" |
51 | #include "intel_backlight.h" |
52 | #include "intel_combo_phy_regs.h" |
53 | #include "intel_connector.h" |
54 | #include "intel_crtc.h" |
55 | #include "intel_ddi.h" |
56 | #include "intel_de.h" |
57 | #include "intel_display_types.h" |
58 | #include "intel_dp.h" |
59 | #include "intel_dp_aux.h" |
60 | #include "intel_dp_hdcp.h" |
61 | #include "intel_dp_link_training.h" |
62 | #include "intel_dp_mst.h" |
63 | #include "intel_dpio_phy.h" |
64 | #include "intel_dpll.h" |
65 | #include "intel_fifo_underrun.h" |
66 | #include "intel_hdcp.h" |
67 | #include "intel_hdmi.h" |
68 | #include "intel_hotplug.h" |
69 | #include "intel_lspcon.h" |
70 | #include "intel_lvds.h" |
71 | #include "intel_panel.h" |
72 | #include "intel_pch_display.h" |
73 | #include "intel_pps.h" |
74 | #include "intel_psr.h" |
75 | #include "intel_tc.h" |
76 | #include "intel_vdsc.h" |
77 | #include "intel_vrr.h" |
78 | |
79 | /* DP DSC throughput values used for slice count calculations KPixels/s */ |
80 | #define DP_DSC_PEAK_PIXEL_RATE2720000 2720000 |
81 | #define DP_DSC_MAX_ENC_THROUGHPUT_0340000 340000 |
82 | #define DP_DSC_MAX_ENC_THROUGHPUT_1400000 400000 |
83 | |
84 | /* DP DSC FEC Overhead factor = 1/(0.972261) */ |
85 | #define DP_DSC_FEC_OVERHEAD_FACTOR972261 972261 |
86 | |
87 | /* Compliance test status bits */ |
88 | #define INTEL_DP_RESOLUTION_SHIFT_MASK0 0 |
89 | #define INTEL_DP_RESOLUTION_PREFERRED(1 << 0) (1 << INTEL_DP_RESOLUTION_SHIFT_MASK0) |
90 | #define INTEL_DP_RESOLUTION_STANDARD(2 << 0) (2 << INTEL_DP_RESOLUTION_SHIFT_MASK0) |
91 | #define INTEL_DP_RESOLUTION_FAILSAFE(3 << 0) (3 << INTEL_DP_RESOLUTION_SHIFT_MASK0) |
92 | |
93 | |
94 | /* Constants for DP DSC configurations */ |
95 | static const u8 valid_dsc_bpp[] = {6, 8, 10, 12, 15}; |
96 | |
97 | /* With Single pipe configuration, HW is capable of supporting maximum |
98 | * of 4 slices per line. |
99 | */ |
100 | static const u8 valid_dsc_slicecount[] = {1, 2, 4}; |
101 | |
102 | /** |
103 | * intel_dp_is_edp - is the given port attached to an eDP panel (either CPU or PCH) |
104 | * @intel_dp: DP struct |
105 | * |
106 | * If a CPU or PCH DP output is attached to an eDP panel, this function |
107 | * will return true, and false otherwise. |
108 | * |
109 | * This function is not safe to use prior to encoder type being set. |
110 | */ |
111 | bool_Bool intel_dp_is_edp(struct intel_dp *intel_dp) |
112 | { |
113 | struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); |
114 | |
115 | return dig_port->base.type == INTEL_OUTPUT_EDP; |
116 | } |
117 | |
118 | static void intel_dp_unset_edid(struct intel_dp *intel_dp); |
119 | static int intel_dp_dsc_compute_bpp(struct intel_dp *intel_dp, u8 dsc_max_bpc); |
120 | |
121 | /* Is link rate UHBR and thus 128b/132b? */ |
122 | bool_Bool intel_dp_is_uhbr(const struct intel_crtc_state *crtc_state) |
123 | { |
124 | return crtc_state->port_clock >= 1000000; |
125 | } |
126 | |
127 | static void intel_dp_set_default_sink_rates(struct intel_dp *intel_dp) |
128 | { |
129 | intel_dp->sink_rates[0] = 162000; |
130 | intel_dp->num_sink_rates = 1; |
131 | } |
132 | |
133 | /* update sink rates from dpcd */ |
134 | static void intel_dp_set_dpcd_sink_rates(struct intel_dp *intel_dp) |
135 | { |
136 | static const int dp_rates[] = { |
137 | 162000, 270000, 540000, 810000 |
138 | }; |
139 | int i, max_rate; |
140 | int max_lttpr_rate; |
141 | |
142 | if (drm_dp_has_quirk(&intel_dp->desc, DP_DPCD_QUIRK_CAN_DO_MAX_LINK_RATE_3_24_GBPS)) { |
143 | /* Needed, e.g., for Apple MBP 2017, 15 inch eDP Retina panel */ |
144 | static const int quirk_rates[] = { 162000, 270000, 324000 }; |
145 | |
146 | memcpy(intel_dp->sink_rates, quirk_rates, sizeof(quirk_rates))__builtin_memcpy((intel_dp->sink_rates), (quirk_rates), (sizeof (quirk_rates))); |
147 | intel_dp->num_sink_rates = ARRAY_SIZE(quirk_rates)(sizeof((quirk_rates)) / sizeof((quirk_rates)[0])); |
148 | |
149 | return; |
150 | } |
151 | |
152 | /* |
153 | * Sink rates for 8b/10b. |
154 | */ |
155 | max_rate = drm_dp_bw_code_to_link_rate(intel_dp->dpcd[DP_MAX_LINK_RATE0x001]); |
156 | max_lttpr_rate = drm_dp_lttpr_max_link_rate(intel_dp->lttpr_common_caps); |
157 | if (max_lttpr_rate) |
158 | max_rate = min(max_rate, max_lttpr_rate)(((max_rate)<(max_lttpr_rate))?(max_rate):(max_lttpr_rate) ); |
159 | |
160 | for (i = 0; i < ARRAY_SIZE(dp_rates)(sizeof((dp_rates)) / sizeof((dp_rates)[0])); i++) { |
161 | if (dp_rates[i] > max_rate) |
162 | break; |
163 | intel_dp->sink_rates[i] = dp_rates[i]; |
164 | } |
165 | |
166 | /* |
167 | * Sink rates for 128b/132b. If set, sink should support all 8b/10b |
168 | * rates and 10 Gbps. |
169 | */ |
170 | if (intel_dp->dpcd[DP_MAIN_LINK_CHANNEL_CODING0x006] & DP_CAP_ANSI_128B132B(1 << 1)) { |
171 | u8 uhbr_rates = 0; |
172 | |
173 | BUILD_BUG_ON(ARRAY_SIZE(intel_dp->sink_rates) < ARRAY_SIZE(dp_rates) + 3)extern char _ctassert[(!((sizeof((intel_dp->sink_rates)) / sizeof((intel_dp->sink_rates)[0])) < (sizeof((dp_rates )) / sizeof((dp_rates)[0])) + 3)) ? 1 : -1 ] __attribute__((__unused__ )); |
174 | |
175 | drm_dp_dpcd_readb(&intel_dp->aux, |
176 | DP_128B132B_SUPPORTED_LINK_RATES0x2215, &uhbr_rates); |
177 | |
178 | if (drm_dp_lttpr_count(intel_dp->lttpr_common_caps)) { |
179 | /* We have a repeater */ |
180 | if (intel_dp->lttpr_common_caps[0] >= 0x20 && |
181 | intel_dp->lttpr_common_caps[DP_MAIN_LINK_CHANNEL_CODING_PHY_REPEATER0xf0006 - |
182 | DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV0xf0000] & |
183 | DP_PHY_REPEATER_128B132B_SUPPORTED(1 << 0)) { |
184 | /* Repeater supports 128b/132b, valid UHBR rates */ |
185 | uhbr_rates &= intel_dp->lttpr_common_caps[DP_PHY_REPEATER_128B132B_RATES0xf0007 - |
186 | DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV0xf0000]; |
187 | } else { |
188 | /* Does not support 128b/132b */ |
189 | uhbr_rates = 0; |
190 | } |
191 | } |
192 | |
193 | if (uhbr_rates & DP_UHBR10(1 << 0)) |
194 | intel_dp->sink_rates[i++] = 1000000; |
195 | if (uhbr_rates & DP_UHBR13_5(1 << 2)) |
196 | intel_dp->sink_rates[i++] = 1350000; |
197 | if (uhbr_rates & DP_UHBR20(1 << 1)) |
198 | intel_dp->sink_rates[i++] = 2000000; |
199 | } |
200 | |
201 | intel_dp->num_sink_rates = i; |
202 | } |
203 | |
204 | static void intel_dp_set_sink_rates(struct intel_dp *intel_dp) |
205 | { |
206 | struct intel_connector *connector = intel_dp->attached_connector; |
207 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); |
208 | struct intel_encoder *encoder = &intel_dig_port->base; |
209 | |
210 | intel_dp_set_dpcd_sink_rates(intel_dp); |
211 | |
212 | if (intel_dp->num_sink_rates) |
213 | return; |
214 | |
215 | drm_err(&dp_to_i915(intel_dp)->drm,printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "[CONNECTOR:%d:%s][ENCODER:%d:%s] Invalid DPCD with no link rates, using defaults\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , connector ->base.base.id, connector->base.name, encoder->base. base.id, encoder->base.name) |
216 | "[CONNECTOR:%d:%s][ENCODER:%d:%s] Invalid DPCD with no link rates, using defaults\n",printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "[CONNECTOR:%d:%s][ENCODER:%d:%s] Invalid DPCD with no link rates, using defaults\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , connector ->base.base.id, connector->base.name, encoder->base. base.id, encoder->base.name) |
217 | connector->base.base.id, connector->base.name,printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "[CONNECTOR:%d:%s][ENCODER:%d:%s] Invalid DPCD with no link rates, using defaults\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , connector ->base.base.id, connector->base.name, encoder->base. base.id, encoder->base.name) |
218 | encoder->base.base.id, encoder->base.name)printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "[CONNECTOR:%d:%s][ENCODER:%d:%s] Invalid DPCD with no link rates, using defaults\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , connector ->base.base.id, connector->base.name, encoder->base. base.id, encoder->base.name); |
219 | |
220 | intel_dp_set_default_sink_rates(intel_dp); |
221 | } |
222 | |
223 | static void intel_dp_set_default_max_sink_lane_count(struct intel_dp *intel_dp) |
224 | { |
225 | intel_dp->max_sink_lane_count = 1; |
226 | } |
227 | |
228 | static void intel_dp_set_max_sink_lane_count(struct intel_dp *intel_dp) |
229 | { |
230 | struct intel_connector *connector = intel_dp->attached_connector; |
231 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); |
232 | struct intel_encoder *encoder = &intel_dig_port->base; |
233 | |
234 | intel_dp->max_sink_lane_count = drm_dp_max_lane_count(intel_dp->dpcd); |
235 | |
236 | switch (intel_dp->max_sink_lane_count) { |
237 | case 1: |
238 | case 2: |
239 | case 4: |
240 | return; |
241 | } |
242 | |
243 | drm_err(&dp_to_i915(intel_dp)->drm,printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "[CONNECTOR:%d:%s][ENCODER:%d:%s] Invalid DPCD max lane count (%d), using default\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , connector ->base.base.id, connector->base.name, encoder->base. base.id, encoder->base.name, intel_dp->max_sink_lane_count ) |
244 | "[CONNECTOR:%d:%s][ENCODER:%d:%s] Invalid DPCD max lane count (%d), using default\n",printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "[CONNECTOR:%d:%s][ENCODER:%d:%s] Invalid DPCD max lane count (%d), using default\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , connector ->base.base.id, connector->base.name, encoder->base. base.id, encoder->base.name, intel_dp->max_sink_lane_count ) |
245 | connector->base.base.id, connector->base.name,printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "[CONNECTOR:%d:%s][ENCODER:%d:%s] Invalid DPCD max lane count (%d), using default\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , connector ->base.base.id, connector->base.name, encoder->base. base.id, encoder->base.name, intel_dp->max_sink_lane_count ) |
246 | encoder->base.base.id, encoder->base.name,printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "[CONNECTOR:%d:%s][ENCODER:%d:%s] Invalid DPCD max lane count (%d), using default\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , connector ->base.base.id, connector->base.name, encoder->base. base.id, encoder->base.name, intel_dp->max_sink_lane_count ) |
247 | intel_dp->max_sink_lane_count)printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "[CONNECTOR:%d:%s][ENCODER:%d:%s] Invalid DPCD max lane count (%d), using default\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , connector ->base.base.id, connector->base.name, encoder->base. base.id, encoder->base.name, intel_dp->max_sink_lane_count ); |
248 | |
249 | intel_dp_set_default_max_sink_lane_count(intel_dp); |
250 | } |
251 | |
252 | /* Get length of rates array potentially limited by max_rate. */ |
253 | static int intel_dp_rate_limit_len(const int *rates, int len, int max_rate) |
254 | { |
255 | int i; |
256 | |
257 | /* Limit results by potentially reduced max rate */ |
258 | for (i = 0; i < len; i++) { |
259 | if (rates[len - i - 1] <= max_rate) |
260 | return len - i; |
261 | } |
262 | |
263 | return 0; |
264 | } |
265 | |
266 | /* Get length of common rates array potentially limited by max_rate. */ |
267 | static int intel_dp_common_len_rate_limit(const struct intel_dp *intel_dp, |
268 | int max_rate) |
269 | { |
270 | return intel_dp_rate_limit_len(intel_dp->common_rates, |
271 | intel_dp->num_common_rates, max_rate); |
272 | } |
273 | |
274 | static int intel_dp_common_rate(struct intel_dp *intel_dp, int index) |
275 | { |
276 | if (drm_WARN_ON(&dp_to_i915(intel_dp)->drm,({ int __ret = !!((index < 0 || index >= intel_dp->num_common_rates )); if (__ret) printf("%s %s: " "%s", dev_driver_string(((& to_i915(dp_to_dig_port(intel_dp)->base.base.dev)->drm)) ->dev), "", "drm_WARN_ON(" "index < 0 || index >= intel_dp->num_common_rates" ")"); __builtin_expect(!!(__ret), 0); }) |
277 | index < 0 || index >= intel_dp->num_common_rates)({ int __ret = !!((index < 0 || index >= intel_dp->num_common_rates )); if (__ret) printf("%s %s: " "%s", dev_driver_string(((& to_i915(dp_to_dig_port(intel_dp)->base.base.dev)->drm)) ->dev), "", "drm_WARN_ON(" "index < 0 || index >= intel_dp->num_common_rates" ")"); __builtin_expect(!!(__ret), 0); })) |
278 | return 162000; |
279 | |
280 | return intel_dp->common_rates[index]; |
281 | } |
282 | |
283 | /* Theoretical max between source and sink */ |
284 | static int intel_dp_max_common_rate(struct intel_dp *intel_dp) |
285 | { |
286 | return intel_dp_common_rate(intel_dp, intel_dp->num_common_rates - 1); |
287 | } |
288 | |
289 | static int intel_dp_max_source_lane_count(struct intel_digital_port *dig_port) |
290 | { |
291 | int vbt_max_lanes = intel_bios_dp_max_lane_count(&dig_port->base); |
292 | int max_lanes = dig_port->max_lanes; |
293 | |
294 | if (vbt_max_lanes) |
295 | max_lanes = min(max_lanes, vbt_max_lanes)(((max_lanes)<(vbt_max_lanes))?(max_lanes):(vbt_max_lanes) ); |
296 | |
297 | return max_lanes; |
298 | } |
299 | |
300 | /* Theoretical max between source and sink */ |
301 | static int intel_dp_max_common_lane_count(struct intel_dp *intel_dp) |
302 | { |
303 | struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); |
304 | int source_max = intel_dp_max_source_lane_count(dig_port); |
305 | int sink_max = intel_dp->max_sink_lane_count; |
306 | int fia_max = intel_tc_port_fia_max_lane_count(dig_port); |
307 | int lttpr_max = drm_dp_lttpr_max_lane_count(intel_dp->lttpr_common_caps); |
308 | |
309 | if (lttpr_max) |
310 | sink_max = min(sink_max, lttpr_max)(((sink_max)<(lttpr_max))?(sink_max):(lttpr_max)); |
311 | |
312 | return min3(source_max, sink_max, fia_max)(((source_max)<((((sink_max)<(fia_max))?(sink_max):(fia_max ))))?(source_max):((((sink_max)<(fia_max))?(sink_max):(fia_max )))); |
313 | } |
314 | |
315 | int intel_dp_max_lane_count(struct intel_dp *intel_dp) |
316 | { |
317 | switch (intel_dp->max_link_lane_count) { |
318 | case 1: |
319 | case 2: |
320 | case 4: |
321 | return intel_dp->max_link_lane_count; |
322 | default: |
323 | MISSING_CASE(intel_dp->max_link_lane_count)({ int __ret = !!(1); if (__ret) printf("Missing case (%s == %ld)\n" , "intel_dp->max_link_lane_count", (long)(intel_dp->max_link_lane_count )); __builtin_expect(!!(__ret), 0); }); |
324 | return 1; |
325 | } |
326 | } |
327 | |
328 | /* |
329 | * The required data bandwidth for a mode with given pixel clock and bpp. This |
330 | * is the required net bandwidth independent of the data bandwidth efficiency. |
331 | */ |
332 | int |
333 | intel_dp_link_required(int pixel_clock, int bpp) |
334 | { |
335 | /* pixel_clock is in kHz, divide bpp by 8 for bit to Byte conversion */ |
336 | return DIV_ROUND_UP(pixel_clock * bpp, 8)(((pixel_clock * bpp) + ((8) - 1)) / (8)); |
337 | } |
338 | |
339 | /* |
340 | * Given a link rate and lanes, get the data bandwidth. |
341 | * |
342 | * Data bandwidth is the actual payload rate, which depends on the data |
343 | * bandwidth efficiency and the link rate. |
344 | * |
345 | * For 8b/10b channel encoding, SST and non-FEC, the data bandwidth efficiency |
346 | * is 80%. For example, for a 1.62 Gbps link, 1.62*10^9 bps * 0.80 * (1/8) = |
347 | * 162000 kBps. With 8-bit symbols, we have 162000 kHz symbol clock. Just by |
348 | * coincidence, the port clock in kHz matches the data bandwidth in kBps, and |
349 | * they equal the link bit rate in Gbps multiplied by 100000. (Note that this no |
350 | * longer holds for data bandwidth as soon as FEC or MST is taken into account!) |
351 | * |
352 | * For 128b/132b channel encoding, the data bandwidth efficiency is 96.71%. For |
353 | * example, for a 10 Gbps link, 10*10^9 bps * 0.9671 * (1/8) = 1208875 |
354 | * kBps. With 32-bit symbols, we have 312500 kHz symbol clock. The value 1000000 |
355 | * does not match the symbol clock, the port clock (not even if you think in |
356 | * terms of a byte clock), nor the data bandwidth. It only matches the link bit |
357 | * rate in units of 10000 bps. |
358 | */ |
359 | int |
360 | intel_dp_max_data_rate(int max_link_rate, int max_lanes) |
361 | { |
362 | if (max_link_rate >= 1000000) { |
363 | /* |
364 | * UHBR rates always use 128b/132b channel encoding, and have |
365 | * 97.71% data bandwidth efficiency. Consider max_link_rate the |
366 | * link bit rate in units of 10000 bps. |
367 | */ |
368 | int max_link_rate_kbps = max_link_rate * 10; |
369 | |
370 | max_link_rate_kbps = DIV_ROUND_CLOSEST_ULL(mul_u32_u32(max_link_rate_kbps, 9671), 10000)(((mul_u32_u32(max_link_rate_kbps, 9671)) + ((10000) / 2)) / ( 10000)); |
371 | max_link_rate = max_link_rate_kbps / 8; |
372 | } |
373 | |
374 | /* |
375 | * Lower than UHBR rates always use 8b/10b channel encoding, and have |
376 | * 80% data bandwidth efficiency for SST non-FEC. However, this turns |
377 | * out to be a nop by coincidence, and can be skipped: |
378 | * |
379 | * int max_link_rate_kbps = max_link_rate * 10; |
380 | * max_link_rate_kbps = DIV_ROUND_CLOSEST_ULL(max_link_rate_kbps * 8, 10); |
381 | * max_link_rate = max_link_rate_kbps / 8; |
382 | */ |
383 | |
384 | return max_link_rate * max_lanes; |
385 | } |
386 | |
387 | bool_Bool intel_dp_can_bigjoiner(struct intel_dp *intel_dp) |
388 | { |
389 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); |
390 | struct intel_encoder *encoder = &intel_dig_port->base; |
391 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
392 | |
393 | return DISPLAY_VER(dev_priv)((&(dev_priv)->__runtime)->display.ip.ver) >= 12 || |
394 | (DISPLAY_VER(dev_priv)((&(dev_priv)->__runtime)->display.ip.ver) == 11 && |
395 | encoder->port != PORT_A); |
396 | } |
397 | |
398 | static int dg2_max_source_rate(struct intel_dp *intel_dp) |
399 | { |
400 | return intel_dp_is_edp(intel_dp) ? 810000 : 1350000; |
401 | } |
402 | |
403 | static int icl_max_source_rate(struct intel_dp *intel_dp) |
404 | { |
405 | struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); |
406 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(dig_port->base.base.dev); |
407 | enum phy phy = intel_port_to_phy(dev_priv, dig_port->base.port); |
408 | |
409 | if (intel_phy_is_combo(dev_priv, phy) && !intel_dp_is_edp(intel_dp)) |
410 | return 540000; |
411 | |
412 | return 810000; |
413 | } |
414 | |
415 | static int ehl_max_source_rate(struct intel_dp *intel_dp) |
416 | { |
417 | if (intel_dp_is_edp(intel_dp)) |
418 | return 540000; |
419 | |
420 | return 810000; |
421 | } |
422 | |
423 | static int vbt_max_link_rate(struct intel_dp *intel_dp) |
424 | { |
425 | struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; |
426 | int max_rate; |
427 | |
428 | max_rate = intel_bios_dp_max_link_rate(encoder); |
429 | |
430 | if (intel_dp_is_edp(intel_dp)) { |
431 | struct intel_connector *connector = intel_dp->attached_connector; |
432 | int edp_max_rate = connector->panel.vbt.edp.max_link_rate; |
433 | |
434 | if (max_rate && edp_max_rate) |
435 | max_rate = min(max_rate, edp_max_rate)(((max_rate)<(edp_max_rate))?(max_rate):(edp_max_rate)); |
436 | else if (edp_max_rate) |
437 | max_rate = edp_max_rate; |
438 | } |
439 | |
440 | return max_rate; |
441 | } |
442 | |
443 | static void |
444 | intel_dp_set_source_rates(struct intel_dp *intel_dp) |
445 | { |
446 | /* The values must be in increasing order */ |
447 | static const int icl_rates[] = { |
448 | 162000, 216000, 270000, 324000, 432000, 540000, 648000, 810000, |
449 | 1000000, 1350000, |
450 | }; |
451 | static const int bxt_rates[] = { |
452 | 162000, 216000, 243000, 270000, 324000, 432000, 540000 |
453 | }; |
454 | static const int skl_rates[] = { |
455 | 162000, 216000, 270000, 324000, 432000, 540000 |
456 | }; |
457 | static const int hsw_rates[] = { |
458 | 162000, 270000, 540000 |
459 | }; |
460 | static const int g4x_rates[] = { |
461 | 162000, 270000 |
462 | }; |
463 | struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); |
464 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(dig_port->base.base.dev); |
465 | const int *source_rates; |
466 | int size, max_rate = 0, vbt_max_rate; |
467 | |
468 | /* This should only be done once */ |
469 | drm_WARN_ON(&dev_priv->drm,({ int __ret = !!((intel_dp->source_rates || intel_dp-> num_source_rates)); if (__ret) printf("%s %s: " "%s", dev_driver_string (((&dev_priv->drm))->dev), "", "drm_WARN_ON(" "intel_dp->source_rates || intel_dp->num_source_rates" ")"); __builtin_expect(!!(__ret), 0); }) |
470 | intel_dp->source_rates || intel_dp->num_source_rates)({ int __ret = !!((intel_dp->source_rates || intel_dp-> num_source_rates)); if (__ret) printf("%s %s: " "%s", dev_driver_string (((&dev_priv->drm))->dev), "", "drm_WARN_ON(" "intel_dp->source_rates || intel_dp->num_source_rates" ")"); __builtin_expect(!!(__ret), 0); }); |
471 | |
472 | if (DISPLAY_VER(dev_priv)((&(dev_priv)->__runtime)->display.ip.ver) >= 11) { |
473 | source_rates = icl_rates; |
474 | size = ARRAY_SIZE(icl_rates)(sizeof((icl_rates)) / sizeof((icl_rates)[0])); |
475 | if (IS_DG2(dev_priv)IS_PLATFORM(dev_priv, INTEL_DG2)) |
476 | max_rate = dg2_max_source_rate(intel_dp); |
477 | else if (IS_ALDERLAKE_P(dev_priv)IS_PLATFORM(dev_priv, INTEL_ALDERLAKE_P) || IS_ALDERLAKE_S(dev_priv)IS_PLATFORM(dev_priv, INTEL_ALDERLAKE_S) || |
478 | IS_DG1(dev_priv)IS_PLATFORM(dev_priv, INTEL_DG1) || IS_ROCKETLAKE(dev_priv)IS_PLATFORM(dev_priv, INTEL_ROCKETLAKE)) |
479 | max_rate = 810000; |
480 | else if (IS_JSL_EHL(dev_priv)(IS_PLATFORM(dev_priv, INTEL_JASPERLAKE) || IS_PLATFORM(dev_priv , INTEL_ELKHARTLAKE))) |
481 | max_rate = ehl_max_source_rate(intel_dp); |
482 | else |
483 | max_rate = icl_max_source_rate(intel_dp); |
484 | } else if (IS_GEMINILAKE(dev_priv)IS_PLATFORM(dev_priv, INTEL_GEMINILAKE) || IS_BROXTON(dev_priv)IS_PLATFORM(dev_priv, INTEL_BROXTON)) { |
485 | source_rates = bxt_rates; |
486 | size = ARRAY_SIZE(bxt_rates)(sizeof((bxt_rates)) / sizeof((bxt_rates)[0])); |
487 | } else if (DISPLAY_VER(dev_priv)((&(dev_priv)->__runtime)->display.ip.ver) == 9) { |
488 | source_rates = skl_rates; |
489 | size = ARRAY_SIZE(skl_rates)(sizeof((skl_rates)) / sizeof((skl_rates)[0])); |
490 | } else if ((IS_HASWELL(dev_priv)IS_PLATFORM(dev_priv, INTEL_HASWELL) && !IS_HSW_ULX(dev_priv)IS_SUBPLATFORM(dev_priv, INTEL_HASWELL, (1))) || |
491 | IS_BROADWELL(dev_priv)IS_PLATFORM(dev_priv, INTEL_BROADWELL)) { |
492 | source_rates = hsw_rates; |
493 | size = ARRAY_SIZE(hsw_rates)(sizeof((hsw_rates)) / sizeof((hsw_rates)[0])); |
494 | } else { |
495 | source_rates = g4x_rates; |
496 | size = ARRAY_SIZE(g4x_rates)(sizeof((g4x_rates)) / sizeof((g4x_rates)[0])); |
497 | } |
498 | |
499 | vbt_max_rate = vbt_max_link_rate(intel_dp); |
500 | if (max_rate && vbt_max_rate) |
501 | max_rate = min(max_rate, vbt_max_rate)(((max_rate)<(vbt_max_rate))?(max_rate):(vbt_max_rate)); |
502 | else if (vbt_max_rate) |
503 | max_rate = vbt_max_rate; |
504 | |
505 | if (max_rate) |
506 | size = intel_dp_rate_limit_len(source_rates, size, max_rate); |
507 | |
508 | intel_dp->source_rates = source_rates; |
509 | intel_dp->num_source_rates = size; |
510 | } |
511 | |
512 | static int intersect_rates(const int *source_rates, int source_len, |
513 | const int *sink_rates, int sink_len, |
514 | int *common_rates) |
515 | { |
516 | int i = 0, j = 0, k = 0; |
517 | |
518 | while (i < source_len && j < sink_len) { |
519 | if (source_rates[i] == sink_rates[j]) { |
520 | if (WARN_ON(k >= DP_MAX_SUPPORTED_RATES)({ int __ret = !!(k >= 8); if (__ret) printf("WARNING %s failed at %s:%d\n" , "k >= 8", "/usr/src/sys/dev/pci/drm/i915/display/intel_dp.c" , 520); __builtin_expect(!!(__ret), 0); })) |
521 | return k; |
522 | common_rates[k] = source_rates[i]; |
523 | ++k; |
524 | ++i; |
525 | ++j; |
526 | } else if (source_rates[i] < sink_rates[j]) { |
527 | ++i; |
528 | } else { |
529 | ++j; |
530 | } |
531 | } |
532 | return k; |
533 | } |
534 | |
535 | /* return index of rate in rates array, or -1 if not found */ |
536 | static int intel_dp_rate_index(const int *rates, int len, int rate) |
537 | { |
538 | int i; |
539 | |
540 | for (i = 0; i < len; i++) |
541 | if (rate == rates[i]) |
542 | return i; |
543 | |
544 | return -1; |
545 | } |
546 | |
547 | static void intel_dp_set_common_rates(struct intel_dp *intel_dp) |
548 | { |
549 | struct drm_i915_privateinteldrm_softc *i915 = dp_to_i915(intel_dp)to_i915(dp_to_dig_port(intel_dp)->base.base.dev); |
550 | |
551 | drm_WARN_ON(&i915->drm,({ int __ret = !!((!intel_dp->num_source_rates || !intel_dp ->num_sink_rates)); if (__ret) printf("%s %s: " "%s", dev_driver_string (((&i915->drm))->dev), "", "drm_WARN_ON(" "!intel_dp->num_source_rates || !intel_dp->num_sink_rates" ")"); __builtin_expect(!!(__ret), 0); }) |
552 | !intel_dp->num_source_rates || !intel_dp->num_sink_rates)({ int __ret = !!((!intel_dp->num_source_rates || !intel_dp ->num_sink_rates)); if (__ret) printf("%s %s: " "%s", dev_driver_string (((&i915->drm))->dev), "", "drm_WARN_ON(" "!intel_dp->num_source_rates || !intel_dp->num_sink_rates" ")"); __builtin_expect(!!(__ret), 0); }); |
553 | |
554 | intel_dp->num_common_rates = intersect_rates(intel_dp->source_rates, |
555 | intel_dp->num_source_rates, |
556 | intel_dp->sink_rates, |
557 | intel_dp->num_sink_rates, |
558 | intel_dp->common_rates); |
559 | |
560 | /* Paranoia, there should always be something in common. */ |
561 | if (drm_WARN_ON(&i915->drm, intel_dp->num_common_rates == 0)({ int __ret = !!((intel_dp->num_common_rates == 0)); if ( __ret) printf("%s %s: " "%s", dev_driver_string(((&i915-> drm))->dev), "", "drm_WARN_ON(" "intel_dp->num_common_rates == 0" ")"); __builtin_expect(!!(__ret), 0); })) { |
562 | intel_dp->common_rates[0] = 162000; |
563 | intel_dp->num_common_rates = 1; |
564 | } |
565 | } |
566 | |
567 | static bool_Bool intel_dp_link_params_valid(struct intel_dp *intel_dp, int link_rate, |
568 | u8 lane_count) |
569 | { |
570 | /* |
571 | * FIXME: we need to synchronize the current link parameters with |
572 | * hardware readout. Currently fast link training doesn't work on |
573 | * boot-up. |
574 | */ |
575 | if (link_rate == 0 || |
576 | link_rate > intel_dp->max_link_rate) |
577 | return false0; |
578 | |
579 | if (lane_count == 0 || |
580 | lane_count > intel_dp_max_lane_count(intel_dp)) |
581 | return false0; |
582 | |
583 | return true1; |
584 | } |
585 | |
586 | static bool_Bool intel_dp_can_link_train_fallback_for_edp(struct intel_dp *intel_dp, |
587 | int link_rate, |
588 | u8 lane_count) |
589 | { |
590 | /* FIXME figure out what we actually want here */ |
591 | const struct drm_display_mode *fixed_mode = |
592 | intel_panel_preferred_fixed_mode(intel_dp->attached_connector); |
593 | int mode_rate, max_rate; |
594 | |
595 | mode_rate = intel_dp_link_required(fixed_mode->clock, 18); |
596 | max_rate = intel_dp_max_data_rate(link_rate, lane_count); |
597 | if (mode_rate > max_rate) |
598 | return false0; |
599 | |
600 | return true1; |
601 | } |
602 | |
603 | int intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp, |
604 | int link_rate, u8 lane_count) |
605 | { |
606 | struct drm_i915_privateinteldrm_softc *i915 = dp_to_i915(intel_dp)to_i915(dp_to_dig_port(intel_dp)->base.base.dev); |
607 | int index; |
608 | |
609 | /* |
610 | * TODO: Enable fallback on MST links once MST link compute can handle |
611 | * the fallback params. |
612 | */ |
613 | if (intel_dp->is_mst) { |
614 | drm_err(&i915->drm, "Link Training Unsuccessful\n")printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "Link Training Unsuccessful\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__); |
615 | return -1; |
616 | } |
617 | |
618 | if (intel_dp_is_edp(intel_dp) && !intel_dp->use_max_params) { |
619 | drm_dbg_kms(&i915->drm,__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "Retrying Link training for eDP with max parameters\n" ) |
620 | "Retrying Link training for eDP with max parameters\n")__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "Retrying Link training for eDP with max parameters\n" ); |
621 | intel_dp->use_max_params = true1; |
622 | return 0; |
623 | } |
624 | |
625 | index = intel_dp_rate_index(intel_dp->common_rates, |
626 | intel_dp->num_common_rates, |
627 | link_rate); |
628 | if (index > 0) { |
629 | if (intel_dp_is_edp(intel_dp) && |
630 | !intel_dp_can_link_train_fallback_for_edp(intel_dp, |
631 | intel_dp_common_rate(intel_dp, index - 1), |
632 | lane_count)) { |
633 | drm_dbg_kms(&i915->drm,__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "Retrying Link training for eDP with same parameters\n" ) |
634 | "Retrying Link training for eDP with same parameters\n")__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "Retrying Link training for eDP with same parameters\n" ); |
635 | return 0; |
636 | } |
637 | intel_dp->max_link_rate = intel_dp_common_rate(intel_dp, index - 1); |
638 | intel_dp->max_link_lane_count = lane_count; |
639 | } else if (lane_count > 1) { |
640 | if (intel_dp_is_edp(intel_dp) && |
641 | !intel_dp_can_link_train_fallback_for_edp(intel_dp, |
642 | intel_dp_max_common_rate(intel_dp), |
643 | lane_count >> 1)) { |
644 | drm_dbg_kms(&i915->drm,__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "Retrying Link training for eDP with same parameters\n" ) |
645 | "Retrying Link training for eDP with same parameters\n")__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "Retrying Link training for eDP with same parameters\n" ); |
646 | return 0; |
647 | } |
648 | intel_dp->max_link_rate = intel_dp_max_common_rate(intel_dp); |
649 | intel_dp->max_link_lane_count = lane_count >> 1; |
650 | } else { |
651 | drm_err(&i915->drm, "Link Training Unsuccessful\n")printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "Link Training Unsuccessful\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__); |
652 | return -1; |
653 | } |
654 | |
655 | return 0; |
656 | } |
657 | |
658 | u32 intel_dp_mode_to_fec_clock(u32 mode_clock) |
659 | { |
660 | return div_u64(mul_u32_u32(mode_clock, 1000000U), |
661 | DP_DSC_FEC_OVERHEAD_FACTOR972261); |
662 | } |
663 | |
664 | static int |
665 | small_joiner_ram_size_bits(struct drm_i915_privateinteldrm_softc *i915) |
666 | { |
667 | if (DISPLAY_VER(i915)((&(i915)->__runtime)->display.ip.ver) >= 13) |
668 | return 17280 * 8; |
669 | else if (DISPLAY_VER(i915)((&(i915)->__runtime)->display.ip.ver) >= 11) |
670 | return 7680 * 8; |
671 | else |
672 | return 6144 * 8; |
673 | } |
674 | |
675 | static u16 intel_dp_dsc_get_output_bpp(struct drm_i915_privateinteldrm_softc *i915, |
676 | u32 link_clock, u32 lane_count, |
677 | u32 mode_clock, u32 mode_hdisplay, |
678 | bool_Bool bigjoiner, |
679 | u32 pipe_bpp) |
680 | { |
681 | u32 bits_per_pixel, max_bpp_small_joiner_ram; |
682 | int i; |
683 | |
684 | /* |
685 | * Available Link Bandwidth(Kbits/sec) = (NumberOfLanes)* |
686 | * (LinkSymbolClock)* 8 * (TimeSlotsPerMTP) |
687 | * for SST -> TimeSlotsPerMTP is 1, |
688 | * for MST -> TimeSlotsPerMTP has to be calculated |
689 | */ |
690 | bits_per_pixel = (link_clock * lane_count * 8) / |
691 | intel_dp_mode_to_fec_clock(mode_clock); |
692 | |
693 | /* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */ |
694 | max_bpp_small_joiner_ram = small_joiner_ram_size_bits(i915) / |
695 | mode_hdisplay; |
696 | |
697 | if (bigjoiner) |
698 | max_bpp_small_joiner_ram *= 2; |
699 | |
700 | /* |
701 | * Greatest allowed DSC BPP = MIN (output BPP from available Link BW |
702 | * check, output bpp from small joiner RAM check) |
703 | */ |
704 | bits_per_pixel = min(bits_per_pixel, max_bpp_small_joiner_ram)(((bits_per_pixel)<(max_bpp_small_joiner_ram))?(bits_per_pixel ):(max_bpp_small_joiner_ram)); |
705 | |
706 | if (bigjoiner) { |
707 | u32 max_bpp_bigjoiner = |
708 | i915->display.cdclk.max_cdclk_freq * 48 / |
709 | intel_dp_mode_to_fec_clock(mode_clock); |
710 | |
711 | bits_per_pixel = min(bits_per_pixel, max_bpp_bigjoiner)(((bits_per_pixel)<(max_bpp_bigjoiner))?(bits_per_pixel):( max_bpp_bigjoiner)); |
712 | } |
713 | |
714 | /* Error out if the max bpp is less than smallest allowed valid bpp */ |
715 | if (bits_per_pixel < valid_dsc_bpp[0]) { |
716 | drm_dbg_kms(&i915->drm, "Unsupported BPP %u, min %u\n",__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "Unsupported BPP %u, min %u\n" , bits_per_pixel, valid_dsc_bpp[0]) |
717 | bits_per_pixel, valid_dsc_bpp[0])__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "Unsupported BPP %u, min %u\n" , bits_per_pixel, valid_dsc_bpp[0]); |
718 | return 0; |
719 | } |
720 | |
721 | /* From XE_LPD onwards we support from bpc upto uncompressed bpp-1 BPPs */ |
722 | if (DISPLAY_VER(i915)((&(i915)->__runtime)->display.ip.ver) >= 13) { |
723 | bits_per_pixel = min(bits_per_pixel, pipe_bpp - 1)(((bits_per_pixel)<(pipe_bpp - 1))?(bits_per_pixel):(pipe_bpp - 1)); |
724 | } else { |
725 | /* Find the nearest match in the array of known BPPs from VESA */ |
726 | for (i = 0; i < ARRAY_SIZE(valid_dsc_bpp)(sizeof((valid_dsc_bpp)) / sizeof((valid_dsc_bpp)[0])) - 1; i++) { |
727 | if (bits_per_pixel < valid_dsc_bpp[i + 1]) |
728 | break; |
729 | } |
730 | bits_per_pixel = valid_dsc_bpp[i]; |
731 | } |
732 | |
733 | /* |
734 | * Compressed BPP in U6.4 format so multiply by 16, for Gen 11, |
735 | * fractional part is 0 |
736 | */ |
737 | return bits_per_pixel << 4; |
738 | } |
739 | |
740 | static u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp, |
741 | int mode_clock, int mode_hdisplay, |
742 | bool_Bool bigjoiner) |
743 | { |
744 | struct drm_i915_privateinteldrm_softc *i915 = dp_to_i915(intel_dp)to_i915(dp_to_dig_port(intel_dp)->base.base.dev); |
745 | u8 min_slice_count, i; |
746 | int max_slice_width; |
747 | |
748 | if (mode_clock <= DP_DSC_PEAK_PIXEL_RATE2720000) |
749 | min_slice_count = DIV_ROUND_UP(mode_clock,(((mode_clock) + ((340000) - 1)) / (340000)) |
750 | DP_DSC_MAX_ENC_THROUGHPUT_0)(((mode_clock) + ((340000) - 1)) / (340000)); |
751 | else |
752 | min_slice_count = DIV_ROUND_UP(mode_clock,(((mode_clock) + ((400000) - 1)) / (400000)) |
753 | DP_DSC_MAX_ENC_THROUGHPUT_1)(((mode_clock) + ((400000) - 1)) / (400000)); |
754 | |
755 | max_slice_width = drm_dp_dsc_sink_max_slice_width(intel_dp->dsc_dpcd); |
756 | if (max_slice_width < DP_DSC_MIN_SLICE_WIDTH_VALUE2560) { |
757 | drm_dbg_kms(&i915->drm,__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "Unsupported slice width %d by DP DSC Sink device\n" , max_slice_width) |
758 | "Unsupported slice width %d by DP DSC Sink device\n",__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "Unsupported slice width %d by DP DSC Sink device\n" , max_slice_width) |
759 | max_slice_width)__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "Unsupported slice width %d by DP DSC Sink device\n" , max_slice_width); |
760 | return 0; |
761 | } |
762 | /* Also take into account max slice width */ |
763 | min_slice_count = max_t(u8, min_slice_count,({ u8 __max_a = (min_slice_count); u8 __max_b = ((((mode_hdisplay ) + ((max_slice_width) - 1)) / (max_slice_width))); __max_a > __max_b ? __max_a : __max_b; }) |
764 | DIV_ROUND_UP(mode_hdisplay,({ u8 __max_a = (min_slice_count); u8 __max_b = ((((mode_hdisplay ) + ((max_slice_width) - 1)) / (max_slice_width))); __max_a > __max_b ? __max_a : __max_b; }) |
765 | max_slice_width))({ u8 __max_a = (min_slice_count); u8 __max_b = ((((mode_hdisplay ) + ((max_slice_width) - 1)) / (max_slice_width))); __max_a > __max_b ? __max_a : __max_b; }); |
766 | |
767 | /* Find the closest match to the valid slice count values */ |
768 | for (i = 0; i < ARRAY_SIZE(valid_dsc_slicecount)(sizeof((valid_dsc_slicecount)) / sizeof((valid_dsc_slicecount )[0])); i++) { |
769 | u8 test_slice_count = valid_dsc_slicecount[i] << bigjoiner; |
770 | |
771 | if (test_slice_count > |
772 | drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd, false0)) |
773 | break; |
774 | |
775 | /* big joiner needs small joiner to be enabled */ |
776 | if (bigjoiner && test_slice_count < 4) |
777 | continue; |
778 | |
779 | if (min_slice_count <= test_slice_count) |
780 | return test_slice_count; |
781 | } |
782 | |
783 | drm_dbg_kms(&i915->drm, "Unsupported Slice Count %d\n",__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "Unsupported Slice Count %d\n" , min_slice_count) |
784 | min_slice_count)__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "Unsupported Slice Count %d\n" , min_slice_count); |
785 | return 0; |
786 | } |
787 | |
788 | static enum intel_output_format |
789 | intel_dp_output_format(struct intel_connector *connector, |
790 | bool_Bool ycbcr_420_output) |
791 | { |
792 | struct intel_dp *intel_dp = intel_attached_dp(connector); |
793 | |
794 | if (!connector->base.ycbcr_420_allowed || !ycbcr_420_output) |
795 | return INTEL_OUTPUT_FORMAT_RGB; |
796 | |
797 | if (intel_dp->dfp.rgb_to_ycbcr && |
798 | intel_dp->dfp.ycbcr_444_to_420) |
799 | return INTEL_OUTPUT_FORMAT_RGB; |
800 | |
801 | if (intel_dp->dfp.ycbcr_444_to_420) |
802 | return INTEL_OUTPUT_FORMAT_YCBCR444; |
803 | else |
804 | return INTEL_OUTPUT_FORMAT_YCBCR420; |
805 | } |
806 | |
807 | int intel_dp_min_bpp(enum intel_output_format output_format) |
808 | { |
809 | if (output_format == INTEL_OUTPUT_FORMAT_RGB) |
810 | return 6 * 3; |
811 | else |
812 | return 8 * 3; |
813 | } |
814 | |
815 | static int intel_dp_output_bpp(enum intel_output_format output_format, int bpp) |
816 | { |
817 | /* |
818 | * bpp value was assumed to RGB format. And YCbCr 4:2:0 output |
819 | * format of the number of bytes per pixel will be half the number |
820 | * of bytes of RGB pixel. |
821 | */ |
822 | if (output_format == INTEL_OUTPUT_FORMAT_YCBCR420) |
823 | bpp /= 2; |
824 | |
825 | return bpp; |
826 | } |
827 | |
828 | static int |
829 | intel_dp_mode_min_output_bpp(struct intel_connector *connector, |
830 | const struct drm_display_mode *mode) |
831 | { |
832 | const struct drm_display_info *info = &connector->base.display_info; |
833 | enum intel_output_format output_format = |
834 | intel_dp_output_format(connector, drm_mode_is_420_only(info, mode)); |
835 | |
836 | return intel_dp_output_bpp(output_format, intel_dp_min_bpp(output_format)); |
837 | } |
838 | |
839 | static bool_Bool intel_dp_hdisplay_bad(struct drm_i915_privateinteldrm_softc *dev_priv, |
840 | int hdisplay) |
841 | { |
842 | /* |
843 | * Older platforms don't like hdisplay==4096 with DP. |
844 | * |
845 | * On ILK/SNB/IVB the pipe seems to be somewhat running (scanline |
846 | * and frame counter increment), but we don't get vblank interrupts, |
847 | * and the pipe underruns immediately. The link also doesn't seem |
848 | * to get trained properly. |
849 | * |
850 | * On CHV the vblank interrupts don't seem to disappear but |
851 | * otherwise the symptoms are similar. |
852 | * |
853 | * TODO: confirm the behaviour on HSW+ |
854 | */ |
855 | return hdisplay == 4096 && !HAS_DDI(dev_priv)((&(dev_priv)->__info)->display.has_ddi); |
856 | } |
857 | |
858 | static int intel_dp_max_tmds_clock(struct intel_dp *intel_dp) |
859 | { |
860 | struct intel_connector *connector = intel_dp->attached_connector; |
861 | const struct drm_display_info *info = &connector->base.display_info; |
862 | int max_tmds_clock = intel_dp->dfp.max_tmds_clock; |
863 | |
864 | /* Only consider the sink's max TMDS clock if we know this is a HDMI DFP */ |
865 | if (max_tmds_clock && info->max_tmds_clock) |
866 | max_tmds_clock = min(max_tmds_clock, info->max_tmds_clock)(((max_tmds_clock)<(info->max_tmds_clock))?(max_tmds_clock ):(info->max_tmds_clock)); |
867 | |
868 | return max_tmds_clock; |
869 | } |
870 | |
871 | static enum drm_mode_status |
872 | intel_dp_tmds_clock_valid(struct intel_dp *intel_dp, |
873 | int clock, int bpc, bool_Bool ycbcr420_output, |
874 | bool_Bool respect_downstream_limits) |
875 | { |
876 | int tmds_clock, min_tmds_clock, max_tmds_clock; |
877 | |
878 | if (!respect_downstream_limits) |
879 | return MODE_OK; |
880 | |
881 | tmds_clock = intel_hdmi_tmds_clock(clock, bpc, ycbcr420_output); |
882 | |
883 | min_tmds_clock = intel_dp->dfp.min_tmds_clock; |
884 | max_tmds_clock = intel_dp_max_tmds_clock(intel_dp); |
885 | |
886 | if (min_tmds_clock && tmds_clock < min_tmds_clock) |
887 | return MODE_CLOCK_LOW; |
888 | |
889 | if (max_tmds_clock && tmds_clock > max_tmds_clock) |
890 | return MODE_CLOCK_HIGH; |
891 | |
892 | return MODE_OK; |
893 | } |
894 | |
895 | static enum drm_mode_status |
896 | intel_dp_mode_valid_downstream(struct intel_connector *connector, |
897 | const struct drm_display_mode *mode, |
898 | int target_clock) |
899 | { |
900 | struct intel_dp *intel_dp = intel_attached_dp(connector); |
901 | const struct drm_display_info *info = &connector->base.display_info; |
902 | enum drm_mode_status status; |
903 | bool_Bool ycbcr_420_only; |
904 | |
905 | /* If PCON supports FRL MODE, check FRL bandwidth constraints */ |
906 | if (intel_dp->dfp.pcon_max_frl_bw) { |
907 | int target_bw; |
908 | int max_frl_bw; |
909 | int bpp = intel_dp_mode_min_output_bpp(connector, mode); |
910 | |
911 | target_bw = bpp * target_clock; |
912 | |
913 | max_frl_bw = intel_dp->dfp.pcon_max_frl_bw; |
914 | |
915 | /* converting bw from Gbps to Kbps*/ |
916 | max_frl_bw = max_frl_bw * 1000000; |
917 | |
918 | if (target_bw > max_frl_bw) |
919 | return MODE_CLOCK_HIGH; |
920 | |
921 | return MODE_OK; |
922 | } |
923 | |
924 | if (intel_dp->dfp.max_dotclock && |
925 | target_clock > intel_dp->dfp.max_dotclock) |
926 | return MODE_CLOCK_HIGH; |
927 | |
928 | ycbcr_420_only = drm_mode_is_420_only(info, mode); |
929 | |
930 | /* Assume 8bpc for the DP++/HDMI/DVI TMDS clock check */ |
931 | status = intel_dp_tmds_clock_valid(intel_dp, target_clock, |
932 | 8, ycbcr_420_only, true1); |
933 | |
934 | if (status != MODE_OK) { |
935 | if (ycbcr_420_only || |
936 | !connector->base.ycbcr_420_allowed || |
937 | !drm_mode_is_420_also(info, mode)) |
938 | return status; |
939 | |
940 | status = intel_dp_tmds_clock_valid(intel_dp, target_clock, |
941 | 8, true1, true1); |
942 | if (status != MODE_OK) |
943 | return status; |
944 | } |
945 | |
946 | return MODE_OK; |
947 | } |
948 | |
949 | static bool_Bool intel_dp_need_bigjoiner(struct intel_dp *intel_dp, |
950 | int hdisplay, int clock) |
951 | { |
952 | struct drm_i915_privateinteldrm_softc *i915 = dp_to_i915(intel_dp)to_i915(dp_to_dig_port(intel_dp)->base.base.dev); |
953 | |
954 | if (!intel_dp_can_bigjoiner(intel_dp)) |
955 | return false0; |
956 | |
957 | return clock > i915->max_dotclk_freq || hdisplay > 5120; |
958 | } |
959 | |
960 | static enum drm_mode_status |
961 | intel_dp_mode_valid(struct drm_connector *_connector, |
962 | struct drm_display_mode *mode) |
963 | { |
964 | struct intel_connector *connector = to_intel_connector(_connector)({ const __typeof( ((struct intel_connector *)0)->base ) * __mptr = (_connector); (struct intel_connector *)( (char *)__mptr - __builtin_offsetof(struct intel_connector, base) );}); |
965 | struct intel_dp *intel_dp = intel_attached_dp(connector); |
966 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev); |
967 | const struct drm_display_mode *fixed_mode; |
968 | int target_clock = mode->clock; |
969 | int max_rate, mode_rate, max_lanes, max_link_clock; |
970 | int max_dotclk = dev_priv->max_dotclk_freq; |
971 | u16 dsc_max_output_bpp = 0; |
972 | u8 dsc_slice_count = 0; |
973 | enum drm_mode_status status; |
974 | bool_Bool dsc = false0, bigjoiner = false0; |
975 | |
976 | status = intel_cpu_transcoder_mode_valid(dev_priv, mode); |
977 | if (status != MODE_OK) |
978 | return status; |
979 | |
980 | if (mode->flags & DRM_MODE_FLAG_DBLCLK(1<<12)) |
981 | return MODE_H_ILLEGAL; |
982 | |
983 | fixed_mode = intel_panel_fixed_mode(connector, mode); |
984 | if (intel_dp_is_edp(intel_dp) && fixed_mode) { |
985 | status = intel_panel_mode_valid(connector, mode); |
986 | if (status != MODE_OK) |
987 | return status; |
988 | |
989 | target_clock = fixed_mode->clock; |
990 | } |
991 | |
992 | if (mode->clock < 10000) |
993 | return MODE_CLOCK_LOW; |
994 | |
995 | if (intel_dp_need_bigjoiner(intel_dp, mode->hdisplay, target_clock)) { |
996 | bigjoiner = true1; |
997 | max_dotclk *= 2; |
998 | } |
999 | if (target_clock > max_dotclk) |
1000 | return MODE_CLOCK_HIGH; |
1001 | |
1002 | max_link_clock = intel_dp_max_link_rate(intel_dp); |
1003 | max_lanes = intel_dp_max_lane_count(intel_dp); |
1004 | |
1005 | max_rate = intel_dp_max_data_rate(max_link_clock, max_lanes); |
1006 | mode_rate = intel_dp_link_required(target_clock, |
1007 | intel_dp_mode_min_output_bpp(connector, mode)); |
1008 | |
1009 | if (intel_dp_hdisplay_bad(dev_priv, mode->hdisplay)) |
1010 | return MODE_H_ILLEGAL; |
1011 | |
1012 | /* |
1013 | * Output bpp is stored in 6.4 format so right shift by 4 to get the |
1014 | * integer value since we support only integer values of bpp. |
1015 | */ |
1016 | if (DISPLAY_VER(dev_priv)((&(dev_priv)->__runtime)->display.ip.ver) >= 10 && |
1017 | drm_dp_sink_supports_dsc(intel_dp->dsc_dpcd)) { |
1018 | /* |
1019 | * TBD pass the connector BPC, |
1020 | * for now U8_MAX so that max BPC on that platform would be picked |
1021 | */ |
1022 | int pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp, U8_MAX0xff); |
1023 | |
1024 | if (intel_dp_is_edp(intel_dp)) { |
1025 | dsc_max_output_bpp = |
1026 | drm_edp_dsc_sink_output_bpp(intel_dp->dsc_dpcd) >> 4; |
1027 | dsc_slice_count = |
1028 | drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd, |
1029 | true1); |
1030 | } else if (drm_dp_sink_supports_fec(intel_dp->fec_capable)) { |
1031 | dsc_max_output_bpp = |
1032 | intel_dp_dsc_get_output_bpp(dev_priv, |
1033 | max_link_clock, |
1034 | max_lanes, |
1035 | target_clock, |
1036 | mode->hdisplay, |
1037 | bigjoiner, |
1038 | pipe_bpp) >> 4; |
1039 | dsc_slice_count = |
1040 | intel_dp_dsc_get_slice_count(intel_dp, |
1041 | target_clock, |
1042 | mode->hdisplay, |
1043 | bigjoiner); |
1044 | } |
1045 | |
1046 | dsc = dsc_max_output_bpp && dsc_slice_count; |
1047 | } |
1048 | |
1049 | /* |
1050 | * Big joiner configuration needs DSC for TGL which is not true for |
1051 | * XE_LPD where uncompressed joiner is supported. |
1052 | */ |
1053 | if (DISPLAY_VER(dev_priv)((&(dev_priv)->__runtime)->display.ip.ver) < 13 && bigjoiner && !dsc) |
1054 | return MODE_CLOCK_HIGH; |
1055 | |
1056 | if (mode_rate > max_rate && !dsc) |
1057 | return MODE_CLOCK_HIGH; |
1058 | |
1059 | status = intel_dp_mode_valid_downstream(connector, mode, target_clock); |
1060 | if (status != MODE_OK) |
1061 | return status; |
1062 | |
1063 | return intel_mode_valid_max_plane_size(dev_priv, mode, bigjoiner); |
1064 | } |
1065 | |
1066 | bool_Bool intel_dp_source_supports_tps3(struct drm_i915_privateinteldrm_softc *i915) |
1067 | { |
1068 | return DISPLAY_VER(i915)((&(i915)->__runtime)->display.ip.ver) >= 9 || IS_BROADWELL(i915)IS_PLATFORM(i915, INTEL_BROADWELL) || IS_HASWELL(i915)IS_PLATFORM(i915, INTEL_HASWELL); |
1069 | } |
1070 | |
1071 | bool_Bool intel_dp_source_supports_tps4(struct drm_i915_privateinteldrm_softc *i915) |
1072 | { |
1073 | return DISPLAY_VER(i915)((&(i915)->__runtime)->display.ip.ver) >= 10; |
1074 | } |
1075 | |
1076 | static void snprintf_int_array(char *str, size_t len, |
1077 | const int *array, int nelem) |
1078 | { |
1079 | int i; |
1080 | |
1081 | str[0] = '\0'; |
1082 | |
1083 | for (i = 0; i < nelem; i++) { |
1084 | int r = snprintf(str, len, "%s%d", i ? ", " : "", array[i]); |
1085 | if (r >= len) |
1086 | return; |
1087 | str += r; |
1088 | len -= r; |
1089 | } |
1090 | } |
1091 | |
1092 | static void intel_dp_print_rates(struct intel_dp *intel_dp) |
1093 | { |
1094 | struct drm_i915_privateinteldrm_softc *i915 = dp_to_i915(intel_dp)to_i915(dp_to_dig_port(intel_dp)->base.base.dev); |
1095 | char str[128]; /* FIXME: too big for stack? */ |
1096 | |
1097 | if (!drm_debug_enabled(DRM_UT_KMS)drm_debug_enabled_raw(DRM_UT_KMS)) |
1098 | return; |
1099 | |
1100 | snprintf_int_array(str, sizeof(str), |
1101 | intel_dp->source_rates, intel_dp->num_source_rates); |
1102 | drm_dbg_kms(&i915->drm, "source rates: %s\n", str)__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "source rates: %s\n", str); |
1103 | |
1104 | snprintf_int_array(str, sizeof(str), |
1105 | intel_dp->sink_rates, intel_dp->num_sink_rates); |
1106 | drm_dbg_kms(&i915->drm, "sink rates: %s\n", str)__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "sink rates: %s\n", str ); |
1107 | |
1108 | snprintf_int_array(str, sizeof(str), |
1109 | intel_dp->common_rates, intel_dp->num_common_rates); |
1110 | drm_dbg_kms(&i915->drm, "common rates: %s\n", str)__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "common rates: %s\n", str); |
1111 | } |
1112 | |
1113 | int |
1114 | intel_dp_max_link_rate(struct intel_dp *intel_dp) |
1115 | { |
1116 | int len; |
1117 | |
1118 | len = intel_dp_common_len_rate_limit(intel_dp, intel_dp->max_link_rate); |
1119 | |
1120 | return intel_dp_common_rate(intel_dp, len - 1); |
1121 | } |
1122 | |
1123 | int intel_dp_rate_select(struct intel_dp *intel_dp, int rate) |
1124 | { |
1125 | struct drm_i915_privateinteldrm_softc *i915 = dp_to_i915(intel_dp)to_i915(dp_to_dig_port(intel_dp)->base.base.dev); |
1126 | int i = intel_dp_rate_index(intel_dp->sink_rates, |
1127 | intel_dp->num_sink_rates, rate); |
1128 | |
1129 | if (drm_WARN_ON(&i915->drm, i < 0)({ int __ret = !!((i < 0)); if (__ret) printf("%s %s: " "%s" , dev_driver_string(((&i915->drm))->dev), "", "drm_WARN_ON(" "i < 0" ")"); __builtin_expect(!!(__ret), 0); })) |
1130 | i = 0; |
1131 | |
1132 | return i; |
1133 | } |
1134 | |
1135 | void intel_dp_compute_rate(struct intel_dp *intel_dp, int port_clock, |
1136 | u8 *link_bw, u8 *rate_select) |
1137 | { |
1138 | /* eDP 1.4 rate select method. */ |
1139 | if (intel_dp->use_rate_select) { |
1140 | *link_bw = 0; |
1141 | *rate_select = |
1142 | intel_dp_rate_select(intel_dp, port_clock); |
1143 | } else { |
1144 | *link_bw = drm_dp_link_rate_to_bw_code(port_clock); |
1145 | *rate_select = 0; |
1146 | } |
1147 | } |
1148 | |
1149 | static bool_Bool intel_dp_source_supports_fec(struct intel_dp *intel_dp, |
1150 | const struct intel_crtc_state *pipe_config) |
1151 | { |
1152 | struct drm_i915_privateinteldrm_softc *dev_priv = dp_to_i915(intel_dp)to_i915(dp_to_dig_port(intel_dp)->base.base.dev); |
1153 | |
1154 | /* On TGL, FEC is supported on all Pipes */ |
1155 | if (DISPLAY_VER(dev_priv)((&(dev_priv)->__runtime)->display.ip.ver) >= 12) |
1156 | return true1; |
1157 | |
1158 | if (DISPLAY_VER(dev_priv)((&(dev_priv)->__runtime)->display.ip.ver) == 11 && pipe_config->cpu_transcoder != TRANSCODER_A) |
1159 | return true1; |
1160 | |
1161 | return false0; |
1162 | } |
1163 | |
1164 | static bool_Bool intel_dp_supports_fec(struct intel_dp *intel_dp, |
1165 | const struct intel_crtc_state *pipe_config) |
1166 | { |
1167 | return intel_dp_source_supports_fec(intel_dp, pipe_config) && |
1168 | drm_dp_sink_supports_fec(intel_dp->fec_capable); |
1169 | } |
1170 | |
1171 | static bool_Bool intel_dp_supports_dsc(struct intel_dp *intel_dp, |
1172 | const struct intel_crtc_state *crtc_state) |
1173 | { |
1174 | if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP) && !crtc_state->fec_enable) |
1175 | return false0; |
1176 | |
1177 | return intel_dsc_source_support(crtc_state) && |
1178 | drm_dp_sink_supports_dsc(intel_dp->dsc_dpcd); |
1179 | } |
1180 | |
1181 | static bool_Bool intel_dp_is_ycbcr420(struct intel_dp *intel_dp, |
1182 | const struct intel_crtc_state *crtc_state) |
1183 | { |
1184 | return crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420 || |
1185 | (crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR444 && |
1186 | intel_dp->dfp.ycbcr_444_to_420); |
1187 | } |
1188 | |
1189 | static int intel_dp_hdmi_compute_bpc(struct intel_dp *intel_dp, |
1190 | const struct intel_crtc_state *crtc_state, |
1191 | int bpc, bool_Bool respect_downstream_limits) |
1192 | { |
1193 | bool_Bool ycbcr420_output = intel_dp_is_ycbcr420(intel_dp, crtc_state); |
1194 | int clock = crtc_state->hw.adjusted_mode.crtc_clock; |
1195 | |
1196 | /* |
1197 | * Current bpc could already be below 8bpc due to |
1198 | * FDI bandwidth constraints or other limits. |
1199 | * HDMI minimum is 8bpc however. |
1200 | */ |
1201 | bpc = max(bpc, 8)(((bpc)>(8))?(bpc):(8)); |
1202 | |
1203 | /* |
1204 | * We will never exceed downstream TMDS clock limits while |
1205 | * attempting deep color. If the user insists on forcing an |
1206 | * out of spec mode they will have to be satisfied with 8bpc. |
1207 | */ |
1208 | if (!respect_downstream_limits) |
1209 | bpc = 8; |
1210 | |
1211 | for (; bpc >= 8; bpc -= 2) { |
1212 | if (intel_hdmi_bpc_possible(crtc_state, bpc, |
1213 | intel_dp->has_hdmi_sink, ycbcr420_output) && |
1214 | intel_dp_tmds_clock_valid(intel_dp, clock, bpc, ycbcr420_output, |
1215 | respect_downstream_limits) == MODE_OK) |
1216 | return bpc; |
1217 | } |
1218 | |
1219 | return -EINVAL22; |
1220 | } |
1221 | |
1222 | static int intel_dp_max_bpp(struct intel_dp *intel_dp, |
1223 | const struct intel_crtc_state *crtc_state, |
1224 | bool_Bool respect_downstream_limits) |
1225 | { |
1226 | struct drm_i915_privateinteldrm_softc *dev_priv = dp_to_i915(intel_dp)to_i915(dp_to_dig_port(intel_dp)->base.base.dev); |
1227 | struct intel_connector *intel_connector = intel_dp->attached_connector; |
1228 | int bpp, bpc; |
1229 | |
1230 | bpc = crtc_state->pipe_bpp / 3; |
1231 | |
1232 | if (intel_dp->dfp.max_bpc) |
1233 | bpc = min_t(int, bpc, intel_dp->dfp.max_bpc)({ int __min_a = (bpc); int __min_b = (intel_dp->dfp.max_bpc ); __min_a < __min_b ? __min_a : __min_b; }); |
1234 | |
1235 | if (intel_dp->dfp.min_tmds_clock) { |
1236 | int max_hdmi_bpc; |
1237 | |
1238 | max_hdmi_bpc = intel_dp_hdmi_compute_bpc(intel_dp, crtc_state, bpc, |
1239 | respect_downstream_limits); |
1240 | if (max_hdmi_bpc < 0) |
1241 | return 0; |
1242 | |
1243 | bpc = min(bpc, max_hdmi_bpc)(((bpc)<(max_hdmi_bpc))?(bpc):(max_hdmi_bpc)); |
1244 | } |
1245 | |
1246 | bpp = bpc * 3; |
1247 | if (intel_dp_is_edp(intel_dp)) { |
1248 | /* Get bpp from vbt only for panels that dont have bpp in edid */ |
1249 | if (intel_connector->base.display_info.bpc == 0 && |
1250 | intel_connector->panel.vbt.edp.bpp && |
1251 | intel_connector->panel.vbt.edp.bpp < bpp) { |
1252 | drm_dbg_kms(&dev_priv->drm,__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "clamping bpp for eDP panel to BIOS-provided %i\n" , intel_connector->panel.vbt.edp.bpp) |
1253 | "clamping bpp for eDP panel to BIOS-provided %i\n",__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "clamping bpp for eDP panel to BIOS-provided %i\n" , intel_connector->panel.vbt.edp.bpp) |
1254 | intel_connector->panel.vbt.edp.bpp)__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "clamping bpp for eDP panel to BIOS-provided %i\n" , intel_connector->panel.vbt.edp.bpp); |
1255 | bpp = intel_connector->panel.vbt.edp.bpp; |
1256 | } |
1257 | } |
1258 | |
1259 | return bpp; |
1260 | } |
1261 | |
1262 | /* Adjust link config limits based on compliance test requests. */ |
1263 | void |
1264 | intel_dp_adjust_compliance_config(struct intel_dp *intel_dp, |
1265 | struct intel_crtc_state *pipe_config, |
1266 | struct link_config_limits *limits) |
1267 | { |
1268 | struct drm_i915_privateinteldrm_softc *i915 = dp_to_i915(intel_dp)to_i915(dp_to_dig_port(intel_dp)->base.base.dev); |
1269 | |
1270 | /* For DP Compliance we override the computed bpp for the pipe */ |
1271 | if (intel_dp->compliance.test_data.bpc != 0) { |
1272 | int bpp = 3 * intel_dp->compliance.test_data.bpc; |
1273 | |
1274 | limits->min_bpp = limits->max_bpp = bpp; |
1275 | pipe_config->dither_force_disable = bpp == 6 * 3; |
1276 | |
1277 | drm_dbg_kms(&i915->drm, "Setting pipe_bpp to %d\n", bpp)__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "Setting pipe_bpp to %d\n" , bpp); |
1278 | } |
1279 | |
1280 | /* Use values requested by Compliance Test Request */ |
1281 | if (intel_dp->compliance.test_type == DP_TEST_LINK_TRAINING(1 << 0)) { |
1282 | int index; |
1283 | |
1284 | /* Validate the compliance test data since max values |
1285 | * might have changed due to link train fallback. |
1286 | */ |
1287 | if (intel_dp_link_params_valid(intel_dp, intel_dp->compliance.test_link_rate, |
1288 | intel_dp->compliance.test_lane_count)) { |
1289 | index = intel_dp_rate_index(intel_dp->common_rates, |
1290 | intel_dp->num_common_rates, |
1291 | intel_dp->compliance.test_link_rate); |
1292 | if (index >= 0) |
1293 | limits->min_rate = limits->max_rate = |
1294 | intel_dp->compliance.test_link_rate; |
1295 | limits->min_lane_count = limits->max_lane_count = |
1296 | intel_dp->compliance.test_lane_count; |
1297 | } |
1298 | } |
1299 | } |
1300 | |
1301 | static bool_Bool has_seamless_m_n(struct intel_connector *connector) |
1302 | { |
1303 | struct drm_i915_privateinteldrm_softc *i915 = to_i915(connector->base.dev); |
1304 | |
1305 | /* |
1306 | * Seamless M/N reprogramming only implemented |
1307 | * for BDW+ double buffered M/N registers so far. |
1308 | */ |
1309 | return HAS_DOUBLE_BUFFERED_M_N(i915)(((&(i915)->__runtime)->display.ip.ver) >= 9 || IS_PLATFORM (i915, INTEL_BROADWELL)) && |
1310 | intel_panel_drrs_type(connector) == DRRS_TYPE_SEAMLESS; |
1311 | } |
1312 | |
1313 | static int intel_dp_mode_clock(const struct intel_crtc_state *crtc_state, |
1314 | const struct drm_connector_state *conn_state) |
1315 | { |
1316 | struct intel_connector *connector = to_intel_connector(conn_state->connector)({ const __typeof( ((struct intel_connector *)0)->base ) * __mptr = (conn_state->connector); (struct intel_connector * )( (char *)__mptr - __builtin_offsetof(struct intel_connector , base) );}); |
1317 | const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; |
1318 | |
1319 | /* FIXME a bit of a mess wrt clock vs. crtc_clock */ |
1320 | if (has_seamless_m_n(connector)) |
1321 | return intel_panel_highest_mode(connector, adjusted_mode)->clock; |
1322 | else |
1323 | return adjusted_mode->crtc_clock; |
1324 | } |
1325 | |
1326 | /* Optimize link config in order: max bpp, min clock, min lanes */ |
1327 | static int |
1328 | intel_dp_compute_link_config_wide(struct intel_dp *intel_dp, |
1329 | struct intel_crtc_state *pipe_config, |
1330 | const struct drm_connector_state *conn_state, |
1331 | const struct link_config_limits *limits) |
1332 | { |
1333 | int bpp, i, lane_count, clock = intel_dp_mode_clock(pipe_config, conn_state); |
1334 | int mode_rate, link_rate, link_avail; |
1335 | |
1336 | for (bpp = limits->max_bpp; bpp >= limits->min_bpp; bpp -= 2 * 3) { |
1337 | int output_bpp = intel_dp_output_bpp(pipe_config->output_format, bpp); |
1338 | |
1339 | mode_rate = intel_dp_link_required(clock, output_bpp); |
1340 | |
1341 | for (i = 0; i < intel_dp->num_common_rates; i++) { |
1342 | link_rate = intel_dp_common_rate(intel_dp, i); |
1343 | if (link_rate < limits->min_rate || |
1344 | link_rate > limits->max_rate) |
1345 | continue; |
1346 | |
1347 | for (lane_count = limits->min_lane_count; |
1348 | lane_count <= limits->max_lane_count; |
1349 | lane_count <<= 1) { |
1350 | link_avail = intel_dp_max_data_rate(link_rate, |
1351 | lane_count); |
1352 | |
1353 | if (mode_rate <= link_avail) { |
1354 | pipe_config->lane_count = lane_count; |
1355 | pipe_config->pipe_bpp = bpp; |
1356 | pipe_config->port_clock = link_rate; |
1357 | |
1358 | return 0; |
1359 | } |
1360 | } |
1361 | } |
1362 | } |
1363 | |
1364 | return -EINVAL22; |
1365 | } |
1366 | |
1367 | static int intel_dp_dsc_compute_bpp(struct intel_dp *intel_dp, u8 max_req_bpc) |
1368 | { |
1369 | struct drm_i915_privateinteldrm_softc *i915 = dp_to_i915(intel_dp)to_i915(dp_to_dig_port(intel_dp)->base.base.dev); |
1370 | int i, num_bpc; |
1371 | u8 dsc_bpc[3] = {0}; |
1372 | u8 dsc_max_bpc; |
1373 | |
1374 | /* Max DSC Input BPC for ICL is 10 and for TGL+ is 12 */ |
1375 | if (DISPLAY_VER(i915)((&(i915)->__runtime)->display.ip.ver) >= 12) |
1376 | dsc_max_bpc = min_t(u8, 12, max_req_bpc)({ u8 __min_a = (12); u8 __min_b = (max_req_bpc); __min_a < __min_b ? __min_a : __min_b; }); |
1377 | else |
1378 | dsc_max_bpc = min_t(u8, 10, max_req_bpc)({ u8 __min_a = (10); u8 __min_b = (max_req_bpc); __min_a < __min_b ? __min_a : __min_b; }); |
1379 | |
1380 | num_bpc = drm_dp_dsc_sink_supported_input_bpcs(intel_dp->dsc_dpcd, |
1381 | dsc_bpc); |
1382 | for (i = 0; i < num_bpc; i++) { |
1383 | if (dsc_max_bpc >= dsc_bpc[i]) |
1384 | return dsc_bpc[i] * 3; |
1385 | } |
1386 | |
1387 | return 0; |
1388 | } |
1389 | |
1390 | static int intel_dp_source_dsc_version_minor(struct intel_dp *intel_dp) |
1391 | { |
1392 | struct drm_i915_privateinteldrm_softc *i915 = dp_to_i915(intel_dp)to_i915(dp_to_dig_port(intel_dp)->base.base.dev); |
1393 | |
1394 | return DISPLAY_VER(i915)((&(i915)->__runtime)->display.ip.ver) >= 14 ? 2 : 1; |
1395 | } |
1396 | |
1397 | static int intel_dp_sink_dsc_version_minor(struct intel_dp *intel_dp) |
1398 | { |
1399 | return (intel_dp->dsc_dpcd[DP_DSC_REV0x061 - DP_DSC_SUPPORT0x060] & DP_DSC_MINOR_MASK(0xf << 4)) >> |
1400 | DP_DSC_MINOR_SHIFT4; |
1401 | } |
1402 | |
1403 | static int intel_dp_dsc_compute_params(struct intel_encoder *encoder, |
1404 | struct intel_crtc_state *crtc_state) |
1405 | { |
1406 | struct drm_i915_privateinteldrm_softc *i915 = to_i915(encoder->base.dev); |
1407 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
1408 | struct drm_dsc_config *vdsc_cfg = &crtc_state->dsc.config; |
1409 | u8 line_buf_depth; |
1410 | int ret; |
1411 | |
1412 | /* |
1413 | * RC_MODEL_SIZE is currently a constant across all configurations. |
1414 | * |
1415 | * FIXME: Look into using sink defined DPCD DP_DSC_RC_BUF_BLK_SIZE and |
1416 | * DP_DSC_RC_BUF_SIZE for this. |
1417 | */ |
1418 | vdsc_cfg->rc_model_size = DSC_RC_MODEL_SIZE_CONST8192; |
1419 | vdsc_cfg->pic_height = crtc_state->hw.adjusted_mode.crtc_vdisplay; |
1420 | |
1421 | /* |
1422 | * Slice Height of 8 works for all currently available panels. So start |
1423 | * with that if pic_height is an integral multiple of 8. Eventually add |
1424 | * logic to try multiple slice heights. |
1425 | */ |
1426 | if (vdsc_cfg->pic_height % 8 == 0) |
1427 | vdsc_cfg->slice_height = 8; |
1428 | else if (vdsc_cfg->pic_height % 4 == 0) |
1429 | vdsc_cfg->slice_height = 4; |
1430 | else |
1431 | vdsc_cfg->slice_height = 2; |
1432 | |
1433 | ret = intel_dsc_compute_params(crtc_state); |
1434 | if (ret) |
1435 | return ret; |
1436 | |
1437 | vdsc_cfg->dsc_version_major = |
1438 | (intel_dp->dsc_dpcd[DP_DSC_REV0x061 - DP_DSC_SUPPORT0x060] & |
1439 | DP_DSC_MAJOR_MASK(0xf << 0)) >> DP_DSC_MAJOR_SHIFT0; |
1440 | vdsc_cfg->dsc_version_minor = |
1441 | min(intel_dp_source_dsc_version_minor(intel_dp),(((intel_dp_source_dsc_version_minor(intel_dp))<(intel_dp_sink_dsc_version_minor (intel_dp)))?(intel_dp_source_dsc_version_minor(intel_dp)):(intel_dp_sink_dsc_version_minor (intel_dp))) |
1442 | intel_dp_sink_dsc_version_minor(intel_dp))(((intel_dp_source_dsc_version_minor(intel_dp))<(intel_dp_sink_dsc_version_minor (intel_dp)))?(intel_dp_source_dsc_version_minor(intel_dp)):(intel_dp_sink_dsc_version_minor (intel_dp))); |
1443 | |
1444 | vdsc_cfg->convert_rgb = intel_dp->dsc_dpcd[DP_DSC_DEC_COLOR_FORMAT_CAP0x069 - DP_DSC_SUPPORT0x060] & |
1445 | DP_DSC_RGB(1 << 0); |
1446 | |
1447 | line_buf_depth = drm_dp_dsc_sink_line_buf_depth(intel_dp->dsc_dpcd); |
1448 | if (!line_buf_depth) { |
1449 | drm_dbg_kms(&i915->drm,__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "DSC Sink Line Buffer Depth invalid\n" ) |
1450 | "DSC Sink Line Buffer Depth invalid\n")__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "DSC Sink Line Buffer Depth invalid\n" ); |
1451 | return -EINVAL22; |
1452 | } |
1453 | |
1454 | if (vdsc_cfg->dsc_version_minor == 2) |
1455 | vdsc_cfg->line_buf_depth = (line_buf_depth == DSC_1_2_MAX_LINEBUF_DEPTH_BITS16) ? |
1456 | DSC_1_2_MAX_LINEBUF_DEPTH_VAL0 : line_buf_depth; |
1457 | else |
1458 | vdsc_cfg->line_buf_depth = (line_buf_depth > DSC_1_1_MAX_LINEBUF_DEPTH_BITS13) ? |
1459 | DSC_1_1_MAX_LINEBUF_DEPTH_BITS13 : line_buf_depth; |
1460 | |
1461 | vdsc_cfg->block_pred_enable = |
1462 | intel_dp->dsc_dpcd[DP_DSC_BLK_PREDICTION_SUPPORT0x066 - DP_DSC_SUPPORT0x060] & |
1463 | DP_DSC_BLK_PREDICTION_IS_SUPPORTED(1 << 0); |
1464 | |
1465 | return drm_dsc_compute_rc_parameters(vdsc_cfg); |
1466 | } |
1467 | |
1468 | static int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, |
1469 | struct intel_crtc_state *pipe_config, |
1470 | struct drm_connector_state *conn_state, |
1471 | struct link_config_limits *limits) |
1472 | { |
1473 | struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); |
1474 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(dig_port->base.base.dev); |
1475 | const struct drm_display_mode *adjusted_mode = |
1476 | &pipe_config->hw.adjusted_mode; |
1477 | int pipe_bpp; |
1478 | int ret; |
1479 | |
1480 | pipe_config->fec_enable = !intel_dp_is_edp(intel_dp) && |
1481 | intel_dp_supports_fec(intel_dp, pipe_config); |
1482 | |
1483 | if (!intel_dp_supports_dsc(intel_dp, pipe_config)) |
1484 | return -EINVAL22; |
1485 | |
1486 | pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp, conn_state->max_requested_bpc); |
1487 | |
1488 | if (intel_dp->force_dsc_bpc) { |
1489 | pipe_bpp = intel_dp->force_dsc_bpc * 3; |
1490 | drm_dbg_kms(&dev_priv->drm, "Input DSC BPP forced to %d", pipe_bpp)__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "Input DSC BPP forced to %d" , pipe_bpp); |
1491 | } |
1492 | |
1493 | /* Min Input BPC for ICL+ is 8 */ |
1494 | if (pipe_bpp < 8 * 3) { |
1495 | drm_dbg_kms(&dev_priv->drm,__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "No DSC support for less than 8bpc\n" ) |
1496 | "No DSC support for less than 8bpc\n")__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "No DSC support for less than 8bpc\n" ); |
1497 | return -EINVAL22; |
1498 | } |
1499 | |
1500 | /* |
1501 | * For now enable DSC for max bpp, max link rate, max lane count. |
1502 | * Optimize this later for the minimum possible link rate/lane count |
1503 | * with DSC enabled for the requested mode. |
1504 | */ |
1505 | pipe_config->pipe_bpp = pipe_bpp; |
1506 | pipe_config->port_clock = limits->max_rate; |
1507 | pipe_config->lane_count = limits->max_lane_count; |
1508 | |
1509 | if (intel_dp_is_edp(intel_dp)) { |
1510 | pipe_config->dsc.compressed_bpp = |
1511 | min_t(u16, drm_edp_dsc_sink_output_bpp(intel_dp->dsc_dpcd) >> 4,({ u16 __min_a = (drm_edp_dsc_sink_output_bpp(intel_dp->dsc_dpcd ) >> 4); u16 __min_b = (pipe_config->pipe_bpp); __min_a < __min_b ? __min_a : __min_b; }) |
1512 | pipe_config->pipe_bpp)({ u16 __min_a = (drm_edp_dsc_sink_output_bpp(intel_dp->dsc_dpcd ) >> 4); u16 __min_b = (pipe_config->pipe_bpp); __min_a < __min_b ? __min_a : __min_b; }); |
1513 | pipe_config->dsc.slice_count = |
1514 | drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd, |
1515 | true1); |
1516 | if (!pipe_config->dsc.slice_count) { |
1517 | drm_dbg_kms(&dev_priv->drm, "Unsupported Slice Count %d\n",__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "Unsupported Slice Count %d\n" , pipe_config->dsc.slice_count) |
1518 | pipe_config->dsc.slice_count)__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "Unsupported Slice Count %d\n" , pipe_config->dsc.slice_count); |
1519 | return -EINVAL22; |
1520 | } |
1521 | } else { |
1522 | u16 dsc_max_output_bpp; |
1523 | u8 dsc_dp_slice_count; |
1524 | |
1525 | dsc_max_output_bpp = |
1526 | intel_dp_dsc_get_output_bpp(dev_priv, |
1527 | pipe_config->port_clock, |
1528 | pipe_config->lane_count, |
1529 | adjusted_mode->crtc_clock, |
1530 | adjusted_mode->crtc_hdisplay, |
1531 | pipe_config->bigjoiner_pipes, |
1532 | pipe_bpp); |
1533 | dsc_dp_slice_count = |
1534 | intel_dp_dsc_get_slice_count(intel_dp, |
1535 | adjusted_mode->crtc_clock, |
1536 | adjusted_mode->crtc_hdisplay, |
1537 | pipe_config->bigjoiner_pipes); |
1538 | if (!dsc_max_output_bpp || !dsc_dp_slice_count) { |
1539 | drm_dbg_kms(&dev_priv->drm,__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "Compressed BPP/Slice Count not supported\n" ) |
1540 | "Compressed BPP/Slice Count not supported\n")__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "Compressed BPP/Slice Count not supported\n" ); |
1541 | return -EINVAL22; |
1542 | } |
1543 | pipe_config->dsc.compressed_bpp = min_t(u16,({ u16 __min_a = (dsc_max_output_bpp >> 4); u16 __min_b = (pipe_config->pipe_bpp); __min_a < __min_b ? __min_a : __min_b; }) |
1544 | dsc_max_output_bpp >> 4,({ u16 __min_a = (dsc_max_output_bpp >> 4); u16 __min_b = (pipe_config->pipe_bpp); __min_a < __min_b ? __min_a : __min_b; }) |
1545 | pipe_config->pipe_bpp)({ u16 __min_a = (dsc_max_output_bpp >> 4); u16 __min_b = (pipe_config->pipe_bpp); __min_a < __min_b ? __min_a : __min_b; }); |
1546 | pipe_config->dsc.slice_count = dsc_dp_slice_count; |
1547 | } |
1548 | |
1549 | /* |
1550 | * VDSC engine operates at 1 Pixel per clock, so if peak pixel rate |
1551 | * is greater than the maximum Cdclock and if slice count is even |
1552 | * then we need to use 2 VDSC instances. |
1553 | */ |
1554 | if (adjusted_mode->crtc_clock > dev_priv->display.cdclk.max_cdclk_freq || |
1555 | pipe_config->bigjoiner_pipes) { |
1556 | if (pipe_config->dsc.slice_count < 2) { |
1557 | drm_dbg_kms(&dev_priv->drm,__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "Cannot split stream to use 2 VDSC instances\n" ) |
1558 | "Cannot split stream to use 2 VDSC instances\n")__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "Cannot split stream to use 2 VDSC instances\n" ); |
1559 | return -EINVAL22; |
1560 | } |
1561 | |
1562 | pipe_config->dsc.dsc_split = true1; |
1563 | } |
1564 | |
1565 | ret = intel_dp_dsc_compute_params(&dig_port->base, pipe_config); |
1566 | if (ret < 0) { |
1567 | drm_dbg_kms(&dev_priv->drm,__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "Cannot compute valid DSC parameters for Input Bpp = %d " "Compressed BPP = %d\n", pipe_config->pipe_bpp, pipe_config ->dsc.compressed_bpp) |
1568 | "Cannot compute valid DSC parameters for Input Bpp = %d "__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "Cannot compute valid DSC parameters for Input Bpp = %d " "Compressed BPP = %d\n", pipe_config->pipe_bpp, pipe_config ->dsc.compressed_bpp) |
1569 | "Compressed BPP = %d\n",__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "Cannot compute valid DSC parameters for Input Bpp = %d " "Compressed BPP = %d\n", pipe_config->pipe_bpp, pipe_config ->dsc.compressed_bpp) |
1570 | pipe_config->pipe_bpp,__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "Cannot compute valid DSC parameters for Input Bpp = %d " "Compressed BPP = %d\n", pipe_config->pipe_bpp, pipe_config ->dsc.compressed_bpp) |
1571 | pipe_config->dsc.compressed_bpp)__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "Cannot compute valid DSC parameters for Input Bpp = %d " "Compressed BPP = %d\n", pipe_config->pipe_bpp, pipe_config ->dsc.compressed_bpp); |
1572 | return ret; |
1573 | } |
1574 | |
1575 | pipe_config->dsc.compression_enable = true1; |
1576 | drm_dbg_kms(&dev_priv->drm, "DP DSC computed with Input Bpp = %d "__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "DP DSC computed with Input Bpp = %d " "Compressed Bpp = %d Slice Count = %d\n", pipe_config->pipe_bpp , pipe_config->dsc.compressed_bpp, pipe_config->dsc.slice_count ) |
1577 | "Compressed Bpp = %d Slice Count = %d\n",__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "DP DSC computed with Input Bpp = %d " "Compressed Bpp = %d Slice Count = %d\n", pipe_config->pipe_bpp , pipe_config->dsc.compressed_bpp, pipe_config->dsc.slice_count ) |
1578 | pipe_config->pipe_bpp,__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "DP DSC computed with Input Bpp = %d " "Compressed Bpp = %d Slice Count = %d\n", pipe_config->pipe_bpp , pipe_config->dsc.compressed_bpp, pipe_config->dsc.slice_count ) |
1579 | pipe_config->dsc.compressed_bpp,__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "DP DSC computed with Input Bpp = %d " "Compressed Bpp = %d Slice Count = %d\n", pipe_config->pipe_bpp , pipe_config->dsc.compressed_bpp, pipe_config->dsc.slice_count ) |
1580 | pipe_config->dsc.slice_count)__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "DP DSC computed with Input Bpp = %d " "Compressed Bpp = %d Slice Count = %d\n", pipe_config->pipe_bpp , pipe_config->dsc.compressed_bpp, pipe_config->dsc.slice_count ); |
1581 | |
1582 | return 0; |
1583 | } |
1584 | |
1585 | static int |
1586 | intel_dp_compute_link_config(struct intel_encoder *encoder, |
1587 | struct intel_crtc_state *pipe_config, |
1588 | struct drm_connector_state *conn_state, |
1589 | bool_Bool respect_downstream_limits) |
1590 | { |
1591 | struct drm_i915_privateinteldrm_softc *i915 = to_i915(encoder->base.dev); |
1592 | struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc)({ const __typeof( ((struct intel_crtc *)0)->base ) *__mptr = (pipe_config->uapi.crtc); (struct intel_crtc *)( (char * )__mptr - __builtin_offsetof(struct intel_crtc, base) );}); |
1593 | const struct drm_display_mode *adjusted_mode = |
1594 | &pipe_config->hw.adjusted_mode; |
1595 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
1596 | struct link_config_limits limits; |
1597 | bool_Bool joiner_needs_dsc = false0; |
1598 | int ret; |
1599 | |
1600 | limits.min_rate = intel_dp_common_rate(intel_dp, 0); |
1601 | limits.max_rate = intel_dp_max_link_rate(intel_dp); |
1602 | |
1603 | limits.min_lane_count = 1; |
1604 | limits.max_lane_count = intel_dp_max_lane_count(intel_dp); |
1605 | |
1606 | limits.min_bpp = intel_dp_min_bpp(pipe_config->output_format); |
1607 | limits.max_bpp = intel_dp_max_bpp(intel_dp, pipe_config, respect_downstream_limits); |
1608 | |
1609 | if (intel_dp->use_max_params) { |
1610 | /* |
1611 | * Use the maximum clock and number of lanes the eDP panel |
1612 | * advertizes being capable of in case the initial fast |
1613 | * optimal params failed us. The panels are generally |
1614 | * designed to support only a single clock and lane |
1615 | * configuration, and typically on older panels these |
1616 | * values correspond to the native resolution of the panel. |
1617 | */ |
1618 | limits.min_lane_count = limits.max_lane_count; |
1619 | limits.min_rate = limits.max_rate; |
1620 | } |
1621 | |
1622 | intel_dp_adjust_compliance_config(intel_dp, pipe_config, &limits); |
1623 | |
1624 | drm_dbg_kms(&i915->drm, "DP link computation with max lane count %i "__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "DP link computation with max lane count %i " "max rate %d max bpp %d pixel clock %iKHz\n", limits.max_lane_count , limits.max_rate, limits.max_bpp, adjusted_mode->crtc_clock ) |
1625 | "max rate %d max bpp %d pixel clock %iKHz\n",__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "DP link computation with max lane count %i " "max rate %d max bpp %d pixel clock %iKHz\n", limits.max_lane_count , limits.max_rate, limits.max_bpp, adjusted_mode->crtc_clock ) |
1626 | limits.max_lane_count, limits.max_rate,__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "DP link computation with max lane count %i " "max rate %d max bpp %d pixel clock %iKHz\n", limits.max_lane_count , limits.max_rate, limits.max_bpp, adjusted_mode->crtc_clock ) |
1627 | limits.max_bpp, adjusted_mode->crtc_clock)__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "DP link computation with max lane count %i " "max rate %d max bpp %d pixel clock %iKHz\n", limits.max_lane_count , limits.max_rate, limits.max_bpp, adjusted_mode->crtc_clock ); |
1628 | |
1629 | if (intel_dp_need_bigjoiner(intel_dp, adjusted_mode->crtc_hdisplay, |
1630 | adjusted_mode->crtc_clock)) |
1631 | pipe_config->bigjoiner_pipes = GENMASK(crtc->pipe + 1, crtc->pipe)(((~0UL) >> (64 - (crtc->pipe + 1) - 1)) & ((~0UL ) << (crtc->pipe))); |
1632 | |
1633 | /* |
1634 | * Pipe joiner needs compression up to display 12 due to bandwidth |
1635 | * limitation. DG2 onwards pipe joiner can be enabled without |
1636 | * compression. |
1637 | */ |
1638 | joiner_needs_dsc = DISPLAY_VER(i915)((&(i915)->__runtime)->display.ip.ver) < 13 && pipe_config->bigjoiner_pipes; |
1639 | |
1640 | /* |
1641 | * Optimize for slow and wide for everything, because there are some |
1642 | * eDP 1.3 and 1.4 panels don't work well with fast and narrow. |
1643 | */ |
1644 | ret = intel_dp_compute_link_config_wide(intel_dp, pipe_config, conn_state, &limits); |
1645 | |
1646 | if (ret || joiner_needs_dsc || intel_dp->force_dsc_en) { |
1647 | drm_dbg_kms(&i915->drm, "Try DSC (fallback=%s, joiner=%s, force=%s)\n",__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "Try DSC (fallback=%s, joiner=%s, force=%s)\n" , str_yes_no(ret), str_yes_no(joiner_needs_dsc), str_yes_no(intel_dp ->force_dsc_en)) |
1648 | str_yes_no(ret), str_yes_no(joiner_needs_dsc),__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "Try DSC (fallback=%s, joiner=%s, force=%s)\n" , str_yes_no(ret), str_yes_no(joiner_needs_dsc), str_yes_no(intel_dp ->force_dsc_en)) |
1649 | str_yes_no(intel_dp->force_dsc_en))__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "Try DSC (fallback=%s, joiner=%s, force=%s)\n" , str_yes_no(ret), str_yes_no(joiner_needs_dsc), str_yes_no(intel_dp ->force_dsc_en)); |
1650 | ret = intel_dp_dsc_compute_config(intel_dp, pipe_config, |
1651 | conn_state, &limits); |
1652 | if (ret < 0) |
1653 | return ret; |
1654 | } |
1655 | |
1656 | if (pipe_config->dsc.compression_enable) { |
1657 | drm_dbg_kms(&i915->drm,__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "DP lane count %d clock %d Input bpp %d Compressed bpp %d\n" , pipe_config->lane_count, pipe_config->port_clock, pipe_config ->pipe_bpp, pipe_config->dsc.compressed_bpp) |
1658 | "DP lane count %d clock %d Input bpp %d Compressed bpp %d\n",__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "DP lane count %d clock %d Input bpp %d Compressed bpp %d\n" , pipe_config->lane_count, pipe_config->port_clock, pipe_config ->pipe_bpp, pipe_config->dsc.compressed_bpp) |
1659 | pipe_config->lane_count, pipe_config->port_clock,__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "DP lane count %d clock %d Input bpp %d Compressed bpp %d\n" , pipe_config->lane_count, pipe_config->port_clock, pipe_config ->pipe_bpp, pipe_config->dsc.compressed_bpp) |
1660 | pipe_config->pipe_bpp,__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "DP lane count %d clock %d Input bpp %d Compressed bpp %d\n" , pipe_config->lane_count, pipe_config->port_clock, pipe_config ->pipe_bpp, pipe_config->dsc.compressed_bpp) |
1661 | pipe_config->dsc.compressed_bpp)__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "DP lane count %d clock %d Input bpp %d Compressed bpp %d\n" , pipe_config->lane_count, pipe_config->port_clock, pipe_config ->pipe_bpp, pipe_config->dsc.compressed_bpp); |
1662 | |
1663 | drm_dbg_kms(&i915->drm,__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "DP link rate required %i available %i\n" , intel_dp_link_required(adjusted_mode->crtc_clock, pipe_config ->dsc.compressed_bpp), intel_dp_max_data_rate(pipe_config-> port_clock, pipe_config->lane_count)) |
1664 | "DP link rate required %i available %i\n",__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "DP link rate required %i available %i\n" , intel_dp_link_required(adjusted_mode->crtc_clock, pipe_config ->dsc.compressed_bpp), intel_dp_max_data_rate(pipe_config-> port_clock, pipe_config->lane_count)) |
1665 | intel_dp_link_required(adjusted_mode->crtc_clock,__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "DP link rate required %i available %i\n" , intel_dp_link_required(adjusted_mode->crtc_clock, pipe_config ->dsc.compressed_bpp), intel_dp_max_data_rate(pipe_config-> port_clock, pipe_config->lane_count)) |
1666 | pipe_config->dsc.compressed_bpp),__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "DP link rate required %i available %i\n" , intel_dp_link_required(adjusted_mode->crtc_clock, pipe_config ->dsc.compressed_bpp), intel_dp_max_data_rate(pipe_config-> port_clock, pipe_config->lane_count)) |
1667 | intel_dp_max_data_rate(pipe_config->port_clock,__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "DP link rate required %i available %i\n" , intel_dp_link_required(adjusted_mode->crtc_clock, pipe_config ->dsc.compressed_bpp), intel_dp_max_data_rate(pipe_config-> port_clock, pipe_config->lane_count)) |
1668 | pipe_config->lane_count))__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "DP link rate required %i available %i\n" , intel_dp_link_required(adjusted_mode->crtc_clock, pipe_config ->dsc.compressed_bpp), intel_dp_max_data_rate(pipe_config-> port_clock, pipe_config->lane_count)); |
1669 | } else { |
1670 | drm_dbg_kms(&i915->drm, "DP lane count %d clock %d bpp %d\n",__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "DP lane count %d clock %d bpp %d\n" , pipe_config->lane_count, pipe_config->port_clock, pipe_config ->pipe_bpp) |
1671 | pipe_config->lane_count, pipe_config->port_clock,__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "DP lane count %d clock %d bpp %d\n" , pipe_config->lane_count, pipe_config->port_clock, pipe_config ->pipe_bpp) |
1672 | pipe_config->pipe_bpp)__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "DP lane count %d clock %d bpp %d\n" , pipe_config->lane_count, pipe_config->port_clock, pipe_config ->pipe_bpp); |
1673 | |
1674 | drm_dbg_kms(&i915->drm,__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "DP link rate required %i available %i\n" , intel_dp_link_required(adjusted_mode->crtc_clock, pipe_config ->pipe_bpp), intel_dp_max_data_rate(pipe_config->port_clock , pipe_config->lane_count)) |
1675 | "DP link rate required %i available %i\n",__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "DP link rate required %i available %i\n" , intel_dp_link_required(adjusted_mode->crtc_clock, pipe_config ->pipe_bpp), intel_dp_max_data_rate(pipe_config->port_clock , pipe_config->lane_count)) |
1676 | intel_dp_link_required(adjusted_mode->crtc_clock,__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "DP link rate required %i available %i\n" , intel_dp_link_required(adjusted_mode->crtc_clock, pipe_config ->pipe_bpp), intel_dp_max_data_rate(pipe_config->port_clock , pipe_config->lane_count)) |
1677 | pipe_config->pipe_bpp),__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "DP link rate required %i available %i\n" , intel_dp_link_required(adjusted_mode->crtc_clock, pipe_config ->pipe_bpp), intel_dp_max_data_rate(pipe_config->port_clock , pipe_config->lane_count)) |
1678 | intel_dp_max_data_rate(pipe_config->port_clock,__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "DP link rate required %i available %i\n" , intel_dp_link_required(adjusted_mode->crtc_clock, pipe_config ->pipe_bpp), intel_dp_max_data_rate(pipe_config->port_clock , pipe_config->lane_count)) |
1679 | pipe_config->lane_count))__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "DP link rate required %i available %i\n" , intel_dp_link_required(adjusted_mode->crtc_clock, pipe_config ->pipe_bpp), intel_dp_max_data_rate(pipe_config->port_clock , pipe_config->lane_count)); |
1680 | } |
1681 | return 0; |
1682 | } |
1683 | |
1684 | bool_Bool intel_dp_limited_color_range(const struct intel_crtc_state *crtc_state, |
1685 | const struct drm_connector_state *conn_state) |
1686 | { |
1687 | const struct intel_digital_connector_state *intel_conn_state = |
1688 | to_intel_digital_connector_state(conn_state)({ const __typeof( ((struct intel_digital_connector_state *)0 )->base ) *__mptr = (conn_state); (struct intel_digital_connector_state *)( (char *)__mptr - __builtin_offsetof(struct intel_digital_connector_state , base) );}); |
1689 | const struct drm_display_mode *adjusted_mode = |
1690 | &crtc_state->hw.adjusted_mode; |
1691 | |
1692 | /* |
1693 | * Our YCbCr output is always limited range. |
1694 | * crtc_state->limited_color_range only applies to RGB, |
1695 | * and it must never be set for YCbCr or we risk setting |
1696 | * some conflicting bits in PIPECONF which will mess up |
1697 | * the colors on the monitor. |
1698 | */ |
1699 | if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB) |
1700 | return false0; |
1701 | |
1702 | if (intel_conn_state->broadcast_rgb == INTEL_BROADCAST_RGB_AUTO) { |
1703 | /* |
1704 | * See: |
1705 | * CEA-861-E - 5.1 Default Encoding Parameters |
1706 | * VESA DisplayPort Ver.1.2a - 5.1.1.1 Video Colorimetry |
1707 | */ |
1708 | return crtc_state->pipe_bpp != 18 && |
1709 | drm_default_rgb_quant_range(adjusted_mode) == |
1710 | HDMI_QUANTIZATION_RANGE_LIMITED; |
1711 | } else { |
1712 | return intel_conn_state->broadcast_rgb == |
1713 | INTEL_BROADCAST_RGB_LIMITED; |
1714 | } |
1715 | } |
1716 | |
1717 | static bool_Bool intel_dp_port_has_audio(struct drm_i915_privateinteldrm_softc *dev_priv, |
1718 | enum port port) |
1719 | { |
1720 | if (IS_G4X(dev_priv)(IS_PLATFORM(dev_priv, INTEL_G45) || IS_PLATFORM(dev_priv, INTEL_GM45 ))) |
1721 | return false0; |
1722 | if (DISPLAY_VER(dev_priv)((&(dev_priv)->__runtime)->display.ip.ver) < 12 && port == PORT_A) |
1723 | return false0; |
1724 | |
1725 | return true1; |
1726 | } |
1727 | |
1728 | static void intel_dp_compute_vsc_colorimetry(const struct intel_crtc_state *crtc_state, |
1729 | const struct drm_connector_state *conn_state, |
1730 | struct drm_dp_vsc_sdp *vsc) |
1731 | { |
1732 | struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc)({ const __typeof( ((struct intel_crtc *)0)->base ) *__mptr = (crtc_state->uapi.crtc); (struct intel_crtc *)( (char * )__mptr - __builtin_offsetof(struct intel_crtc, base) );}); |
1733 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(crtc->base.dev); |
1734 | |
1735 | /* |
1736 | * Prepare VSC Header for SU as per DP 1.4 spec, Table 2-118 |
1737 | * VSC SDP supporting 3D stereo, PSR2, and Pixel Encoding/ |
1738 | * Colorimetry Format indication. |
1739 | */ |
1740 | vsc->revision = 0x5; |
1741 | vsc->length = 0x13; |
1742 | |
1743 | /* DP 1.4a spec, Table 2-120 */ |
1744 | switch (crtc_state->output_format) { |
1745 | case INTEL_OUTPUT_FORMAT_YCBCR444: |
1746 | vsc->pixelformat = DP_PIXELFORMAT_YUV444; |
1747 | break; |
1748 | case INTEL_OUTPUT_FORMAT_YCBCR420: |
1749 | vsc->pixelformat = DP_PIXELFORMAT_YUV420; |
1750 | break; |
1751 | case INTEL_OUTPUT_FORMAT_RGB: |
1752 | default: |
1753 | vsc->pixelformat = DP_PIXELFORMAT_RGB; |
1754 | } |
1755 | |
1756 | switch (conn_state->colorspace) { |
1757 | case DRM_MODE_COLORIMETRY_BT709_YCC2: |
1758 | vsc->colorimetry = DP_COLORIMETRY_BT709_YCC; |
1759 | break; |
1760 | case DRM_MODE_COLORIMETRY_XVYCC_6013: |
1761 | vsc->colorimetry = DP_COLORIMETRY_XVYCC_601; |
1762 | break; |
1763 | case DRM_MODE_COLORIMETRY_XVYCC_7094: |
1764 | vsc->colorimetry = DP_COLORIMETRY_XVYCC_709; |
1765 | break; |
1766 | case DRM_MODE_COLORIMETRY_SYCC_6015: |
1767 | vsc->colorimetry = DP_COLORIMETRY_SYCC_601; |
1768 | break; |
1769 | case DRM_MODE_COLORIMETRY_OPYCC_6016: |
1770 | vsc->colorimetry = DP_COLORIMETRY_OPYCC_601; |
1771 | break; |
1772 | case DRM_MODE_COLORIMETRY_BT2020_CYCC8: |
1773 | vsc->colorimetry = DP_COLORIMETRY_BT2020_CYCC; |
1774 | break; |
1775 | case DRM_MODE_COLORIMETRY_BT2020_RGB9: |
1776 | vsc->colorimetry = DP_COLORIMETRY_BT2020_RGB; |
1777 | break; |
1778 | case DRM_MODE_COLORIMETRY_BT2020_YCC10: |
1779 | vsc->colorimetry = DP_COLORIMETRY_BT2020_YCC; |
1780 | break; |
1781 | case DRM_MODE_COLORIMETRY_DCI_P3_RGB_D6511: |
1782 | case DRM_MODE_COLORIMETRY_DCI_P3_RGB_THEATER12: |
1783 | vsc->colorimetry = DP_COLORIMETRY_DCI_P3_RGB; |
1784 | break; |
1785 | default: |
1786 | /* |
1787 | * RGB->YCBCR color conversion uses the BT.709 |
1788 | * color space. |
1789 | */ |
1790 | if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420) |
1791 | vsc->colorimetry = DP_COLORIMETRY_BT709_YCC; |
1792 | else |
1793 | vsc->colorimetry = DP_COLORIMETRY_DEFAULT; |
1794 | break; |
1795 | } |
1796 | |
1797 | vsc->bpc = crtc_state->pipe_bpp / 3; |
1798 | |
1799 | /* only RGB pixelformat supports 6 bpc */ |
1800 | drm_WARN_ON(&dev_priv->drm,({ int __ret = !!((vsc->bpc == 6 && vsc->pixelformat != DP_PIXELFORMAT_RGB)); if (__ret) printf("%s %s: " "%s", dev_driver_string (((&dev_priv->drm))->dev), "", "drm_WARN_ON(" "vsc->bpc == 6 && vsc->pixelformat != DP_PIXELFORMAT_RGB" ")"); __builtin_expect(!!(__ret), 0); }) |
1801 | vsc->bpc == 6 && vsc->pixelformat != DP_PIXELFORMAT_RGB)({ int __ret = !!((vsc->bpc == 6 && vsc->pixelformat != DP_PIXELFORMAT_RGB)); if (__ret) printf("%s %s: " "%s", dev_driver_string (((&dev_priv->drm))->dev), "", "drm_WARN_ON(" "vsc->bpc == 6 && vsc->pixelformat != DP_PIXELFORMAT_RGB" ")"); __builtin_expect(!!(__ret), 0); }); |
1802 | |
1803 | /* all YCbCr are always limited range */ |
1804 | vsc->dynamic_range = DP_DYNAMIC_RANGE_CTA; |
1805 | vsc->content_type = DP_CONTENT_TYPE_NOT_DEFINED; |
1806 | } |
1807 | |
1808 | static void intel_dp_compute_vsc_sdp(struct intel_dp *intel_dp, |
1809 | struct intel_crtc_state *crtc_state, |
1810 | const struct drm_connector_state *conn_state) |
1811 | { |
1812 | struct drm_dp_vsc_sdp *vsc = &crtc_state->infoframes.vsc; |
1813 | |
1814 | /* When a crtc state has PSR, VSC SDP will be handled by PSR routine */ |
1815 | if (crtc_state->has_psr) |
1816 | return; |
1817 | |
1818 | if (!intel_dp_needs_vsc_sdp(crtc_state, conn_state)) |
1819 | return; |
1820 | |
1821 | crtc_state->infoframes.enable |= intel_hdmi_infoframe_enable(DP_SDP_VSC0x07); |
1822 | vsc->sdp_type = DP_SDP_VSC0x07; |
1823 | intel_dp_compute_vsc_colorimetry(crtc_state, conn_state, |
1824 | &crtc_state->infoframes.vsc); |
1825 | } |
1826 | |
1827 | void intel_dp_compute_psr_vsc_sdp(struct intel_dp *intel_dp, |
1828 | const struct intel_crtc_state *crtc_state, |
1829 | const struct drm_connector_state *conn_state, |
1830 | struct drm_dp_vsc_sdp *vsc) |
1831 | { |
1832 | vsc->sdp_type = DP_SDP_VSC0x07; |
1833 | |
1834 | if (crtc_state->has_psr2) { |
1835 | if (intel_dp->psr.colorimetry_support && |
1836 | intel_dp_needs_vsc_sdp(crtc_state, conn_state)) { |
1837 | /* [PSR2, +Colorimetry] */ |
1838 | intel_dp_compute_vsc_colorimetry(crtc_state, conn_state, |
1839 | vsc); |
1840 | } else { |
1841 | /* |
1842 | * [PSR2, -Colorimetry] |
1843 | * Prepare VSC Header for SU as per eDP 1.4 spec, Table 6-11 |
1844 | * 3D stereo + PSR/PSR2 + Y-coordinate. |
1845 | */ |
1846 | vsc->revision = 0x4; |
1847 | vsc->length = 0xe; |
1848 | } |
1849 | } else { |
1850 | /* |
1851 | * [PSR1] |
1852 | * Prepare VSC Header for SU as per DP 1.4 spec, Table 2-118 |
1853 | * VSC SDP supporting 3D stereo + PSR (applies to eDP v1.3 or |
1854 | * higher). |
1855 | */ |
1856 | vsc->revision = 0x2; |
1857 | vsc->length = 0x8; |
1858 | } |
1859 | } |
1860 | |
1861 | static void |
1862 | intel_dp_compute_hdr_metadata_infoframe_sdp(struct intel_dp *intel_dp, |
1863 | struct intel_crtc_state *crtc_state, |
1864 | const struct drm_connector_state *conn_state) |
1865 | { |
1866 | int ret; |
1867 | struct drm_i915_privateinteldrm_softc *dev_priv = dp_to_i915(intel_dp)to_i915(dp_to_dig_port(intel_dp)->base.base.dev); |
1868 | struct hdmi_drm_infoframe *drm_infoframe = &crtc_state->infoframes.drm.drm; |
1869 | |
1870 | if (!conn_state->hdr_output_metadata) |
1871 | return; |
1872 | |
1873 | ret = drm_hdmi_infoframe_set_hdr_metadata(drm_infoframe, conn_state); |
1874 | |
1875 | if (ret) { |
1876 | drm_dbg_kms(&dev_priv->drm, "couldn't set HDR metadata in infoframe\n")__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "couldn't set HDR metadata in infoframe\n" ); |
1877 | return; |
1878 | } |
1879 | |
1880 | crtc_state->infoframes.enable |= |
1881 | intel_hdmi_infoframe_enable(HDMI_PACKET_TYPE_GAMUT_METADATA); |
1882 | } |
1883 | |
1884 | static bool_Bool cpu_transcoder_has_drrs(struct drm_i915_privateinteldrm_softc *i915, |
1885 | enum transcoder cpu_transcoder) |
1886 | { |
1887 | if (HAS_DOUBLE_BUFFERED_M_N(i915)(((&(i915)->__runtime)->display.ip.ver) >= 9 || IS_PLATFORM (i915, INTEL_BROADWELL))) |
1888 | return true1; |
1889 | |
1890 | return intel_cpu_transcoder_has_m2_n2(i915, cpu_transcoder); |
1891 | } |
1892 | |
1893 | static bool_Bool can_enable_drrs(struct intel_connector *connector, |
1894 | const struct intel_crtc_state *pipe_config, |
1895 | const struct drm_display_mode *downclock_mode) |
1896 | { |
1897 | struct drm_i915_privateinteldrm_softc *i915 = to_i915(connector->base.dev); |
1898 | |
1899 | if (pipe_config->vrr.enable) |
1900 | return false0; |
1901 | |
1902 | /* |
1903 | * DRRS and PSR can't be enable together, so giving preference to PSR |
1904 | * as it allows more power-savings by complete shutting down display, |
1905 | * so to guarantee this, intel_drrs_compute_config() must be called |
1906 | * after intel_psr_compute_config(). |
1907 | */ |
1908 | if (pipe_config->has_psr) |
1909 | return false0; |
1910 | |
1911 | /* FIXME missing FDI M2/N2 etc. */ |
1912 | if (pipe_config->has_pch_encoder) |
1913 | return false0; |
1914 | |
1915 | if (!cpu_transcoder_has_drrs(i915, pipe_config->cpu_transcoder)) |
1916 | return false0; |
1917 | |
1918 | return downclock_mode && |
1919 | intel_panel_drrs_type(connector) == DRRS_TYPE_SEAMLESS; |
1920 | } |
1921 | |
1922 | static void |
1923 | intel_dp_drrs_compute_config(struct intel_connector *connector, |
1924 | struct intel_crtc_state *pipe_config, |
1925 | int output_bpp) |
1926 | { |
1927 | struct drm_i915_privateinteldrm_softc *i915 = to_i915(connector->base.dev); |
1928 | const struct drm_display_mode *downclock_mode = |
1929 | intel_panel_downclock_mode(connector, &pipe_config->hw.adjusted_mode); |
1930 | int pixel_clock; |
1931 | |
1932 | if (has_seamless_m_n(connector)) |
1933 | pipe_config->seamless_m_n = true1; |
1934 | |
1935 | if (!can_enable_drrs(connector, pipe_config, downclock_mode)) { |
1936 | if (intel_cpu_transcoder_has_m2_n2(i915, pipe_config->cpu_transcoder)) |
1937 | intel_zero_m_n(&pipe_config->dp_m2_n2); |
1938 | return; |
1939 | } |
1940 | |
1941 | if (IS_IRONLAKE(i915)IS_PLATFORM(i915, INTEL_IRONLAKE) || IS_SANDYBRIDGE(i915)IS_PLATFORM(i915, INTEL_SANDYBRIDGE) || IS_IVYBRIDGE(i915)IS_PLATFORM(i915, INTEL_IVYBRIDGE)) |
1942 | pipe_config->msa_timing_delay = connector->panel.vbt.edp.drrs_msa_timing_delay; |
1943 | |
1944 | pipe_config->has_drrs = true1; |
1945 | |
1946 | pixel_clock = downclock_mode->clock; |
1947 | if (pipe_config->splitter.enable) |
1948 | pixel_clock /= pipe_config->splitter.link_count; |
1949 | |
1950 | intel_link_compute_m_n(output_bpp, pipe_config->lane_count, pixel_clock, |
1951 | pipe_config->port_clock, &pipe_config->dp_m2_n2, |
1952 | pipe_config->fec_enable); |
1953 | |
1954 | /* FIXME: abstract this better */ |
1955 | if (pipe_config->splitter.enable) |
1956 | pipe_config->dp_m2_n2.data_m *= pipe_config->splitter.link_count; |
1957 | } |
1958 | |
1959 | static bool_Bool intel_dp_has_audio(struct intel_encoder *encoder, |
1960 | const struct intel_crtc_state *crtc_state, |
1961 | const struct drm_connector_state *conn_state) |
1962 | { |
1963 | struct drm_i915_privateinteldrm_softc *i915 = to_i915(encoder->base.dev); |
1964 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
1965 | const struct intel_digital_connector_state *intel_conn_state = |
1966 | to_intel_digital_connector_state(conn_state)({ const __typeof( ((struct intel_digital_connector_state *)0 )->base ) *__mptr = (conn_state); (struct intel_digital_connector_state *)( (char *)__mptr - __builtin_offsetof(struct intel_digital_connector_state , base) );}); |
1967 | |
1968 | if (!intel_dp_port_has_audio(i915, encoder->port)) |
1969 | return false0; |
1970 | |
1971 | if (intel_conn_state->force_audio == HDMI_AUDIO_AUTO) |
1972 | return intel_dp->has_audio; |
1973 | else |
1974 | return intel_conn_state->force_audio == HDMI_AUDIO_ON; |
1975 | } |
1976 | |
1977 | static int |
1978 | intel_dp_compute_output_format(struct intel_encoder *encoder, |
1979 | struct intel_crtc_state *crtc_state, |
1980 | struct drm_connector_state *conn_state, |
1981 | bool_Bool respect_downstream_limits) |
1982 | { |
1983 | struct drm_i915_privateinteldrm_softc *i915 = to_i915(encoder->base.dev); |
1984 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
1985 | struct intel_connector *connector = intel_dp->attached_connector; |
1986 | const struct drm_display_info *info = &connector->base.display_info; |
1987 | const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; |
1988 | bool_Bool ycbcr_420_only; |
1989 | int ret; |
1990 | |
1991 | ycbcr_420_only = drm_mode_is_420_only(info, adjusted_mode); |
1992 | |
1993 | crtc_state->output_format = intel_dp_output_format(connector, ycbcr_420_only); |
1994 | |
1995 | if (ycbcr_420_only && !intel_dp_is_ycbcr420(intel_dp, crtc_state)) { |
1996 | drm_dbg_kms(&i915->drm,__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "YCbCr 4:2:0 mode but YCbCr 4:2:0 output not possible. Falling back to RGB.\n" ) |
1997 | "YCbCr 4:2:0 mode but YCbCr 4:2:0 output not possible. Falling back to RGB.\n")__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "YCbCr 4:2:0 mode but YCbCr 4:2:0 output not possible. Falling back to RGB.\n" ); |
1998 | crtc_state->output_format = INTEL_OUTPUT_FORMAT_RGB; |
1999 | } |
2000 | |
2001 | ret = intel_dp_compute_link_config(encoder, crtc_state, conn_state, |
2002 | respect_downstream_limits); |
2003 | if (ret) { |
2004 | if (intel_dp_is_ycbcr420(intel_dp, crtc_state) || |
2005 | !connector->base.ycbcr_420_allowed || |
2006 | !drm_mode_is_420_also(info, adjusted_mode)) |
2007 | return ret; |
2008 | |
2009 | crtc_state->output_format = intel_dp_output_format(connector, true1); |
2010 | ret = intel_dp_compute_link_config(encoder, crtc_state, conn_state, |
2011 | respect_downstream_limits); |
2012 | } |
2013 | |
2014 | return ret; |
2015 | } |
2016 | |
2017 | int |
2018 | intel_dp_compute_config(struct intel_encoder *encoder, |
2019 | struct intel_crtc_state *pipe_config, |
2020 | struct drm_connector_state *conn_state) |
2021 | { |
2022 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
2023 | struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode; |
2024 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
2025 | const struct drm_display_mode *fixed_mode; |
2026 | struct intel_connector *connector = intel_dp->attached_connector; |
2027 | int ret = 0, output_bpp; |
2028 | |
2029 | if (HAS_PCH_SPLIT(dev_priv)(((dev_priv)->pch_type) != PCH_NONE) && !HAS_DDI(dev_priv)((&(dev_priv)->__info)->display.has_ddi) && encoder->port != PORT_A) |
2030 | pipe_config->has_pch_encoder = true1; |
2031 | |
2032 | pipe_config->has_audio = intel_dp_has_audio(encoder, pipe_config, conn_state); |
2033 | |
2034 | fixed_mode = intel_panel_fixed_mode(connector, adjusted_mode); |
2035 | if (intel_dp_is_edp(intel_dp) && fixed_mode) { |
2036 | ret = intel_panel_compute_config(connector, adjusted_mode); |
2037 | if (ret) |
2038 | return ret; |
2039 | } |
2040 | |
2041 | if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN(1<<5)) |
2042 | return -EINVAL22; |
2043 | |
2044 | if (HAS_GMCH(dev_priv)((&(dev_priv)->__info)->display.has_gmch) && |
2045 | adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE(1<<4)) |
2046 | return -EINVAL22; |
2047 | |
2048 | if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK(1<<12)) |
2049 | return -EINVAL22; |
2050 | |
2051 | if (intel_dp_hdisplay_bad(dev_priv, adjusted_mode->crtc_hdisplay)) |
2052 | return -EINVAL22; |
2053 | |
2054 | /* |
2055 | * Try to respect downstream TMDS clock limits first, if |
2056 | * that fails assume the user might know something we don't. |
2057 | */ |
2058 | ret = intel_dp_compute_output_format(encoder, pipe_config, conn_state, true1); |
2059 | if (ret) |
2060 | ret = intel_dp_compute_output_format(encoder, pipe_config, conn_state, false0); |
2061 | if (ret) |
2062 | return ret; |
2063 | |
2064 | if ((intel_dp_is_edp(intel_dp) && fixed_mode) || |
2065 | pipe_config->output_format == INTEL_OUTPUT_FORMAT_YCBCR420) { |
2066 | ret = intel_panel_fitting(pipe_config, conn_state); |
2067 | if (ret) |
2068 | return ret; |
2069 | } |
2070 | |
2071 | pipe_config->limited_color_range = |
2072 | intel_dp_limited_color_range(pipe_config, conn_state); |
2073 | |
2074 | if (pipe_config->dsc.compression_enable) |
2075 | output_bpp = pipe_config->dsc.compressed_bpp; |
2076 | else |
2077 | output_bpp = intel_dp_output_bpp(pipe_config->output_format, |
2078 | pipe_config->pipe_bpp); |
2079 | |
2080 | if (intel_dp->mso_link_count) { |
2081 | int n = intel_dp->mso_link_count; |
2082 | int overlap = intel_dp->mso_pixel_overlap; |
2083 | |
2084 | pipe_config->splitter.enable = true1; |
2085 | pipe_config->splitter.link_count = n; |
2086 | pipe_config->splitter.pixel_overlap = overlap; |
2087 | |
2088 | drm_dbg_kms(&dev_priv->drm, "MSO link count %d, pixel overlap %d\n",__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "MSO link count %d, pixel overlap %d\n" , n, overlap) |
2089 | n, overlap)__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "MSO link count %d, pixel overlap %d\n" , n, overlap); |
2090 | |
2091 | adjusted_mode->crtc_hdisplay = adjusted_mode->crtc_hdisplay / n + overlap; |
2092 | adjusted_mode->crtc_hblank_start = adjusted_mode->crtc_hblank_start / n + overlap; |
2093 | adjusted_mode->crtc_hblank_end = adjusted_mode->crtc_hblank_end / n + overlap; |
2094 | adjusted_mode->crtc_hsync_start = adjusted_mode->crtc_hsync_start / n + overlap; |
2095 | adjusted_mode->crtc_hsync_end = adjusted_mode->crtc_hsync_end / n + overlap; |
2096 | adjusted_mode->crtc_htotal = adjusted_mode->crtc_htotal / n + overlap; |
2097 | adjusted_mode->crtc_clock /= n; |
2098 | } |
2099 | |
2100 | intel_link_compute_m_n(output_bpp, |
2101 | pipe_config->lane_count, |
2102 | adjusted_mode->crtc_clock, |
2103 | pipe_config->port_clock, |
2104 | &pipe_config->dp_m_n, |
2105 | pipe_config->fec_enable); |
2106 | |
2107 | /* FIXME: abstract this better */ |
2108 | if (pipe_config->splitter.enable) |
2109 | pipe_config->dp_m_n.data_m *= pipe_config->splitter.link_count; |
2110 | |
2111 | if (!HAS_DDI(dev_priv)((&(dev_priv)->__info)->display.has_ddi)) |
2112 | g4x_dp_set_clock(encoder, pipe_config); |
2113 | |
2114 | intel_vrr_compute_config(pipe_config, conn_state); |
2115 | intel_psr_compute_config(intel_dp, pipe_config, conn_state); |
2116 | intel_dp_drrs_compute_config(connector, pipe_config, output_bpp); |
2117 | intel_dp_compute_vsc_sdp(intel_dp, pipe_config, conn_state); |
2118 | intel_dp_compute_hdr_metadata_infoframe_sdp(intel_dp, pipe_config, conn_state); |
2119 | |
2120 | return 0; |
2121 | } |
2122 | |
2123 | void intel_dp_set_link_params(struct intel_dp *intel_dp, |
2124 | int link_rate, int lane_count) |
2125 | { |
2126 | memset(intel_dp->train_set, 0, sizeof(intel_dp->train_set))__builtin_memset((intel_dp->train_set), (0), (sizeof(intel_dp ->train_set))); |
2127 | intel_dp->link_trained = false0; |
2128 | intel_dp->link_rate = link_rate; |
2129 | intel_dp->lane_count = lane_count; |
2130 | } |
2131 | |
2132 | static void intel_dp_reset_max_link_params(struct intel_dp *intel_dp) |
2133 | { |
2134 | intel_dp->max_link_lane_count = intel_dp_max_common_lane_count(intel_dp); |
2135 | intel_dp->max_link_rate = intel_dp_max_common_rate(intel_dp); |
2136 | } |
2137 | |
2138 | /* Enable backlight PWM and backlight PP control. */ |
2139 | void intel_edp_backlight_on(const struct intel_crtc_state *crtc_state, |
2140 | const struct drm_connector_state *conn_state) |
2141 | { |
2142 | struct intel_dp *intel_dp = enc_to_intel_dp(to_intel_encoder(conn_state->best_encoder)({ const __typeof( ((struct intel_encoder *)0)->base ) *__mptr = (conn_state->best_encoder); (struct intel_encoder *)( ( char *)__mptr - __builtin_offsetof(struct intel_encoder, base ) );})); |
2143 | struct drm_i915_privateinteldrm_softc *i915 = dp_to_i915(intel_dp)to_i915(dp_to_dig_port(intel_dp)->base.base.dev); |
2144 | |
2145 | if (!intel_dp_is_edp(intel_dp)) |
2146 | return; |
2147 | |
2148 | drm_dbg_kms(&i915->drm, "\n")__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "\n"); |
2149 | |
2150 | intel_backlight_enable(crtc_state, conn_state); |
2151 | intel_pps_backlight_on(intel_dp); |
2152 | } |
2153 | |
2154 | /* Disable backlight PP control and backlight PWM. */ |
2155 | void intel_edp_backlight_off(const struct drm_connector_state *old_conn_state) |
2156 | { |
2157 | struct intel_dp *intel_dp = enc_to_intel_dp(to_intel_encoder(old_conn_state->best_encoder)({ const __typeof( ((struct intel_encoder *)0)->base ) *__mptr = (old_conn_state->best_encoder); (struct intel_encoder * )( (char *)__mptr - __builtin_offsetof(struct intel_encoder, base ) );})); |
2158 | struct drm_i915_privateinteldrm_softc *i915 = dp_to_i915(intel_dp)to_i915(dp_to_dig_port(intel_dp)->base.base.dev); |
2159 | |
2160 | if (!intel_dp_is_edp(intel_dp)) |
2161 | return; |
2162 | |
2163 | drm_dbg_kms(&i915->drm, "\n")__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "\n"); |
2164 | |
2165 | intel_pps_backlight_off(intel_dp); |
2166 | intel_backlight_disable(old_conn_state); |
2167 | } |
2168 | |
2169 | static bool_Bool downstream_hpd_needs_d0(struct intel_dp *intel_dp) |
2170 | { |
2171 | /* |
2172 | * DPCD 1.2+ should support BRANCH_DEVICE_CTRL, and thus |
2173 | * be capable of signalling downstream hpd with a long pulse. |
2174 | * Whether or not that means D3 is safe to use is not clear, |
2175 | * but let's assume so until proven otherwise. |
2176 | * |
2177 | * FIXME should really check all downstream ports... |
2178 | */ |
2179 | return intel_dp->dpcd[DP_DPCD_REV0x000] == 0x11 && |
2180 | drm_dp_is_branch(intel_dp->dpcd) && |
2181 | intel_dp->downstream_ports[0] & DP_DS_PORT_HPD(1 << 3); |
2182 | } |
2183 | |
2184 | void intel_dp_sink_set_decompression_state(struct intel_dp *intel_dp, |
2185 | const struct intel_crtc_state *crtc_state, |
2186 | bool_Bool enable) |
2187 | { |
2188 | struct drm_i915_privateinteldrm_softc *i915 = dp_to_i915(intel_dp)to_i915(dp_to_dig_port(intel_dp)->base.base.dev); |
2189 | int ret; |
2190 | |
2191 | if (!crtc_state->dsc.compression_enable) |
2192 | return; |
2193 | |
2194 | ret = drm_dp_dpcd_writeb(&intel_dp->aux, DP_DSC_ENABLE0x160, |
2195 | enable ? DP_DECOMPRESSION_EN(1 << 0) : 0); |
2196 | if (ret < 0) |
2197 | drm_dbg_kms(&i915->drm,__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "Failed to %s sink decompression state\n" , str_enable_disable(enable)) |
2198 | "Failed to %s sink decompression state\n",__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "Failed to %s sink decompression state\n" , str_enable_disable(enable)) |
2199 | str_enable_disable(enable))__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "Failed to %s sink decompression state\n" , str_enable_disable(enable)); |
2200 | } |
2201 | |
2202 | static void |
2203 | intel_edp_init_source_oui(struct intel_dp *intel_dp, bool_Bool careful) |
2204 | { |
2205 | struct drm_i915_privateinteldrm_softc *i915 = dp_to_i915(intel_dp)to_i915(dp_to_dig_port(intel_dp)->base.base.dev); |
Value stored to 'i915' during its initialization is never read | |
2206 | u8 oui[] = { 0x00, 0xaa, 0x01 }; |
2207 | u8 buf[3] = { 0 }; |
2208 | |
2209 | /* |
2210 | * During driver init, we want to be careful and avoid changing the source OUI if it's |
2211 | * already set to what we want, so as to avoid clearing any state by accident |
2212 | */ |
2213 | if (careful) { |
2214 | if (drm_dp_dpcd_read(&intel_dp->aux, DP_SOURCE_OUI0x300, buf, sizeof(buf)) < 0) |
2215 | drm_err(&i915->drm, "Failed to read source OUI\n")printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "Failed to read source OUI\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__); |
2216 | |
2217 | if (memcmp(oui, buf, sizeof(oui))__builtin_memcmp((oui), (buf), (sizeof(oui))) == 0) |
2218 | return; |
2219 | } |
2220 | |
2221 | if (drm_dp_dpcd_write(&intel_dp->aux, DP_SOURCE_OUI0x300, oui, sizeof(oui)) < 0) |
2222 | drm_err(&i915->drm, "Failed to write source OUI\n")printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "Failed to write source OUI\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__); |
2223 | |
2224 | intel_dp->last_oui_write = jiffies; |
2225 | } |
2226 | |
2227 | void intel_dp_wait_source_oui(struct intel_dp *intel_dp) |
2228 | { |
2229 | struct drm_i915_privateinteldrm_softc *i915 = dp_to_i915(intel_dp)to_i915(dp_to_dig_port(intel_dp)->base.base.dev); |
2230 | |
2231 | drm_dbg_kms(&i915->drm, "Performing OUI wait\n")__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "Performing OUI wait\n" ); |
2232 | wait_remaining_ms_from_jiffies(intel_dp->last_oui_write, 30); |
2233 | } |
2234 | |
2235 | /* If the device supports it, try to set the power state appropriately */ |
2236 | void intel_dp_set_power(struct intel_dp *intel_dp, u8 mode) |
2237 | { |
2238 | struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; |
2239 | struct drm_i915_privateinteldrm_softc *i915 = to_i915(encoder->base.dev); |
2240 | int ret, i; |
2241 | |
2242 | /* Should have a valid DPCD by this point */ |
2243 | if (intel_dp->dpcd[DP_DPCD_REV0x000] < 0x11) |
2244 | return; |
2245 | |
2246 | if (mode != DP_SET_POWER_D00x1) { |
2247 | if (downstream_hpd_needs_d0(intel_dp)) |
2248 | return; |
2249 | |
2250 | ret = drm_dp_dpcd_writeb(&intel_dp->aux, DP_SET_POWER0x600, mode); |
2251 | } else { |
2252 | struct intel_lspcon *lspcon = dp_to_lspcon(intel_dp); |
2253 | |
2254 | lspcon_resume(dp_to_dig_port(intel_dp)); |
2255 | |
2256 | /* Write the source OUI as early as possible */ |
2257 | if (intel_dp_is_edp(intel_dp)) |
2258 | intel_edp_init_source_oui(intel_dp, false0); |
2259 | |
2260 | /* |
2261 | * When turning on, we need to retry for 1ms to give the sink |
2262 | * time to wake up. |
2263 | */ |
2264 | for (i = 0; i < 3; i++) { |
2265 | ret = drm_dp_dpcd_writeb(&intel_dp->aux, DP_SET_POWER0x600, mode); |
2266 | if (ret == 1) |
2267 | break; |
2268 | drm_msleep(1)mdelay(1); |
2269 | } |
2270 | |
2271 | if (ret == 1 && lspcon->active) |
2272 | lspcon_wait_pcon_mode(lspcon); |
2273 | } |
2274 | |
2275 | if (ret != 1) |
2276 | drm_dbg_kms(&i915->drm, "[ENCODER:%d:%s] Set power to %s failed\n",__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "[ENCODER:%d:%s] Set power to %s failed\n" , encoder->base.base.id, encoder->base.name, mode == 0x1 ? "D0" : "D3") |
2277 | encoder->base.base.id, encoder->base.name,__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "[ENCODER:%d:%s] Set power to %s failed\n" , encoder->base.base.id, encoder->base.name, mode == 0x1 ? "D0" : "D3") |
2278 | mode == DP_SET_POWER_D0 ? "D0" : "D3")__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "[ENCODER:%d:%s] Set power to %s failed\n" , encoder->base.base.id, encoder->base.name, mode == 0x1 ? "D0" : "D3"); |
2279 | } |
2280 | |
2281 | static bool_Bool |
2282 | intel_dp_get_dpcd(struct intel_dp *intel_dp); |
2283 | |
2284 | /** |
2285 | * intel_dp_sync_state - sync the encoder state during init/resume |
2286 | * @encoder: intel encoder to sync |
2287 | * @crtc_state: state for the CRTC connected to the encoder |
2288 | * |
2289 | * Sync any state stored in the encoder wrt. HW state during driver init |
2290 | * and system resume. |
2291 | */ |
2292 | void intel_dp_sync_state(struct intel_encoder *encoder, |
2293 | const struct intel_crtc_state *crtc_state) |
2294 | { |
2295 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
2296 | |
2297 | if (!crtc_state) |
2298 | return; |
2299 | |
2300 | /* |
2301 | * Don't clobber DPCD if it's been already read out during output |
2302 | * setup (eDP) or detect. |
2303 | */ |
2304 | if (intel_dp->dpcd[DP_DPCD_REV0x000] == 0) |
2305 | intel_dp_get_dpcd(intel_dp); |
2306 | |
2307 | intel_dp_reset_max_link_params(intel_dp); |
2308 | } |
2309 | |
2310 | bool_Bool intel_dp_initial_fastset_check(struct intel_encoder *encoder, |
2311 | struct intel_crtc_state *crtc_state) |
2312 | { |
2313 | struct drm_i915_privateinteldrm_softc *i915 = to_i915(encoder->base.dev); |
2314 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
2315 | |
2316 | /* |
2317 | * If BIOS has set an unsupported or non-standard link rate for some |
2318 | * reason force an encoder recompute and full modeset. |
2319 | */ |
2320 | if (intel_dp_rate_index(intel_dp->source_rates, intel_dp->num_source_rates, |
2321 | crtc_state->port_clock) < 0) { |
2322 | drm_dbg_kms(&i915->drm, "Forcing full modeset due to unsupported link rate\n")__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "Forcing full modeset due to unsupported link rate\n" ); |
2323 | crtc_state->uapi.connectors_changed = true1; |
2324 | return false0; |
2325 | } |
2326 | |
2327 | /* |
2328 | * FIXME hack to force full modeset when DSC is being used. |
2329 | * |
2330 | * As long as we do not have full state readout and config comparison |
2331 | * of crtc_state->dsc, we have no way to ensure reliable fastset. |
2332 | * Remove once we have readout for DSC. |
2333 | */ |
2334 | if (crtc_state->dsc.compression_enable) { |
2335 | drm_dbg_kms(&i915->drm, "Forcing full modeset due to DSC being enabled\n")__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "Forcing full modeset due to DSC being enabled\n" ); |
2336 | crtc_state->uapi.mode_changed = true1; |
2337 | return false0; |
2338 | } |
2339 | |
2340 | if (CAN_PSR(intel_dp)((intel_dp)->psr.sink_support && (intel_dp)->psr .source_support)) { |
2341 | drm_dbg_kms(&i915->drm, "Forcing full modeset to compute PSR state\n")__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "Forcing full modeset to compute PSR state\n" ); |
2342 | crtc_state->uapi.mode_changed = true1; |
2343 | return false0; |
2344 | } |
2345 | |
2346 | return true1; |
2347 | } |
2348 | |
2349 | static void intel_dp_get_pcon_dsc_cap(struct intel_dp *intel_dp) |
2350 | { |
2351 | struct drm_i915_privateinteldrm_softc *i915 = dp_to_i915(intel_dp)to_i915(dp_to_dig_port(intel_dp)->base.base.dev); |
2352 | |
2353 | /* Clear the cached register set to avoid using stale values */ |
2354 | |
2355 | memset(intel_dp->pcon_dsc_dpcd, 0, sizeof(intel_dp->pcon_dsc_dpcd))__builtin_memset((intel_dp->pcon_dsc_dpcd), (0), (sizeof(intel_dp ->pcon_dsc_dpcd))); |
2356 | |
2357 | if (drm_dp_dpcd_read(&intel_dp->aux, DP_PCON_DSC_ENCODER0x092, |
2358 | intel_dp->pcon_dsc_dpcd, |
2359 | sizeof(intel_dp->pcon_dsc_dpcd)) < 0) |
2360 | drm_err(&i915->drm, "Failed to read DPCD register 0x%x\n",printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "Failed to read DPCD register 0x%x\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , 0x092) |
2361 | DP_PCON_DSC_ENCODER)printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "Failed to read DPCD register 0x%x\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , 0x092); |
2362 | |
2363 | drm_dbg_kms(&i915->drm, "PCON ENCODER DSC DPCD: %*ph\n",__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "PCON ENCODER DSC DPCD: %*ph\n" , (int)sizeof(intel_dp->pcon_dsc_dpcd), intel_dp->pcon_dsc_dpcd ) |
2364 | (int)sizeof(intel_dp->pcon_dsc_dpcd), intel_dp->pcon_dsc_dpcd)__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "PCON ENCODER DSC DPCD: %*ph\n" , (int)sizeof(intel_dp->pcon_dsc_dpcd), intel_dp->pcon_dsc_dpcd ); |
2365 | } |
2366 | |
2367 | static int intel_dp_pcon_get_frl_mask(u8 frl_bw_mask) |
2368 | { |
2369 | int bw_gbps[] = {9, 18, 24, 32, 40, 48}; |
2370 | int i; |
2371 | |
2372 | for (i = ARRAY_SIZE(bw_gbps)(sizeof((bw_gbps)) / sizeof((bw_gbps)[0])) - 1; i >= 0; i--) { |
2373 | if (frl_bw_mask & (1 << i)) |
2374 | return bw_gbps[i]; |
2375 | } |
2376 | return 0; |
2377 | } |
2378 | |
2379 | static int intel_dp_pcon_set_frl_mask(int max_frl) |
2380 | { |
2381 | switch (max_frl) { |
2382 | case 48: |
2383 | return DP_PCON_FRL_BW_MASK_48GBPS(1 << 5); |
2384 | case 40: |
2385 | return DP_PCON_FRL_BW_MASK_40GBPS(1 << 4); |
2386 | case 32: |
2387 | return DP_PCON_FRL_BW_MASK_32GBPS(1 << 3); |
2388 | case 24: |
2389 | return DP_PCON_FRL_BW_MASK_24GBPS(1 << 2); |
2390 | case 18: |
2391 | return DP_PCON_FRL_BW_MASK_18GBPS(1 << 1); |
2392 | case 9: |
2393 | return DP_PCON_FRL_BW_MASK_9GBPS(1 << 0); |
2394 | } |
2395 | |
2396 | return 0; |
2397 | } |
2398 | |
2399 | static int intel_dp_hdmi_sink_max_frl(struct intel_dp *intel_dp) |
2400 | { |
2401 | struct intel_connector *intel_connector = intel_dp->attached_connector; |
2402 | struct drm_connector *connector = &intel_connector->base; |
2403 | int max_frl_rate; |
2404 | int max_lanes, rate_per_lane; |
2405 | int max_dsc_lanes, dsc_rate_per_lane; |
2406 | |
2407 | max_lanes = connector->display_info.hdmi.max_lanes; |
2408 | rate_per_lane = connector->display_info.hdmi.max_frl_rate_per_lane; |
2409 | max_frl_rate = max_lanes * rate_per_lane; |
2410 | |
2411 | if (connector->display_info.hdmi.dsc_cap.v_1p2) { |
2412 | max_dsc_lanes = connector->display_info.hdmi.dsc_cap.max_lanes; |
2413 | dsc_rate_per_lane = connector->display_info.hdmi.dsc_cap.max_frl_rate_per_lane; |
2414 | if (max_dsc_lanes && dsc_rate_per_lane) |
2415 | max_frl_rate = min(max_frl_rate, max_dsc_lanes * dsc_rate_per_lane)(((max_frl_rate)<(max_dsc_lanes * dsc_rate_per_lane))?(max_frl_rate ):(max_dsc_lanes * dsc_rate_per_lane)); |
2416 | } |
2417 | |
2418 | return max_frl_rate; |
2419 | } |
2420 | |
2421 | static bool_Bool |
2422 | intel_dp_pcon_is_frl_trained(struct intel_dp *intel_dp, |
2423 | u8 max_frl_bw_mask, u8 *frl_trained_mask) |
2424 | { |
2425 | if (drm_dp_pcon_hdmi_link_active(&intel_dp->aux) && |
2426 | drm_dp_pcon_hdmi_link_mode(&intel_dp->aux, frl_trained_mask) == DP_PCON_HDMI_MODE_FRL1 && |
2427 | *frl_trained_mask >= max_frl_bw_mask) |
2428 | return true1; |
2429 | |
2430 | return false0; |
2431 | } |
2432 | |
2433 | static int intel_dp_pcon_start_frl_training(struct intel_dp *intel_dp) |
2434 | { |
2435 | #define TIMEOUT_FRL_READY_MS500 500 |
2436 | #define TIMEOUT_HDMI_LINK_ACTIVE_MS1000 1000 |
2437 | |
2438 | struct drm_i915_privateinteldrm_softc *i915 = dp_to_i915(intel_dp)to_i915(dp_to_dig_port(intel_dp)->base.base.dev); |
2439 | int max_frl_bw, max_pcon_frl_bw, max_edid_frl_bw, ret; |
2440 | u8 max_frl_bw_mask = 0, frl_trained_mask; |
2441 | bool_Bool is_active; |
2442 | |
2443 | max_pcon_frl_bw = intel_dp->dfp.pcon_max_frl_bw; |
2444 | drm_dbg(&i915->drm, "PCON max rate = %d Gbps\n", max_pcon_frl_bw)__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_DRIVER, "PCON max rate = %d Gbps\n" , max_pcon_frl_bw); |
2445 | |
2446 | max_edid_frl_bw = intel_dp_hdmi_sink_max_frl(intel_dp); |
2447 | drm_dbg(&i915->drm, "Sink max rate from EDID = %d Gbps\n", max_edid_frl_bw)__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_DRIVER, "Sink max rate from EDID = %d Gbps\n" , max_edid_frl_bw); |
2448 | |
2449 | max_frl_bw = min(max_edid_frl_bw, max_pcon_frl_bw)(((max_edid_frl_bw)<(max_pcon_frl_bw))?(max_edid_frl_bw):( max_pcon_frl_bw)); |
2450 | |
2451 | if (max_frl_bw <= 0) |
2452 | return -EINVAL22; |
2453 | |
2454 | max_frl_bw_mask = intel_dp_pcon_set_frl_mask(max_frl_bw); |
2455 | drm_dbg(&i915->drm, "MAX_FRL_BW_MASK = %u\n", max_frl_bw_mask)__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_DRIVER, "MAX_FRL_BW_MASK = %u\n" , max_frl_bw_mask); |
2456 | |
2457 | if (intel_dp_pcon_is_frl_trained(intel_dp, max_frl_bw_mask, &frl_trained_mask)) |
2458 | goto frl_trained; |
2459 | |
2460 | ret = drm_dp_pcon_frl_prepare(&intel_dp->aux, false0); |
2461 | if (ret < 0) |
2462 | return ret; |
2463 | /* Wait for PCON to be FRL Ready */ |
2464 | wait_for(is_active = drm_dp_pcon_is_frl_ready(&intel_dp->aux) == true, TIMEOUT_FRL_READY_MS)({ const ktime_t end__ = ktime_add_ns(ktime_get_raw(), 1000ll * (((500) * 1000))); long wait__ = ((10)); int ret__; assertwaitok (); for (;;) { const _Bool expired__ = ktime_after(ktime_get_raw (), end__); ; __asm volatile("" : : : "memory"); if (((is_active = drm_dp_pcon_is_frl_ready(&intel_dp->aux) == 1))) { ret__ = 0; break; } if (expired__) { ret__ = -60; break; } usleep_range (wait__, wait__ * 2); if (wait__ < ((1000))) wait__ <<= 1; } ret__; }); |
2465 | |
2466 | if (!is_active) |
2467 | return -ETIMEDOUT60; |
2468 | |
2469 | ret = drm_dp_pcon_frl_configure_1(&intel_dp->aux, max_frl_bw, |
2470 | DP_PCON_ENABLE_SEQUENTIAL_LINK(0 << 4)); |
2471 | if (ret < 0) |
2472 | return ret; |
2473 | ret = drm_dp_pcon_frl_configure_2(&intel_dp->aux, max_frl_bw_mask, |
2474 | DP_PCON_FRL_LINK_TRAIN_NORMAL(0 << 6)); |
2475 | if (ret < 0) |
2476 | return ret; |
2477 | ret = drm_dp_pcon_frl_enable(&intel_dp->aux); |
2478 | if (ret < 0) |
2479 | return ret; |
2480 | /* |
2481 | * Wait for FRL to be completed |
2482 | * Check if the HDMI Link is up and active. |
2483 | */ |
2484 | wait_for(is_active =({ const ktime_t end__ = ktime_add_ns(ktime_get_raw(), 1000ll * (((1000) * 1000))); long wait__ = ((10)); int ret__; assertwaitok (); for (;;) { const _Bool expired__ = ktime_after(ktime_get_raw (), end__); ; __asm volatile("" : : : "memory"); if (((is_active = intel_dp_pcon_is_frl_trained(intel_dp, max_frl_bw_mask, & frl_trained_mask)))) { ret__ = 0; break; } if (expired__) { ret__ = -60; break; } usleep_range(wait__, wait__ * 2); if (wait__ < ((1000))) wait__ <<= 1; } ret__; }) |
2485 | intel_dp_pcon_is_frl_trained(intel_dp, max_frl_bw_mask, &frl_trained_mask),({ const ktime_t end__ = ktime_add_ns(ktime_get_raw(), 1000ll * (((1000) * 1000))); long wait__ = ((10)); int ret__; assertwaitok (); for (;;) { const _Bool expired__ = ktime_after(ktime_get_raw (), end__); ; __asm volatile("" : : : "memory"); if (((is_active = intel_dp_pcon_is_frl_trained(intel_dp, max_frl_bw_mask, & frl_trained_mask)))) { ret__ = 0; break; } if (expired__) { ret__ = -60; break; } usleep_range(wait__, wait__ * 2); if (wait__ < ((1000))) wait__ <<= 1; } ret__; }) |
2486 | TIMEOUT_HDMI_LINK_ACTIVE_MS)({ const ktime_t end__ = ktime_add_ns(ktime_get_raw(), 1000ll * (((1000) * 1000))); long wait__ = ((10)); int ret__; assertwaitok (); for (;;) { const _Bool expired__ = ktime_after(ktime_get_raw (), end__); ; __asm volatile("" : : : "memory"); if (((is_active = intel_dp_pcon_is_frl_trained(intel_dp, max_frl_bw_mask, & frl_trained_mask)))) { ret__ = 0; break; } if (expired__) { ret__ = -60; break; } usleep_range(wait__, wait__ * 2); if (wait__ < ((1000))) wait__ <<= 1; } ret__; }); |
2487 | |
2488 | if (!is_active) |
2489 | return -ETIMEDOUT60; |
2490 | |
2491 | frl_trained: |
2492 | drm_dbg(&i915->drm, "FRL_TRAINED_MASK = %u\n", frl_trained_mask)__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_DRIVER, "FRL_TRAINED_MASK = %u\n" , frl_trained_mask); |
2493 | intel_dp->frl.trained_rate_gbps = intel_dp_pcon_get_frl_mask(frl_trained_mask); |
2494 | intel_dp->frl.is_trained = true1; |
2495 | drm_dbg(&i915->drm, "FRL trained with : %d Gbps\n", intel_dp->frl.trained_rate_gbps)__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_DRIVER, "FRL trained with : %d Gbps\n" , intel_dp->frl.trained_rate_gbps); |
2496 | |
2497 | return 0; |
2498 | } |
2499 | |
2500 | static bool_Bool intel_dp_is_hdmi_2_1_sink(struct intel_dp *intel_dp) |
2501 | { |
2502 | if (drm_dp_is_branch(intel_dp->dpcd) && |
2503 | intel_dp->has_hdmi_sink && |
2504 | intel_dp_hdmi_sink_max_frl(intel_dp) > 0) |
2505 | return true1; |
2506 | |
2507 | return false0; |
2508 | } |
2509 | |
2510 | static |
2511 | int intel_dp_pcon_set_tmds_mode(struct intel_dp *intel_dp) |
2512 | { |
2513 | int ret; |
2514 | u8 buf = 0; |
2515 | |
2516 | /* Set PCON source control mode */ |
2517 | buf |= DP_PCON_ENABLE_SOURCE_CTL_MODE(1 << 3); |
2518 | |
2519 | ret = drm_dp_dpcd_writeb(&intel_dp->aux, DP_PCON_HDMI_LINK_CONFIG_10x305A, buf); |
2520 | if (ret < 0) |
2521 | return ret; |
2522 | |
2523 | /* Set HDMI LINK ENABLE */ |
2524 | buf |= DP_PCON_ENABLE_HDMI_LINK(1 << 7); |
2525 | ret = drm_dp_dpcd_writeb(&intel_dp->aux, DP_PCON_HDMI_LINK_CONFIG_10x305A, buf); |
2526 | if (ret < 0) |
2527 | return ret; |
2528 | |
2529 | return 0; |
2530 | } |
2531 | |
2532 | void intel_dp_check_frl_training(struct intel_dp *intel_dp) |
2533 | { |
2534 | struct drm_i915_privateinteldrm_softc *dev_priv = dp_to_i915(intel_dp)to_i915(dp_to_dig_port(intel_dp)->base.base.dev); |
2535 | |
2536 | /* |
2537 | * Always go for FRL training if: |
2538 | * -PCON supports SRC_CTL_MODE (VESA DP2.0-HDMI2.1 PCON Spec Draft-1 Sec-7) |
2539 | * -sink is HDMI2.1 |
2540 | */ |
2541 | if (!(intel_dp->downstream_ports[2] & DP_PCON_SOURCE_CTL_MODE(1 << 5)) || |
2542 | !intel_dp_is_hdmi_2_1_sink(intel_dp) || |
2543 | intel_dp->frl.is_trained) |
2544 | return; |
2545 | |
2546 | if (intel_dp_pcon_start_frl_training(intel_dp) < 0) { |
2547 | int ret, mode; |
2548 | |
2549 | drm_dbg(&dev_priv->drm, "Couldn't set FRL mode, continuing with TMDS mode\n")__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_DRIVER, "Couldn't set FRL mode, continuing with TMDS mode\n" ); |
2550 | ret = intel_dp_pcon_set_tmds_mode(intel_dp); |
2551 | mode = drm_dp_pcon_hdmi_link_mode(&intel_dp->aux, NULL((void *)0)); |
2552 | |
2553 | if (ret < 0 || mode != DP_PCON_HDMI_MODE_TMDS0) |
2554 | drm_dbg(&dev_priv->drm, "Issue with PCON, cannot set TMDS mode\n")__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_DRIVER, "Issue with PCON, cannot set TMDS mode\n" ); |
2555 | } else { |
2556 | drm_dbg(&dev_priv->drm, "FRL training Completed\n")__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_DRIVER, "FRL training Completed\n" ); |
2557 | } |
2558 | } |
2559 | |
2560 | static int |
2561 | intel_dp_pcon_dsc_enc_slice_height(const struct intel_crtc_state *crtc_state) |
2562 | { |
2563 | int vactive = crtc_state->hw.adjusted_mode.vdisplay; |
2564 | |
2565 | return intel_hdmi_dsc_get_slice_height(vactive); |
2566 | } |
2567 | |
2568 | static int |
2569 | intel_dp_pcon_dsc_enc_slices(struct intel_dp *intel_dp, |
2570 | const struct intel_crtc_state *crtc_state) |
2571 | { |
2572 | struct intel_connector *intel_connector = intel_dp->attached_connector; |
2573 | struct drm_connector *connector = &intel_connector->base; |
2574 | int hdmi_throughput = connector->display_info.hdmi.dsc_cap.clk_per_slice; |
2575 | int hdmi_max_slices = connector->display_info.hdmi.dsc_cap.max_slices; |
2576 | int pcon_max_slices = drm_dp_pcon_dsc_max_slices(intel_dp->pcon_dsc_dpcd); |
2577 | int pcon_max_slice_width = drm_dp_pcon_dsc_max_slice_width(intel_dp->pcon_dsc_dpcd); |
2578 | |
2579 | return intel_hdmi_dsc_get_num_slices(crtc_state, pcon_max_slices, |
2580 | pcon_max_slice_width, |
2581 | hdmi_max_slices, hdmi_throughput); |
2582 | } |
2583 | |
2584 | static int |
2585 | intel_dp_pcon_dsc_enc_bpp(struct intel_dp *intel_dp, |
2586 | const struct intel_crtc_state *crtc_state, |
2587 | int num_slices, int slice_width) |
2588 | { |
2589 | struct intel_connector *intel_connector = intel_dp->attached_connector; |
2590 | struct drm_connector *connector = &intel_connector->base; |
2591 | int output_format = crtc_state->output_format; |
2592 | bool_Bool hdmi_all_bpp = connector->display_info.hdmi.dsc_cap.all_bpp; |
2593 | int pcon_fractional_bpp = drm_dp_pcon_dsc_bpp_incr(intel_dp->pcon_dsc_dpcd); |
2594 | int hdmi_max_chunk_bytes = |
2595 | connector->display_info.hdmi.dsc_cap.total_chunk_kbytes * 1024; |
2596 | |
2597 | return intel_hdmi_dsc_get_bpp(pcon_fractional_bpp, slice_width, |
2598 | num_slices, output_format, hdmi_all_bpp, |
2599 | hdmi_max_chunk_bytes); |
2600 | } |
2601 | |
2602 | void |
2603 | intel_dp_pcon_dsc_configure(struct intel_dp *intel_dp, |
2604 | const struct intel_crtc_state *crtc_state) |
2605 | { |
2606 | u8 pps_param[6]; |
2607 | int slice_height; |
2608 | int slice_width; |
2609 | int num_slices; |
2610 | int bits_per_pixel; |
2611 | int ret; |
2612 | struct intel_connector *intel_connector = intel_dp->attached_connector; |
2613 | struct drm_i915_privateinteldrm_softc *i915 = dp_to_i915(intel_dp)to_i915(dp_to_dig_port(intel_dp)->base.base.dev); |
2614 | struct drm_connector *connector; |
2615 | bool_Bool hdmi_is_dsc_1_2; |
2616 | |
2617 | if (!intel_dp_is_hdmi_2_1_sink(intel_dp)) |
2618 | return; |
2619 | |
2620 | if (!intel_connector) |
2621 | return; |
2622 | connector = &intel_connector->base; |
2623 | hdmi_is_dsc_1_2 = connector->display_info.hdmi.dsc_cap.v_1p2; |
2624 | |
2625 | if (!drm_dp_pcon_enc_is_dsc_1_2(intel_dp->pcon_dsc_dpcd) || |
2626 | !hdmi_is_dsc_1_2) |
2627 | return; |
2628 | |
2629 | slice_height = intel_dp_pcon_dsc_enc_slice_height(crtc_state); |
2630 | if (!slice_height) |
2631 | return; |
2632 | |
2633 | num_slices = intel_dp_pcon_dsc_enc_slices(intel_dp, crtc_state); |
2634 | if (!num_slices) |
2635 | return; |
2636 | |
2637 | slice_width = DIV_ROUND_UP(crtc_state->hw.adjusted_mode.hdisplay,(((crtc_state->hw.adjusted_mode.hdisplay) + ((num_slices) - 1)) / (num_slices)) |
2638 | num_slices)(((crtc_state->hw.adjusted_mode.hdisplay) + ((num_slices) - 1)) / (num_slices)); |
2639 | |
2640 | bits_per_pixel = intel_dp_pcon_dsc_enc_bpp(intel_dp, crtc_state, |
2641 | num_slices, slice_width); |
2642 | if (!bits_per_pixel) |
2643 | return; |
2644 | |
2645 | pps_param[0] = slice_height & 0xFF; |
2646 | pps_param[1] = slice_height >> 8; |
2647 | pps_param[2] = slice_width & 0xFF; |
2648 | pps_param[3] = slice_width >> 8; |
2649 | pps_param[4] = bits_per_pixel & 0xFF; |
2650 | pps_param[5] = (bits_per_pixel >> 8) & 0x3; |
2651 | |
2652 | ret = drm_dp_pcon_pps_override_param(&intel_dp->aux, pps_param); |
2653 | if (ret < 0) |
2654 | drm_dbg_kms(&i915->drm, "Failed to set pcon DSC\n")__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "Failed to set pcon DSC\n" ); |
2655 | } |
2656 | |
2657 | void intel_dp_configure_protocol_converter(struct intel_dp *intel_dp, |
2658 | const struct intel_crtc_state *crtc_state) |
2659 | { |
2660 | struct drm_i915_privateinteldrm_softc *i915 = dp_to_i915(intel_dp)to_i915(dp_to_dig_port(intel_dp)->base.base.dev); |
2661 | u8 tmp; |
2662 | |
2663 | if (intel_dp->dpcd[DP_DPCD_REV0x000] < 0x13) |
2664 | return; |
2665 | |
2666 | if (!drm_dp_is_branch(intel_dp->dpcd)) |
2667 | return; |
2668 | |
2669 | tmp = intel_dp->has_hdmi_sink ? |
2670 | DP_HDMI_DVI_OUTPUT_CONFIG(1 << 0) : 0; |
2671 | |
2672 | if (drm_dp_dpcd_writeb(&intel_dp->aux, |
2673 | DP_PROTOCOL_CONVERTER_CONTROL_00x3050, tmp) != 1) |
2674 | drm_dbg_kms(&i915->drm, "Failed to %s protocol converter HDMI mode\n",__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "Failed to %s protocol converter HDMI mode\n" , str_enable_disable(intel_dp->has_hdmi_sink)) |
2675 | str_enable_disable(intel_dp->has_hdmi_sink))__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "Failed to %s protocol converter HDMI mode\n" , str_enable_disable(intel_dp->has_hdmi_sink)); |
2676 | |
2677 | tmp = crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR444 && |
2678 | intel_dp->dfp.ycbcr_444_to_420 ? DP_CONVERSION_TO_YCBCR420_ENABLE(1 << 0) : 0; |
2679 | |
2680 | if (drm_dp_dpcd_writeb(&intel_dp->aux, |
2681 | DP_PROTOCOL_CONVERTER_CONTROL_10x3051, tmp) != 1) |
2682 | drm_dbg_kms(&i915->drm,__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "Failed to %s protocol converter YCbCr 4:2:0 conversion mode\n" , str_enable_disable(intel_dp->dfp.ycbcr_444_to_420)) |
2683 | "Failed to %s protocol converter YCbCr 4:2:0 conversion mode\n",__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "Failed to %s protocol converter YCbCr 4:2:0 conversion mode\n" , str_enable_disable(intel_dp->dfp.ycbcr_444_to_420)) |
2684 | str_enable_disable(intel_dp->dfp.ycbcr_444_to_420))__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "Failed to %s protocol converter YCbCr 4:2:0 conversion mode\n" , str_enable_disable(intel_dp->dfp.ycbcr_444_to_420)); |
2685 | |
2686 | tmp = intel_dp->dfp.rgb_to_ycbcr ? |
2687 | DP_CONVERSION_BT709_RGB_YCBCR_ENABLE(1 << 5) : 0; |
2688 | |
2689 | if (drm_dp_pcon_convert_rgb_to_ycbcr(&intel_dp->aux, tmp) < 0) |
2690 | drm_dbg_kms(&i915->drm,__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "Failed to %s protocol converter RGB->YCbCr conversion mode\n" , str_enable_disable(tmp)) |
2691 | "Failed to %s protocol converter RGB->YCbCr conversion mode\n",__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "Failed to %s protocol converter RGB->YCbCr conversion mode\n" , str_enable_disable(tmp)) |
2692 | str_enable_disable(tmp))__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "Failed to %s protocol converter RGB->YCbCr conversion mode\n" , str_enable_disable(tmp)); |
2693 | } |
2694 | |
2695 | |
2696 | bool_Bool intel_dp_get_colorimetry_status(struct intel_dp *intel_dp) |
2697 | { |
2698 | u8 dprx = 0; |
2699 | |
2700 | if (drm_dp_dpcd_readb(&intel_dp->aux, DP_DPRX_FEATURE_ENUMERATION_LIST0x2210, |
2701 | &dprx) != 1) |
2702 | return false0; |
2703 | return dprx & DP_VSC_SDP_EXT_FOR_COLORIMETRY_SUPPORTED(1 << 3); |
2704 | } |
2705 | |
2706 | static void intel_dp_get_dsc_sink_cap(struct intel_dp *intel_dp) |
2707 | { |
2708 | struct drm_i915_privateinteldrm_softc *i915 = dp_to_i915(intel_dp)to_i915(dp_to_dig_port(intel_dp)->base.base.dev); |
2709 | |
2710 | /* |
2711 | * Clear the cached register set to avoid using stale values |
2712 | * for the sinks that do not support DSC. |
2713 | */ |
2714 | memset(intel_dp->dsc_dpcd, 0, sizeof(intel_dp->dsc_dpcd))__builtin_memset((intel_dp->dsc_dpcd), (0), (sizeof(intel_dp ->dsc_dpcd))); |
2715 | |
2716 | /* Clear fec_capable to avoid using stale values */ |
2717 | intel_dp->fec_capable = 0; |
2718 | |
2719 | /* Cache the DSC DPCD if eDP or DP rev >= 1.4 */ |
2720 | if (intel_dp->dpcd[DP_DPCD_REV0x000] >= 0x14 || |
2721 | intel_dp->edp_dpcd[0] >= DP_EDP_140x03) { |
2722 | if (drm_dp_dpcd_read(&intel_dp->aux, DP_DSC_SUPPORT0x060, |
2723 | intel_dp->dsc_dpcd, |
2724 | sizeof(intel_dp->dsc_dpcd)) < 0) |
2725 | drm_err(&i915->drm,printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "Failed to read DPCD register 0x%x\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , 0x060) |
2726 | "Failed to read DPCD register 0x%x\n",printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "Failed to read DPCD register 0x%x\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , 0x060) |
2727 | DP_DSC_SUPPORT)printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "Failed to read DPCD register 0x%x\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , 0x060); |
2728 | |
2729 | drm_dbg_kms(&i915->drm, "DSC DPCD: %*ph\n",__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "DSC DPCD: %*ph\n", ( int)sizeof(intel_dp->dsc_dpcd), intel_dp->dsc_dpcd) |
2730 | (int)sizeof(intel_dp->dsc_dpcd),__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "DSC DPCD: %*ph\n", ( int)sizeof(intel_dp->dsc_dpcd), intel_dp->dsc_dpcd) |
2731 | intel_dp->dsc_dpcd)__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "DSC DPCD: %*ph\n", ( int)sizeof(intel_dp->dsc_dpcd), intel_dp->dsc_dpcd); |
2732 | |
2733 | /* FEC is supported only on DP 1.4 */ |
2734 | if (!intel_dp_is_edp(intel_dp) && |
2735 | drm_dp_dpcd_readb(&intel_dp->aux, DP_FEC_CAPABILITY0x090, |
2736 | &intel_dp->fec_capable) < 0) |
2737 | drm_err(&i915->drm,printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "Failed to read FEC DPCD register\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__) |
2738 | "Failed to read FEC DPCD register\n")printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "Failed to read FEC DPCD register\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__); |
2739 | |
2740 | drm_dbg_kms(&i915->drm, "FEC CAPABILITY: %x\n",__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "FEC CAPABILITY: %x\n" , intel_dp->fec_capable) |
2741 | intel_dp->fec_capable)__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "FEC CAPABILITY: %x\n" , intel_dp->fec_capable); |
2742 | } |
2743 | } |
2744 | |
2745 | static void intel_edp_mso_mode_fixup(struct intel_connector *connector, |
2746 | struct drm_display_mode *mode) |
2747 | { |
2748 | struct intel_dp *intel_dp = intel_attached_dp(connector); |
2749 | struct drm_i915_privateinteldrm_softc *i915 = to_i915(connector->base.dev); |
2750 | int n = intel_dp->mso_link_count; |
2751 | int overlap = intel_dp->mso_pixel_overlap; |
2752 | |
2753 | if (!mode || !n) |
2754 | return; |
2755 | |
2756 | mode->hdisplay = (mode->hdisplay - overlap) * n; |
2757 | mode->hsync_start = (mode->hsync_start - overlap) * n; |
2758 | mode->hsync_end = (mode->hsync_end - overlap) * n; |
2759 | mode->htotal = (mode->htotal - overlap) * n; |
2760 | mode->clock *= n; |
2761 | |
2762 | drm_mode_set_name(mode); |
2763 | |
2764 | drm_dbg_kms(&i915->drm,__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "[CONNECTOR:%d:%s] using generated MSO mode: " "\"%s\": %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x" "\n", connector ->base.base.id, connector->base.name, (mode)->name, drm_mode_vrefresh (mode), (mode)->clock, (mode)->hdisplay, (mode)->hsync_start , (mode)->hsync_end, (mode)->htotal, (mode)->vdisplay , (mode)->vsync_start, (mode)->vsync_end, (mode)->vtotal , (mode)->type, (mode)->flags) |
2765 | "[CONNECTOR:%d:%s] using generated MSO mode: " DRM_MODE_FMT "\n",__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "[CONNECTOR:%d:%s] using generated MSO mode: " "\"%s\": %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x" "\n", connector ->base.base.id, connector->base.name, (mode)->name, drm_mode_vrefresh (mode), (mode)->clock, (mode)->hdisplay, (mode)->hsync_start , (mode)->hsync_end, (mode)->htotal, (mode)->vdisplay , (mode)->vsync_start, (mode)->vsync_end, (mode)->vtotal , (mode)->type, (mode)->flags) |
2766 | connector->base.base.id, connector->base.name,__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "[CONNECTOR:%d:%s] using generated MSO mode: " "\"%s\": %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x" "\n", connector ->base.base.id, connector->base.name, (mode)->name, drm_mode_vrefresh (mode), (mode)->clock, (mode)->hdisplay, (mode)->hsync_start , (mode)->hsync_end, (mode)->htotal, (mode)->vdisplay , (mode)->vsync_start, (mode)->vsync_end, (mode)->vtotal , (mode)->type, (mode)->flags) |
2767 | DRM_MODE_ARG(mode))__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "[CONNECTOR:%d:%s] using generated MSO mode: " "\"%s\": %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x" "\n", connector ->base.base.id, connector->base.name, (mode)->name, drm_mode_vrefresh (mode), (mode)->clock, (mode)->hdisplay, (mode)->hsync_start , (mode)->hsync_end, (mode)->htotal, (mode)->vdisplay , (mode)->vsync_start, (mode)->vsync_end, (mode)->vtotal , (mode)->type, (mode)->flags); |
2768 | } |
2769 | |
2770 | void intel_edp_fixup_vbt_bpp(struct intel_encoder *encoder, int pipe_bpp) |
2771 | { |
2772 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
2773 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
2774 | struct intel_connector *connector = intel_dp->attached_connector; |
2775 | |
2776 | if (connector->panel.vbt.edp.bpp && pipe_bpp > connector->panel.vbt.edp.bpp) { |
2777 | /* |
2778 | * This is a big fat ugly hack. |
2779 | * |
2780 | * Some machines in UEFI boot mode provide us a VBT that has 18 |
2781 | * bpp and 1.62 GHz link bandwidth for eDP, which for reasons |
2782 | * unknown we fail to light up. Yet the same BIOS boots up with |
2783 | * 24 bpp and 2.7 GHz link. Use the same bpp as the BIOS uses as |
2784 | * max, not what it tells us to use. |
2785 | * |
2786 | * Note: This will still be broken if the eDP panel is not lit |
2787 | * up by the BIOS, and thus we can't get the mode at module |
2788 | * load. |
2789 | */ |
2790 | drm_dbg_kms(&dev_priv->drm,__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "pipe has %d bpp for eDP panel, overriding BIOS-provided max %d bpp\n" , pipe_bpp, connector->panel.vbt.edp.bpp) |
2791 | "pipe has %d bpp for eDP panel, overriding BIOS-provided max %d bpp\n",__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "pipe has %d bpp for eDP panel, overriding BIOS-provided max %d bpp\n" , pipe_bpp, connector->panel.vbt.edp.bpp) |
2792 | pipe_bpp, connector->panel.vbt.edp.bpp)__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "pipe has %d bpp for eDP panel, overriding BIOS-provided max %d bpp\n" , pipe_bpp, connector->panel.vbt.edp.bpp); |
2793 | connector->panel.vbt.edp.bpp = pipe_bpp; |
2794 | } |
2795 | } |
2796 | |
2797 | static void intel_edp_mso_init(struct intel_dp *intel_dp) |
2798 | { |
2799 | struct drm_i915_privateinteldrm_softc *i915 = dp_to_i915(intel_dp)to_i915(dp_to_dig_port(intel_dp)->base.base.dev); |
2800 | struct intel_connector *connector = intel_dp->attached_connector; |
2801 | struct drm_display_info *info = &connector->base.display_info; |
2802 | u8 mso; |
2803 | |
2804 | if (intel_dp->edp_dpcd[0] < DP_EDP_140x03) |
2805 | return; |
2806 | |
2807 | if (drm_dp_dpcd_readb(&intel_dp->aux, DP_EDP_MSO_LINK_CAPABILITIES0x7a4, &mso) != 1) { |
2808 | drm_err(&i915->drm, "Failed to read MSO cap\n")printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "Failed to read MSO cap\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__); |
2809 | return; |
2810 | } |
2811 | |
2812 | /* Valid configurations are SST or MSO 2x1, 2x2, 4x1 */ |
2813 | mso &= DP_EDP_MSO_NUMBER_OF_LINKS_MASK(7 << 0); |
2814 | if (mso % 2 || mso > drm_dp_max_lane_count(intel_dp->dpcd)) { |
2815 | drm_err(&i915->drm, "Invalid MSO link count cap %u\n", mso)printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "Invalid MSO link count cap %u\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , mso); |
2816 | mso = 0; |
2817 | } |
2818 | |
2819 | if (mso) { |
2820 | drm_dbg_kms(&i915->drm, "Sink MSO %ux%u configuration, pixel overlap %u\n",__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "Sink MSO %ux%u configuration, pixel overlap %u\n" , mso, drm_dp_max_lane_count(intel_dp->dpcd) / mso, info-> mso_pixel_overlap) |
2821 | mso, drm_dp_max_lane_count(intel_dp->dpcd) / mso,__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "Sink MSO %ux%u configuration, pixel overlap %u\n" , mso, drm_dp_max_lane_count(intel_dp->dpcd) / mso, info-> mso_pixel_overlap) |
2822 | info->mso_pixel_overlap)__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "Sink MSO %ux%u configuration, pixel overlap %u\n" , mso, drm_dp_max_lane_count(intel_dp->dpcd) / mso, info-> mso_pixel_overlap); |
2823 | if (!HAS_MSO(i915)(((&(i915)->__runtime)->display.ip.ver) >= 12)) { |
2824 | drm_err(&i915->drm, "No source MSO support, disabling\n")printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "No source MSO support, disabling\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__); |
2825 | mso = 0; |
2826 | } |
2827 | } |
2828 | |
2829 | intel_dp->mso_link_count = mso; |
2830 | intel_dp->mso_pixel_overlap = mso ? info->mso_pixel_overlap : 0; |
2831 | } |
2832 | |
2833 | static bool_Bool |
2834 | intel_edp_init_dpcd(struct intel_dp *intel_dp) |
2835 | { |
2836 | struct drm_i915_privateinteldrm_softc *dev_priv = |
2837 | to_i915(dp_to_dig_port(intel_dp)->base.base.dev); |
2838 | |
2839 | /* this function is meant to be called only once */ |
2840 | drm_WARN_ON(&dev_priv->drm, intel_dp->dpcd[DP_DPCD_REV] != 0)({ int __ret = !!((intel_dp->dpcd[0x000] != 0)); if (__ret ) printf("%s %s: " "%s", dev_driver_string(((&dev_priv-> drm))->dev), "", "drm_WARN_ON(" "intel_dp->dpcd[0x000] != 0" ")"); __builtin_expect(!!(__ret), 0); }); |
2841 | |
2842 | if (drm_dp_read_dpcd_caps(&intel_dp->aux, intel_dp->dpcd) != 0) |
2843 | return false0; |
2844 | |
2845 | drm_dp_read_desc(&intel_dp->aux, &intel_dp->desc, |
2846 | drm_dp_is_branch(intel_dp->dpcd)); |
2847 | |
2848 | /* |
2849 | * Read the eDP display control registers. |
2850 | * |
2851 | * Do this independent of DP_DPCD_DISPLAY_CONTROL_CAPABLE bit in |
2852 | * DP_EDP_CONFIGURATION_CAP, because some buggy displays do not have it |
2853 | * set, but require eDP 1.4+ detection (e.g. for supported link rates |
2854 | * method). The display control registers should read zero if they're |
2855 | * not supported anyway. |
2856 | */ |
2857 | if (drm_dp_dpcd_read(&intel_dp->aux, DP_EDP_DPCD_REV0x700, |
2858 | intel_dp->edp_dpcd, sizeof(intel_dp->edp_dpcd)) == |
2859 | sizeof(intel_dp->edp_dpcd)) { |
2860 | drm_dbg_kms(&dev_priv->drm, "eDP DPCD: %*ph\n",__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "eDP DPCD: %*ph\n" , (int)sizeof(intel_dp->edp_dpcd), intel_dp->edp_dpcd) |
2861 | (int)sizeof(intel_dp->edp_dpcd),__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "eDP DPCD: %*ph\n" , (int)sizeof(intel_dp->edp_dpcd), intel_dp->edp_dpcd) |
2862 | intel_dp->edp_dpcd)__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "eDP DPCD: %*ph\n" , (int)sizeof(intel_dp->edp_dpcd), intel_dp->edp_dpcd); |
2863 | |
2864 | intel_dp->use_max_params = intel_dp->edp_dpcd[0] < DP_EDP_140x03; |
2865 | } |
2866 | |
2867 | /* |
2868 | * This has to be called after intel_dp->edp_dpcd is filled, PSR checks |
2869 | * for SET_POWER_CAPABLE bit in intel_dp->edp_dpcd[1] |
2870 | */ |
2871 | intel_psr_init_dpcd(intel_dp); |
2872 | |
2873 | /* Clear the default sink rates */ |
2874 | intel_dp->num_sink_rates = 0; |
2875 | |
2876 | /* Read the eDP 1.4+ supported link rates. */ |
2877 | if (intel_dp->edp_dpcd[0] >= DP_EDP_140x03) { |
2878 | __le16 sink_rates[DP_MAX_SUPPORTED_RATES8]; |
2879 | int i; |
2880 | |
2881 | drm_dp_dpcd_read(&intel_dp->aux, DP_SUPPORTED_LINK_RATES0x010, |
2882 | sink_rates, sizeof(sink_rates)); |
2883 | |
2884 | for (i = 0; i < ARRAY_SIZE(sink_rates)(sizeof((sink_rates)) / sizeof((sink_rates)[0])); i++) { |
2885 | int val = le16_to_cpu(sink_rates[i])((__uint16_t)(sink_rates[i])); |
2886 | |
2887 | if (val == 0) |
2888 | break; |
2889 | |
2890 | /* Value read multiplied by 200kHz gives the per-lane |
2891 | * link rate in kHz. The source rates are, however, |
2892 | * stored in terms of LS_Clk kHz. The full conversion |
2893 | * back to symbols is |
2894 | * (val * 200kHz)*(8/10 ch. encoding)*(1/8 bit to Byte) |
2895 | */ |
2896 | intel_dp->sink_rates[i] = (val * 200) / 10; |
2897 | } |
2898 | intel_dp->num_sink_rates = i; |
2899 | } |
2900 | |
2901 | /* |
2902 | * Use DP_LINK_RATE_SET if DP_SUPPORTED_LINK_RATES are available, |
2903 | * default to DP_MAX_LINK_RATE and DP_LINK_BW_SET otherwise. |
2904 | */ |
2905 | if (intel_dp->num_sink_rates) |
2906 | intel_dp->use_rate_select = true1; |
2907 | else |
2908 | intel_dp_set_sink_rates(intel_dp); |
2909 | intel_dp_set_max_sink_lane_count(intel_dp); |
2910 | |
2911 | /* Read the eDP DSC DPCD registers */ |
2912 | if (DISPLAY_VER(dev_priv)((&(dev_priv)->__runtime)->display.ip.ver) >= 10) |
2913 | intel_dp_get_dsc_sink_cap(intel_dp); |
2914 | |
2915 | /* |
2916 | * If needed, program our source OUI so we can make various Intel-specific AUX services |
2917 | * available (such as HDR backlight controls) |
2918 | */ |
2919 | intel_edp_init_source_oui(intel_dp, true1); |
2920 | |
2921 | return true1; |
2922 | } |
2923 | |
2924 | static bool_Bool |
2925 | intel_dp_has_sink_count(struct intel_dp *intel_dp) |
2926 | { |
2927 | if (!intel_dp->attached_connector) |
2928 | return false0; |
2929 | |
2930 | return drm_dp_read_sink_count_cap(&intel_dp->attached_connector->base, |
2931 | intel_dp->dpcd, |
2932 | &intel_dp->desc); |
2933 | } |
2934 | |
2935 | static bool_Bool |
2936 | intel_dp_get_dpcd(struct intel_dp *intel_dp) |
2937 | { |
2938 | int ret; |
2939 | |
2940 | if (intel_dp_init_lttpr_and_dprx_caps(intel_dp) < 0) |
2941 | return false0; |
2942 | |
2943 | /* |
2944 | * Don't clobber cached eDP rates. Also skip re-reading |
2945 | * the OUI/ID since we know it won't change. |
2946 | */ |
2947 | if (!intel_dp_is_edp(intel_dp)) { |
2948 | drm_dp_read_desc(&intel_dp->aux, &intel_dp->desc, |
2949 | drm_dp_is_branch(intel_dp->dpcd)); |
2950 | |
2951 | intel_dp_set_sink_rates(intel_dp); |
2952 | intel_dp_set_max_sink_lane_count(intel_dp); |
2953 | intel_dp_set_common_rates(intel_dp); |
2954 | } |
2955 | |
2956 | if (intel_dp_has_sink_count(intel_dp)) { |
2957 | ret = drm_dp_read_sink_count(&intel_dp->aux); |
2958 | if (ret < 0) |
2959 | return false0; |
2960 | |
2961 | /* |
2962 | * Sink count can change between short pulse hpd hence |
2963 | * a member variable in intel_dp will track any changes |
2964 | * between short pulse interrupts. |
2965 | */ |
2966 | intel_dp->sink_count = ret; |
2967 | |
2968 | /* |
2969 | * SINK_COUNT == 0 and DOWNSTREAM_PORT_PRESENT == 1 implies that |
2970 | * a dongle is present but no display. Unless we require to know |
2971 | * if a dongle is present or not, we don't need to update |
2972 | * downstream port information. So, an early return here saves |
2973 | * time from performing other operations which are not required. |
2974 | */ |
2975 | if (!intel_dp->sink_count) |
2976 | return false0; |
2977 | } |
2978 | |
2979 | return drm_dp_read_downstream_info(&intel_dp->aux, intel_dp->dpcd, |
2980 | intel_dp->downstream_ports) == 0; |
2981 | } |
2982 | |
2983 | static bool_Bool |
2984 | intel_dp_can_mst(struct intel_dp *intel_dp) |
2985 | { |
2986 | struct drm_i915_privateinteldrm_softc *i915 = dp_to_i915(intel_dp)to_i915(dp_to_dig_port(intel_dp)->base.base.dev); |
2987 | |
2988 | return i915->params.enable_dp_mst && |
2989 | intel_dp_mst_source_support(intel_dp) && |
2990 | drm_dp_read_mst_cap(&intel_dp->aux, intel_dp->dpcd); |
2991 | } |
2992 | |
2993 | static void |
2994 | intel_dp_configure_mst(struct intel_dp *intel_dp) |
2995 | { |
2996 | struct drm_i915_privateinteldrm_softc *i915 = dp_to_i915(intel_dp)to_i915(dp_to_dig_port(intel_dp)->base.base.dev); |
2997 | struct intel_encoder *encoder = |
2998 | &dp_to_dig_port(intel_dp)->base; |
2999 | bool_Bool sink_can_mst = drm_dp_read_mst_cap(&intel_dp->aux, intel_dp->dpcd); |
3000 | |
3001 | drm_dbg_kms(&i915->drm,__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "[ENCODER:%d:%s] MST support: port: %s, sink: %s, modparam: %s\n" , encoder->base.base.id, encoder->base.name, str_yes_no (intel_dp_mst_source_support(intel_dp)), str_yes_no(sink_can_mst ), str_yes_no(i915->params.enable_dp_mst)) |
3002 | "[ENCODER:%d:%s] MST support: port: %s, sink: %s, modparam: %s\n",__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "[ENCODER:%d:%s] MST support: port: %s, sink: %s, modparam: %s\n" , encoder->base.base.id, encoder->base.name, str_yes_no (intel_dp_mst_source_support(intel_dp)), str_yes_no(sink_can_mst ), str_yes_no(i915->params.enable_dp_mst)) |
3003 | encoder->base.base.id, encoder->base.name,__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "[ENCODER:%d:%s] MST support: port: %s, sink: %s, modparam: %s\n" , encoder->base.base.id, encoder->base.name, str_yes_no (intel_dp_mst_source_support(intel_dp)), str_yes_no(sink_can_mst ), str_yes_no(i915->params.enable_dp_mst)) |
3004 | str_yes_no(intel_dp_mst_source_support(intel_dp)),__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "[ENCODER:%d:%s] MST support: port: %s, sink: %s, modparam: %s\n" , encoder->base.base.id, encoder->base.name, str_yes_no (intel_dp_mst_source_support(intel_dp)), str_yes_no(sink_can_mst ), str_yes_no(i915->params.enable_dp_mst)) |
3005 | str_yes_no(sink_can_mst),__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "[ENCODER:%d:%s] MST support: port: %s, sink: %s, modparam: %s\n" , encoder->base.base.id, encoder->base.name, str_yes_no (intel_dp_mst_source_support(intel_dp)), str_yes_no(sink_can_mst ), str_yes_no(i915->params.enable_dp_mst)) |
3006 | str_yes_no(i915->params.enable_dp_mst))__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "[ENCODER:%d:%s] MST support: port: %s, sink: %s, modparam: %s\n" , encoder->base.base.id, encoder->base.name, str_yes_no (intel_dp_mst_source_support(intel_dp)), str_yes_no(sink_can_mst ), str_yes_no(i915->params.enable_dp_mst)); |
3007 | |
3008 | if (!intel_dp_mst_source_support(intel_dp)) |
3009 | return; |
3010 | |
3011 | intel_dp->is_mst = sink_can_mst && |
3012 | i915->params.enable_dp_mst; |
3013 | |
3014 | drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst_mgr, |
3015 | intel_dp->is_mst); |
3016 | } |
3017 | |
3018 | static bool_Bool |
3019 | intel_dp_get_sink_irq_esi(struct intel_dp *intel_dp, u8 *esi) |
3020 | { |
3021 | return drm_dp_dpcd_read(&intel_dp->aux, DP_SINK_COUNT_ESI0x2002, esi, 4) == 4; |
3022 | } |
3023 | |
3024 | static bool_Bool intel_dp_ack_sink_irq_esi(struct intel_dp *intel_dp, u8 esi[4]) |
3025 | { |
3026 | int retry; |
3027 | |
3028 | for (retry = 0; retry < 3; retry++) { |
3029 | if (drm_dp_dpcd_write(&intel_dp->aux, DP_SINK_COUNT_ESI0x2002 + 1, |
3030 | &esi[1], 3) == 3) |
3031 | return true1; |
3032 | } |
3033 | |
3034 | return false0; |
3035 | } |
3036 | |
3037 | bool_Bool |
3038 | intel_dp_needs_vsc_sdp(const struct intel_crtc_state *crtc_state, |
3039 | const struct drm_connector_state *conn_state) |
3040 | { |
3041 | /* |
3042 | * As per DP 1.4a spec section 2.2.4.3 [MSA Field for Indication |
3043 | * of Color Encoding Format and Content Color Gamut], in order to |
3044 | * sending YCBCR 420 or HDR BT.2020 signals we should use DP VSC SDP. |
3045 | */ |
3046 | if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420) |
3047 | return true1; |
3048 | |
3049 | switch (conn_state->colorspace) { |
3050 | case DRM_MODE_COLORIMETRY_SYCC_6015: |
3051 | case DRM_MODE_COLORIMETRY_OPYCC_6016: |
3052 | case DRM_MODE_COLORIMETRY_BT2020_YCC10: |
3053 | case DRM_MODE_COLORIMETRY_BT2020_RGB9: |
3054 | case DRM_MODE_COLORIMETRY_BT2020_CYCC8: |
3055 | return true1; |
3056 | default: |
3057 | break; |
3058 | } |
3059 | |
3060 | return false0; |
3061 | } |
3062 | |
3063 | static ssize_t intel_dp_vsc_sdp_pack(const struct drm_dp_vsc_sdp *vsc, |
3064 | struct dp_sdp *sdp, size_t size) |
3065 | { |
3066 | size_t length = sizeof(struct dp_sdp); |
3067 | |
3068 | if (size < length) |
3069 | return -ENOSPC28; |
3070 | |
3071 | memset(sdp, 0, size)__builtin_memset((sdp), (0), (size)); |
3072 | |
3073 | /* |
3074 | * Prepare VSC Header for SU as per DP 1.4a spec, Table 2-119 |
3075 | * VSC SDP Header Bytes |
3076 | */ |
3077 | sdp->sdp_header.HB0 = 0; /* Secondary-Data Packet ID = 0 */ |
3078 | sdp->sdp_header.HB1 = vsc->sdp_type; /* Secondary-data Packet Type */ |
3079 | sdp->sdp_header.HB2 = vsc->revision; /* Revision Number */ |
3080 | sdp->sdp_header.HB3 = vsc->length; /* Number of Valid Data Bytes */ |
3081 | |
3082 | /* |
3083 | * Only revision 0x5 supports Pixel Encoding/Colorimetry Format as |
3084 | * per DP 1.4a spec. |
3085 | */ |
3086 | if (vsc->revision != 0x5) |
3087 | goto out; |
3088 | |
3089 | /* VSC SDP Payload for DB16 through DB18 */ |
3090 | /* Pixel Encoding and Colorimetry Formats */ |
3091 | sdp->db[16] = (vsc->pixelformat & 0xf) << 4; /* DB16[7:4] */ |
3092 | sdp->db[16] |= vsc->colorimetry & 0xf; /* DB16[3:0] */ |
3093 | |
3094 | switch (vsc->bpc) { |
3095 | case 6: |
3096 | /* 6bpc: 0x0 */ |
3097 | break; |
3098 | case 8: |
3099 | sdp->db[17] = 0x1; /* DB17[3:0] */ |
3100 | break; |
3101 | case 10: |
3102 | sdp->db[17] = 0x2; |
3103 | break; |
3104 | case 12: |
3105 | sdp->db[17] = 0x3; |
3106 | break; |
3107 | case 16: |
3108 | sdp->db[17] = 0x4; |
3109 | break; |
3110 | default: |
3111 | MISSING_CASE(vsc->bpc)({ int __ret = !!(1); if (__ret) printf("Missing case (%s == %ld)\n" , "vsc->bpc", (long)(vsc->bpc)); __builtin_expect(!!(__ret ), 0); }); |
3112 | break; |
3113 | } |
3114 | /* Dynamic Range and Component Bit Depth */ |
3115 | if (vsc->dynamic_range == DP_DYNAMIC_RANGE_CTA) |
3116 | sdp->db[17] |= 0x80; /* DB17[7] */ |
3117 | |
3118 | /* Content Type */ |
3119 | sdp->db[18] = vsc->content_type & 0x7; |
3120 | |
3121 | out: |
3122 | return length; |
3123 | } |
3124 | |
3125 | static ssize_t |
3126 | intel_dp_hdr_metadata_infoframe_sdp_pack(struct drm_i915_privateinteldrm_softc *i915, |
3127 | const struct hdmi_drm_infoframe *drm_infoframe, |
3128 | struct dp_sdp *sdp, |
3129 | size_t size) |
3130 | { |
3131 | size_t length = sizeof(struct dp_sdp); |
3132 | const int infoframe_size = HDMI_INFOFRAME_HEADER_SIZE4 + HDMI_DRM_INFOFRAME_SIZE26; |
3133 | unsigned char buf[HDMI_INFOFRAME_HEADER_SIZE4 + HDMI_DRM_INFOFRAME_SIZE26]; |
3134 | ssize_t len; |
3135 | |
3136 | if (size < length) |
3137 | return -ENOSPC28; |
3138 | |
3139 | memset(sdp, 0, size)__builtin_memset((sdp), (0), (size)); |
3140 | |
3141 | len = hdmi_drm_infoframe_pack_only(drm_infoframe, buf, sizeof(buf)); |
3142 | if (len < 0) { |
3143 | drm_dbg_kms(&i915->drm, "buffer size is smaller than hdr metadata infoframe\n")__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "buffer size is smaller than hdr metadata infoframe\n" ); |
3144 | return -ENOSPC28; |
3145 | } |
3146 | |
3147 | if (len != infoframe_size) { |
3148 | drm_dbg_kms(&i915->drm, "wrong static hdr metadata size\n")__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "wrong static hdr metadata size\n" ); |
3149 | return -ENOSPC28; |
3150 | } |
3151 | |
3152 | /* |
3153 | * Set up the infoframe sdp packet for HDR static metadata. |
3154 | * Prepare VSC Header for SU as per DP 1.4a spec, |
3155 | * Table 2-100 and Table 2-101 |
3156 | */ |
3157 | |
3158 | /* Secondary-Data Packet ID, 00h for non-Audio INFOFRAME */ |
3159 | sdp->sdp_header.HB0 = 0; |
3160 | /* |
3161 | * Packet Type 80h + Non-audio INFOFRAME Type value |
3162 | * HDMI_INFOFRAME_TYPE_DRM: 0x87 |
3163 | * - 80h + Non-audio INFOFRAME Type value |
3164 | * - InfoFrame Type: 0x07 |
3165 | * [CTA-861-G Table-42 Dynamic Range and Mastering InfoFrame] |
3166 | */ |
3167 | sdp->sdp_header.HB1 = drm_infoframe->type; |
3168 | /* |
3169 | * Least Significant Eight Bits of (Data Byte Count – 1) |
3170 | * infoframe_size - 1 |
3171 | */ |
3172 | sdp->sdp_header.HB2 = 0x1D; |
3173 | /* INFOFRAME SDP Version Number */ |
3174 | sdp->sdp_header.HB3 = (0x13 << 2); |
3175 | /* CTA Header Byte 2 (INFOFRAME Version Number) */ |
3176 | sdp->db[0] = drm_infoframe->version; |
3177 | /* CTA Header Byte 3 (Length of INFOFRAME): HDMI_DRM_INFOFRAME_SIZE */ |
3178 | sdp->db[1] = drm_infoframe->length; |
3179 | /* |
3180 | * Copy HDMI_DRM_INFOFRAME_SIZE size from a buffer after |
3181 | * HDMI_INFOFRAME_HEADER_SIZE |
3182 | */ |
3183 | BUILD_BUG_ON(sizeof(sdp->db) < HDMI_DRM_INFOFRAME_SIZE + 2)extern char _ctassert[(!(sizeof(sdp->db) < 26 + 2)) ? 1 : -1 ] __attribute__((__unused__)); |
3184 | memcpy(&sdp->db[2], &buf[HDMI_INFOFRAME_HEADER_SIZE],__builtin_memcpy((&sdp->db[2]), (&buf[4]), (26)) |
3185 | HDMI_DRM_INFOFRAME_SIZE)__builtin_memcpy((&sdp->db[2]), (&buf[4]), (26)); |
3186 | |
3187 | /* |
3188 | * Size of DP infoframe sdp packet for HDR static metadata consists of |
3189 | * - DP SDP Header(struct dp_sdp_header): 4 bytes |
3190 | * - Two Data Blocks: 2 bytes |
3191 | * CTA Header Byte2 (INFOFRAME Version Number) |
3192 | * CTA Header Byte3 (Length of INFOFRAME) |
3193 | * - HDMI_DRM_INFOFRAME_SIZE: 26 bytes |
3194 | * |
3195 | * Prior to GEN11's GMP register size is identical to DP HDR static metadata |
3196 | * infoframe size. But GEN11+ has larger than that size, write_infoframe |
3197 | * will pad rest of the size. |
3198 | */ |
3199 | return sizeof(struct dp_sdp_header) + 2 + HDMI_DRM_INFOFRAME_SIZE26; |
3200 | } |
3201 | |
3202 | static void intel_write_dp_sdp(struct intel_encoder *encoder, |
3203 | const struct intel_crtc_state *crtc_state, |
3204 | unsigned int type) |
3205 | { |
3206 | struct intel_digital_port *dig_port = enc_to_dig_port(encoder); |
3207 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
3208 | struct dp_sdp sdp = {}; |
3209 | ssize_t len; |
3210 | |
3211 | if ((crtc_state->infoframes.enable & |
3212 | intel_hdmi_infoframe_enable(type)) == 0) |
3213 | return; |
3214 | |
3215 | switch (type) { |
3216 | case DP_SDP_VSC0x07: |
3217 | len = intel_dp_vsc_sdp_pack(&crtc_state->infoframes.vsc, &sdp, |
3218 | sizeof(sdp)); |
3219 | break; |
3220 | case HDMI_PACKET_TYPE_GAMUT_METADATA: |
3221 | len = intel_dp_hdr_metadata_infoframe_sdp_pack(dev_priv, |
3222 | &crtc_state->infoframes.drm.drm, |
3223 | &sdp, sizeof(sdp)); |
3224 | break; |
3225 | default: |
3226 | MISSING_CASE(type)({ int __ret = !!(1); if (__ret) printf("Missing case (%s == %ld)\n" , "type", (long)(type)); __builtin_expect(!!(__ret), 0); }); |
3227 | return; |
3228 | } |
3229 | |
3230 | if (drm_WARN_ON(&dev_priv->drm, len < 0)({ int __ret = !!((len < 0)); if (__ret) printf("%s %s: " "%s" , dev_driver_string(((&dev_priv->drm))->dev), "", "drm_WARN_ON(" "len < 0" ")"); __builtin_expect(!!(__ret), 0); })) |
3231 | return; |
3232 | |
3233 | dig_port->write_infoframe(encoder, crtc_state, type, &sdp, len); |
3234 | } |
3235 | |
3236 | void intel_write_dp_vsc_sdp(struct intel_encoder *encoder, |
3237 | const struct intel_crtc_state *crtc_state, |
3238 | const struct drm_dp_vsc_sdp *vsc) |
3239 | { |
3240 | struct intel_digital_port *dig_port = enc_to_dig_port(encoder); |
3241 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
3242 | struct dp_sdp sdp = {}; |
3243 | ssize_t len; |
3244 | |
3245 | len = intel_dp_vsc_sdp_pack(vsc, &sdp, sizeof(sdp)); |
3246 | |
3247 | if (drm_WARN_ON(&dev_priv->drm, len < 0)({ int __ret = !!((len < 0)); if (__ret) printf("%s %s: " "%s" , dev_driver_string(((&dev_priv->drm))->dev), "", "drm_WARN_ON(" "len < 0" ")"); __builtin_expect(!!(__ret), 0); })) |
3248 | return; |
3249 | |
3250 | dig_port->write_infoframe(encoder, crtc_state, DP_SDP_VSC0x07, |
3251 | &sdp, len); |
3252 | } |
3253 | |
3254 | void intel_dp_set_infoframes(struct intel_encoder *encoder, |
3255 | bool_Bool enable, |
3256 | const struct intel_crtc_state *crtc_state, |
3257 | const struct drm_connector_state *conn_state) |
3258 | { |
3259 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
3260 | i915_reg_t reg = HSW_TVIDEO_DIP_CTL(crtc_state->cpu_transcoder)((const i915_reg_t){ .reg = ((&(dev_priv)->__info)-> display.trans_offsets[(crtc_state->cpu_transcoder)] - (& (dev_priv)->__info)->display.trans_offsets[TRANSCODER_A ] + ((&(dev_priv)->__info)->display.mmio_offset) + ( 0x60200)) }); |
3261 | u32 dip_enable = VIDEO_DIP_ENABLE_AVI_HSW(1 << 12) | VIDEO_DIP_ENABLE_GCP_HSW(1 << 16) | |
3262 | VIDEO_DIP_ENABLE_VS_HSW(1 << 8) | VIDEO_DIP_ENABLE_GMP_HSW(1 << 4) | |
3263 | VIDEO_DIP_ENABLE_SPD_HSW(1 << 0) | VIDEO_DIP_ENABLE_DRM_GLK(1 << 28); |
3264 | u32 val = intel_de_read(dev_priv, reg) & ~dip_enable; |
3265 | |
3266 | /* TODO: Add DSC case (DIP_ENABLE_PPS) */ |
3267 | /* When PSR is enabled, this routine doesn't disable VSC DIP */ |
3268 | if (!crtc_state->has_psr) |
3269 | val &= ~VIDEO_DIP_ENABLE_VSC_HSW(1 << 20); |
3270 | |
3271 | intel_de_write(dev_priv, reg, val); |
3272 | intel_de_posting_read(dev_priv, reg); |
3273 | |
3274 | if (!enable) |
3275 | return; |
3276 | |
3277 | /* When PSR is enabled, VSC SDP is handled by PSR routine */ |
3278 | if (!crtc_state->has_psr) |
3279 | intel_write_dp_sdp(encoder, crtc_state, DP_SDP_VSC0x07); |
3280 | |
3281 | intel_write_dp_sdp(encoder, crtc_state, HDMI_PACKET_TYPE_GAMUT_METADATA); |
3282 | } |
3283 | |
3284 | static int intel_dp_vsc_sdp_unpack(struct drm_dp_vsc_sdp *vsc, |
3285 | const void *buffer, size_t size) |
3286 | { |
3287 | const struct dp_sdp *sdp = buffer; |
3288 | |
3289 | if (size < sizeof(struct dp_sdp)) |
3290 | return -EINVAL22; |
3291 | |
3292 | memset(vsc, 0, sizeof(*vsc))__builtin_memset((vsc), (0), (sizeof(*vsc))); |
3293 | |
3294 | if (sdp->sdp_header.HB0 != 0) |
3295 | return -EINVAL22; |
3296 | |
3297 | if (sdp->sdp_header.HB1 != DP_SDP_VSC0x07) |
3298 | return -EINVAL22; |
3299 | |
3300 | vsc->sdp_type = sdp->sdp_header.HB1; |
3301 | vsc->revision = sdp->sdp_header.HB2; |
3302 | vsc->length = sdp->sdp_header.HB3; |
3303 | |
3304 | if ((sdp->sdp_header.HB2 == 0x2 && sdp->sdp_header.HB3 == 0x8) || |
3305 | (sdp->sdp_header.HB2 == 0x4 && sdp->sdp_header.HB3 == 0xe)) { |
3306 | /* |
3307 | * - HB2 = 0x2, HB3 = 0x8 |
3308 | * VSC SDP supporting 3D stereo + PSR |
3309 | * - HB2 = 0x4, HB3 = 0xe |
3310 | * VSC SDP supporting 3D stereo + PSR2 with Y-coordinate of |
3311 | * first scan line of the SU region (applies to eDP v1.4b |
3312 | * and higher). |
3313 | */ |
3314 | return 0; |
3315 | } else if (sdp->sdp_header.HB2 == 0x5 && sdp->sdp_header.HB3 == 0x13) { |
3316 | /* |
3317 | * - HB2 = 0x5, HB3 = 0x13 |
3318 | * VSC SDP supporting 3D stereo + PSR2 + Pixel Encoding/Colorimetry |
3319 | * Format. |
3320 | */ |
3321 | vsc->pixelformat = (sdp->db[16] >> 4) & 0xf; |
3322 | vsc->colorimetry = sdp->db[16] & 0xf; |
3323 | vsc->dynamic_range = (sdp->db[17] >> 7) & 0x1; |
3324 | |
3325 | switch (sdp->db[17] & 0x7) { |
3326 | case 0x0: |
3327 | vsc->bpc = 6; |
3328 | break; |
3329 | case 0x1: |
3330 | vsc->bpc = 8; |
3331 | break; |
3332 | case 0x2: |
3333 | vsc->bpc = 10; |
3334 | break; |
3335 | case 0x3: |
3336 | vsc->bpc = 12; |
3337 | break; |
3338 | case 0x4: |
3339 | vsc->bpc = 16; |
3340 | break; |
3341 | default: |
3342 | MISSING_CASE(sdp->db[17] & 0x7)({ int __ret = !!(1); if (__ret) printf("Missing case (%s == %ld)\n" , "sdp->db[17] & 0x7", (long)(sdp->db[17] & 0x7 )); __builtin_expect(!!(__ret), 0); }); |
3343 | return -EINVAL22; |
3344 | } |
3345 | |
3346 | vsc->content_type = sdp->db[18] & 0x7; |
3347 | } else { |
3348 | return -EINVAL22; |
3349 | } |
3350 | |
3351 | return 0; |
3352 | } |
3353 | |
3354 | static int |
3355 | intel_dp_hdr_metadata_infoframe_sdp_unpack(struct hdmi_drm_infoframe *drm_infoframe, |
3356 | const void *buffer, size_t size) |
3357 | { |
3358 | int ret; |
3359 | |
3360 | const struct dp_sdp *sdp = buffer; |
3361 | |
3362 | if (size < sizeof(struct dp_sdp)) |
3363 | return -EINVAL22; |
3364 | |
3365 | if (sdp->sdp_header.HB0 != 0) |
3366 | return -EINVAL22; |
3367 | |
3368 | if (sdp->sdp_header.HB1 != HDMI_INFOFRAME_TYPE_DRM) |
3369 | return -EINVAL22; |
3370 | |
3371 | /* |
3372 | * Least Significant Eight Bits of (Data Byte Count – 1) |
3373 | * 1Dh (i.e., Data Byte Count = 30 bytes). |
3374 | */ |
3375 | if (sdp->sdp_header.HB2 != 0x1D) |
3376 | return -EINVAL22; |
3377 | |
3378 | /* Most Significant Two Bits of (Data Byte Count – 1), Clear to 00b. */ |
3379 | if ((sdp->sdp_header.HB3 & 0x3) != 0) |
3380 | return -EINVAL22; |
3381 | |
3382 | /* INFOFRAME SDP Version Number */ |
3383 | if (((sdp->sdp_header.HB3 >> 2) & 0x3f) != 0x13) |
3384 | return -EINVAL22; |
3385 | |
3386 | /* CTA Header Byte 2 (INFOFRAME Version Number) */ |
3387 | if (sdp->db[0] != 1) |
3388 | return -EINVAL22; |
3389 | |
3390 | /* CTA Header Byte 3 (Length of INFOFRAME): HDMI_DRM_INFOFRAME_SIZE */ |
3391 | if (sdp->db[1] != HDMI_DRM_INFOFRAME_SIZE26) |
3392 | return -EINVAL22; |
3393 | |
3394 | ret = hdmi_drm_infoframe_unpack_only(drm_infoframe, &sdp->db[2], |
3395 | HDMI_DRM_INFOFRAME_SIZE26); |
3396 | |
3397 | return ret; |
3398 | } |
3399 | |
3400 | static void intel_read_dp_vsc_sdp(struct intel_encoder *encoder, |
3401 | struct intel_crtc_state *crtc_state, |
3402 | struct drm_dp_vsc_sdp *vsc) |
3403 | { |
3404 | struct intel_digital_port *dig_port = enc_to_dig_port(encoder); |
3405 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
3406 | unsigned int type = DP_SDP_VSC0x07; |
3407 | struct dp_sdp sdp = {}; |
3408 | int ret; |
3409 | |
3410 | /* When PSR is enabled, VSC SDP is handled by PSR routine */ |
3411 | if (crtc_state->has_psr) |
3412 | return; |
3413 | |
3414 | if ((crtc_state->infoframes.enable & |
3415 | intel_hdmi_infoframe_enable(type)) == 0) |
3416 | return; |
3417 | |
3418 | dig_port->read_infoframe(encoder, crtc_state, type, &sdp, sizeof(sdp)); |
3419 | |
3420 | ret = intel_dp_vsc_sdp_unpack(vsc, &sdp, sizeof(sdp)); |
3421 | |
3422 | if (ret) |
3423 | drm_dbg_kms(&dev_priv->drm, "Failed to unpack DP VSC SDP\n")__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "Failed to unpack DP VSC SDP\n" ); |
3424 | } |
3425 | |
3426 | static void intel_read_dp_hdr_metadata_infoframe_sdp(struct intel_encoder *encoder, |
3427 | struct intel_crtc_state *crtc_state, |
3428 | struct hdmi_drm_infoframe *drm_infoframe) |
3429 | { |
3430 | struct intel_digital_port *dig_port = enc_to_dig_port(encoder); |
3431 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
3432 | unsigned int type = HDMI_PACKET_TYPE_GAMUT_METADATA; |
3433 | struct dp_sdp sdp = {}; |
3434 | int ret; |
3435 | |
3436 | if ((crtc_state->infoframes.enable & |
3437 | intel_hdmi_infoframe_enable(type)) == 0) |
3438 | return; |
3439 | |
3440 | dig_port->read_infoframe(encoder, crtc_state, type, &sdp, |
3441 | sizeof(sdp)); |
3442 | |
3443 | ret = intel_dp_hdr_metadata_infoframe_sdp_unpack(drm_infoframe, &sdp, |
3444 | sizeof(sdp)); |
3445 | |
3446 | if (ret) |
3447 | drm_dbg_kms(&dev_priv->drm,__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "Failed to unpack DP HDR Metadata Infoframe SDP\n" ) |
3448 | "Failed to unpack DP HDR Metadata Infoframe SDP\n")__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "Failed to unpack DP HDR Metadata Infoframe SDP\n" ); |
3449 | } |
3450 | |
3451 | void intel_read_dp_sdp(struct intel_encoder *encoder, |
3452 | struct intel_crtc_state *crtc_state, |
3453 | unsigned int type) |
3454 | { |
3455 | switch (type) { |
3456 | case DP_SDP_VSC0x07: |
3457 | intel_read_dp_vsc_sdp(encoder, crtc_state, |
3458 | &crtc_state->infoframes.vsc); |
3459 | break; |
3460 | case HDMI_PACKET_TYPE_GAMUT_METADATA: |
3461 | intel_read_dp_hdr_metadata_infoframe_sdp(encoder, crtc_state, |
3462 | &crtc_state->infoframes.drm.drm); |
3463 | break; |
3464 | default: |
3465 | MISSING_CASE(type)({ int __ret = !!(1); if (__ret) printf("Missing case (%s == %ld)\n" , "type", (long)(type)); __builtin_expect(!!(__ret), 0); }); |
3466 | break; |
3467 | } |
3468 | } |
3469 | |
3470 | static u8 intel_dp_autotest_link_training(struct intel_dp *intel_dp) |
3471 | { |
3472 | struct drm_i915_privateinteldrm_softc *i915 = dp_to_i915(intel_dp)to_i915(dp_to_dig_port(intel_dp)->base.base.dev); |
3473 | int status = 0; |
3474 | int test_link_rate; |
3475 | u8 test_lane_count, test_link_bw; |
3476 | /* (DP CTS 1.2) |
3477 | * 4.3.1.11 |
3478 | */ |
3479 | /* Read the TEST_LANE_COUNT and TEST_LINK_RTAE fields (DP CTS 3.1.4) */ |
3480 | status = drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_LANE_COUNT0x220, |
3481 | &test_lane_count); |
3482 | |
3483 | if (status <= 0) { |
3484 | drm_dbg_kms(&i915->drm, "Lane count read failed\n")__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "Lane count read failed\n" ); |
3485 | return DP_TEST_NAK(1 << 1); |
3486 | } |
3487 | test_lane_count &= DP_MAX_LANE_COUNT_MASK0x1f; |
3488 | |
3489 | status = drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_LINK_RATE0x219, |
3490 | &test_link_bw); |
3491 | if (status <= 0) { |
3492 | drm_dbg_kms(&i915->drm, "Link Rate read failed\n")__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "Link Rate read failed\n" ); |
3493 | return DP_TEST_NAK(1 << 1); |
3494 | } |
3495 | test_link_rate = drm_dp_bw_code_to_link_rate(test_link_bw); |
3496 | |
3497 | /* Validate the requested link rate and lane count */ |
3498 | if (!intel_dp_link_params_valid(intel_dp, test_link_rate, |
3499 | test_lane_count)) |
3500 | return DP_TEST_NAK(1 << 1); |
3501 | |
3502 | intel_dp->compliance.test_lane_count = test_lane_count; |
3503 | intel_dp->compliance.test_link_rate = test_link_rate; |
3504 | |
3505 | return DP_TEST_ACK(1 << 0); |
3506 | } |
3507 | |
3508 | static u8 intel_dp_autotest_video_pattern(struct intel_dp *intel_dp) |
3509 | { |
3510 | struct drm_i915_privateinteldrm_softc *i915 = dp_to_i915(intel_dp)to_i915(dp_to_dig_port(intel_dp)->base.base.dev); |
3511 | u8 test_pattern; |
3512 | u8 test_misc; |
3513 | __be16 h_width, v_height; |
3514 | int status = 0; |
3515 | |
3516 | /* Read the TEST_PATTERN (DP CTS 3.1.5) */ |
3517 | status = drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_PATTERN0x221, |
3518 | &test_pattern); |
3519 | if (status <= 0) { |
3520 | drm_dbg_kms(&i915->drm, "Test pattern read failed\n")__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "Test pattern read failed\n" ); |
3521 | return DP_TEST_NAK(1 << 1); |
3522 | } |
3523 | if (test_pattern != DP_COLOR_RAMP0x1) |
3524 | return DP_TEST_NAK(1 << 1); |
3525 | |
3526 | status = drm_dp_dpcd_read(&intel_dp->aux, DP_TEST_H_WIDTH_HI0x22E, |
3527 | &h_width, 2); |
3528 | if (status <= 0) { |
3529 | drm_dbg_kms(&i915->drm, "H Width read failed\n")__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "H Width read failed\n" ); |
3530 | return DP_TEST_NAK(1 << 1); |
3531 | } |
3532 | |
3533 | status = drm_dp_dpcd_read(&intel_dp->aux, DP_TEST_V_HEIGHT_HI0x230, |
3534 | &v_height, 2); |
3535 | if (status <= 0) { |
3536 | drm_dbg_kms(&i915->drm, "V Height read failed\n")__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "V Height read failed\n" ); |
3537 | return DP_TEST_NAK(1 << 1); |
3538 | } |
3539 | |
3540 | status = drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_MISC00x232, |
3541 | &test_misc); |
3542 | if (status <= 0) { |
3543 | drm_dbg_kms(&i915->drm, "TEST MISC read failed\n")__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "TEST MISC read failed\n" ); |
3544 | return DP_TEST_NAK(1 << 1); |
3545 | } |
3546 | if ((test_misc & DP_TEST_COLOR_FORMAT_MASK(3 << 1)) != DP_COLOR_FORMAT_RGB(0 << 1)) |
3547 | return DP_TEST_NAK(1 << 1); |
3548 | if (test_misc & DP_TEST_DYNAMIC_RANGE_CEA(1 << 3)) |
3549 | return DP_TEST_NAK(1 << 1); |
3550 | switch (test_misc & DP_TEST_BIT_DEPTH_MASK(7 << 5)) { |
3551 | case DP_TEST_BIT_DEPTH_6(0 << 5): |
3552 | intel_dp->compliance.test_data.bpc = 6; |
3553 | break; |
3554 | case DP_TEST_BIT_DEPTH_8(1 << 5): |
3555 | intel_dp->compliance.test_data.bpc = 8; |
3556 | break; |
3557 | default: |
3558 | return DP_TEST_NAK(1 << 1); |
3559 | } |
3560 | |
3561 | intel_dp->compliance.test_data.video_pattern = test_pattern; |
3562 | intel_dp->compliance.test_data.hdisplay = be16_to_cpu(h_width)(__uint16_t)(__builtin_constant_p(h_width) ? (__uint16_t)(((__uint16_t )(h_width) & 0xffU) << 8 | ((__uint16_t)(h_width) & 0xff00U) >> 8) : __swap16md(h_width)); |
3563 | intel_dp->compliance.test_data.vdisplay = be16_to_cpu(v_height)(__uint16_t)(__builtin_constant_p(v_height) ? (__uint16_t)((( __uint16_t)(v_height) & 0xffU) << 8 | ((__uint16_t) (v_height) & 0xff00U) >> 8) : __swap16md(v_height)); |
3564 | /* Set test active flag here so userspace doesn't interrupt things */ |
3565 | intel_dp->compliance.test_active = true1; |
3566 | |
3567 | return DP_TEST_ACK(1 << 0); |
3568 | } |
3569 | |
3570 | static u8 intel_dp_autotest_edid(struct intel_dp *intel_dp) |
3571 | { |
3572 | struct drm_i915_privateinteldrm_softc *i915 = dp_to_i915(intel_dp)to_i915(dp_to_dig_port(intel_dp)->base.base.dev); |
3573 | u8 test_result = DP_TEST_ACK(1 << 0); |
3574 | struct intel_connector *intel_connector = intel_dp->attached_connector; |
3575 | struct drm_connector *connector = &intel_connector->base; |
3576 | |
3577 | if (intel_connector->detect_edid == NULL((void *)0) || |
3578 | connector->edid_corrupt || |
3579 | intel_dp->aux.i2c_defer_count > 6) { |
3580 | /* Check EDID read for NACKs, DEFERs and corruption |
3581 | * (DP CTS 1.2 Core r1.1) |
3582 | * 4.2.2.4 : Failed EDID read, I2C_NAK |
3583 | * 4.2.2.5 : Failed EDID read, I2C_DEFER |
3584 | * 4.2.2.6 : EDID corruption detected |
3585 | * Use failsafe mode for all cases |
3586 | */ |
3587 | if (intel_dp->aux.i2c_nack_count > 0 || |
3588 | intel_dp->aux.i2c_defer_count > 0) |
3589 | drm_dbg_kms(&i915->drm,__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "EDID read had %d NACKs, %d DEFERs\n" , intel_dp->aux.i2c_nack_count, intel_dp->aux.i2c_defer_count ) |
3590 | "EDID read had %d NACKs, %d DEFERs\n",__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "EDID read had %d NACKs, %d DEFERs\n" , intel_dp->aux.i2c_nack_count, intel_dp->aux.i2c_defer_count ) |
3591 | intel_dp->aux.i2c_nack_count,__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "EDID read had %d NACKs, %d DEFERs\n" , intel_dp->aux.i2c_nack_count, intel_dp->aux.i2c_defer_count ) |
3592 | intel_dp->aux.i2c_defer_count)__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "EDID read had %d NACKs, %d DEFERs\n" , intel_dp->aux.i2c_nack_count, intel_dp->aux.i2c_defer_count ); |
3593 | intel_dp->compliance.test_data.edid = INTEL_DP_RESOLUTION_FAILSAFE(3 << 0); |
3594 | } else { |
3595 | struct edid *block = intel_connector->detect_edid; |
3596 | |
3597 | /* We have to write the checksum |
3598 | * of the last block read |
3599 | */ |
3600 | block += intel_connector->detect_edid->extensions; |
3601 | |
3602 | if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_TEST_EDID_CHECKSUM0x261, |
3603 | block->checksum) <= 0) |
3604 | drm_dbg_kms(&i915->drm,__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "Failed to write EDID checksum\n" ) |
3605 | "Failed to write EDID checksum\n")__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "Failed to write EDID checksum\n" ); |
3606 | |
3607 | test_result = DP_TEST_ACK(1 << 0) | DP_TEST_EDID_CHECKSUM_WRITE(1 << 2); |
3608 | intel_dp->compliance.test_data.edid = INTEL_DP_RESOLUTION_PREFERRED(1 << 0); |
3609 | } |
3610 | |
3611 | /* Set test active flag here so userspace doesn't interrupt things */ |
3612 | intel_dp->compliance.test_active = true1; |
3613 | |
3614 | return test_result; |
3615 | } |
3616 | |
3617 | static void intel_dp_phy_pattern_update(struct intel_dp *intel_dp, |
3618 | const struct intel_crtc_state *crtc_state) |
3619 | { |
3620 | struct drm_i915_privateinteldrm_softc *dev_priv = |
3621 | to_i915(dp_to_dig_port(intel_dp)->base.base.dev); |
3622 | struct drm_dp_phy_test_params *data = |
3623 | &intel_dp->compliance.test_data.phytest; |
3624 | struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc)({ const __typeof( ((struct intel_crtc *)0)->base ) *__mptr = (crtc_state->uapi.crtc); (struct intel_crtc *)( (char * )__mptr - __builtin_offsetof(struct intel_crtc, base) );}); |
3625 | enum pipe pipe = crtc->pipe; |
3626 | u32 pattern_val; |
3627 | |
3628 | switch (data->phy_pattern) { |
3629 | case DP_PHY_TEST_PATTERN_NONE0x0: |
3630 | drm_dbg_kms(&dev_priv->drm, "Disable Phy Test Pattern\n")__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "Disable Phy Test Pattern\n" ); |
3631 | intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe)((const i915_reg_t){ .reg = (((0x605F0) + (pipe) * ((0x615F0) - (0x605F0)))) }), 0x0); |
3632 | break; |
3633 | case DP_PHY_TEST_PATTERN_D10_20x1: |
3634 | drm_dbg_kms(&dev_priv->drm, "Set D10.2 Phy Test Pattern\n")__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "Set D10.2 Phy Test Pattern\n" ); |
3635 | intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe)((const i915_reg_t){ .reg = (((0x605F0) + (pipe) * ((0x615F0) - (0x605F0)))) }), |
3636 | DDI_DP_COMP_CTL_ENABLE(1 << 31) | DDI_DP_COMP_CTL_D10_2(0 << 28)); |
3637 | break; |
3638 | case DP_PHY_TEST_PATTERN_ERROR_COUNT0x2: |
3639 | drm_dbg_kms(&dev_priv->drm, "Set Error Count Phy Test Pattern\n")__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "Set Error Count Phy Test Pattern\n" ); |
3640 | intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe)((const i915_reg_t){ .reg = (((0x605F0) + (pipe) * ((0x615F0) - (0x605F0)))) }), |
3641 | DDI_DP_COMP_CTL_ENABLE(1 << 31) | |
3642 | DDI_DP_COMP_CTL_SCRAMBLED_0(1 << 28)); |
3643 | break; |
3644 | case DP_PHY_TEST_PATTERN_PRBS70x3: |
3645 | drm_dbg_kms(&dev_priv->drm, "Set PRBS7 Phy Test Pattern\n")__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "Set PRBS7 Phy Test Pattern\n" ); |
3646 | intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe)((const i915_reg_t){ .reg = (((0x605F0) + (pipe) * ((0x615F0) - (0x605F0)))) }), |
3647 | DDI_DP_COMP_CTL_ENABLE(1 << 31) | DDI_DP_COMP_CTL_PRBS7(2 << 28)); |
3648 | break; |
3649 | case DP_PHY_TEST_PATTERN_80BIT_CUSTOM0x4: |
3650 | /* |
3651 | * FIXME: Ideally pattern should come from DPCD 0x250. As |
3652 | * current firmware of DPR-100 could not set it, so hardcoding |
3653 | * now for complaince test. |
3654 | */ |
3655 | drm_dbg_kms(&dev_priv->drm,__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "Set 80Bit Custom Phy Test Pattern 0x3e0f83e0 0x0f83e0f8 0x0000f83e\n" ) |
3656 | "Set 80Bit Custom Phy Test Pattern 0x3e0f83e0 0x0f83e0f8 0x0000f83e\n")__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "Set 80Bit Custom Phy Test Pattern 0x3e0f83e0 0x0f83e0f8 0x0000f83e\n" ); |
3657 | pattern_val = 0x3e0f83e0; |
3658 | intel_de_write(dev_priv, DDI_DP_COMP_PAT(pipe, 0)((const i915_reg_t){ .reg = (((0x605F4) + (pipe) * ((0x615F4) - (0x605F4))) + (0) * 4) }), pattern_val); |
3659 | pattern_val = 0x0f83e0f8; |
3660 | intel_de_write(dev_priv, DDI_DP_COMP_PAT(pipe, 1)((const i915_reg_t){ .reg = (((0x605F4) + (pipe) * ((0x615F4) - (0x605F4))) + (1) * 4) }), pattern_val); |
3661 | pattern_val = 0x0000f83e; |
3662 | intel_de_write(dev_priv, DDI_DP_COMP_PAT(pipe, 2)((const i915_reg_t){ .reg = (((0x605F4) + (pipe) * ((0x615F4) - (0x605F4))) + (2) * 4) }), pattern_val); |
3663 | intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe)((const i915_reg_t){ .reg = (((0x605F0) + (pipe) * ((0x615F0) - (0x605F0)))) }), |
3664 | DDI_DP_COMP_CTL_ENABLE(1 << 31) | |
3665 | DDI_DP_COMP_CTL_CUSTOM80(3 << 28)); |
3666 | break; |
3667 | case DP_PHY_TEST_PATTERN_CP25200x5: |
3668 | /* |
3669 | * FIXME: Ideally pattern should come from DPCD 0x24A. As |
3670 | * current firmware of DPR-100 could not set it, so hardcoding |
3671 | * now for complaince test. |
3672 | */ |
3673 | drm_dbg_kms(&dev_priv->drm, "Set HBR2 compliance Phy Test Pattern\n")__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "Set HBR2 compliance Phy Test Pattern\n" ); |
3674 | pattern_val = 0xFB; |
3675 | intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe)((const i915_reg_t){ .reg = (((0x605F0) + (pipe) * ((0x615F0) - (0x605F0)))) }), |
3676 | DDI_DP_COMP_CTL_ENABLE(1 << 31) | DDI_DP_COMP_CTL_HBR2(4 << 28) | |
3677 | pattern_val); |
3678 | break; |
3679 | default: |
3680 | WARN(1, "Invalid Phy Test Pattern\n")({ int __ret = !!(1); if (__ret) printf("Invalid Phy Test Pattern\n" ); __builtin_expect(!!(__ret), 0); }); |
3681 | } |
3682 | } |
3683 | |
3684 | static void intel_dp_process_phy_request(struct intel_dp *intel_dp, |
3685 | const struct intel_crtc_state *crtc_state) |
3686 | { |
3687 | struct drm_i915_privateinteldrm_softc *i915 = dp_to_i915(intel_dp)to_i915(dp_to_dig_port(intel_dp)->base.base.dev); |
3688 | struct drm_dp_phy_test_params *data = |
3689 | &intel_dp->compliance.test_data.phytest; |
3690 | u8 link_status[DP_LINK_STATUS_SIZE6]; |
3691 | |
3692 | if (drm_dp_dpcd_read_phy_link_status(&intel_dp->aux, DP_PHY_DPRX, |
3693 | link_status) < 0) { |
3694 | drm_dbg_kms(&i915->drm, "failed to get link status\n")__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "failed to get link status\n" ); |
3695 | return; |
3696 | } |
3697 | |
3698 | /* retrieve vswing & pre-emphasis setting */ |
3699 | intel_dp_get_adjust_train(intel_dp, crtc_state, DP_PHY_DPRX, |
3700 | link_status); |
3701 | |
3702 | intel_dp_set_signal_levels(intel_dp, crtc_state, DP_PHY_DPRX); |
3703 | |
3704 | intel_dp_phy_pattern_update(intel_dp, crtc_state); |
3705 | |
3706 | drm_dp_dpcd_write(&intel_dp->aux, DP_TRAINING_LANE0_SET0x103, |
3707 | intel_dp->train_set, crtc_state->lane_count); |
3708 | |
3709 | drm_dp_set_phy_test_pattern(&intel_dp->aux, data, |
3710 | link_status[DP_DPCD_REV0x000]); |
3711 | } |
3712 | |
3713 | static u8 intel_dp_autotest_phy_pattern(struct intel_dp *intel_dp) |
3714 | { |
3715 | struct drm_i915_privateinteldrm_softc *i915 = dp_to_i915(intel_dp)to_i915(dp_to_dig_port(intel_dp)->base.base.dev); |
3716 | struct drm_dp_phy_test_params *data = |
3717 | &intel_dp->compliance.test_data.phytest; |
3718 | |
3719 | if (drm_dp_get_phy_test_pattern(&intel_dp->aux, data)) { |
3720 | drm_dbg_kms(&i915->drm, "DP Phy Test pattern AUX read failure\n")__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "DP Phy Test pattern AUX read failure\n" ); |
3721 | return DP_TEST_NAK(1 << 1); |
3722 | } |
3723 | |
3724 | /* Set test active flag here so userspace doesn't interrupt things */ |
3725 | intel_dp->compliance.test_active = true1; |
3726 | |
3727 | return DP_TEST_ACK(1 << 0); |
3728 | } |
3729 | |
3730 | static void intel_dp_handle_test_request(struct intel_dp *intel_dp) |
3731 | { |
3732 | struct drm_i915_privateinteldrm_softc *i915 = dp_to_i915(intel_dp)to_i915(dp_to_dig_port(intel_dp)->base.base.dev); |
3733 | u8 response = DP_TEST_NAK(1 << 1); |
3734 | u8 request = 0; |
3735 | int status; |
3736 | |
3737 | status = drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_REQUEST0x218, &request); |
3738 | if (status <= 0) { |
3739 | drm_dbg_kms(&i915->drm,__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "Could not read test request from sink\n" ) |
3740 | "Could not read test request from sink\n")__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "Could not read test request from sink\n" ); |
3741 | goto update_status; |
3742 | } |
3743 | |
3744 | switch (request) { |
3745 | case DP_TEST_LINK_TRAINING(1 << 0): |
3746 | drm_dbg_kms(&i915->drm, "LINK_TRAINING test requested\n")__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "LINK_TRAINING test requested\n" ); |
3747 | response = intel_dp_autotest_link_training(intel_dp); |
3748 | break; |
3749 | case DP_TEST_LINK_VIDEO_PATTERN(1 << 1): |
3750 | drm_dbg_kms(&i915->drm, "TEST_PATTERN test requested\n")__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "TEST_PATTERN test requested\n" ); |
3751 | response = intel_dp_autotest_video_pattern(intel_dp); |
3752 | break; |
3753 | case DP_TEST_LINK_EDID_READ(1 << 2): |
3754 | drm_dbg_kms(&i915->drm, "EDID test requested\n")__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "EDID test requested\n" ); |
3755 | response = intel_dp_autotest_edid(intel_dp); |
3756 | break; |
3757 | case DP_TEST_LINK_PHY_TEST_PATTERN(1 << 3): |
3758 | drm_dbg_kms(&i915->drm, "PHY_PATTERN test requested\n")__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "PHY_PATTERN test requested\n" ); |
3759 | response = intel_dp_autotest_phy_pattern(intel_dp); |
3760 | break; |
3761 | default: |
3762 | drm_dbg_kms(&i915->drm, "Invalid test request '%02x'\n",__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "Invalid test request '%02x'\n" , request) |
3763 | request)__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "Invalid test request '%02x'\n" , request); |
3764 | break; |
3765 | } |
3766 | |
3767 | if (response & DP_TEST_ACK(1 << 0)) |
3768 | intel_dp->compliance.test_type = request; |
3769 | |
3770 | update_status: |
3771 | status = drm_dp_dpcd_writeb(&intel_dp->aux, DP_TEST_RESPONSE0x260, response); |
3772 | if (status <= 0) |
3773 | drm_dbg_kms(&i915->drm,__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "Could not write test response to sink\n" ) |
3774 | "Could not write test response to sink\n")__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "Could not write test response to sink\n" ); |
3775 | } |
3776 | |
3777 | static bool_Bool intel_dp_link_ok(struct intel_dp *intel_dp, |
3778 | u8 link_status[DP_LINK_STATUS_SIZE6]) |
3779 | { |
3780 | struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; |
3781 | struct drm_i915_privateinteldrm_softc *i915 = to_i915(encoder->base.dev); |
3782 | bool_Bool uhbr = intel_dp->link_rate >= 1000000; |
3783 | bool_Bool ok; |
3784 | |
3785 | if (uhbr) |
3786 | ok = drm_dp_128b132b_lane_channel_eq_done(link_status, |
3787 | intel_dp->lane_count); |
3788 | else |
3789 | ok = drm_dp_channel_eq_ok(link_status, intel_dp->lane_count); |
3790 | |
3791 | if (ok) |
3792 | return true1; |
3793 | |
3794 | intel_dp_dump_link_status(intel_dp, DP_PHY_DPRX, link_status); |
3795 | drm_dbg_kms(&i915->drm,__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "[ENCODER:%d:%s] %s link not ok, retraining\n" , encoder->base.base.id, encoder->base.name, uhbr ? "128b/132b" : "8b/10b") |
3796 | "[ENCODER:%d:%s] %s link not ok, retraining\n",__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "[ENCODER:%d:%s] %s link not ok, retraining\n" , encoder->base.base.id, encoder->base.name, uhbr ? "128b/132b" : "8b/10b") |
3797 | encoder->base.base.id, encoder->base.name,__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "[ENCODER:%d:%s] %s link not ok, retraining\n" , encoder->base.base.id, encoder->base.name, uhbr ? "128b/132b" : "8b/10b") |
3798 | uhbr ? "128b/132b" : "8b/10b")__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "[ENCODER:%d:%s] %s link not ok, retraining\n" , encoder->base.base.id, encoder->base.name, uhbr ? "128b/132b" : "8b/10b"); |
3799 | |
3800 | return false0; |
3801 | } |
3802 | |
3803 | static void |
3804 | intel_dp_mst_hpd_irq(struct intel_dp *intel_dp, u8 *esi, u8 *ack) |
3805 | { |
3806 | bool_Bool handled = false0; |
3807 | |
3808 | drm_dp_mst_hpd_irq_handle_event(&intel_dp->mst_mgr, esi, ack, &handled); |
3809 | |
3810 | if (esi[1] & DP_CP_IRQ(1 << 2)) { |
3811 | intel_hdcp_handle_cp_irq(intel_dp->attached_connector); |
3812 | ack[1] |= DP_CP_IRQ(1 << 2); |
3813 | } |
3814 | } |
3815 | |
3816 | static bool_Bool intel_dp_mst_link_status(struct intel_dp *intel_dp) |
3817 | { |
3818 | struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; |
3819 | struct drm_i915_privateinteldrm_softc *i915 = to_i915(encoder->base.dev); |
3820 | u8 link_status[DP_LINK_STATUS_SIZE6] = {}; |
3821 | const size_t esi_link_status_size = DP_LINK_STATUS_SIZE6 - 2; |
3822 | |
3823 | if (drm_dp_dpcd_read(&intel_dp->aux, DP_LANE0_1_STATUS_ESI0x200c, link_status, |
3824 | esi_link_status_size) != esi_link_status_size) { |
3825 | drm_err(&i915->drm,printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "[ENCODER:%d:%s] Failed to read link status\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , encoder ->base.base.id, encoder->base.name) |
3826 | "[ENCODER:%d:%s] Failed to read link status\n",printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "[ENCODER:%d:%s] Failed to read link status\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , encoder ->base.base.id, encoder->base.name) |
3827 | encoder->base.base.id, encoder->base.name)printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "[ENCODER:%d:%s] Failed to read link status\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , encoder ->base.base.id, encoder->base.name); |
3828 | return false0; |
3829 | } |
3830 | |
3831 | return intel_dp_link_ok(intel_dp, link_status); |
3832 | } |
3833 | |
3834 | /** |
3835 | * intel_dp_check_mst_status - service any pending MST interrupts, check link status |
3836 | * @intel_dp: Intel DP struct |
3837 | * |
3838 | * Read any pending MST interrupts, call MST core to handle these and ack the |
3839 | * interrupts. Check if the main and AUX link state is ok. |
3840 | * |
3841 | * Returns: |
3842 | * - %true if pending interrupts were serviced (or no interrupts were |
3843 | * pending) w/o detecting an error condition. |
3844 | * - %false if an error condition - like AUX failure or a loss of link - is |
3845 | * detected, which needs servicing from the hotplug work. |
3846 | */ |
3847 | static bool_Bool |
3848 | intel_dp_check_mst_status(struct intel_dp *intel_dp) |
3849 | { |
3850 | struct drm_i915_privateinteldrm_softc *i915 = dp_to_i915(intel_dp)to_i915(dp_to_dig_port(intel_dp)->base.base.dev); |
3851 | bool_Bool link_ok = true1; |
3852 | |
3853 | drm_WARN_ON_ONCE(&i915->drm, intel_dp->active_mst_links < 0)({ static int __warned; int __ret = !!((intel_dp->active_mst_links < 0)); if (__ret && !__warned) { printf("%s %s: " "%s", dev_driver_string(((&i915->drm))->dev), "", "drm_WARN_ON_ONCE(" "intel_dp->active_mst_links < 0" ")"); __warned = 1; } __builtin_expect(!!(__ret), 0); }); |
3854 | |
3855 | for (;;) { |
3856 | u8 esi[4] = {}; |
3857 | u8 ack[4] = {}; |
3858 | |
3859 | if (!intel_dp_get_sink_irq_esi(intel_dp, esi)) { |
3860 | drm_dbg_kms(&i915->drm,__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "failed to get ESI - device may have failed\n" ) |
3861 | "failed to get ESI - device may have failed\n")__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "failed to get ESI - device may have failed\n" ); |
3862 | link_ok = false0; |
3863 | |
3864 | break; |
3865 | } |
3866 | |
3867 | drm_dbg_kms(&i915->drm, "DPRX ESI: %4ph\n", esi)__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "DPRX ESI: %4ph\n", esi ); |
3868 | |
3869 | if (intel_dp->active_mst_links > 0 && link_ok && |
3870 | esi[3] & LINK_STATUS_CHANGED(1 << 1)) { |
3871 | if (!intel_dp_mst_link_status(intel_dp)) |
3872 | link_ok = false0; |
3873 | ack[3] |= LINK_STATUS_CHANGED(1 << 1); |
3874 | } |
3875 | |
3876 | intel_dp_mst_hpd_irq(intel_dp, esi, ack); |
3877 | |
3878 | if (!memchr_inv(ack, 0, sizeof(ack))) |
3879 | break; |
3880 | |
3881 | if (!intel_dp_ack_sink_irq_esi(intel_dp, ack)) |
3882 | drm_dbg_kms(&i915->drm, "Failed to ack ESI\n")__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "Failed to ack ESI\n" ); |
3883 | |
3884 | if (ack[1] & (DP_DOWN_REP_MSG_RDY(1 << 4) | DP_UP_REQ_MSG_RDY(1 << 5))) |
3885 | drm_dp_mst_hpd_irq_send_new_request(&intel_dp->mst_mgr); |
3886 | } |
3887 | |
3888 | return link_ok; |
3889 | } |
3890 | |
3891 | static void |
3892 | intel_dp_handle_hdmi_link_status_change(struct intel_dp *intel_dp) |
3893 | { |
3894 | bool_Bool is_active; |
3895 | u8 buf = 0; |
3896 | |
3897 | is_active = drm_dp_pcon_hdmi_link_active(&intel_dp->aux); |
3898 | if (intel_dp->frl.is_trained && !is_active) { |
3899 | if (drm_dp_dpcd_readb(&intel_dp->aux, DP_PCON_HDMI_LINK_CONFIG_10x305A, &buf) < 0) |
3900 | return; |
3901 | |
3902 | buf &= ~DP_PCON_ENABLE_HDMI_LINK(1 << 7); |
3903 | if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_PCON_HDMI_LINK_CONFIG_10x305A, buf) < 0) |
3904 | return; |
3905 | |
3906 | drm_dp_pcon_hdmi_frl_link_error_count(&intel_dp->aux, &intel_dp->attached_connector->base); |
3907 | |
3908 | intel_dp->frl.is_trained = false0; |
3909 | |
3910 | /* Restart FRL training or fall back to TMDS mode */ |
3911 | intel_dp_check_frl_training(intel_dp); |
3912 | } |
3913 | } |
3914 | |
3915 | static bool_Bool |
3916 | intel_dp_needs_link_retrain(struct intel_dp *intel_dp) |
3917 | { |
3918 | u8 link_status[DP_LINK_STATUS_SIZE6]; |
3919 | |
3920 | if (!intel_dp->link_trained) |
3921 | return false0; |
3922 | |
3923 | /* |
3924 | * While PSR source HW is enabled, it will control main-link sending |
3925 | * frames, enabling and disabling it so trying to do a retrain will fail |
3926 | * as the link would or not be on or it could mix training patterns |
3927 | * and frame data at the same time causing retrain to fail. |
3928 | * Also when exiting PSR, HW will retrain the link anyways fixing |
3929 | * any link status error. |
3930 | */ |
3931 | if (intel_psr_enabled(intel_dp)) |
3932 | return false0; |
3933 | |
3934 | if (drm_dp_dpcd_read_phy_link_status(&intel_dp->aux, DP_PHY_DPRX, |
3935 | link_status) < 0) |
3936 | return false0; |
3937 | |
3938 | /* |
3939 | * Validate the cached values of intel_dp->link_rate and |
3940 | * intel_dp->lane_count before attempting to retrain. |
3941 | * |
3942 | * FIXME would be nice to user the crtc state here, but since |
3943 | * we need to call this from the short HPD handler that seems |
3944 | * a bit hard. |
3945 | */ |
3946 | if (!intel_dp_link_params_valid(intel_dp, intel_dp->link_rate, |
3947 | intel_dp->lane_count)) |
3948 | return false0; |
3949 | |
3950 | /* Retrain if link not ok */ |
3951 | return !intel_dp_link_ok(intel_dp, link_status); |
3952 | } |
3953 | |
3954 | static bool_Bool intel_dp_has_connector(struct intel_dp *intel_dp, |
3955 | const struct drm_connector_state *conn_state) |
3956 | { |
3957 | struct drm_i915_privateinteldrm_softc *i915 = dp_to_i915(intel_dp)to_i915(dp_to_dig_port(intel_dp)->base.base.dev); |
3958 | struct intel_encoder *encoder; |
3959 | enum pipe pipe; |
3960 | |
3961 | if (!conn_state->best_encoder) |
3962 | return false0; |
3963 | |
3964 | /* SST */ |
3965 | encoder = &dp_to_dig_port(intel_dp)->base; |
3966 | if (conn_state->best_encoder == &encoder->base) |
3967 | return true1; |
3968 | |
3969 | /* MST */ |
3970 | for_each_pipe(i915, pipe)for ((pipe) = 0; (pipe) < I915_MAX_PIPES; (pipe)++) if (!( (&(i915)->__runtime)->pipe_mask & (1UL << (pipe)))) {} else { |
3971 | encoder = &intel_dp->mst_encoders[pipe]->base; |
3972 | if (conn_state->best_encoder == &encoder->base) |
3973 | return true1; |
3974 | } |
3975 | |
3976 | return false0; |
3977 | } |
3978 | |
3979 | static int intel_dp_prep_link_retrain(struct intel_dp *intel_dp, |
3980 | struct drm_modeset_acquire_ctx *ctx, |
3981 | u8 *pipe_mask) |
3982 | { |
3983 | struct drm_i915_privateinteldrm_softc *i915 = dp_to_i915(intel_dp)to_i915(dp_to_dig_port(intel_dp)->base.base.dev); |
3984 | struct drm_connector_list_iter conn_iter; |
3985 | struct intel_connector *connector; |
3986 | int ret = 0; |
3987 | |
3988 | *pipe_mask = 0; |
3989 | |
3990 | if (!intel_dp_needs_link_retrain(intel_dp)) |
3991 | return 0; |
3992 | |
3993 | drm_connector_list_iter_begin(&i915->drm, &conn_iter); |
3994 | for_each_intel_connector_iter(connector, &conn_iter)while ((connector = ({ const __typeof( ((struct intel_connector *)0)->base ) *__mptr = (drm_connector_list_iter_next(& conn_iter)); (struct intel_connector *)( (char *)__mptr - __builtin_offsetof (struct intel_connector, base) );}))) { |
3995 | struct drm_connector_state *conn_state = |
3996 | connector->base.state; |
3997 | struct intel_crtc_state *crtc_state; |
3998 | struct intel_crtc *crtc; |
3999 | |
4000 | if (!intel_dp_has_connector(intel_dp, conn_state)) |
4001 | continue; |
4002 | |
4003 | crtc = to_intel_crtc(conn_state->crtc)({ const __typeof( ((struct intel_crtc *)0)->base ) *__mptr = (conn_state->crtc); (struct intel_crtc *)( (char *)__mptr - __builtin_offsetof(struct intel_crtc, base) );}); |
4004 | if (!crtc) |
4005 | continue; |
4006 | |
4007 | ret = drm_modeset_lock(&crtc->base.mutex, ctx); |
4008 | if (ret) |
4009 | break; |
4010 | |
4011 | crtc_state = to_intel_crtc_state(crtc->base.state)({ const __typeof( ((struct intel_crtc_state *)0)->uapi ) * __mptr = (crtc->base.state); (struct intel_crtc_state *)( ( char *)__mptr - __builtin_offsetof(struct intel_crtc_state, uapi ) );}); |
4012 | |
4013 | drm_WARN_ON(&i915->drm, !intel_crtc_has_dp_encoder(crtc_state))({ int __ret = !!((!intel_crtc_has_dp_encoder(crtc_state))); if (__ret) printf("%s %s: " "%s", dev_driver_string(((&i915 ->drm))->dev), "", "drm_WARN_ON(" "!intel_crtc_has_dp_encoder(crtc_state)" ")"); __builtin_expect(!!(__ret), 0); }); |
4014 | |
4015 | if (!crtc_state->hw.active) |
4016 | continue; |
4017 | |
4018 | if (conn_state->commit && |
4019 | !try_wait_for_completion(&conn_state->commit->hw_done)) |
4020 | continue; |
4021 | |
4022 | *pipe_mask |= BIT(crtc->pipe)(1UL << (crtc->pipe)); |
4023 | } |
4024 | drm_connector_list_iter_end(&conn_iter); |
4025 | |
4026 | if (!intel_dp_needs_link_retrain(intel_dp)) |
4027 | *pipe_mask = 0; |
4028 | |
4029 | return ret; |
4030 | } |
4031 | |
4032 | static bool_Bool intel_dp_is_connected(struct intel_dp *intel_dp) |
4033 | { |
4034 | struct intel_connector *connector = intel_dp->attached_connector; |
4035 | |
4036 | return connector->base.status == connector_status_connected || |
4037 | intel_dp->is_mst; |
4038 | } |
4039 | |
4040 | int intel_dp_retrain_link(struct intel_encoder *encoder, |
4041 | struct drm_modeset_acquire_ctx *ctx) |
4042 | { |
4043 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
4044 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
4045 | struct intel_crtc *crtc; |
4046 | u8 pipe_mask; |
4047 | int ret; |
4048 | |
4049 | if (!intel_dp_is_connected(intel_dp)) |
4050 | return 0; |
4051 | |
4052 | ret = drm_modeset_lock(&dev_priv->drm.mode_config.connection_mutex, |
4053 | ctx); |
4054 | if (ret) |
4055 | return ret; |
4056 | |
4057 | ret = intel_dp_prep_link_retrain(intel_dp, ctx, &pipe_mask); |
4058 | if (ret) |
4059 | return ret; |
4060 | |
4061 | if (pipe_mask == 0) |
4062 | return 0; |
4063 | |
4064 | drm_dbg_kms(&dev_priv->drm, "[ENCODER:%d:%s] retraining link\n",__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "[ENCODER:%d:%s] retraining link\n" , encoder->base.base.id, encoder->base.name) |
4065 | encoder->base.base.id, encoder->base.name)__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "[ENCODER:%d:%s] retraining link\n" , encoder->base.base.id, encoder->base.name); |
4066 | |
4067 | for_each_intel_crtc_in_pipe_mask(&dev_priv->drm, crtc, pipe_mask)for (crtc = ({ const __typeof( ((__typeof(*crtc) *)0)->base .head ) *__mptr = ((&(&dev_priv->drm)->mode_config .crtc_list)->next); (__typeof(*crtc) *)( (char *)__mptr - __builtin_offsetof (__typeof(*crtc), base.head) );}); &crtc->base.head != (&(&dev_priv->drm)->mode_config.crtc_list); crtc = ({ const __typeof( ((__typeof(*crtc) *)0)->base.head ) * __mptr = (crtc->base.head.next); (__typeof(*crtc) *)( (char *)__mptr - __builtin_offsetof(__typeof(*crtc), base.head) ); })) if (!((pipe_mask) & (1UL << (crtc->pipe)))) { } else { |
4068 | const struct intel_crtc_state *crtc_state = |
4069 | to_intel_crtc_state(crtc->base.state)({ const __typeof( ((struct intel_crtc_state *)0)->uapi ) * __mptr = (crtc->base.state); (struct intel_crtc_state *)( ( char *)__mptr - __builtin_offsetof(struct intel_crtc_state, uapi ) );}); |
4070 | |
4071 | /* Suppress underruns caused by re-training */ |
4072 | intel_set_cpu_fifo_underrun_reporting(dev_priv, crtc->pipe, false0); |
4073 | if (crtc_state->has_pch_encoder) |
4074 | intel_set_pch_fifo_underrun_reporting(dev_priv, |
4075 | intel_crtc_pch_transcoder(crtc), false0); |
4076 | } |
4077 | |
4078 | for_each_intel_crtc_in_pipe_mask(&dev_priv->drm, crtc, pipe_mask)for (crtc = ({ const __typeof( ((__typeof(*crtc) *)0)->base .head ) *__mptr = ((&(&dev_priv->drm)->mode_config .crtc_list)->next); (__typeof(*crtc) *)( (char *)__mptr - __builtin_offsetof (__typeof(*crtc), base.head) );}); &crtc->base.head != (&(&dev_priv->drm)->mode_config.crtc_list); crtc = ({ const __typeof( ((__typeof(*crtc) *)0)->base.head ) * __mptr = (crtc->base.head.next); (__typeof(*crtc) *)( (char *)__mptr - __builtin_offsetof(__typeof(*crtc), base.head) ); })) if (!((pipe_mask) & (1UL << (crtc->pipe)))) { } else { |
4079 | const struct intel_crtc_state *crtc_state = |
4080 | to_intel_crtc_state(crtc->base.state)({ const __typeof( ((struct intel_crtc_state *)0)->uapi ) * __mptr = (crtc->base.state); (struct intel_crtc_state *)( ( char *)__mptr - __builtin_offsetof(struct intel_crtc_state, uapi ) );}); |
4081 | |
4082 | /* retrain on the MST master transcoder */ |
4083 | if (DISPLAY_VER(dev_priv)((&(dev_priv)->__runtime)->display.ip.ver) >= 12 && |
4084 | intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST) && |
4085 | !intel_dp_mst_is_master_trans(crtc_state)) |
4086 | continue; |
4087 | |
4088 | intel_dp_check_frl_training(intel_dp); |
4089 | intel_dp_pcon_dsc_configure(intel_dp, crtc_state); |
4090 | intel_dp_start_link_train(intel_dp, crtc_state); |
4091 | intel_dp_stop_link_train(intel_dp, crtc_state); |
4092 | break; |
4093 | } |
4094 | |
4095 | for_each_intel_crtc_in_pipe_mask(&dev_priv->drm, crtc, pipe_mask)for (crtc = ({ const __typeof( ((__typeof(*crtc) *)0)->base .head ) *__mptr = ((&(&dev_priv->drm)->mode_config .crtc_list)->next); (__typeof(*crtc) *)( (char *)__mptr - __builtin_offsetof (__typeof(*crtc), base.head) );}); &crtc->base.head != (&(&dev_priv->drm)->mode_config.crtc_list); crtc = ({ const __typeof( ((__typeof(*crtc) *)0)->base.head ) * __mptr = (crtc->base.head.next); (__typeof(*crtc) *)( (char *)__mptr - __builtin_offsetof(__typeof(*crtc), base.head) ); })) if (!((pipe_mask) & (1UL << (crtc->pipe)))) { } else { |
4096 | const struct intel_crtc_state *crtc_state = |
4097 | to_intel_crtc_state(crtc->base.state)({ const __typeof( ((struct intel_crtc_state *)0)->uapi ) * __mptr = (crtc->base.state); (struct intel_crtc_state *)( ( char *)__mptr - __builtin_offsetof(struct intel_crtc_state, uapi ) );}); |
4098 | |
4099 | /* Keep underrun reporting disabled until things are stable */ |
4100 | intel_crtc_wait_for_next_vblank(crtc); |
4101 | |
4102 | intel_set_cpu_fifo_underrun_reporting(dev_priv, crtc->pipe, true1); |
4103 | if (crtc_state->has_pch_encoder) |
4104 | intel_set_pch_fifo_underrun_reporting(dev_priv, |
4105 | intel_crtc_pch_transcoder(crtc), true1); |
4106 | } |
4107 | |
4108 | return 0; |
4109 | } |
4110 | |
4111 | static int intel_dp_prep_phy_test(struct intel_dp *intel_dp, |
4112 | struct drm_modeset_acquire_ctx *ctx, |
4113 | u8 *pipe_mask) |
4114 | { |
4115 | struct drm_i915_privateinteldrm_softc *i915 = dp_to_i915(intel_dp)to_i915(dp_to_dig_port(intel_dp)->base.base.dev); |
4116 | struct drm_connector_list_iter conn_iter; |
4117 | struct intel_connector *connector; |
4118 | int ret = 0; |
4119 | |
4120 | *pipe_mask = 0; |
4121 | |
4122 | drm_connector_list_iter_begin(&i915->drm, &conn_iter); |
4123 | for_each_intel_connector_iter(connector, &conn_iter)while ((connector = ({ const __typeof( ((struct intel_connector *)0)->base ) *__mptr = (drm_connector_list_iter_next(& conn_iter)); (struct intel_connector *)( (char *)__mptr - __builtin_offsetof (struct intel_connector, base) );}))) { |
4124 | struct drm_connector_state *conn_state = |
4125 | connector->base.state; |
4126 | struct intel_crtc_state *crtc_state; |
4127 | struct intel_crtc *crtc; |
4128 | |
4129 | if (!intel_dp_has_connector(intel_dp, conn_state)) |
4130 | continue; |
4131 | |
4132 | crtc = to_intel_crtc(conn_state->crtc)({ const __typeof( ((struct intel_crtc *)0)->base ) *__mptr = (conn_state->crtc); (struct intel_crtc *)( (char *)__mptr - __builtin_offsetof(struct intel_crtc, base) );}); |
4133 | if (!crtc) |
4134 | continue; |
4135 | |
4136 | ret = drm_modeset_lock(&crtc->base.mutex, ctx); |
4137 | if (ret) |
4138 | break; |
4139 | |
4140 | crtc_state = to_intel_crtc_state(crtc->base.state)({ const __typeof( ((struct intel_crtc_state *)0)->uapi ) * __mptr = (crtc->base.state); (struct intel_crtc_state *)( ( char *)__mptr - __builtin_offsetof(struct intel_crtc_state, uapi ) );}); |
4141 | |
4142 | drm_WARN_ON(&i915->drm, !intel_crtc_has_dp_encoder(crtc_state))({ int __ret = !!((!intel_crtc_has_dp_encoder(crtc_state))); if (__ret) printf("%s %s: " "%s", dev_driver_string(((&i915 ->drm))->dev), "", "drm_WARN_ON(" "!intel_crtc_has_dp_encoder(crtc_state)" ")"); __builtin_expect(!!(__ret), 0); }); |
4143 | |
4144 | if (!crtc_state->hw.active) |
4145 | continue; |
4146 | |
4147 | if (conn_state->commit && |
4148 | !try_wait_for_completion(&conn_state->commit->hw_done)) |
4149 | continue; |
4150 | |
4151 | *pipe_mask |= BIT(crtc->pipe)(1UL << (crtc->pipe)); |
4152 | } |
4153 | drm_connector_list_iter_end(&conn_iter); |
4154 | |
4155 | return ret; |
4156 | } |
4157 | |
4158 | static int intel_dp_do_phy_test(struct intel_encoder *encoder, |
4159 | struct drm_modeset_acquire_ctx *ctx) |
4160 | { |
4161 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
4162 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
4163 | struct intel_crtc *crtc; |
4164 | u8 pipe_mask; |
4165 | int ret; |
4166 | |
4167 | ret = drm_modeset_lock(&dev_priv->drm.mode_config.connection_mutex, |
4168 | ctx); |
4169 | if (ret) |
4170 | return ret; |
4171 | |
4172 | ret = intel_dp_prep_phy_test(intel_dp, ctx, &pipe_mask); |
4173 | if (ret) |
4174 | return ret; |
4175 | |
4176 | if (pipe_mask == 0) |
4177 | return 0; |
4178 | |
4179 | drm_dbg_kms(&dev_priv->drm, "[ENCODER:%d:%s] PHY test\n",__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "[ENCODER:%d:%s] PHY test\n" , encoder->base.base.id, encoder->base.name) |
4180 | encoder->base.base.id, encoder->base.name)__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "[ENCODER:%d:%s] PHY test\n" , encoder->base.base.id, encoder->base.name); |
4181 | |
4182 | for_each_intel_crtc_in_pipe_mask(&dev_priv->drm, crtc, pipe_mask)for (crtc = ({ const __typeof( ((__typeof(*crtc) *)0)->base .head ) *__mptr = ((&(&dev_priv->drm)->mode_config .crtc_list)->next); (__typeof(*crtc) *)( (char *)__mptr - __builtin_offsetof (__typeof(*crtc), base.head) );}); &crtc->base.head != (&(&dev_priv->drm)->mode_config.crtc_list); crtc = ({ const __typeof( ((__typeof(*crtc) *)0)->base.head ) * __mptr = (crtc->base.head.next); (__typeof(*crtc) *)( (char *)__mptr - __builtin_offsetof(__typeof(*crtc), base.head) ); })) if (!((pipe_mask) & (1UL << (crtc->pipe)))) { } else { |
4183 | const struct intel_crtc_state *crtc_state = |
4184 | to_intel_crtc_state(crtc->base.state)({ const __typeof( ((struct intel_crtc_state *)0)->uapi ) * __mptr = (crtc->base.state); (struct intel_crtc_state *)( ( char *)__mptr - __builtin_offsetof(struct intel_crtc_state, uapi ) );}); |
4185 | |
4186 | /* test on the MST master transcoder */ |
4187 | if (DISPLAY_VER(dev_priv)((&(dev_priv)->__runtime)->display.ip.ver) >= 12 && |
4188 | intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST) && |
4189 | !intel_dp_mst_is_master_trans(crtc_state)) |
4190 | continue; |
4191 | |
4192 | intel_dp_process_phy_request(intel_dp, crtc_state); |
4193 | break; |
4194 | } |
4195 | |
4196 | return 0; |
4197 | } |
4198 | |
4199 | void intel_dp_phy_test(struct intel_encoder *encoder) |
4200 | { |
4201 | struct drm_modeset_acquire_ctx ctx; |
4202 | int ret; |
4203 | |
4204 | drm_modeset_acquire_init(&ctx, 0); |
4205 | |
4206 | for (;;) { |
4207 | ret = intel_dp_do_phy_test(encoder, &ctx); |
4208 | |
4209 | if (ret == -EDEADLK11) { |
4210 | drm_modeset_backoff(&ctx); |
4211 | continue; |
4212 | } |
4213 | |
4214 | break; |
4215 | } |
4216 | |
4217 | drm_modeset_drop_locks(&ctx); |
4218 | drm_modeset_acquire_fini(&ctx); |
4219 | drm_WARN(encoder->base.dev, ret,({ int __ret = !!(ret); if (__ret) printf("%s %s: " "Acquiring modeset locks failed with %i\n" , dev_driver_string((encoder->base.dev)->dev), "", ret) ; __builtin_expect(!!(__ret), 0); }) |
4220 | "Acquiring modeset locks failed with %i\n", ret)({ int __ret = !!(ret); if (__ret) printf("%s %s: " "Acquiring modeset locks failed with %i\n" , dev_driver_string((encoder->base.dev)->dev), "", ret) ; __builtin_expect(!!(__ret), 0); }); |
4221 | } |
4222 | |
4223 | static void intel_dp_check_device_service_irq(struct intel_dp *intel_dp) |
4224 | { |
4225 | struct drm_i915_privateinteldrm_softc *i915 = dp_to_i915(intel_dp)to_i915(dp_to_dig_port(intel_dp)->base.base.dev); |
4226 | u8 val; |
4227 | |
4228 | if (intel_dp->dpcd[DP_DPCD_REV0x000] < 0x11) |
4229 | return; |
4230 | |
4231 | if (drm_dp_dpcd_readb(&intel_dp->aux, |
4232 | DP_DEVICE_SERVICE_IRQ_VECTOR0x201, &val) != 1 || !val) |
4233 | return; |
4234 | |
4235 | drm_dp_dpcd_writeb(&intel_dp->aux, DP_DEVICE_SERVICE_IRQ_VECTOR0x201, val); |
4236 | |
4237 | if (val & DP_AUTOMATED_TEST_REQUEST(1 << 1)) |
4238 | intel_dp_handle_test_request(intel_dp); |
4239 | |
4240 | if (val & DP_CP_IRQ(1 << 2)) |
4241 | intel_hdcp_handle_cp_irq(intel_dp->attached_connector); |
4242 | |
4243 | if (val & DP_SINK_SPECIFIC_IRQ(1 << 6)) |
4244 | drm_dbg_kms(&i915->drm, "Sink specific irq unhandled\n")__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "Sink specific irq unhandled\n" ); |
4245 | } |
4246 | |
4247 | static void intel_dp_check_link_service_irq(struct intel_dp *intel_dp) |
4248 | { |
4249 | u8 val; |
4250 | |
4251 | if (intel_dp->dpcd[DP_DPCD_REV0x000] < 0x11) |
4252 | return; |
4253 | |
4254 | if (drm_dp_dpcd_readb(&intel_dp->aux, |
4255 | DP_LINK_SERVICE_IRQ_VECTOR_ESI00x2005, &val) != 1 || !val) |
4256 | return; |
4257 | |
4258 | if (drm_dp_dpcd_writeb(&intel_dp->aux, |
4259 | DP_LINK_SERVICE_IRQ_VECTOR_ESI00x2005, val) != 1) |
4260 | return; |
4261 | |
4262 | if (val & HDMI_LINK_STATUS_CHANGED(1 << 3)) |
4263 | intel_dp_handle_hdmi_link_status_change(intel_dp); |
4264 | } |
4265 | |
4266 | /* |
4267 | * According to DP spec |
4268 | * 5.1.2: |
4269 | * 1. Read DPCD |
4270 | * 2. Configure link according to Receiver Capabilities |
4271 | * 3. Use Link Training from 2.5.3.3 and 3.5.1.3 |
4272 | * 4. Check link status on receipt of hot-plug interrupt |
4273 | * |
4274 | * intel_dp_short_pulse - handles short pulse interrupts |
4275 | * when full detection is not required. |
4276 | * Returns %true if short pulse is handled and full detection |
4277 | * is NOT required and %false otherwise. |
4278 | */ |
4279 | static bool_Bool |
4280 | intel_dp_short_pulse(struct intel_dp *intel_dp) |
4281 | { |
4282 | struct drm_i915_privateinteldrm_softc *dev_priv = dp_to_i915(intel_dp)to_i915(dp_to_dig_port(intel_dp)->base.base.dev); |
4283 | u8 old_sink_count = intel_dp->sink_count; |
4284 | bool_Bool ret; |
4285 | |
4286 | /* |
4287 | * Clearing compliance test variables to allow capturing |
4288 | * of values for next automated test request. |
4289 | */ |
4290 | memset(&intel_dp->compliance, 0, sizeof(intel_dp->compliance))__builtin_memset((&intel_dp->compliance), (0), (sizeof (intel_dp->compliance))); |
4291 | |
4292 | /* |
4293 | * Now read the DPCD to see if it's actually running |
4294 | * If the current value of sink count doesn't match with |
4295 | * the value that was stored earlier or dpcd read failed |
4296 | * we need to do full detection |
4297 | */ |
4298 | ret = intel_dp_get_dpcd(intel_dp); |
4299 | |
4300 | if ((old_sink_count != intel_dp->sink_count) || !ret) { |
4301 | /* No need to proceed if we are going to do full detect */ |
4302 | return false0; |
4303 | } |
4304 | |
4305 | intel_dp_check_device_service_irq(intel_dp); |
4306 | intel_dp_check_link_service_irq(intel_dp); |
4307 | |
4308 | /* Handle CEC interrupts, if any */ |
4309 | drm_dp_cec_irq(&intel_dp->aux); |
4310 | |
4311 | /* defer to the hotplug work for link retraining if needed */ |
4312 | if (intel_dp_needs_link_retrain(intel_dp)) |
4313 | return false0; |
4314 | |
4315 | intel_psr_short_pulse(intel_dp); |
4316 | |
4317 | switch (intel_dp->compliance.test_type) { |
4318 | case DP_TEST_LINK_TRAINING(1 << 0): |
4319 | drm_dbg_kms(&dev_priv->drm,__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "Link Training Compliance Test requested\n" ) |
4320 | "Link Training Compliance Test requested\n")__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "Link Training Compliance Test requested\n" ); |
4321 | /* Send a Hotplug Uevent to userspace to start modeset */ |
4322 | drm_kms_helper_hotplug_event(&dev_priv->drm); |
4323 | break; |
4324 | case DP_TEST_LINK_PHY_TEST_PATTERN(1 << 3): |
4325 | drm_dbg_kms(&dev_priv->drm,__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "PHY test pattern Compliance Test requested\n" ) |
4326 | "PHY test pattern Compliance Test requested\n")__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "PHY test pattern Compliance Test requested\n" ); |
4327 | /* |
4328 | * Schedule long hpd to do the test |
4329 | * |
4330 | * FIXME get rid of the ad-hoc phy test modeset code |
4331 | * and properly incorporate it into the normal modeset. |
4332 | */ |
4333 | return false0; |
4334 | } |
4335 | |
4336 | return true1; |
4337 | } |
4338 | |
4339 | /* XXX this is probably wrong for multiple downstream ports */ |
4340 | static enum drm_connector_status |
4341 | intel_dp_detect_dpcd(struct intel_dp *intel_dp) |
4342 | { |
4343 | struct drm_i915_privateinteldrm_softc *i915 = dp_to_i915(intel_dp)to_i915(dp_to_dig_port(intel_dp)->base.base.dev); |
4344 | struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); |
4345 | u8 *dpcd = intel_dp->dpcd; |
4346 | u8 type; |
4347 | |
4348 | if (drm_WARN_ON(&i915->drm, intel_dp_is_edp(intel_dp))({ int __ret = !!((intel_dp_is_edp(intel_dp))); if (__ret) printf ("%s %s: " "%s", dev_driver_string(((&i915->drm))-> dev), "", "drm_WARN_ON(" "intel_dp_is_edp(intel_dp)" ")"); __builtin_expect (!!(__ret), 0); })) |
4349 | return connector_status_connected; |
4350 | |
4351 | lspcon_resume(dig_port); |
4352 | |
4353 | if (!intel_dp_get_dpcd(intel_dp)) |
4354 | return connector_status_disconnected; |
4355 | |
4356 | /* if there's no downstream port, we're done */ |
4357 | if (!drm_dp_is_branch(dpcd)) |
4358 | return connector_status_connected; |
4359 | |
4360 | /* If we're HPD-aware, SINK_COUNT changes dynamically */ |
4361 | if (intel_dp_has_sink_count(intel_dp) && |
4362 | intel_dp->downstream_ports[0] & DP_DS_PORT_HPD(1 << 3)) { |
4363 | return intel_dp->sink_count ? |
4364 | connector_status_connected : connector_status_disconnected; |
4365 | } |
4366 | |
4367 | if (intel_dp_can_mst(intel_dp)) |
4368 | return connector_status_connected; |
4369 | |
4370 | /* If no HPD, poke DDC gently */ |
4371 | if (drm_probe_ddc(&intel_dp->aux.ddc)) |
4372 | return connector_status_connected; |
4373 | |
4374 | /* Well we tried, say unknown for unreliable port types */ |
4375 | if (intel_dp->dpcd[DP_DPCD_REV0x000] >= 0x11) { |
4376 | type = intel_dp->downstream_ports[0] & DP_DS_PORT_TYPE_MASK(7 << 0); |
4377 | if (type == DP_DS_PORT_TYPE_VGA1 || |
4378 | type == DP_DS_PORT_TYPE_NON_EDID4) |
4379 | return connector_status_unknown; |
4380 | } else { |
4381 | type = intel_dp->dpcd[DP_DOWNSTREAMPORT_PRESENT0x005] & |
4382 | DP_DWN_STRM_PORT_TYPE_MASK0x06; |
4383 | if (type == DP_DWN_STRM_PORT_TYPE_ANALOG(1 << 1) || |
4384 | type == DP_DWN_STRM_PORT_TYPE_OTHER(3 << 1)) |
4385 | return connector_status_unknown; |
4386 | } |
4387 | |
4388 | /* Anything else is out of spec, warn and ignore */ |
4389 | drm_dbg_kms(&i915->drm, "Broken DP branch device, ignoring\n")__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "Broken DP branch device, ignoring\n" ); |
4390 | return connector_status_disconnected; |
4391 | } |
4392 | |
4393 | static enum drm_connector_status |
4394 | edp_detect(struct intel_dp *intel_dp) |
4395 | { |
4396 | return connector_status_connected; |
4397 | } |
4398 | |
4399 | /* |
4400 | * intel_digital_port_connected - is the specified port connected? |
4401 | * @encoder: intel_encoder |
4402 | * |
4403 | * In cases where there's a connector physically connected but it can't be used |
4404 | * by our hardware we also return false, since the rest of the driver should |
4405 | * pretty much treat the port as disconnected. This is relevant for type-C |
4406 | * (starting on ICL) where there's ownership involved. |
4407 | * |
4408 | * Return %true if port is connected, %false otherwise. |
4409 | */ |
4410 | bool_Bool intel_digital_port_connected(struct intel_encoder *encoder) |
4411 | { |
4412 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
4413 | struct intel_digital_port *dig_port = enc_to_dig_port(encoder); |
4414 | bool_Bool is_connected = false0; |
4415 | intel_wakeref_t wakeref; |
4416 | |
4417 | with_intel_display_power(dev_priv, POWER_DOMAIN_DISPLAY_CORE, wakeref)for ((wakeref) = intel_display_power_get((dev_priv), (POWER_DOMAIN_DISPLAY_CORE )); (wakeref); intel_display_power_put_async((dev_priv), (POWER_DOMAIN_DISPLAY_CORE ), (wakeref)), (wakeref) = 0) |
4418 | is_connected = dig_port->connected(encoder); |
4419 | |
4420 | return is_connected; |
4421 | } |
4422 | |
4423 | static struct edid * |
4424 | intel_dp_get_edid(struct intel_dp *intel_dp) |
4425 | { |
4426 | struct intel_connector *intel_connector = intel_dp->attached_connector; |
4427 | |
4428 | /* use cached edid if we have one */ |
4429 | if (intel_connector->edid) { |
4430 | /* invalid edid */ |
4431 | if (IS_ERR(intel_connector->edid)) |
4432 | return NULL((void *)0); |
4433 | |
4434 | return drm_edid_duplicate(intel_connector->edid); |
4435 | } else |
4436 | return drm_get_edid(&intel_connector->base, |
4437 | &intel_dp->aux.ddc); |
4438 | } |
4439 | |
4440 | static void |
4441 | intel_dp_update_dfp(struct intel_dp *intel_dp, |
4442 | const struct edid *edid) |
4443 | { |
4444 | struct drm_i915_privateinteldrm_softc *i915 = dp_to_i915(intel_dp)to_i915(dp_to_dig_port(intel_dp)->base.base.dev); |
4445 | struct intel_connector *connector = intel_dp->attached_connector; |
4446 | |
4447 | intel_dp->dfp.max_bpc = |
4448 | drm_dp_downstream_max_bpc(intel_dp->dpcd, |
4449 | intel_dp->downstream_ports, edid); |
4450 | |
4451 | intel_dp->dfp.max_dotclock = |
4452 | drm_dp_downstream_max_dotclock(intel_dp->dpcd, |
4453 | intel_dp->downstream_ports); |
4454 | |
4455 | intel_dp->dfp.min_tmds_clock = |
4456 | drm_dp_downstream_min_tmds_clock(intel_dp->dpcd, |
4457 | intel_dp->downstream_ports, |
4458 | edid); |
4459 | intel_dp->dfp.max_tmds_clock = |
4460 | drm_dp_downstream_max_tmds_clock(intel_dp->dpcd, |
4461 | intel_dp->downstream_ports, |
4462 | edid); |
4463 | |
4464 | intel_dp->dfp.pcon_max_frl_bw = |
4465 | drm_dp_get_pcon_max_frl_bw(intel_dp->dpcd, |
4466 | intel_dp->downstream_ports); |
4467 | |
4468 | drm_dbg_kms(&i915->drm,__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "[CONNECTOR:%d:%s] DFP max bpc %d, max dotclock %d, TMDS clock %d-%d, PCON Max FRL BW %dGbps\n" , connector->base.base.id, connector->base.name, intel_dp ->dfp.max_bpc, intel_dp->dfp.max_dotclock, intel_dp-> dfp.min_tmds_clock, intel_dp->dfp.max_tmds_clock, intel_dp ->dfp.pcon_max_frl_bw) |
4469 | "[CONNECTOR:%d:%s] DFP max bpc %d, max dotclock %d, TMDS clock %d-%d, PCON Max FRL BW %dGbps\n",__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "[CONNECTOR:%d:%s] DFP max bpc %d, max dotclock %d, TMDS clock %d-%d, PCON Max FRL BW %dGbps\n" , connector->base.base.id, connector->base.name, intel_dp ->dfp.max_bpc, intel_dp->dfp.max_dotclock, intel_dp-> dfp.min_tmds_clock, intel_dp->dfp.max_tmds_clock, intel_dp ->dfp.pcon_max_frl_bw) |
4470 | connector->base.base.id, connector->base.name,__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "[CONNECTOR:%d:%s] DFP max bpc %d, max dotclock %d, TMDS clock %d-%d, PCON Max FRL BW %dGbps\n" , connector->base.base.id, connector->base.name, intel_dp ->dfp.max_bpc, intel_dp->dfp.max_dotclock, intel_dp-> dfp.min_tmds_clock, intel_dp->dfp.max_tmds_clock, intel_dp ->dfp.pcon_max_frl_bw) |
4471 | intel_dp->dfp.max_bpc,__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "[CONNECTOR:%d:%s] DFP max bpc %d, max dotclock %d, TMDS clock %d-%d, PCON Max FRL BW %dGbps\n" , connector->base.base.id, connector->base.name, intel_dp ->dfp.max_bpc, intel_dp->dfp.max_dotclock, intel_dp-> dfp.min_tmds_clock, intel_dp->dfp.max_tmds_clock, intel_dp ->dfp.pcon_max_frl_bw) |
4472 | intel_dp->dfp.max_dotclock,__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "[CONNECTOR:%d:%s] DFP max bpc %d, max dotclock %d, TMDS clock %d-%d, PCON Max FRL BW %dGbps\n" , connector->base.base.id, connector->base.name, intel_dp ->dfp.max_bpc, intel_dp->dfp.max_dotclock, intel_dp-> dfp.min_tmds_clock, intel_dp->dfp.max_tmds_clock, intel_dp ->dfp.pcon_max_frl_bw) |
4473 | intel_dp->dfp.min_tmds_clock,__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "[CONNECTOR:%d:%s] DFP max bpc %d, max dotclock %d, TMDS clock %d-%d, PCON Max FRL BW %dGbps\n" , connector->base.base.id, connector->base.name, intel_dp ->dfp.max_bpc, intel_dp->dfp.max_dotclock, intel_dp-> dfp.min_tmds_clock, intel_dp->dfp.max_tmds_clock, intel_dp ->dfp.pcon_max_frl_bw) |
4474 | intel_dp->dfp.max_tmds_clock,__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "[CONNECTOR:%d:%s] DFP max bpc %d, max dotclock %d, TMDS clock %d-%d, PCON Max FRL BW %dGbps\n" , connector->base.base.id, connector->base.name, intel_dp ->dfp.max_bpc, intel_dp->dfp.max_dotclock, intel_dp-> dfp.min_tmds_clock, intel_dp->dfp.max_tmds_clock, intel_dp ->dfp.pcon_max_frl_bw) |
4475 | intel_dp->dfp.pcon_max_frl_bw)__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "[CONNECTOR:%d:%s] DFP max bpc %d, max dotclock %d, TMDS clock %d-%d, PCON Max FRL BW %dGbps\n" , connector->base.base.id, connector->base.name, intel_dp ->dfp.max_bpc, intel_dp->dfp.max_dotclock, intel_dp-> dfp.min_tmds_clock, intel_dp->dfp.max_tmds_clock, intel_dp ->dfp.pcon_max_frl_bw); |
4476 | |
4477 | intel_dp_get_pcon_dsc_cap(intel_dp); |
4478 | } |
4479 | |
4480 | static void |
4481 | intel_dp_update_420(struct intel_dp *intel_dp) |
4482 | { |
4483 | struct drm_i915_privateinteldrm_softc *i915 = dp_to_i915(intel_dp)to_i915(dp_to_dig_port(intel_dp)->base.base.dev); |
4484 | struct intel_connector *connector = intel_dp->attached_connector; |
4485 | bool_Bool is_branch, ycbcr_420_passthrough, ycbcr_444_to_420, rgb_to_ycbcr; |
4486 | |
4487 | /* No YCbCr output support on gmch platforms */ |
4488 | if (HAS_GMCH(i915)((&(i915)->__info)->display.has_gmch)) |
4489 | return; |
4490 | |
4491 | /* |
4492 | * ILK doesn't seem capable of DP YCbCr output. The |
4493 | * displayed image is severly corrupted. SNB+ is fine. |
4494 | */ |
4495 | if (IS_IRONLAKE(i915)IS_PLATFORM(i915, INTEL_IRONLAKE)) |
4496 | return; |
4497 | |
4498 | is_branch = drm_dp_is_branch(intel_dp->dpcd); |
4499 | ycbcr_420_passthrough = |
4500 | drm_dp_downstream_420_passthrough(intel_dp->dpcd, |
4501 | intel_dp->downstream_ports); |
4502 | /* on-board LSPCON always assumed to support 4:4:4->4:2:0 conversion */ |
4503 | ycbcr_444_to_420 = |
4504 | dp_to_dig_port(intel_dp)->lspcon.active || |
4505 | drm_dp_downstream_444_to_420_conversion(intel_dp->dpcd, |
4506 | intel_dp->downstream_ports); |
4507 | rgb_to_ycbcr = drm_dp_downstream_rgb_to_ycbcr_conversion(intel_dp->dpcd, |
4508 | intel_dp->downstream_ports, |
4509 | DP_DS_HDMI_BT709_RGB_YCBCR_CONV(1 << 6)); |
4510 | |
4511 | if (DISPLAY_VER(i915)((&(i915)->__runtime)->display.ip.ver) >= 11) { |
4512 | /* Let PCON convert from RGB->YCbCr if possible */ |
4513 | if (is_branch && rgb_to_ycbcr && ycbcr_444_to_420) { |
4514 | intel_dp->dfp.rgb_to_ycbcr = true1; |
4515 | intel_dp->dfp.ycbcr_444_to_420 = true1; |
4516 | connector->base.ycbcr_420_allowed = true1; |
4517 | } else { |
4518 | /* Prefer 4:2:0 passthrough over 4:4:4->4:2:0 conversion */ |
4519 | intel_dp->dfp.ycbcr_444_to_420 = |
4520 | ycbcr_444_to_420 && !ycbcr_420_passthrough; |
4521 | |
4522 | connector->base.ycbcr_420_allowed = |
4523 | !is_branch || ycbcr_444_to_420 || ycbcr_420_passthrough; |
4524 | } |
4525 | } else { |
4526 | /* 4:4:4->4:2:0 conversion is the only way */ |
4527 | intel_dp->dfp.ycbcr_444_to_420 = ycbcr_444_to_420; |
4528 | |
4529 | connector->base.ycbcr_420_allowed = ycbcr_444_to_420; |
4530 | } |
4531 | |
4532 | drm_dbg_kms(&i915->drm,__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "[CONNECTOR:%d:%s] RGB->YcbCr conversion? %s, YCbCr 4:2:0 allowed? %s, YCbCr 4:4:4->4:2:0 conversion? %s\n" , connector->base.base.id, connector->base.name, str_yes_no (intel_dp->dfp.rgb_to_ycbcr), str_yes_no(connector->base .ycbcr_420_allowed), str_yes_no(intel_dp->dfp.ycbcr_444_to_420 )) |
4533 | "[CONNECTOR:%d:%s] RGB->YcbCr conversion? %s, YCbCr 4:2:0 allowed? %s, YCbCr 4:4:4->4:2:0 conversion? %s\n",__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "[CONNECTOR:%d:%s] RGB->YcbCr conversion? %s, YCbCr 4:2:0 allowed? %s, YCbCr 4:4:4->4:2:0 conversion? %s\n" , connector->base.base.id, connector->base.name, str_yes_no (intel_dp->dfp.rgb_to_ycbcr), str_yes_no(connector->base .ycbcr_420_allowed), str_yes_no(intel_dp->dfp.ycbcr_444_to_420 )) |
4534 | connector->base.base.id, connector->base.name,__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "[CONNECTOR:%d:%s] RGB->YcbCr conversion? %s, YCbCr 4:2:0 allowed? %s, YCbCr 4:4:4->4:2:0 conversion? %s\n" , connector->base.base.id, connector->base.name, str_yes_no (intel_dp->dfp.rgb_to_ycbcr), str_yes_no(connector->base .ycbcr_420_allowed), str_yes_no(intel_dp->dfp.ycbcr_444_to_420 )) |
4535 | str_yes_no(intel_dp->dfp.rgb_to_ycbcr),__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "[CONNECTOR:%d:%s] RGB->YcbCr conversion? %s, YCbCr 4:2:0 allowed? %s, YCbCr 4:4:4->4:2:0 conversion? %s\n" , connector->base.base.id, connector->base.name, str_yes_no (intel_dp->dfp.rgb_to_ycbcr), str_yes_no(connector->base .ycbcr_420_allowed), str_yes_no(intel_dp->dfp.ycbcr_444_to_420 )) |
4536 | str_yes_no(connector->base.ycbcr_420_allowed),__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "[CONNECTOR:%d:%s] RGB->YcbCr conversion? %s, YCbCr 4:2:0 allowed? %s, YCbCr 4:4:4->4:2:0 conversion? %s\n" , connector->base.base.id, connector->base.name, str_yes_no (intel_dp->dfp.rgb_to_ycbcr), str_yes_no(connector->base .ycbcr_420_allowed), str_yes_no(intel_dp->dfp.ycbcr_444_to_420 )) |
4537 | str_yes_no(intel_dp->dfp.ycbcr_444_to_420))__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "[CONNECTOR:%d:%s] RGB->YcbCr conversion? %s, YCbCr 4:2:0 allowed? %s, YCbCr 4:4:4->4:2:0 conversion? %s\n" , connector->base.base.id, connector->base.name, str_yes_no (intel_dp->dfp.rgb_to_ycbcr), str_yes_no(connector->base .ycbcr_420_allowed), str_yes_no(intel_dp->dfp.ycbcr_444_to_420 )); |
4538 | } |
4539 | |
4540 | static void |
4541 | intel_dp_set_edid(struct intel_dp *intel_dp) |
4542 | { |
4543 | struct drm_i915_privateinteldrm_softc *i915 = dp_to_i915(intel_dp)to_i915(dp_to_dig_port(intel_dp)->base.base.dev); |
4544 | struct intel_connector *connector = intel_dp->attached_connector; |
4545 | struct edid *edid; |
4546 | bool_Bool vrr_capable; |
4547 | |
4548 | intel_dp_unset_edid(intel_dp); |
4549 | edid = intel_dp_get_edid(intel_dp); |
4550 | connector->detect_edid = edid; |
4551 | |
4552 | vrr_capable = intel_vrr_is_capable(connector); |
4553 | drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s] VRR capable: %s\n",__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "[CONNECTOR:%d:%s] VRR capable: %s\n" , connector->base.base.id, connector->base.name, str_yes_no (vrr_capable)) |
4554 | connector->base.base.id, connector->base.name, str_yes_no(vrr_capable))__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "[CONNECTOR:%d:%s] VRR capable: %s\n" , connector->base.base.id, connector->base.name, str_yes_no (vrr_capable)); |
4555 | drm_connector_set_vrr_capable_property(&connector->base, vrr_capable); |
4556 | |
4557 | intel_dp_update_dfp(intel_dp, edid); |
4558 | intel_dp_update_420(intel_dp); |
4559 | |
4560 | if (edid && edid->input & DRM_EDID_INPUT_DIGITAL(1 << 7)) { |
4561 | intel_dp->has_hdmi_sink = drm_detect_hdmi_monitor(edid); |
4562 | intel_dp->has_audio = drm_detect_monitor_audio(edid); |
4563 | } |
4564 | |
4565 | drm_dp_cec_set_edid(&intel_dp->aux, edid); |
4566 | } |
4567 | |
4568 | static void |
4569 | intel_dp_unset_edid(struct intel_dp *intel_dp) |
4570 | { |
4571 | struct intel_connector *connector = intel_dp->attached_connector; |
4572 | |
4573 | drm_dp_cec_unset_edid(&intel_dp->aux); |
4574 | kfree(connector->detect_edid); |
4575 | connector->detect_edid = NULL((void *)0); |
4576 | |
4577 | intel_dp->has_hdmi_sink = false0; |
4578 | intel_dp->has_audio = false0; |
4579 | |
4580 | intel_dp->dfp.max_bpc = 0; |
4581 | intel_dp->dfp.max_dotclock = 0; |
4582 | intel_dp->dfp.min_tmds_clock = 0; |
4583 | intel_dp->dfp.max_tmds_clock = 0; |
4584 | |
4585 | intel_dp->dfp.pcon_max_frl_bw = 0; |
4586 | |
4587 | intel_dp->dfp.ycbcr_444_to_420 = false0; |
4588 | connector->base.ycbcr_420_allowed = false0; |
4589 | |
4590 | drm_connector_set_vrr_capable_property(&connector->base, |
4591 | false0); |
4592 | } |
4593 | |
4594 | static int |
4595 | intel_dp_detect(struct drm_connector *connector, |
4596 | struct drm_modeset_acquire_ctx *ctx, |
4597 | bool_Bool force) |
4598 | { |
4599 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->dev); |
4600 | struct intel_dp *intel_dp = intel_attached_dp(to_intel_connector(connector)({ const __typeof( ((struct intel_connector *)0)->base ) * __mptr = (connector); (struct intel_connector *)( (char *)__mptr - __builtin_offsetof(struct intel_connector, base) );})); |
4601 | struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); |
4602 | struct intel_encoder *encoder = &dig_port->base; |
4603 | enum drm_connector_status status; |
4604 | |
4605 | drm_dbg_kms(&dev_priv->drm, "[CONNECTOR:%d:%s]\n",__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "[CONNECTOR:%d:%s]\n" , connector->base.id, connector->name) |
4606 | connector->base.id, connector->name)__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "[CONNECTOR:%d:%s]\n" , connector->base.id, connector->name); |
4607 | drm_WARN_ON(&dev_priv->drm,({ int __ret = !!((!drm_modeset_is_locked(&dev_priv->drm .mode_config.connection_mutex))); if (__ret) printf("%s %s: " "%s", dev_driver_string(((&dev_priv->drm))->dev), "" , "drm_WARN_ON(" "!drm_modeset_is_locked(&dev_priv->drm.mode_config.connection_mutex)" ")"); __builtin_expect(!!(__ret), 0); }) |
4608 | !drm_modeset_is_locked(&dev_priv->drm.mode_config.connection_mutex))({ int __ret = !!((!drm_modeset_is_locked(&dev_priv->drm .mode_config.connection_mutex))); if (__ret) printf("%s %s: " "%s", dev_driver_string(((&dev_priv->drm))->dev), "" , "drm_WARN_ON(" "!drm_modeset_is_locked(&dev_priv->drm.mode_config.connection_mutex)" ")"); __builtin_expect(!!(__ret), 0); }); |
4609 | |
4610 | if (!INTEL_DISPLAY_ENABLED(dev_priv)(({ int __ret = !!((!((&(dev_priv)->__runtime)->pipe_mask != 0))); if (__ret) printf("%s %s: " "%s", dev_driver_string (((&(dev_priv)->drm))->dev), "", "drm_WARN_ON(" "!((&(dev_priv)->__runtime)->pipe_mask != 0)" ")"); __builtin_expect(!!(__ret), 0); }), !(dev_priv)->params .disable_display && !intel_opregion_headless_sku(dev_priv ))) |
4611 | return connector_status_disconnected; |
4612 | |
4613 | /* Can't disconnect eDP */ |
4614 | if (intel_dp_is_edp(intel_dp)) |
4615 | status = edp_detect(intel_dp); |
4616 | else if (intel_digital_port_connected(encoder)) |
4617 | status = intel_dp_detect_dpcd(intel_dp); |
4618 | else |
4619 | status = connector_status_disconnected; |
4620 | |
4621 | if (status == connector_status_disconnected) { |
4622 | memset(&intel_dp->compliance, 0, sizeof(intel_dp->compliance))__builtin_memset((&intel_dp->compliance), (0), (sizeof (intel_dp->compliance))); |
4623 | memset(intel_dp->dsc_dpcd, 0, sizeof(intel_dp->dsc_dpcd))__builtin_memset((intel_dp->dsc_dpcd), (0), (sizeof(intel_dp ->dsc_dpcd))); |
4624 | |
4625 | if (intel_dp->is_mst) { |
4626 | drm_dbg_kms(&dev_priv->drm,__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "MST device may have disappeared %d vs %d\n" , intel_dp->is_mst, intel_dp->mst_mgr.mst_state) |
4627 | "MST device may have disappeared %d vs %d\n",__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "MST device may have disappeared %d vs %d\n" , intel_dp->is_mst, intel_dp->mst_mgr.mst_state) |
4628 | intel_dp->is_mst,__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "MST device may have disappeared %d vs %d\n" , intel_dp->is_mst, intel_dp->mst_mgr.mst_state) |
4629 | intel_dp->mst_mgr.mst_state)__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "MST device may have disappeared %d vs %d\n" , intel_dp->is_mst, intel_dp->mst_mgr.mst_state); |
4630 | intel_dp->is_mst = false0; |
4631 | drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst_mgr, |
4632 | intel_dp->is_mst); |
4633 | } |
4634 | |
4635 | goto out; |
4636 | } |
4637 | |
4638 | /* Read DP Sink DSC Cap DPCD regs for DP v1.4 */ |
4639 | if (DISPLAY_VER(dev_priv)((&(dev_priv)->__runtime)->display.ip.ver) >= 11) |
4640 | intel_dp_get_dsc_sink_cap(intel_dp); |
4641 | |
4642 | intel_dp_configure_mst(intel_dp); |
4643 | |
4644 | /* |
4645 | * TODO: Reset link params when switching to MST mode, until MST |
4646 | * supports link training fallback params. |
4647 | */ |
4648 | if (intel_dp->reset_link_params || intel_dp->is_mst) { |
4649 | intel_dp_reset_max_link_params(intel_dp); |
4650 | intel_dp->reset_link_params = false0; |
4651 | } |
4652 | |
4653 | intel_dp_print_rates(intel_dp); |
4654 | |
4655 | if (intel_dp->is_mst) { |
4656 | /* |
4657 | * If we are in MST mode then this connector |
4658 | * won't appear connected or have anything |
4659 | * with EDID on it |
4660 | */ |
4661 | status = connector_status_disconnected; |
4662 | goto out; |
4663 | } |
4664 | |
4665 | /* |
4666 | * Some external monitors do not signal loss of link synchronization |
4667 | * with an IRQ_HPD, so force a link status check. |
4668 | */ |
4669 | if (!intel_dp_is_edp(intel_dp)) { |
4670 | int ret; |
4671 | |
4672 | ret = intel_dp_retrain_link(encoder, ctx); |
4673 | if (ret) |
4674 | return ret; |
4675 | } |
4676 | |
4677 | /* |
4678 | * Clearing NACK and defer counts to get their exact values |
4679 | * while reading EDID which are required by Compliance tests |
4680 | * 4.2.2.4 and 4.2.2.5 |
4681 | */ |
4682 | intel_dp->aux.i2c_nack_count = 0; |
4683 | intel_dp->aux.i2c_defer_count = 0; |
4684 | |
4685 | intel_dp_set_edid(intel_dp); |
4686 | if (intel_dp_is_edp(intel_dp) || |
4687 | to_intel_connector(connector)({ const __typeof( ((struct intel_connector *)0)->base ) * __mptr = (connector); (struct intel_connector *)( (char *)__mptr - __builtin_offsetof(struct intel_connector, base) );})->detect_edid) |
4688 | status = connector_status_connected; |
4689 | |
4690 | intel_dp_check_device_service_irq(intel_dp); |
4691 | |
4692 | out: |
4693 | if (status != connector_status_connected && !intel_dp->is_mst) |
4694 | intel_dp_unset_edid(intel_dp); |
4695 | |
4696 | /* |
4697 | * Make sure the refs for power wells enabled during detect are |
4698 | * dropped to avoid a new detect cycle triggered by HPD polling. |
4699 | */ |
4700 | intel_display_power_flush_work(dev_priv); |
4701 | |
4702 | if (!intel_dp_is_edp(intel_dp)) |
4703 | drm_dp_set_subconnector_property(connector, |
4704 | status, |
4705 | intel_dp->dpcd, |
4706 | intel_dp->downstream_ports); |
4707 | return status; |
4708 | } |
4709 | |
4710 | static void |
4711 | intel_dp_force(struct drm_connector *connector) |
4712 | { |
4713 | struct intel_dp *intel_dp = intel_attached_dp(to_intel_connector(connector)({ const __typeof( ((struct intel_connector *)0)->base ) * __mptr = (connector); (struct intel_connector *)( (char *)__mptr - __builtin_offsetof(struct intel_connector, base) );})); |
4714 | struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); |
4715 | struct intel_encoder *intel_encoder = &dig_port->base; |
4716 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(intel_encoder->base.dev); |
4717 | enum intel_display_power_domain aux_domain = |
4718 | intel_aux_power_domain(dig_port); |
4719 | intel_wakeref_t wakeref; |
4720 | |
4721 | drm_dbg_kms(&dev_priv->drm, "[CONNECTOR:%d:%s]\n",__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "[CONNECTOR:%d:%s]\n" , connector->base.id, connector->name) |
4722 | connector->base.id, connector->name)__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "[CONNECTOR:%d:%s]\n" , connector->base.id, connector->name); |
4723 | intel_dp_unset_edid(intel_dp); |
4724 | |
4725 | if (connector->status != connector_status_connected) |
4726 | return; |
4727 | |
4728 | wakeref = intel_display_power_get(dev_priv, aux_domain); |
4729 | |
4730 | intel_dp_set_edid(intel_dp); |
4731 | |
4732 | intel_display_power_put(dev_priv, aux_domain, wakeref); |
4733 | } |
4734 | |
4735 | static int intel_dp_get_modes(struct drm_connector *connector) |
4736 | { |
4737 | struct intel_connector *intel_connector = to_intel_connector(connector)({ const __typeof( ((struct intel_connector *)0)->base ) * __mptr = (connector); (struct intel_connector *)( (char *)__mptr - __builtin_offsetof(struct intel_connector, base) );}); |
4738 | struct edid *edid; |
4739 | int num_modes = 0; |
4740 | |
4741 | edid = intel_connector->detect_edid; |
4742 | if (edid) |
4743 | num_modes = intel_connector_update_modes(connector, edid); |
4744 | |
4745 | /* Also add fixed mode, which may or may not be present in EDID */ |
4746 | if (intel_dp_is_edp(intel_attached_dp(intel_connector))) |
4747 | num_modes += intel_panel_get_modes(intel_connector); |
4748 | |
4749 | if (num_modes) |
4750 | return num_modes; |
4751 | |
4752 | if (!edid) { |
4753 | struct intel_dp *intel_dp = intel_attached_dp(intel_connector); |
4754 | struct drm_display_mode *mode; |
4755 | |
4756 | mode = drm_dp_downstream_mode(connector->dev, |
4757 | intel_dp->dpcd, |
4758 | intel_dp->downstream_ports); |
4759 | if (mode) { |
4760 | drm_mode_probed_add(connector, mode); |
4761 | num_modes++; |
4762 | } |
4763 | } |
4764 | |
4765 | return num_modes; |
4766 | } |
4767 | |
4768 | static int |
4769 | intel_dp_connector_register(struct drm_connector *connector) |
4770 | { |
4771 | struct drm_i915_privateinteldrm_softc *i915 = to_i915(connector->dev); |
4772 | struct intel_dp *intel_dp = intel_attached_dp(to_intel_connector(connector)({ const __typeof( ((struct intel_connector *)0)->base ) * __mptr = (connector); (struct intel_connector *)( (char *)__mptr - __builtin_offsetof(struct intel_connector, base) );})); |
4773 | struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); |
4774 | struct intel_lspcon *lspcon = &dig_port->lspcon; |
4775 | int ret; |
4776 | |
4777 | ret = intel_connector_register(connector); |
4778 | if (ret) |
4779 | return ret; |
4780 | |
4781 | #ifdef notyet |
4782 | drm_dbg_kms(&i915->drm, "registering %s bus for %s\n",__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "registering %s bus for %s\n" , intel_dp->aux.name, connector->kdev->kobj.name) |
4783 | intel_dp->aux.name, connector->kdev->kobj.name)__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "registering %s bus for %s\n" , intel_dp->aux.name, connector->kdev->kobj.name); |
4784 | #endif |
4785 | |
4786 | intel_dp->aux.dev = connector->kdev; |
4787 | ret = drm_dp_aux_register(&intel_dp->aux); |
4788 | if (!ret) |
4789 | drm_dp_cec_register_connector(&intel_dp->aux, connector); |
4790 | |
4791 | if (!intel_bios_is_lspcon_present(i915, dig_port->base.port)) |
4792 | return ret; |
4793 | |
4794 | /* |
4795 | * ToDo: Clean this up to handle lspcon init and resume more |
4796 | * efficiently and streamlined. |
4797 | */ |
4798 | if (lspcon_init(dig_port)) { |
4799 | lspcon_detect_hdr_capability(lspcon); |
4800 | if (lspcon->hdr_supported) |
4801 | drm_connector_attach_hdr_output_metadata_property(connector); |
4802 | } |
4803 | |
4804 | return ret; |
4805 | } |
4806 | |
4807 | static void |
4808 | intel_dp_connector_unregister(struct drm_connector *connector) |
4809 | { |
4810 | struct intel_dp *intel_dp = intel_attached_dp(to_intel_connector(connector)({ const __typeof( ((struct intel_connector *)0)->base ) * __mptr = (connector); (struct intel_connector *)( (char *)__mptr - __builtin_offsetof(struct intel_connector, base) );})); |
4811 | |
4812 | drm_dp_cec_unregister_connector(&intel_dp->aux); |
4813 | drm_dp_aux_unregister(&intel_dp->aux); |
4814 | intel_connector_unregister(connector); |
4815 | } |
4816 | |
4817 | void intel_dp_encoder_flush_work(struct drm_encoder *encoder) |
4818 | { |
4819 | struct intel_digital_port *dig_port = enc_to_dig_port(to_intel_encoder(encoder)({ const __typeof( ((struct intel_encoder *)0)->base ) *__mptr = (encoder); (struct intel_encoder *)( (char *)__mptr - __builtin_offsetof (struct intel_encoder, base) );})); |
4820 | struct intel_dp *intel_dp = &dig_port->dp; |
4821 | |
4822 | intel_dp_mst_encoder_cleanup(dig_port); |
4823 | |
4824 | intel_pps_vdd_off_sync(intel_dp); |
4825 | |
4826 | intel_dp_aux_fini(intel_dp); |
4827 | } |
4828 | |
4829 | void intel_dp_encoder_suspend(struct intel_encoder *intel_encoder) |
4830 | { |
4831 | struct intel_dp *intel_dp = enc_to_intel_dp(intel_encoder); |
4832 | |
4833 | intel_pps_vdd_off_sync(intel_dp); |
4834 | } |
4835 | |
4836 | void intel_dp_encoder_shutdown(struct intel_encoder *intel_encoder) |
4837 | { |
4838 | struct intel_dp *intel_dp = enc_to_intel_dp(intel_encoder); |
4839 | |
4840 | intel_pps_wait_power_cycle(intel_dp); |
4841 | } |
4842 | |
4843 | static int intel_modeset_tile_group(struct intel_atomic_state *state, |
4844 | int tile_group_id) |
4845 | { |
4846 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(state->base.dev); |
4847 | struct drm_connector_list_iter conn_iter; |
4848 | struct drm_connector *connector; |
4849 | int ret = 0; |
4850 | |
4851 | drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter); |
4852 | drm_for_each_connector_iter(connector, &conn_iter)while ((connector = drm_connector_list_iter_next(&conn_iter ))) { |
4853 | struct drm_connector_state *conn_state; |
4854 | struct intel_crtc_state *crtc_state; |
4855 | struct intel_crtc *crtc; |
4856 | |
4857 | if (!connector->has_tile || |
4858 | connector->tile_group->id != tile_group_id) |
4859 | continue; |
4860 | |
4861 | conn_state = drm_atomic_get_connector_state(&state->base, |
4862 | connector); |
4863 | if (IS_ERR(conn_state)) { |
4864 | ret = PTR_ERR(conn_state); |
4865 | break; |
4866 | } |
4867 | |
4868 | crtc = to_intel_crtc(conn_state->crtc)({ const __typeof( ((struct intel_crtc *)0)->base ) *__mptr = (conn_state->crtc); (struct intel_crtc *)( (char *)__mptr - __builtin_offsetof(struct intel_crtc, base) );}); |
4869 | |
4870 | if (!crtc) |
4871 | continue; |
4872 | |
4873 | crtc_state = intel_atomic_get_new_crtc_state(state, crtc); |
4874 | crtc_state->uapi.mode_changed = true1; |
4875 | |
4876 | ret = drm_atomic_add_affected_planes(&state->base, &crtc->base); |
4877 | if (ret) |
4878 | break; |
4879 | } |
4880 | drm_connector_list_iter_end(&conn_iter); |
4881 | |
4882 | return ret; |
4883 | } |
4884 | |
4885 | static int intel_modeset_affected_transcoders(struct intel_atomic_state *state, u8 transcoders) |
4886 | { |
4887 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(state->base.dev); |
4888 | struct intel_crtc *crtc; |
4889 | |
4890 | if (transcoders == 0) |
4891 | return 0; |
4892 | |
4893 | for_each_intel_crtc(&dev_priv->drm, crtc)for (crtc = ({ const __typeof( ((__typeof(*crtc) *)0)->base .head ) *__mptr = ((&(&dev_priv->drm)->mode_config .crtc_list)->next); (__typeof(*crtc) *)( (char *)__mptr - __builtin_offsetof (__typeof(*crtc), base.head) );}); &crtc->base.head != (&(&dev_priv->drm)->mode_config.crtc_list); crtc = ({ const __typeof( ((__typeof(*crtc) *)0)->base.head ) * __mptr = (crtc->base.head.next); (__typeof(*crtc) *)( (char *)__mptr - __builtin_offsetof(__typeof(*crtc), base.head) ); })) { |
4894 | struct intel_crtc_state *crtc_state; |
4895 | int ret; |
4896 | |
4897 | crtc_state = intel_atomic_get_crtc_state(&state->base, crtc); |
4898 | if (IS_ERR(crtc_state)) |
4899 | return PTR_ERR(crtc_state); |
4900 | |
4901 | if (!crtc_state->hw.enable) |
4902 | continue; |
4903 | |
4904 | if (!(transcoders & BIT(crtc_state->cpu_transcoder)(1UL << (crtc_state->cpu_transcoder)))) |
4905 | continue; |
4906 | |
4907 | crtc_state->uapi.mode_changed = true1; |
4908 | |
4909 | ret = drm_atomic_add_affected_connectors(&state->base, &crtc->base); |
4910 | if (ret) |
4911 | return ret; |
4912 | |
4913 | ret = drm_atomic_add_affected_planes(&state->base, &crtc->base); |
4914 | if (ret) |
4915 | return ret; |
4916 | |
4917 | transcoders &= ~BIT(crtc_state->cpu_transcoder)(1UL << (crtc_state->cpu_transcoder)); |
4918 | } |
4919 | |
4920 | drm_WARN_ON(&dev_priv->drm, transcoders != 0)({ int __ret = !!((transcoders != 0)); if (__ret) printf("%s %s: " "%s", dev_driver_string(((&dev_priv->drm))->dev), "" , "drm_WARN_ON(" "transcoders != 0" ")"); __builtin_expect(!! (__ret), 0); }); |
4921 | |
4922 | return 0; |
4923 | } |
4924 | |
4925 | static int intel_modeset_synced_crtcs(struct intel_atomic_state *state, |
4926 | struct drm_connector *connector) |
4927 | { |
4928 | const struct drm_connector_state *old_conn_state = |
4929 | drm_atomic_get_old_connector_state(&state->base, connector); |
4930 | const struct intel_crtc_state *old_crtc_state; |
4931 | struct intel_crtc *crtc; |
4932 | u8 transcoders; |
4933 | |
4934 | crtc = to_intel_crtc(old_conn_state->crtc)({ const __typeof( ((struct intel_crtc *)0)->base ) *__mptr = (old_conn_state->crtc); (struct intel_crtc *)( (char *) __mptr - __builtin_offsetof(struct intel_crtc, base) );}); |
4935 | if (!crtc) |
4936 | return 0; |
4937 | |
4938 | old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc); |
4939 | |
4940 | if (!old_crtc_state->hw.active) |
4941 | return 0; |
4942 | |
4943 | transcoders = old_crtc_state->sync_mode_slaves_mask; |
4944 | if (old_crtc_state->master_transcoder != INVALID_TRANSCODER) |
4945 | transcoders |= BIT(old_crtc_state->master_transcoder)(1UL << (old_crtc_state->master_transcoder)); |
4946 | |
4947 | return intel_modeset_affected_transcoders(state, |
4948 | transcoders); |
4949 | } |
4950 | |
4951 | static int intel_dp_connector_atomic_check(struct drm_connector *conn, |
4952 | struct drm_atomic_state *_state) |
4953 | { |
4954 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(conn->dev); |
4955 | struct intel_atomic_state *state = to_intel_atomic_state(_state)({ const __typeof( ((struct intel_atomic_state *)0)->base ) *__mptr = (_state); (struct intel_atomic_state *)( (char *)__mptr - __builtin_offsetof(struct intel_atomic_state, base) );}); |
4956 | struct drm_connector_state *conn_state = drm_atomic_get_new_connector_state(_state, conn); |
4957 | struct intel_connector *intel_conn = to_intel_connector(conn)({ const __typeof( ((struct intel_connector *)0)->base ) * __mptr = (conn); (struct intel_connector *)( (char *)__mptr - __builtin_offsetof(struct intel_connector, base) );}); |
4958 | struct intel_dp *intel_dp = enc_to_intel_dp(intel_conn->encoder); |
4959 | int ret; |
4960 | |
4961 | ret = intel_digital_connector_atomic_check(conn, &state->base); |
4962 | if (ret) |
4963 | return ret; |
4964 | |
4965 | if (intel_dp_mst_source_support(intel_dp)) { |
4966 | ret = drm_dp_mst_root_conn_atomic_check(conn_state, &intel_dp->mst_mgr); |
4967 | if (ret) |
4968 | return ret; |
4969 | } |
4970 | |
4971 | /* |
4972 | * We don't enable port sync on BDW due to missing w/as and |
4973 | * due to not having adjusted the modeset sequence appropriately. |
4974 | */ |
4975 | if (DISPLAY_VER(dev_priv)((&(dev_priv)->__runtime)->display.ip.ver) < 9) |
4976 | return 0; |
4977 | |
4978 | if (!intel_connector_needs_modeset(state, conn)) |
4979 | return 0; |
4980 | |
4981 | if (conn->has_tile) { |
4982 | ret = intel_modeset_tile_group(state, conn->tile_group->id); |
4983 | if (ret) |
4984 | return ret; |
4985 | } |
4986 | |
4987 | return intel_modeset_synced_crtcs(state, conn); |
4988 | } |
4989 | |
4990 | static void intel_dp_oob_hotplug_event(struct drm_connector *connector) |
4991 | { |
4992 | struct intel_encoder *encoder = intel_attached_encoder(to_intel_connector(connector)({ const __typeof( ((struct intel_connector *)0)->base ) * __mptr = (connector); (struct intel_connector *)( (char *)__mptr - __builtin_offsetof(struct intel_connector, base) );})); |
4993 | struct drm_i915_privateinteldrm_softc *i915 = to_i915(connector->dev); |
4994 | |
4995 | spin_lock_irq(&i915->irq_lock)mtx_enter(&i915->irq_lock); |
4996 | i915->display.hotplug.event_bits |= BIT(encoder->hpd_pin)(1UL << (encoder->hpd_pin)); |
4997 | spin_unlock_irq(&i915->irq_lock)mtx_leave(&i915->irq_lock); |
4998 | queue_delayed_work(system_wq, &i915->display.hotplug.hotplug_work, 0); |
4999 | } |
5000 | |
5001 | static const struct drm_connector_funcs intel_dp_connector_funcs = { |
5002 | .force = intel_dp_force, |
5003 | .fill_modes = drm_helper_probe_single_connector_modes, |
5004 | .atomic_get_property = intel_digital_connector_atomic_get_property, |
5005 | .atomic_set_property = intel_digital_connector_atomic_set_property, |
5006 | .late_register = intel_dp_connector_register, |
5007 | .early_unregister = intel_dp_connector_unregister, |
5008 | .destroy = intel_connector_destroy, |
5009 | .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, |
5010 | .atomic_duplicate_state = intel_digital_connector_duplicate_state, |
5011 | .oob_hotplug_event = intel_dp_oob_hotplug_event, |
5012 | }; |
5013 | |
5014 | static const struct drm_connector_helper_funcs intel_dp_connector_helper_funcs = { |
5015 | .detect_ctx = intel_dp_detect, |
5016 | .get_modes = intel_dp_get_modes, |
5017 | .mode_valid = intel_dp_mode_valid, |
5018 | .atomic_check = intel_dp_connector_atomic_check, |
5019 | }; |
5020 | |
5021 | enum irqreturn |
5022 | intel_dp_hpd_pulse(struct intel_digital_port *dig_port, bool_Bool long_hpd) |
5023 | { |
5024 | struct drm_i915_privateinteldrm_softc *i915 = to_i915(dig_port->base.base.dev); |
5025 | struct intel_dp *intel_dp = &dig_port->dp; |
5026 | |
5027 | if (dig_port->base.type == INTEL_OUTPUT_EDP && |
5028 | (long_hpd || !intel_pps_have_panel_power_or_vdd(intel_dp))) { |
5029 | /* |
5030 | * vdd off can generate a long/short pulse on eDP which |
5031 | * would require vdd on to handle it, and thus we |
5032 | * would end up in an endless cycle of |
5033 | * "vdd off -> long/short hpd -> vdd on -> detect -> vdd off -> ..." |
5034 | */ |
5035 | drm_dbg_kms(&i915->drm,__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "ignoring %s hpd on eDP [ENCODER:%d:%s]\n" , long_hpd ? "long" : "short", dig_port->base.base.base.id , dig_port->base.base.name) |
5036 | "ignoring %s hpd on eDP [ENCODER:%d:%s]\n",__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "ignoring %s hpd on eDP [ENCODER:%d:%s]\n" , long_hpd ? "long" : "short", dig_port->base.base.base.id , dig_port->base.base.name) |
5037 | long_hpd ? "long" : "short",__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "ignoring %s hpd on eDP [ENCODER:%d:%s]\n" , long_hpd ? "long" : "short", dig_port->base.base.base.id , dig_port->base.base.name) |
5038 | dig_port->base.base.base.id,__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "ignoring %s hpd on eDP [ENCODER:%d:%s]\n" , long_hpd ? "long" : "short", dig_port->base.base.base.id , dig_port->base.base.name) |
5039 | dig_port->base.base.name)__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "ignoring %s hpd on eDP [ENCODER:%d:%s]\n" , long_hpd ? "long" : "short", dig_port->base.base.base.id , dig_port->base.base.name); |
5040 | return IRQ_HANDLED; |
5041 | } |
5042 | |
5043 | drm_dbg_kms(&i915->drm, "got hpd irq on [ENCODER:%d:%s] - %s\n",__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "got hpd irq on [ENCODER:%d:%s] - %s\n" , dig_port->base.base.base.id, dig_port->base.base.name , long_hpd ? "long" : "short") |
5044 | dig_port->base.base.base.id,__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "got hpd irq on [ENCODER:%d:%s] - %s\n" , dig_port->base.base.base.id, dig_port->base.base.name , long_hpd ? "long" : "short") |
5045 | dig_port->base.base.name,__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "got hpd irq on [ENCODER:%d:%s] - %s\n" , dig_port->base.base.base.id, dig_port->base.base.name , long_hpd ? "long" : "short") |
5046 | long_hpd ? "long" : "short")__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "got hpd irq on [ENCODER:%d:%s] - %s\n" , dig_port->base.base.base.id, dig_port->base.base.name , long_hpd ? "long" : "short"); |
5047 | |
5048 | if (long_hpd) { |
5049 | intel_dp->reset_link_params = true1; |
5050 | return IRQ_NONE; |
5051 | } |
5052 | |
5053 | if (intel_dp->is_mst) { |
5054 | if (!intel_dp_check_mst_status(intel_dp)) |
5055 | return IRQ_NONE; |
5056 | } else if (!intel_dp_short_pulse(intel_dp)) { |
5057 | return IRQ_NONE; |
5058 | } |
5059 | |
5060 | return IRQ_HANDLED; |
5061 | } |
5062 | |
5063 | /* check the VBT to see whether the eDP is on another port */ |
5064 | bool_Bool intel_dp_is_port_edp(struct drm_i915_privateinteldrm_softc *dev_priv, enum port port) |
5065 | { |
5066 | /* |
5067 | * eDP not supported on g4x. so bail out early just |
5068 | * for a bit extra safety in case the VBT is bonkers. |
5069 | */ |
5070 | if (DISPLAY_VER(dev_priv)((&(dev_priv)->__runtime)->display.ip.ver) < 5) |
5071 | return false0; |
5072 | |
5073 | if (DISPLAY_VER(dev_priv)((&(dev_priv)->__runtime)->display.ip.ver) < 9 && port == PORT_A) |
5074 | return true1; |
5075 | |
5076 | return intel_bios_is_port_edp(dev_priv, port); |
5077 | } |
5078 | |
5079 | static bool_Bool |
5080 | has_gamut_metadata_dip(struct drm_i915_privateinteldrm_softc *i915, enum port port) |
5081 | { |
5082 | if (intel_bios_is_lspcon_present(i915, port)) |
5083 | return false0; |
5084 | |
5085 | if (DISPLAY_VER(i915)((&(i915)->__runtime)->display.ip.ver) >= 11) |
5086 | return true1; |
5087 | |
5088 | if (port == PORT_A) |
5089 | return false0; |
5090 | |
5091 | if (IS_HASWELL(i915)IS_PLATFORM(i915, INTEL_HASWELL) || IS_BROADWELL(i915)IS_PLATFORM(i915, INTEL_BROADWELL) || |
5092 | DISPLAY_VER(i915)((&(i915)->__runtime)->display.ip.ver) >= 9) |
5093 | return true1; |
5094 | |
5095 | return false0; |
5096 | } |
5097 | |
5098 | static void |
5099 | intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *connector) |
5100 | { |
5101 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->dev); |
5102 | enum port port = dp_to_dig_port(intel_dp)->base.port; |
5103 | |
5104 | if (!intel_dp_is_edp(intel_dp)) |
5105 | drm_connector_attach_dp_subconnector_property(connector); |
5106 | |
5107 | if (!IS_G4X(dev_priv)(IS_PLATFORM(dev_priv, INTEL_G45) || IS_PLATFORM(dev_priv, INTEL_GM45 )) && port != PORT_A) |
5108 | intel_attach_force_audio_property(connector); |
5109 | |
5110 | intel_attach_broadcast_rgb_property(connector); |
5111 | if (HAS_GMCH(dev_priv)((&(dev_priv)->__info)->display.has_gmch)) |
5112 | drm_connector_attach_max_bpc_property(connector, 6, 10); |
5113 | else if (DISPLAY_VER(dev_priv)((&(dev_priv)->__runtime)->display.ip.ver) >= 5) |
5114 | drm_connector_attach_max_bpc_property(connector, 6, 12); |
5115 | |
5116 | /* Register HDMI colorspace for case of lspcon */ |
5117 | if (intel_bios_is_lspcon_present(dev_priv, port)) { |
5118 | drm_connector_attach_content_type_property(connector); |
5119 | intel_attach_hdmi_colorspace_property(connector); |
5120 | } else { |
5121 | intel_attach_dp_colorspace_property(connector); |
5122 | } |
5123 | |
5124 | if (has_gamut_metadata_dip(dev_priv, port)) |
5125 | drm_connector_attach_hdr_output_metadata_property(connector); |
5126 | |
5127 | if (intel_dp_is_edp(intel_dp)) { |
5128 | u32 allowed_scalers; |
5129 | |
5130 | allowed_scalers = BIT(DRM_MODE_SCALE_ASPECT)(1UL << (3)) | BIT(DRM_MODE_SCALE_FULLSCREEN)(1UL << (1)); |
5131 | if (!HAS_GMCH(dev_priv)((&(dev_priv)->__info)->display.has_gmch)) |
5132 | allowed_scalers |= BIT(DRM_MODE_SCALE_CENTER)(1UL << (2)); |
5133 | |
5134 | drm_connector_attach_scaling_mode_property(connector, allowed_scalers); |
5135 | |
5136 | connector->state->scaling_mode = DRM_MODE_SCALE_ASPECT3; |
5137 | |
5138 | } |
5139 | |
5140 | if (HAS_VRR(dev_priv)(((&(dev_priv)->__runtime)->display.ip.ver) >= 11 )) |
5141 | drm_connector_attach_vrr_capable_property(connector); |
5142 | } |
5143 | |
5144 | static void |
5145 | intel_edp_add_properties(struct intel_dp *intel_dp) |
5146 | { |
5147 | struct intel_connector *connector = intel_dp->attached_connector; |
5148 | struct drm_i915_privateinteldrm_softc *i915 = to_i915(connector->base.dev); |
5149 | const struct drm_display_mode *fixed_mode = |
5150 | intel_panel_preferred_fixed_mode(connector); |
5151 | |
5152 | if (!fixed_mode) |
5153 | return; |
5154 | |
5155 | drm_connector_set_panel_orientation_with_quirk(&connector->base, |
5156 | i915->display.vbt.orientation, |
5157 | fixed_mode->hdisplay, |
5158 | fixed_mode->vdisplay); |
5159 | } |
5160 | |
5161 | static bool_Bool intel_edp_init_connector(struct intel_dp *intel_dp, |
5162 | struct intel_connector *intel_connector) |
5163 | { |
5164 | struct drm_i915_privateinteldrm_softc *dev_priv = dp_to_i915(intel_dp)to_i915(dp_to_dig_port(intel_dp)->base.base.dev); |
5165 | struct drm_device *dev = &dev_priv->drm; |
5166 | struct drm_connector *connector = &intel_connector->base; |
5167 | struct drm_display_mode *fixed_mode; |
5168 | struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; |
5169 | bool_Bool has_dpcd; |
5170 | enum pipe pipe = INVALID_PIPE; |
5171 | struct edid *edid; |
5172 | |
5173 | if (!intel_dp_is_edp(intel_dp)) |
5174 | return true1; |
5175 | |
5176 | /* |
5177 | * On IBX/CPT we may get here with LVDS already registered. Since the |
5178 | * driver uses the only internal power sequencer available for both |
5179 | * eDP and LVDS bail out early in this case to prevent interfering |
5180 | * with an already powered-on LVDS power sequencer. |
5181 | */ |
5182 | if (intel_get_lvds_encoder(dev_priv)) { |
5183 | drm_WARN_ON(dev,({ int __ret = !!((!((((dev_priv)->pch_type) == PCH_IBX) || (((dev_priv)->pch_type) == PCH_CPT)))); if (__ret) printf ("%s %s: " "%s", dev_driver_string(((dev))->dev), "", "drm_WARN_ON(" "!((((dev_priv)->pch_type) == PCH_IBX) || (((dev_priv)->pch_type) == PCH_CPT))" ")"); __builtin_expect(!!(__ret), 0); }) |
5184 | !(HAS_PCH_IBX(dev_priv) || HAS_PCH_CPT(dev_priv)))({ int __ret = !!((!((((dev_priv)->pch_type) == PCH_IBX) || (((dev_priv)->pch_type) == PCH_CPT)))); if (__ret) printf ("%s %s: " "%s", dev_driver_string(((dev))->dev), "", "drm_WARN_ON(" "!((((dev_priv)->pch_type) == PCH_IBX) || (((dev_priv)->pch_type) == PCH_CPT))" ")"); __builtin_expect(!!(__ret), 0); }); |
5185 | drm_info(&dev_priv->drm,do { } while(0) |
5186 | "LVDS was detected, not registering eDP\n")do { } while(0); |
5187 | |
5188 | return false0; |
5189 | } |
5190 | |
5191 | intel_bios_init_panel_early(dev_priv, &intel_connector->panel, |
5192 | encoder->devdata); |
5193 | |
5194 | intel_pps_init(intel_dp); |
5195 | |
5196 | /* Cache DPCD and EDID for edp. */ |
5197 | has_dpcd = intel_edp_init_dpcd(intel_dp); |
5198 | |
5199 | if (!has_dpcd) { |
5200 | /* if this fails, presume the device is a ghost */ |
5201 | drm_info(&dev_priv->drm,do { } while(0) |
5202 | "failed to retrieve link info, disabling eDP\n")do { } while(0); |
5203 | goto out_vdd_off; |
5204 | } |
5205 | |
5206 | mutex_lock(&dev->mode_config.mutex)rw_enter_write(&dev->mode_config.mutex); |
5207 | edid = drm_get_edid(connector, &intel_dp->aux.ddc); |
5208 | if (!edid) { |
5209 | /* Fallback to EDID from ACPI OpRegion, if any */ |
5210 | edid = intel_opregion_get_edid(intel_connector); |
5211 | if (edid) |
5212 | drm_dbg_kms(&dev_priv->drm,__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "[CONNECTOR:%d:%s] Using OpRegion EDID\n" , connector->base.id, connector->name) |
5213 | "[CONNECTOR:%d:%s] Using OpRegion EDID\n",__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "[CONNECTOR:%d:%s] Using OpRegion EDID\n" , connector->base.id, connector->name) |
5214 | connector->base.id, connector->name)__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "[CONNECTOR:%d:%s] Using OpRegion EDID\n" , connector->base.id, connector->name); |
5215 | } |
5216 | if (edid) { |
5217 | if (drm_add_edid_modes(connector, edid)) { |
5218 | drm_connector_update_edid_property(connector, edid); |
5219 | } else { |
5220 | kfree(edid); |
5221 | edid = ERR_PTR(-EINVAL22); |
5222 | } |
5223 | } else { |
5224 | edid = ERR_PTR(-ENOENT2); |
5225 | } |
5226 | intel_connector->edid = edid; |
5227 | |
5228 | intel_bios_init_panel_late(dev_priv, &intel_connector->panel, |
5229 | encoder->devdata, IS_ERR(edid) ? NULL((void *)0) : edid); |
5230 | |
5231 | intel_panel_add_edid_fixed_modes(intel_connector, true1); |
5232 | |
5233 | /* MSO requires information from the EDID */ |
5234 | intel_edp_mso_init(intel_dp); |
5235 | |
5236 | /* multiply the mode clock and horizontal timings for MSO */ |
5237 | list_for_each_entry(fixed_mode, &intel_connector->panel.fixed_modes, head)for (fixed_mode = ({ const __typeof( ((__typeof(*fixed_mode) * )0)->head ) *__mptr = ((&intel_connector->panel.fixed_modes )->next); (__typeof(*fixed_mode) *)( (char *)__mptr - __builtin_offsetof (__typeof(*fixed_mode), head) );}); &fixed_mode->head != (&intel_connector->panel.fixed_modes); fixed_mode = ( { const __typeof( ((__typeof(*fixed_mode) *)0)->head ) *__mptr = (fixed_mode->head.next); (__typeof(*fixed_mode) *)( (char *)__mptr - __builtin_offsetof(__typeof(*fixed_mode), head) ) ;})) |
5238 | intel_edp_mso_mode_fixup(intel_connector, fixed_mode); |
5239 | |
5240 | /* fallback to VBT if available for eDP */ |
5241 | if (!intel_panel_preferred_fixed_mode(intel_connector)) |
5242 | intel_panel_add_vbt_lfp_fixed_mode(intel_connector); |
5243 | |
5244 | mutex_unlock(&dev->mode_config.mutex)rw_exit_write(&dev->mode_config.mutex); |
5245 | |
5246 | if (IS_VALLEYVIEW(dev_priv)IS_PLATFORM(dev_priv, INTEL_VALLEYVIEW) || IS_CHERRYVIEW(dev_priv)IS_PLATFORM(dev_priv, INTEL_CHERRYVIEW)) { |
5247 | /* |
5248 | * Figure out the current pipe for the initial backlight setup. |
5249 | * If the current pipe isn't valid, try the PPS pipe, and if that |
5250 | * fails just assume pipe A. |
5251 | */ |
5252 | pipe = vlv_active_pipe(intel_dp); |
5253 | |
5254 | if (pipe != PIPE_A && pipe != PIPE_B) |
5255 | pipe = intel_dp->pps.pps_pipe; |
5256 | |
5257 | if (pipe != PIPE_A && pipe != PIPE_B) |
5258 | pipe = PIPE_A; |
5259 | |
5260 | drm_dbg_kms(&dev_priv->drm,__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "using pipe %c for initial backlight setup\n" , ((pipe) + 'A')) |
5261 | "using pipe %c for initial backlight setup\n",__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "using pipe %c for initial backlight setup\n" , ((pipe) + 'A')) |
5262 | pipe_name(pipe))__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "using pipe %c for initial backlight setup\n" , ((pipe) + 'A')); |
5263 | } |
5264 | |
5265 | intel_panel_init(intel_connector); |
5266 | |
5267 | intel_backlight_setup(intel_connector, pipe); |
5268 | |
5269 | intel_edp_add_properties(intel_dp); |
5270 | |
5271 | intel_pps_init_late(intel_dp); |
5272 | |
5273 | return true1; |
5274 | |
5275 | out_vdd_off: |
5276 | intel_pps_vdd_off_sync(intel_dp); |
5277 | |
5278 | return false0; |
5279 | } |
5280 | |
5281 | static void intel_dp_modeset_retry_work_fn(struct work_struct *work) |
5282 | { |
5283 | struct intel_connector *intel_connector; |
5284 | struct drm_connector *connector; |
5285 | |
5286 | intel_connector = container_of(work, typeof(*intel_connector),({ const __typeof( ((typeof(*intel_connector) *)0)->modeset_retry_work ) *__mptr = (work); (typeof(*intel_connector) *)( (char *)__mptr - __builtin_offsetof(typeof(*intel_connector), modeset_retry_work ) );}) |
5287 | modeset_retry_work)({ const __typeof( ((typeof(*intel_connector) *)0)->modeset_retry_work ) *__mptr = (work); (typeof(*intel_connector) *)( (char *)__mptr - __builtin_offsetof(typeof(*intel_connector), modeset_retry_work ) );}); |
5288 | connector = &intel_connector->base; |
5289 | drm_dbg_kms(connector->dev, "[CONNECTOR:%d:%s]\n", connector->base.id,__drm_dev_dbg(((void *)0), (connector->dev) ? (connector-> dev)->dev : ((void *)0), DRM_UT_KMS, "[CONNECTOR:%d:%s]\n" , connector->base.id, connector->name) |
5290 | connector->name)__drm_dev_dbg(((void *)0), (connector->dev) ? (connector-> dev)->dev : ((void *)0), DRM_UT_KMS, "[CONNECTOR:%d:%s]\n" , connector->base.id, connector->name); |
5291 | |
5292 | /* Grab the locks before changing connector property*/ |
5293 | mutex_lock(&connector->dev->mode_config.mutex)rw_enter_write(&connector->dev->mode_config.mutex); |
5294 | /* Set connector link status to BAD and send a Uevent to notify |
5295 | * userspace to do a modeset. |
5296 | */ |
5297 | drm_connector_set_link_status_property(connector, |
5298 | DRM_MODE_LINK_STATUS_BAD1); |
5299 | mutex_unlock(&connector->dev->mode_config.mutex)rw_exit_write(&connector->dev->mode_config.mutex); |
5300 | /* Send Hotplug uevent so userspace can reprobe */ |
5301 | drm_kms_helper_connector_hotplug_event(connector); |
5302 | } |
5303 | |
5304 | bool_Bool |
5305 | intel_dp_init_connector(struct intel_digital_port *dig_port, |
5306 | struct intel_connector *intel_connector) |
5307 | { |
5308 | struct drm_connector *connector = &intel_connector->base; |
5309 | struct intel_dp *intel_dp = &dig_port->dp; |
5310 | struct intel_encoder *intel_encoder = &dig_port->base; |
5311 | struct drm_device *dev = intel_encoder->base.dev; |
5312 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(dev); |
5313 | enum port port = intel_encoder->port; |
5314 | enum phy phy = intel_port_to_phy(dev_priv, port); |
5315 | int type; |
5316 | |
5317 | /* Initialize the work for modeset in case of link train failure */ |
5318 | INIT_WORK(&intel_connector->modeset_retry_work, |
5319 | intel_dp_modeset_retry_work_fn); |
5320 | |
5321 | if (drm_WARN(dev, dig_port->max_lanes < 1,({ int __ret = !!(dig_port->max_lanes < 1); if (__ret) printf ("%s %s: " "Not enough lanes (%d) for DP on [ENCODER:%d:%s]\n" , dev_driver_string((dev)->dev), "", dig_port->max_lanes , intel_encoder->base.base.id, intel_encoder->base.name ); __builtin_expect(!!(__ret), 0); }) |
5322 | "Not enough lanes (%d) for DP on [ENCODER:%d:%s]\n",({ int __ret = !!(dig_port->max_lanes < 1); if (__ret) printf ("%s %s: " "Not enough lanes (%d) for DP on [ENCODER:%d:%s]\n" , dev_driver_string((dev)->dev), "", dig_port->max_lanes , intel_encoder->base.base.id, intel_encoder->base.name ); __builtin_expect(!!(__ret), 0); }) |
5323 | dig_port->max_lanes, intel_encoder->base.base.id,({ int __ret = !!(dig_port->max_lanes < 1); if (__ret) printf ("%s %s: " "Not enough lanes (%d) for DP on [ENCODER:%d:%s]\n" , dev_driver_string((dev)->dev), "", dig_port->max_lanes , intel_encoder->base.base.id, intel_encoder->base.name ); __builtin_expect(!!(__ret), 0); }) |
5324 | intel_encoder->base.name)({ int __ret = !!(dig_port->max_lanes < 1); if (__ret) printf ("%s %s: " "Not enough lanes (%d) for DP on [ENCODER:%d:%s]\n" , dev_driver_string((dev)->dev), "", dig_port->max_lanes , intel_encoder->base.base.id, intel_encoder->base.name ); __builtin_expect(!!(__ret), 0); })) |
5325 | return false0; |
5326 | |
5327 | intel_dp->reset_link_params = true1; |
5328 | intel_dp->pps.pps_pipe = INVALID_PIPE; |
5329 | intel_dp->pps.active_pipe = INVALID_PIPE; |
5330 | |
5331 | /* Preserve the current hw state. */ |
5332 | intel_dp->DP = intel_de_read(dev_priv, intel_dp->output_reg); |
5333 | intel_dp->attached_connector = intel_connector; |
5334 | |
5335 | if (intel_dp_is_port_edp(dev_priv, port)) { |
5336 | /* |
5337 | * Currently we don't support eDP on TypeC ports, although in |
5338 | * theory it could work on TypeC legacy ports. |
5339 | */ |
5340 | drm_WARN_ON(dev, intel_phy_is_tc(dev_priv, phy))({ int __ret = !!((intel_phy_is_tc(dev_priv, phy))); if (__ret ) printf("%s %s: " "%s", dev_driver_string(((dev))->dev), "" , "drm_WARN_ON(" "intel_phy_is_tc(dev_priv, phy)" ")"); __builtin_expect (!!(__ret), 0); }); |
5341 | type = DRM_MODE_CONNECTOR_eDP14; |
5342 | intel_encoder->type = INTEL_OUTPUT_EDP; |
5343 | |
5344 | /* eDP only on port B and/or C on vlv/chv */ |
5345 | if (drm_WARN_ON(dev, (IS_VALLEYVIEW(dev_priv) ||({ int __ret = !!(((IS_PLATFORM(dev_priv, INTEL_VALLEYVIEW) || IS_PLATFORM(dev_priv, INTEL_CHERRYVIEW)) && port != PORT_B && port != PORT_C)); if (__ret) printf("%s %s: " "%s" , dev_driver_string(((dev))->dev), "", "drm_WARN_ON(" "(IS_PLATFORM(dev_priv, INTEL_VALLEYVIEW) || IS_PLATFORM(dev_priv, INTEL_CHERRYVIEW)) && port != PORT_B && port != PORT_C" ")"); __builtin_expect(!!(__ret), 0); }) |
5346 | IS_CHERRYVIEW(dev_priv)) &&({ int __ret = !!(((IS_PLATFORM(dev_priv, INTEL_VALLEYVIEW) || IS_PLATFORM(dev_priv, INTEL_CHERRYVIEW)) && port != PORT_B && port != PORT_C)); if (__ret) printf("%s %s: " "%s" , dev_driver_string(((dev))->dev), "", "drm_WARN_ON(" "(IS_PLATFORM(dev_priv, INTEL_VALLEYVIEW) || IS_PLATFORM(dev_priv, INTEL_CHERRYVIEW)) && port != PORT_B && port != PORT_C" ")"); __builtin_expect(!!(__ret), 0); }) |
5347 | port != PORT_B && port != PORT_C)({ int __ret = !!(((IS_PLATFORM(dev_priv, INTEL_VALLEYVIEW) || IS_PLATFORM(dev_priv, INTEL_CHERRYVIEW)) && port != PORT_B && port != PORT_C)); if (__ret) printf("%s %s: " "%s" , dev_driver_string(((dev))->dev), "", "drm_WARN_ON(" "(IS_PLATFORM(dev_priv, INTEL_VALLEYVIEW) || IS_PLATFORM(dev_priv, INTEL_CHERRYVIEW)) && port != PORT_B && port != PORT_C" ")"); __builtin_expect(!!(__ret), 0); })) |
5348 | return false0; |
5349 | } else { |
5350 | type = DRM_MODE_CONNECTOR_DisplayPort10; |
5351 | } |
5352 | |
5353 | intel_dp_set_default_sink_rates(intel_dp); |
5354 | intel_dp_set_default_max_sink_lane_count(intel_dp); |
5355 | |
5356 | if (IS_VALLEYVIEW(dev_priv)IS_PLATFORM(dev_priv, INTEL_VALLEYVIEW) || IS_CHERRYVIEW(dev_priv)IS_PLATFORM(dev_priv, INTEL_CHERRYVIEW)) |
5357 | intel_dp->pps.active_pipe = vlv_active_pipe(intel_dp); |
5358 | |
5359 | drm_dbg_kms(&dev_priv->drm,__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "Adding %s connector on [ENCODER:%d:%s]\n" , type == 14 ? "eDP" : "DP", intel_encoder->base.base.id, intel_encoder ->base.name) |
5360 | "Adding %s connector on [ENCODER:%d:%s]\n",__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "Adding %s connector on [ENCODER:%d:%s]\n" , type == 14 ? "eDP" : "DP", intel_encoder->base.base.id, intel_encoder ->base.name) |
5361 | type == DRM_MODE_CONNECTOR_eDP ? "eDP" : "DP",__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "Adding %s connector on [ENCODER:%d:%s]\n" , type == 14 ? "eDP" : "DP", intel_encoder->base.base.id, intel_encoder ->base.name) |
5362 | intel_encoder->base.base.id, intel_encoder->base.name)__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "Adding %s connector on [ENCODER:%d:%s]\n" , type == 14 ? "eDP" : "DP", intel_encoder->base.base.id, intel_encoder ->base.name); |
5363 | |
5364 | drm_connector_init(dev, connector, &intel_dp_connector_funcs, type); |
5365 | drm_connector_helper_add(connector, &intel_dp_connector_helper_funcs); |
5366 | |
5367 | if (!HAS_GMCH(dev_priv)((&(dev_priv)->__info)->display.has_gmch)) |
5368 | connector->interlace_allowed = true1; |
5369 | connector->doublescan_allowed = 0; |
5370 | |
5371 | intel_connector->polled = DRM_CONNECTOR_POLL_HPD(1 << 0); |
5372 | |
5373 | intel_dp_aux_init(intel_dp); |
5374 | |
5375 | intel_connector_attach_encoder(intel_connector, intel_encoder); |
5376 | |
5377 | if (HAS_DDI(dev_priv)((&(dev_priv)->__info)->display.has_ddi)) |
5378 | intel_connector->get_hw_state = intel_ddi_connector_get_hw_state; |
5379 | else |
5380 | intel_connector->get_hw_state = intel_connector_get_hw_state; |
5381 | |
5382 | if (!intel_edp_init_connector(intel_dp, intel_connector)) { |
5383 | intel_dp_aux_fini(intel_dp); |
5384 | goto fail; |
5385 | } |
5386 | |
5387 | intel_dp_set_source_rates(intel_dp); |
5388 | intel_dp_set_common_rates(intel_dp); |
5389 | intel_dp_reset_max_link_params(intel_dp); |
5390 | |
5391 | /* init MST on ports that can support it */ |
5392 | intel_dp_mst_encoder_init(dig_port, |
5393 | intel_connector->base.base.id); |
5394 | |
5395 | intel_dp_add_properties(intel_dp, connector); |
5396 | |
5397 | if (is_hdcp_supported(dev_priv, port) && !intel_dp_is_edp(intel_dp)) { |
5398 | int ret = intel_dp_hdcp_init(dig_port, intel_connector); |
5399 | if (ret) |
5400 | drm_dbg_kms(&dev_priv->drm,__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "HDCP init failed, skipping.\n" ) |
5401 | "HDCP init failed, skipping.\n")__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "HDCP init failed, skipping.\n" ); |
5402 | } |
5403 | |
5404 | /* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written |
5405 | * 0xd. Failure to do so will result in spurious interrupts being |
5406 | * generated on the port when a cable is not attached. |
5407 | */ |
5408 | if (IS_G45(dev_priv)IS_PLATFORM(dev_priv, INTEL_G45)) { |
5409 | u32 temp = intel_de_read(dev_priv, PEG_BAND_GAP_DATA((const i915_reg_t){ .reg = (0x14d68) })); |
5410 | intel_de_write(dev_priv, PEG_BAND_GAP_DATA((const i915_reg_t){ .reg = (0x14d68) }), |
5411 | (temp & ~0xf) | 0xd); |
5412 | } |
5413 | |
5414 | intel_dp->frl.is_trained = false0; |
5415 | intel_dp->frl.trained_rate_gbps = 0; |
5416 | |
5417 | intel_psr_init(intel_dp); |
5418 | |
5419 | return true1; |
5420 | |
5421 | fail: |
5422 | drm_connector_cleanup(connector); |
5423 | |
5424 | return false0; |
5425 | } |
5426 | |
5427 | void intel_dp_mst_suspend(struct drm_i915_privateinteldrm_softc *dev_priv) |
5428 | { |
5429 | struct intel_encoder *encoder; |
5430 | |
5431 | if (!HAS_DISPLAY(dev_priv)((&(dev_priv)->__runtime)->pipe_mask != 0)) |
5432 | return; |
5433 | |
5434 | for_each_intel_encoder(&dev_priv->drm, encoder)for (encoder = ({ const __typeof( ((__typeof(*encoder) *)0)-> base.head ) *__mptr = ((&(&dev_priv->drm)->mode_config .encoder_list)->next); (__typeof(*encoder) *)( (char *)__mptr - __builtin_offsetof(__typeof(*encoder), base.head) );}); & encoder->base.head != (&(&dev_priv->drm)->mode_config .encoder_list); encoder = ({ const __typeof( ((__typeof(*encoder ) *)0)->base.head ) *__mptr = (encoder->base.head.next) ; (__typeof(*encoder) *)( (char *)__mptr - __builtin_offsetof (__typeof(*encoder), base.head) );})) { |
5435 | struct intel_dp *intel_dp; |
5436 | |
5437 | if (encoder->type != INTEL_OUTPUT_DDI) |
5438 | continue; |
5439 | |
5440 | intel_dp = enc_to_intel_dp(encoder); |
5441 | |
5442 | if (!intel_dp_mst_source_support(intel_dp)) |
5443 | continue; |
5444 | |
5445 | if (intel_dp->is_mst) |
5446 | drm_dp_mst_topology_mgr_suspend(&intel_dp->mst_mgr); |
5447 | } |
5448 | } |
5449 | |
5450 | void intel_dp_mst_resume(struct drm_i915_privateinteldrm_softc *dev_priv) |
5451 | { |
5452 | struct intel_encoder *encoder; |
5453 | |
5454 | if (!HAS_DISPLAY(dev_priv)((&(dev_priv)->__runtime)->pipe_mask != 0)) |
5455 | return; |
5456 | |
5457 | for_each_intel_encoder(&dev_priv->drm, encoder)for (encoder = ({ const __typeof( ((__typeof(*encoder) *)0)-> base.head ) *__mptr = ((&(&dev_priv->drm)->mode_config .encoder_list)->next); (__typeof(*encoder) *)( (char *)__mptr - __builtin_offsetof(__typeof(*encoder), base.head) );}); & encoder->base.head != (&(&dev_priv->drm)->mode_config .encoder_list); encoder = ({ const __typeof( ((__typeof(*encoder ) *)0)->base.head ) *__mptr = (encoder->base.head.next) ; (__typeof(*encoder) *)( (char *)__mptr - __builtin_offsetof (__typeof(*encoder), base.head) );})) { |
5458 | struct intel_dp *intel_dp; |
5459 | int ret; |
5460 | |
5461 | if (encoder->type != INTEL_OUTPUT_DDI) |
5462 | continue; |
5463 | |
5464 | intel_dp = enc_to_intel_dp(encoder); |
5465 | |
5466 | if (!intel_dp_mst_source_support(intel_dp)) |
5467 | continue; |
5468 | |
5469 | ret = drm_dp_mst_topology_mgr_resume(&intel_dp->mst_mgr, |
5470 | true1); |
5471 | if (ret) { |
5472 | intel_dp->is_mst = false0; |
5473 | drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst_mgr, |
5474 | false0); |
5475 | } |
5476 | } |
5477 | } |