Line data Source code
1 : /*
2 : * Copyright © 2008 Keith Packard
3 : *
4 : * Permission to use, copy, modify, distribute, and sell this software and its
5 : * documentation for any purpose is hereby granted without fee, provided that
6 : * the above copyright notice appear in all copies and that both that copyright
7 : * notice and this permission notice appear in supporting documentation, and
8 : * that the name of the copyright holders not be used in advertising or
9 : * publicity pertaining to distribution of the software without specific,
10 : * written prior permission. The copyright holders make no representations
11 : * about the suitability of this software for any purpose. It is provided "as
12 : * is" without express or implied warranty.
13 : *
14 : * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 : * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 : * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 : * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 : * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 : * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
20 : * OF THIS SOFTWARE.
21 : */
22 :
23 : #ifndef _DRM_DP_HELPER_H_
24 : #define _DRM_DP_HELPER_H_
25 :
26 : #include <linux/delay.h>
27 : #include <linux/i2c.h>
28 :
29 : #include <drm/display/drm_dp.h>
30 : #include <drm/drm_connector.h>
31 :
32 : struct drm_device;
33 : struct drm_dp_aux;
34 : struct drm_panel;
35 :
36 : bool drm_dp_channel_eq_ok(const u8 link_status[DP_LINK_STATUS_SIZE],
37 : int lane_count);
38 : bool drm_dp_clock_recovery_ok(const u8 link_status[DP_LINK_STATUS_SIZE],
39 : int lane_count);
40 : u8 drm_dp_get_adjust_request_voltage(const u8 link_status[DP_LINK_STATUS_SIZE],
41 : int lane);
42 : u8 drm_dp_get_adjust_request_pre_emphasis(const u8 link_status[DP_LINK_STATUS_SIZE],
43 : int lane);
44 : u8 drm_dp_get_adjust_tx_ffe_preset(const u8 link_status[DP_LINK_STATUS_SIZE],
45 : int lane);
46 :
47 : int drm_dp_read_clock_recovery_delay(struct drm_dp_aux *aux, const u8 dpcd[DP_RECEIVER_CAP_SIZE],
48 : enum drm_dp_phy dp_phy, bool uhbr);
49 : int drm_dp_read_channel_eq_delay(struct drm_dp_aux *aux, const u8 dpcd[DP_RECEIVER_CAP_SIZE],
50 : enum drm_dp_phy dp_phy, bool uhbr);
51 :
52 : void drm_dp_link_train_clock_recovery_delay(const struct drm_dp_aux *aux,
53 : const u8 dpcd[DP_RECEIVER_CAP_SIZE]);
54 : void drm_dp_lttpr_link_train_clock_recovery_delay(void);
55 : void drm_dp_link_train_channel_eq_delay(const struct drm_dp_aux *aux,
56 : const u8 dpcd[DP_RECEIVER_CAP_SIZE]);
57 : void drm_dp_lttpr_link_train_channel_eq_delay(const struct drm_dp_aux *aux,
58 : const u8 caps[DP_LTTPR_PHY_CAP_SIZE]);
59 :
60 : int drm_dp_128b132b_read_aux_rd_interval(struct drm_dp_aux *aux);
61 : bool drm_dp_128b132b_lane_channel_eq_done(const u8 link_status[DP_LINK_STATUS_SIZE],
62 : int lane_count);
63 : bool drm_dp_128b132b_lane_symbol_locked(const u8 link_status[DP_LINK_STATUS_SIZE],
64 : int lane_count);
65 : bool drm_dp_128b132b_eq_interlane_align_done(const u8 link_status[DP_LINK_STATUS_SIZE]);
66 : bool drm_dp_128b132b_cds_interlane_align_done(const u8 link_status[DP_LINK_STATUS_SIZE]);
67 : bool drm_dp_128b132b_link_training_failed(const u8 link_status[DP_LINK_STATUS_SIZE]);
68 :
69 : u8 drm_dp_link_rate_to_bw_code(int link_rate);
70 : int drm_dp_bw_code_to_link_rate(u8 link_bw);
71 :
72 : /**
73 : * struct drm_dp_vsc_sdp - drm DP VSC SDP
74 : *
75 : * This structure represents a DP VSC SDP of drm
76 : * It is based on DP 1.4 spec [Table 2-116: VSC SDP Header Bytes] and
77 : * [Table 2-117: VSC SDP Payload for DB16 through DB18]
78 : *
79 : * @sdp_type: secondary-data packet type
80 : * @revision: revision number
81 : * @length: number of valid data bytes
82 : * @pixelformat: pixel encoding format
83 : * @colorimetry: colorimetry format
84 : * @bpc: bit per color
85 : * @dynamic_range: dynamic range information
86 : * @content_type: CTA-861-G defines content types and expected processing by a sink device
87 : */
88 : struct drm_dp_vsc_sdp {
89 : unsigned char sdp_type;
90 : unsigned char revision;
91 : unsigned char length;
92 : enum dp_pixelformat pixelformat;
93 : enum dp_colorimetry colorimetry;
94 : int bpc;
95 : enum dp_dynamic_range dynamic_range;
96 : enum dp_content_type content_type;
97 : };
98 :
99 : void drm_dp_vsc_sdp_log(const char *level, struct device *dev,
100 : const struct drm_dp_vsc_sdp *vsc);
101 :
102 : int drm_dp_psr_setup_time(const u8 psr_cap[EDP_PSR_RECEIVER_CAP_SIZE]);
103 :
104 : static inline int
105 : drm_dp_max_link_rate(const u8 dpcd[DP_RECEIVER_CAP_SIZE])
106 : {
107 0 : return drm_dp_bw_code_to_link_rate(dpcd[DP_MAX_LINK_RATE]);
108 : }
109 :
110 : static inline u8
111 : drm_dp_max_lane_count(const u8 dpcd[DP_RECEIVER_CAP_SIZE])
112 : {
113 0 : return dpcd[DP_MAX_LANE_COUNT] & DP_MAX_LANE_COUNT_MASK;
114 : }
115 :
116 : static inline bool
117 : drm_dp_enhanced_frame_cap(const u8 dpcd[DP_RECEIVER_CAP_SIZE])
118 : {
119 0 : return dpcd[DP_DPCD_REV] >= 0x11 &&
120 0 : (dpcd[DP_MAX_LANE_COUNT] & DP_ENHANCED_FRAME_CAP);
121 : }
122 :
123 : static inline bool
124 : drm_dp_fast_training_cap(const u8 dpcd[DP_RECEIVER_CAP_SIZE])
125 : {
126 : return dpcd[DP_DPCD_REV] >= 0x11 &&
127 : (dpcd[DP_MAX_DOWNSPREAD] & DP_NO_AUX_HANDSHAKE_LINK_TRAINING);
128 : }
129 :
130 : static inline bool
131 : drm_dp_tps3_supported(const u8 dpcd[DP_RECEIVER_CAP_SIZE])
132 : {
133 : return dpcd[DP_DPCD_REV] >= 0x12 &&
134 : dpcd[DP_MAX_LANE_COUNT] & DP_TPS3_SUPPORTED;
135 : }
136 :
137 : static inline bool
138 : drm_dp_max_downspread(const u8 dpcd[DP_RECEIVER_CAP_SIZE])
139 : {
140 : return dpcd[DP_DPCD_REV] >= 0x11 ||
141 : dpcd[DP_MAX_DOWNSPREAD] & DP_MAX_DOWNSPREAD_0_5;
142 : }
143 :
144 : static inline bool
145 : drm_dp_tps4_supported(const u8 dpcd[DP_RECEIVER_CAP_SIZE])
146 : {
147 : return dpcd[DP_DPCD_REV] >= 0x14 &&
148 : dpcd[DP_MAX_DOWNSPREAD] & DP_TPS4_SUPPORTED;
149 : }
150 :
151 : static inline u8
152 : drm_dp_training_pattern_mask(const u8 dpcd[DP_RECEIVER_CAP_SIZE])
153 : {
154 : return (dpcd[DP_DPCD_REV] >= 0x14) ? DP_TRAINING_PATTERN_MASK_1_4 :
155 : DP_TRAINING_PATTERN_MASK;
156 : }
157 :
158 : static inline bool
159 : drm_dp_is_branch(const u8 dpcd[DP_RECEIVER_CAP_SIZE])
160 : {
161 0 : return dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_PRESENT;
162 : }
163 :
164 : /* DP/eDP DSC support */
165 : u8 drm_dp_dsc_sink_max_slice_count(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE],
166 : bool is_edp);
167 : u8 drm_dp_dsc_sink_line_buf_depth(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE]);
168 : int drm_dp_dsc_sink_supported_input_bpcs(const u8 dsc_dpc[DP_DSC_RECEIVER_CAP_SIZE],
169 : u8 dsc_bpc[3]);
170 :
171 : static inline bool
172 : drm_dp_sink_supports_dsc(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE])
173 : {
174 : return dsc_dpcd[DP_DSC_SUPPORT - DP_DSC_SUPPORT] &
175 : DP_DSC_DECOMPRESSION_IS_SUPPORTED;
176 : }
177 :
178 : static inline u16
179 : drm_edp_dsc_sink_output_bpp(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE])
180 : {
181 : return dsc_dpcd[DP_DSC_MAX_BITS_PER_PIXEL_LOW - DP_DSC_SUPPORT] |
182 : (dsc_dpcd[DP_DSC_MAX_BITS_PER_PIXEL_HI - DP_DSC_SUPPORT] &
183 : DP_DSC_MAX_BITS_PER_PIXEL_HI_MASK <<
184 : DP_DSC_MAX_BITS_PER_PIXEL_HI_SHIFT);
185 : }
186 :
187 : static inline u32
188 : drm_dp_dsc_sink_max_slice_width(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE])
189 : {
190 : /* Max Slicewidth = Number of Pixels * 320 */
191 : return dsc_dpcd[DP_DSC_MAX_SLICE_WIDTH - DP_DSC_SUPPORT] *
192 : DP_DSC_SLICE_WIDTH_MULTIPLIER;
193 : }
194 :
195 : /* Forward Error Correction Support on DP 1.4 */
196 : static inline bool
197 : drm_dp_sink_supports_fec(const u8 fec_capable)
198 : {
199 : return fec_capable & DP_FEC_CAPABLE;
200 : }
201 :
202 : static inline bool
203 : drm_dp_channel_coding_supported(const u8 dpcd[DP_RECEIVER_CAP_SIZE])
204 : {
205 : return dpcd[DP_MAIN_LINK_CHANNEL_CODING] & DP_CAP_ANSI_8B10B;
206 : }
207 :
208 : static inline bool
209 : drm_dp_alternate_scrambler_reset_cap(const u8 dpcd[DP_RECEIVER_CAP_SIZE])
210 : {
211 : return dpcd[DP_EDP_CONFIGURATION_CAP] &
212 : DP_ALTERNATE_SCRAMBLER_RESET_CAP;
213 : }
214 :
215 : /* Ignore MSA timing for Adaptive Sync support on DP 1.4 */
216 : static inline bool
217 : drm_dp_sink_can_do_video_without_timing_msa(const u8 dpcd[DP_RECEIVER_CAP_SIZE])
218 : {
219 : return dpcd[DP_DOWN_STREAM_PORT_COUNT] &
220 : DP_MSA_TIMING_PAR_IGNORED;
221 : }
222 :
223 : /**
224 : * drm_edp_backlight_supported() - Check an eDP DPCD for VESA backlight support
225 : * @edp_dpcd: The DPCD to check
226 : *
227 : * Note that currently this function will return %false for panels which support various DPCD
228 : * backlight features but which require the brightness be set through PWM, and don't support setting
229 : * the brightness level via the DPCD.
230 : *
231 : * Returns: %True if @edp_dpcd indicates that VESA backlight controls are supported, %false
232 : * otherwise
233 : */
234 : static inline bool
235 : drm_edp_backlight_supported(const u8 edp_dpcd[EDP_DISPLAY_CTL_CAP_SIZE])
236 : {
237 0 : return !!(edp_dpcd[1] & DP_EDP_TCON_BACKLIGHT_ADJUSTMENT_CAP);
238 : }
239 :
240 : /*
241 : * DisplayPort AUX channel
242 : */
243 :
244 : /**
245 : * struct drm_dp_aux_msg - DisplayPort AUX channel transaction
246 : * @address: address of the (first) register to access
247 : * @request: contains the type of transaction (see DP_AUX_* macros)
248 : * @reply: upon completion, contains the reply type of the transaction
249 : * @buffer: pointer to a transmission or reception buffer
250 : * @size: size of @buffer
251 : */
252 : struct drm_dp_aux_msg {
253 : unsigned int address;
254 : u8 request;
255 : u8 reply;
256 : void *buffer;
257 : size_t size;
258 : };
259 :
260 : struct cec_adapter;
261 : struct edid;
262 : struct drm_connector;
263 :
264 : /**
265 : * struct drm_dp_aux_cec - DisplayPort CEC-Tunneling-over-AUX
266 : * @lock: mutex protecting this struct
267 : * @adap: the CEC adapter for CEC-Tunneling-over-AUX support.
268 : * @connector: the connector this CEC adapter is associated with
269 : * @unregister_work: unregister the CEC adapter
270 : */
271 : struct drm_dp_aux_cec {
272 : struct mutex lock;
273 : struct cec_adapter *adap;
274 : struct drm_connector *connector;
275 : struct delayed_work unregister_work;
276 : };
277 :
278 : /**
279 : * struct drm_dp_aux - DisplayPort AUX channel
280 : *
281 : * An AUX channel can also be used to transport I2C messages to a sink. A
282 : * typical application of that is to access an EDID that's present in the sink
283 : * device. The @transfer() function can also be used to execute such
284 : * transactions. The drm_dp_aux_register() function registers an I2C adapter
285 : * that can be passed to drm_probe_ddc(). Upon removal, drivers should call
286 : * drm_dp_aux_unregister() to remove the I2C adapter. The I2C adapter uses long
287 : * transfers by default; if a partial response is received, the adapter will
288 : * drop down to the size given by the partial response for this transaction
289 : * only.
290 : */
291 : struct drm_dp_aux {
292 : /**
293 : * @name: user-visible name of this AUX channel and the
294 : * I2C-over-AUX adapter.
295 : *
296 : * It's also used to specify the name of the I2C adapter. If set
297 : * to %NULL, dev_name() of @dev will be used.
298 : */
299 : const char *name;
300 :
301 : /**
302 : * @ddc: I2C adapter that can be used for I2C-over-AUX
303 : * communication
304 : */
305 : struct i2c_adapter ddc;
306 :
307 : /**
308 : * @dev: pointer to struct device that is the parent for this
309 : * AUX channel.
310 : */
311 : struct device *dev;
312 :
313 : /**
314 : * @drm_dev: pointer to the &drm_device that owns this AUX channel.
315 : * Beware, this may be %NULL before drm_dp_aux_register() has been
316 : * called.
317 : *
318 : * It should be set to the &drm_device that will be using this AUX
319 : * channel as early as possible. For many graphics drivers this should
320 : * happen before drm_dp_aux_init(), however it's perfectly fine to set
321 : * this field later so long as it's assigned before calling
322 : * drm_dp_aux_register().
323 : */
324 : struct drm_device *drm_dev;
325 :
326 : /**
327 : * @crtc: backpointer to the crtc that is currently using this
328 : * AUX channel
329 : */
330 : struct drm_crtc *crtc;
331 :
332 : /**
333 : * @hw_mutex: internal mutex used for locking transfers.
334 : *
335 : * Note that if the underlying hardware is shared among multiple
336 : * channels, the driver needs to do additional locking to
337 : * prevent concurrent access.
338 : */
339 : struct mutex hw_mutex;
340 :
341 : /**
342 : * @crc_work: worker that captures CRCs for each frame
343 : */
344 : struct work_struct crc_work;
345 :
346 : /**
347 : * @crc_count: counter of captured frame CRCs
348 : */
349 : u8 crc_count;
350 :
351 : /**
352 : * @transfer: transfers a message representing a single AUX
353 : * transaction.
354 : *
355 : * This is a hardware-specific implementation of how
356 : * transactions are executed that the drivers must provide.
357 : *
358 : * A pointer to a &drm_dp_aux_msg structure describing the
359 : * transaction is passed into this function. Upon success, the
360 : * implementation should return the number of payload bytes that
361 : * were transferred, or a negative error-code on failure.
362 : *
363 : * Helpers will propagate these errors, with the exception of
364 : * the %-EBUSY error, which causes a transaction to be retried.
365 : * On a short, helpers will return %-EPROTO to make it simpler
366 : * to check for failure.
367 : *
368 : * The @transfer() function must only modify the reply field of
369 : * the &drm_dp_aux_msg structure. The retry logic and i2c
370 : * helpers assume this is the case.
371 : *
372 : * Also note that this callback can be called no matter the
373 : * state @dev is in. Drivers that need that device to be powered
374 : * to perform this operation will first need to make sure it's
375 : * been properly enabled.
376 : */
377 : ssize_t (*transfer)(struct drm_dp_aux *aux,
378 : struct drm_dp_aux_msg *msg);
379 :
380 : /**
381 : * @i2c_nack_count: Counts I2C NACKs, used for DP validation.
382 : */
383 : unsigned i2c_nack_count;
384 : /**
385 : * @i2c_defer_count: Counts I2C DEFERs, used for DP validation.
386 : */
387 : unsigned i2c_defer_count;
388 : /**
389 : * @cec: struct containing fields used for CEC-Tunneling-over-AUX.
390 : */
391 : struct drm_dp_aux_cec cec;
392 : /**
393 : * @is_remote: Is this AUX CH actually using sideband messaging.
394 : */
395 : bool is_remote;
396 : };
397 :
398 : int drm_dp_dpcd_probe(struct drm_dp_aux *aux, unsigned int offset);
399 : ssize_t drm_dp_dpcd_read(struct drm_dp_aux *aux, unsigned int offset,
400 : void *buffer, size_t size);
401 : ssize_t drm_dp_dpcd_write(struct drm_dp_aux *aux, unsigned int offset,
402 : void *buffer, size_t size);
403 :
404 : /**
405 : * drm_dp_dpcd_readb() - read a single byte from the DPCD
406 : * @aux: DisplayPort AUX channel
407 : * @offset: address of the register to read
408 : * @valuep: location where the value of the register will be stored
409 : *
410 : * Returns the number of bytes transferred (1) on success, or a negative
411 : * error code on failure.
412 : */
413 : static inline ssize_t drm_dp_dpcd_readb(struct drm_dp_aux *aux,
414 : unsigned int offset, u8 *valuep)
415 : {
416 0 : return drm_dp_dpcd_read(aux, offset, valuep, 1);
417 : }
418 :
419 : /**
420 : * drm_dp_dpcd_writeb() - write a single byte to the DPCD
421 : * @aux: DisplayPort AUX channel
422 : * @offset: address of the register to write
423 : * @value: value to write to the register
424 : *
425 : * Returns the number of bytes transferred (1) on success, or a negative
426 : * error code on failure.
427 : */
428 : static inline ssize_t drm_dp_dpcd_writeb(struct drm_dp_aux *aux,
429 : unsigned int offset, u8 value)
430 : {
431 0 : return drm_dp_dpcd_write(aux, offset, &value, 1);
432 : }
433 :
434 : int drm_dp_read_dpcd_caps(struct drm_dp_aux *aux,
435 : u8 dpcd[DP_RECEIVER_CAP_SIZE]);
436 :
437 : int drm_dp_dpcd_read_link_status(struct drm_dp_aux *aux,
438 : u8 status[DP_LINK_STATUS_SIZE]);
439 :
440 : int drm_dp_dpcd_read_phy_link_status(struct drm_dp_aux *aux,
441 : enum drm_dp_phy dp_phy,
442 : u8 link_status[DP_LINK_STATUS_SIZE]);
443 :
444 : bool drm_dp_send_real_edid_checksum(struct drm_dp_aux *aux,
445 : u8 real_edid_checksum);
446 :
447 : int drm_dp_read_downstream_info(struct drm_dp_aux *aux,
448 : const u8 dpcd[DP_RECEIVER_CAP_SIZE],
449 : u8 downstream_ports[DP_MAX_DOWNSTREAM_PORTS]);
450 : bool drm_dp_downstream_is_type(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
451 : const u8 port_cap[4], u8 type);
452 : bool drm_dp_downstream_is_tmds(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
453 : const u8 port_cap[4],
454 : const struct edid *edid);
455 : int drm_dp_downstream_max_dotclock(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
456 : const u8 port_cap[4]);
457 : int drm_dp_downstream_max_tmds_clock(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
458 : const u8 port_cap[4],
459 : const struct edid *edid);
460 : int drm_dp_downstream_min_tmds_clock(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
461 : const u8 port_cap[4],
462 : const struct edid *edid);
463 : int drm_dp_downstream_max_bpc(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
464 : const u8 port_cap[4],
465 : const struct edid *edid);
466 : bool drm_dp_downstream_420_passthrough(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
467 : const u8 port_cap[4]);
468 : bool drm_dp_downstream_444_to_420_conversion(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
469 : const u8 port_cap[4]);
470 : struct drm_display_mode *drm_dp_downstream_mode(struct drm_device *dev,
471 : const u8 dpcd[DP_RECEIVER_CAP_SIZE],
472 : const u8 port_cap[4]);
473 : int drm_dp_downstream_id(struct drm_dp_aux *aux, char id[6]);
474 : void drm_dp_downstream_debug(struct seq_file *m,
475 : const u8 dpcd[DP_RECEIVER_CAP_SIZE],
476 : const u8 port_cap[4],
477 : const struct edid *edid,
478 : struct drm_dp_aux *aux);
479 : enum drm_mode_subconnector
480 : drm_dp_subconnector_type(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
481 : const u8 port_cap[4]);
482 : void drm_dp_set_subconnector_property(struct drm_connector *connector,
483 : enum drm_connector_status status,
484 : const u8 *dpcd,
485 : const u8 port_cap[4]);
486 :
487 : struct drm_dp_desc;
488 : bool drm_dp_read_sink_count_cap(struct drm_connector *connector,
489 : const u8 dpcd[DP_RECEIVER_CAP_SIZE],
490 : const struct drm_dp_desc *desc);
491 : int drm_dp_read_sink_count(struct drm_dp_aux *aux);
492 :
493 : int drm_dp_read_lttpr_common_caps(struct drm_dp_aux *aux,
494 : const u8 dpcd[DP_RECEIVER_CAP_SIZE],
495 : u8 caps[DP_LTTPR_COMMON_CAP_SIZE]);
496 : int drm_dp_read_lttpr_phy_caps(struct drm_dp_aux *aux,
497 : const u8 dpcd[DP_RECEIVER_CAP_SIZE],
498 : enum drm_dp_phy dp_phy,
499 : u8 caps[DP_LTTPR_PHY_CAP_SIZE]);
500 : int drm_dp_lttpr_count(const u8 cap[DP_LTTPR_COMMON_CAP_SIZE]);
501 : int drm_dp_lttpr_max_link_rate(const u8 caps[DP_LTTPR_COMMON_CAP_SIZE]);
502 : int drm_dp_lttpr_max_lane_count(const u8 caps[DP_LTTPR_COMMON_CAP_SIZE]);
503 : bool drm_dp_lttpr_voltage_swing_level_3_supported(const u8 caps[DP_LTTPR_PHY_CAP_SIZE]);
504 : bool drm_dp_lttpr_pre_emphasis_level_3_supported(const u8 caps[DP_LTTPR_PHY_CAP_SIZE]);
505 :
506 : void drm_dp_remote_aux_init(struct drm_dp_aux *aux);
507 : void drm_dp_aux_init(struct drm_dp_aux *aux);
508 : int drm_dp_aux_register(struct drm_dp_aux *aux);
509 : void drm_dp_aux_unregister(struct drm_dp_aux *aux);
510 :
511 : int drm_dp_start_crc(struct drm_dp_aux *aux, struct drm_crtc *crtc);
512 : int drm_dp_stop_crc(struct drm_dp_aux *aux);
513 :
514 : struct drm_dp_dpcd_ident {
515 : u8 oui[3];
516 : u8 device_id[6];
517 : u8 hw_rev;
518 : u8 sw_major_rev;
519 : u8 sw_minor_rev;
520 : } __packed;
521 :
522 : /**
523 : * struct drm_dp_desc - DP branch/sink device descriptor
524 : * @ident: DP device identification from DPCD 0x400 (sink) or 0x500 (branch).
525 : * @quirks: Quirks; use drm_dp_has_quirk() to query for the quirks.
526 : */
527 : struct drm_dp_desc {
528 : struct drm_dp_dpcd_ident ident;
529 : u32 quirks;
530 : };
531 :
532 : int drm_dp_read_desc(struct drm_dp_aux *aux, struct drm_dp_desc *desc,
533 : bool is_branch);
534 :
535 : /**
536 : * enum drm_dp_quirk - Display Port sink/branch device specific quirks
537 : *
538 : * Display Port sink and branch devices in the wild have a variety of bugs, try
539 : * to collect them here. The quirks are shared, but it's up to the drivers to
540 : * implement workarounds for them.
541 : */
542 : enum drm_dp_quirk {
543 : /**
544 : * @DP_DPCD_QUIRK_CONSTANT_N:
545 : *
546 : * The device requires main link attributes Mvid and Nvid to be limited
547 : * to 16 bits. So will give a constant value (0x8000) for compatability.
548 : */
549 : DP_DPCD_QUIRK_CONSTANT_N,
550 : /**
551 : * @DP_DPCD_QUIRK_NO_PSR:
552 : *
553 : * The device does not support PSR even if reports that it supports or
554 : * driver still need to implement proper handling for such device.
555 : */
556 : DP_DPCD_QUIRK_NO_PSR,
557 : /**
558 : * @DP_DPCD_QUIRK_NO_SINK_COUNT:
559 : *
560 : * The device does not set SINK_COUNT to a non-zero value.
561 : * The driver should ignore SINK_COUNT during detection. Note that
562 : * drm_dp_read_sink_count_cap() automatically checks for this quirk.
563 : */
564 : DP_DPCD_QUIRK_NO_SINK_COUNT,
565 : /**
566 : * @DP_DPCD_QUIRK_DSC_WITHOUT_VIRTUAL_DPCD:
567 : *
568 : * The device supports MST DSC despite not supporting Virtual DPCD.
569 : * The DSC caps can be read from the physical aux instead.
570 : */
571 : DP_DPCD_QUIRK_DSC_WITHOUT_VIRTUAL_DPCD,
572 : /**
573 : * @DP_DPCD_QUIRK_CAN_DO_MAX_LINK_RATE_3_24_GBPS:
574 : *
575 : * The device supports a link rate of 3.24 Gbps (multiplier 0xc) despite
576 : * the DP_MAX_LINK_RATE register reporting a lower max multiplier.
577 : */
578 : DP_DPCD_QUIRK_CAN_DO_MAX_LINK_RATE_3_24_GBPS,
579 : };
580 :
581 : /**
582 : * drm_dp_has_quirk() - does the DP device have a specific quirk
583 : * @desc: Device descriptor filled by drm_dp_read_desc()
584 : * @quirk: Quirk to query for
585 : *
586 : * Return true if DP device identified by @desc has @quirk.
587 : */
588 : static inline bool
589 : drm_dp_has_quirk(const struct drm_dp_desc *desc, enum drm_dp_quirk quirk)
590 : {
591 : return desc->quirks & BIT(quirk);
592 : }
593 :
594 : /**
595 : * struct drm_edp_backlight_info - Probed eDP backlight info struct
596 : * @pwmgen_bit_count: The pwmgen bit count
597 : * @pwm_freq_pre_divider: The PWM frequency pre-divider value being used for this backlight, if any
598 : * @max: The maximum backlight level that may be set
599 : * @lsb_reg_used: Do we also write values to the DP_EDP_BACKLIGHT_BRIGHTNESS_LSB register?
600 : * @aux_enable: Does the panel support the AUX enable cap?
601 : * @aux_set: Does the panel support setting the brightness through AUX?
602 : *
603 : * This structure contains various data about an eDP backlight, which can be populated by using
604 : * drm_edp_backlight_init().
605 : */
606 : struct drm_edp_backlight_info {
607 : u8 pwmgen_bit_count;
608 : u8 pwm_freq_pre_divider;
609 : u16 max;
610 :
611 : bool lsb_reg_used : 1;
612 : bool aux_enable : 1;
613 : bool aux_set : 1;
614 : };
615 :
616 : int
617 : drm_edp_backlight_init(struct drm_dp_aux *aux, struct drm_edp_backlight_info *bl,
618 : u16 driver_pwm_freq_hz, const u8 edp_dpcd[EDP_DISPLAY_CTL_CAP_SIZE],
619 : u16 *current_level, u8 *current_mode);
620 : int drm_edp_backlight_set_level(struct drm_dp_aux *aux, const struct drm_edp_backlight_info *bl,
621 : u16 level);
622 : int drm_edp_backlight_enable(struct drm_dp_aux *aux, const struct drm_edp_backlight_info *bl,
623 : u16 level);
624 : int drm_edp_backlight_disable(struct drm_dp_aux *aux, const struct drm_edp_backlight_info *bl);
625 :
626 : #if IS_ENABLED(CONFIG_DRM_KMS_HELPER) && (IS_BUILTIN(CONFIG_BACKLIGHT_CLASS_DEVICE) || \
627 : (IS_MODULE(CONFIG_DRM_KMS_HELPER) && IS_MODULE(CONFIG_BACKLIGHT_CLASS_DEVICE)))
628 :
629 : int drm_panel_dp_aux_backlight(struct drm_panel *panel, struct drm_dp_aux *aux);
630 :
631 : #else
632 :
633 : static inline int drm_panel_dp_aux_backlight(struct drm_panel *panel,
634 : struct drm_dp_aux *aux)
635 : {
636 : return 0;
637 : }
638 :
639 : #endif
640 :
641 : #ifdef CONFIG_DRM_DP_CEC
642 : void drm_dp_cec_irq(struct drm_dp_aux *aux);
643 : void drm_dp_cec_register_connector(struct drm_dp_aux *aux,
644 : struct drm_connector *connector);
645 : void drm_dp_cec_unregister_connector(struct drm_dp_aux *aux);
646 : void drm_dp_cec_set_edid(struct drm_dp_aux *aux, const struct edid *edid);
647 : void drm_dp_cec_unset_edid(struct drm_dp_aux *aux);
648 : #else
649 : static inline void drm_dp_cec_irq(struct drm_dp_aux *aux)
650 : {
651 : }
652 :
653 : static inline void
654 : drm_dp_cec_register_connector(struct drm_dp_aux *aux,
655 : struct drm_connector *connector)
656 : {
657 : }
658 :
659 : static inline void drm_dp_cec_unregister_connector(struct drm_dp_aux *aux)
660 : {
661 : }
662 :
663 : static inline void drm_dp_cec_set_edid(struct drm_dp_aux *aux,
664 : const struct edid *edid)
665 : {
666 : }
667 :
668 : static inline void drm_dp_cec_unset_edid(struct drm_dp_aux *aux)
669 : {
670 : }
671 :
672 : #endif
673 :
674 : /**
675 : * struct drm_dp_phy_test_params - DP Phy Compliance parameters
676 : * @link_rate: Requested Link rate from DPCD 0x219
677 : * @num_lanes: Number of lanes requested by sing through DPCD 0x220
678 : * @phy_pattern: DP Phy test pattern from DPCD 0x248
679 : * @hbr2_reset: DP HBR2_COMPLIANCE_SCRAMBLER_RESET from DCPD 0x24A and 0x24B
680 : * @custom80: DP Test_80BIT_CUSTOM_PATTERN from DPCDs 0x250 through 0x259
681 : * @enhanced_frame_cap: flag for enhanced frame capability.
682 : */
683 : struct drm_dp_phy_test_params {
684 : int link_rate;
685 : u8 num_lanes;
686 : u8 phy_pattern;
687 : u8 hbr2_reset[2];
688 : u8 custom80[10];
689 : bool enhanced_frame_cap;
690 : };
691 :
692 : int drm_dp_get_phy_test_pattern(struct drm_dp_aux *aux,
693 : struct drm_dp_phy_test_params *data);
694 : int drm_dp_set_phy_test_pattern(struct drm_dp_aux *aux,
695 : struct drm_dp_phy_test_params *data, u8 dp_rev);
696 : int drm_dp_get_pcon_max_frl_bw(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
697 : const u8 port_cap[4]);
698 : int drm_dp_pcon_frl_prepare(struct drm_dp_aux *aux, bool enable_frl_ready_hpd);
699 : bool drm_dp_pcon_is_frl_ready(struct drm_dp_aux *aux);
700 : int drm_dp_pcon_frl_configure_1(struct drm_dp_aux *aux, int max_frl_gbps,
701 : u8 frl_mode);
702 : int drm_dp_pcon_frl_configure_2(struct drm_dp_aux *aux, int max_frl_mask,
703 : u8 frl_type);
704 : int drm_dp_pcon_reset_frl_config(struct drm_dp_aux *aux);
705 : int drm_dp_pcon_frl_enable(struct drm_dp_aux *aux);
706 :
707 : bool drm_dp_pcon_hdmi_link_active(struct drm_dp_aux *aux);
708 : int drm_dp_pcon_hdmi_link_mode(struct drm_dp_aux *aux, u8 *frl_trained_mask);
709 : void drm_dp_pcon_hdmi_frl_link_error_count(struct drm_dp_aux *aux,
710 : struct drm_connector *connector);
711 : bool drm_dp_pcon_enc_is_dsc_1_2(const u8 pcon_dsc_dpcd[DP_PCON_DSC_ENCODER_CAP_SIZE]);
712 : int drm_dp_pcon_dsc_max_slices(const u8 pcon_dsc_dpcd[DP_PCON_DSC_ENCODER_CAP_SIZE]);
713 : int drm_dp_pcon_dsc_max_slice_width(const u8 pcon_dsc_dpcd[DP_PCON_DSC_ENCODER_CAP_SIZE]);
714 : int drm_dp_pcon_dsc_bpp_incr(const u8 pcon_dsc_dpcd[DP_PCON_DSC_ENCODER_CAP_SIZE]);
715 : int drm_dp_pcon_pps_default(struct drm_dp_aux *aux);
716 : int drm_dp_pcon_pps_override_buf(struct drm_dp_aux *aux, u8 pps_buf[128]);
717 : int drm_dp_pcon_pps_override_param(struct drm_dp_aux *aux, u8 pps_param[6]);
718 : bool drm_dp_downstream_rgb_to_ycbcr_conversion(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
719 : const u8 port_cap[4], u8 color_spc);
720 : int drm_dp_pcon_convert_rgb_to_ycbcr(struct drm_dp_aux *aux, u8 color_spc);
721 :
722 : #endif /* _DRM_DP_HELPER_H_ */
|