Line data Source code
1 : /*
2 : * Copyright © 2009 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 : #ifdef __linux__
24 : #include <linux/kernel.h>
25 : #include <linux/module.h>
26 : #include <linux/delay.h>
27 : #include <linux/init.h>
28 : #include <linux/errno.h>
29 : #include <linux/sched.h>
30 : #include <linux/i2c.h>
31 : #include <drm/drm_dp_helper.h>
32 : #include <drm/drmP.h>
33 : #else
34 : #include <dev/pci/drm/drm_dp_helper.h>
35 : #include <dev/pci/drm/drmP.h>
36 : #endif
37 :
38 : /**
39 : * DOC: dp helpers
40 : *
41 : * These functions contain some common logic and helpers at various abstraction
42 : * levels to deal with Display Port sink devices and related things like DP aux
43 : * channel transfers, EDID reading over DP aux channels, decoding certain DPCD
44 : * blocks, ...
45 : */
46 :
47 : /* Helpers for DP link training */
48 0 : static u8 dp_link_status(const u8 link_status[DP_LINK_STATUS_SIZE], int r)
49 : {
50 0 : return link_status[r - DP_LANE0_1_STATUS];
51 : }
52 :
53 0 : static u8 dp_get_lane_status(const u8 link_status[DP_LINK_STATUS_SIZE],
54 : int lane)
55 : {
56 0 : int i = DP_LANE0_1_STATUS + (lane >> 1);
57 0 : int s = (lane & 1) * 4;
58 0 : u8 l = dp_link_status(link_status, i);
59 0 : return (l >> s) & 0xf;
60 : }
61 :
62 0 : bool drm_dp_channel_eq_ok(const u8 link_status[DP_LINK_STATUS_SIZE],
63 : int lane_count)
64 : {
65 : u8 lane_align;
66 : u8 lane_status;
67 : int lane;
68 :
69 0 : lane_align = dp_link_status(link_status,
70 : DP_LANE_ALIGN_STATUS_UPDATED);
71 0 : if ((lane_align & DP_INTERLANE_ALIGN_DONE) == 0)
72 0 : return false;
73 0 : for (lane = 0; lane < lane_count; lane++) {
74 0 : lane_status = dp_get_lane_status(link_status, lane);
75 0 : if ((lane_status & DP_CHANNEL_EQ_BITS) != DP_CHANNEL_EQ_BITS)
76 0 : return false;
77 : }
78 0 : return true;
79 0 : }
80 : EXPORT_SYMBOL(drm_dp_channel_eq_ok);
81 :
82 0 : bool drm_dp_clock_recovery_ok(const u8 link_status[DP_LINK_STATUS_SIZE],
83 : int lane_count)
84 : {
85 : int lane;
86 : u8 lane_status;
87 :
88 0 : for (lane = 0; lane < lane_count; lane++) {
89 0 : lane_status = dp_get_lane_status(link_status, lane);
90 0 : if ((lane_status & DP_LANE_CR_DONE) == 0)
91 0 : return false;
92 : }
93 0 : return true;
94 0 : }
95 : EXPORT_SYMBOL(drm_dp_clock_recovery_ok);
96 :
97 0 : u8 drm_dp_get_adjust_request_voltage(const u8 link_status[DP_LINK_STATUS_SIZE],
98 : int lane)
99 : {
100 0 : int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1);
101 0 : int s = ((lane & 1) ?
102 : DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT :
103 : DP_ADJUST_VOLTAGE_SWING_LANE0_SHIFT);
104 0 : u8 l = dp_link_status(link_status, i);
105 :
106 0 : return ((l >> s) & 0x3) << DP_TRAIN_VOLTAGE_SWING_SHIFT;
107 : }
108 : EXPORT_SYMBOL(drm_dp_get_adjust_request_voltage);
109 :
110 0 : u8 drm_dp_get_adjust_request_pre_emphasis(const u8 link_status[DP_LINK_STATUS_SIZE],
111 : int lane)
112 : {
113 0 : int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1);
114 0 : int s = ((lane & 1) ?
115 : DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT :
116 : DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT);
117 0 : u8 l = dp_link_status(link_status, i);
118 :
119 0 : return ((l >> s) & 0x3) << DP_TRAIN_PRE_EMPHASIS_SHIFT;
120 : }
121 : EXPORT_SYMBOL(drm_dp_get_adjust_request_pre_emphasis);
122 :
123 0 : void drm_dp_link_train_clock_recovery_delay(const u8 dpcd[DP_RECEIVER_CAP_SIZE]) {
124 0 : if (dpcd[DP_TRAINING_AUX_RD_INTERVAL] == 0)
125 0 : udelay(100);
126 : else
127 0 : mdelay(dpcd[DP_TRAINING_AUX_RD_INTERVAL] * 4);
128 0 : }
129 : EXPORT_SYMBOL(drm_dp_link_train_clock_recovery_delay);
130 :
131 0 : void drm_dp_link_train_channel_eq_delay(const u8 dpcd[DP_RECEIVER_CAP_SIZE]) {
132 0 : if (dpcd[DP_TRAINING_AUX_RD_INTERVAL] == 0)
133 0 : udelay(400);
134 : else
135 0 : mdelay(dpcd[DP_TRAINING_AUX_RD_INTERVAL] * 4);
136 0 : }
137 : EXPORT_SYMBOL(drm_dp_link_train_channel_eq_delay);
138 :
139 0 : u8 drm_dp_link_rate_to_bw_code(int link_rate)
140 : {
141 0 : switch (link_rate) {
142 : case 162000:
143 : default:
144 0 : return DP_LINK_BW_1_62;
145 : case 270000:
146 0 : return DP_LINK_BW_2_7;
147 : case 540000:
148 0 : return DP_LINK_BW_5_4;
149 : }
150 0 : }
151 : EXPORT_SYMBOL(drm_dp_link_rate_to_bw_code);
152 :
153 0 : int drm_dp_bw_code_to_link_rate(u8 link_bw)
154 : {
155 0 : switch (link_bw) {
156 : case DP_LINK_BW_1_62:
157 : default:
158 0 : return 162000;
159 : case DP_LINK_BW_2_7:
160 0 : return 270000;
161 : case DP_LINK_BW_5_4:
162 0 : return 540000;
163 : }
164 0 : }
165 : EXPORT_SYMBOL(drm_dp_bw_code_to_link_rate);
166 :
167 : #define AUX_RETRY_INTERVAL 500 /* us */
168 :
169 : /**
170 : * DOC: dp helpers
171 : *
172 : * The DisplayPort AUX channel is an abstraction to allow generic, driver-
173 : * independent access to AUX functionality. Drivers can take advantage of
174 : * this by filling in the fields of the drm_dp_aux structure.
175 : *
176 : * Transactions are described using a hardware-independent drm_dp_aux_msg
177 : * structure, which is passed into a driver's .transfer() implementation.
178 : * Both native and I2C-over-AUX transactions are supported.
179 : */
180 :
181 0 : static int drm_dp_dpcd_access(struct drm_dp_aux *aux, u8 request,
182 : unsigned int offset, void *buffer, size_t size)
183 : {
184 0 : struct drm_dp_aux_msg msg;
185 : unsigned int retry;
186 : int err = 0;
187 :
188 0 : memset(&msg, 0, sizeof(msg));
189 0 : msg.address = offset;
190 0 : msg.request = request;
191 0 : msg.buffer = buffer;
192 0 : msg.size = size;
193 :
194 0 : mutex_lock(&aux->hw_mutex);
195 :
196 : /*
197 : * The specification doesn't give any recommendation on how often to
198 : * retry native transactions. We used to retry 7 times like for
199 : * aux i2c transactions but real world devices this wasn't
200 : * sufficient, bump to 32 which makes Dell 4k monitors happier.
201 : */
202 0 : for (retry = 0; retry < 32; retry++) {
203 :
204 0 : err = aux->transfer(aux, &msg);
205 0 : if (err < 0) {
206 0 : if (err == -EBUSY)
207 : continue;
208 :
209 : goto unlock;
210 : }
211 :
212 :
213 0 : switch (msg.reply & DP_AUX_NATIVE_REPLY_MASK) {
214 : case DP_AUX_NATIVE_REPLY_ACK:
215 0 : if (err < size)
216 0 : err = -EPROTO;
217 : goto unlock;
218 :
219 : case DP_AUX_NATIVE_REPLY_NACK:
220 : err = -EIO;
221 0 : goto unlock;
222 :
223 : case DP_AUX_NATIVE_REPLY_DEFER:
224 0 : usleep_range(AUX_RETRY_INTERVAL, AUX_RETRY_INTERVAL + 100);
225 0 : break;
226 : }
227 : }
228 :
229 : DRM_DEBUG_KMS("too many retries, giving up\n");
230 0 : err = -EIO;
231 :
232 : unlock:
233 0 : mutex_unlock(&aux->hw_mutex);
234 0 : return err;
235 0 : }
236 :
237 : /**
238 : * drm_dp_dpcd_read() - read a series of bytes from the DPCD
239 : * @aux: DisplayPort AUX channel
240 : * @offset: address of the (first) register to read
241 : * @buffer: buffer to store the register values
242 : * @size: number of bytes in @buffer
243 : *
244 : * Returns the number of bytes transferred on success, or a negative error
245 : * code on failure. -EIO is returned if the request was NAKed by the sink or
246 : * if the retry count was exceeded. If not all bytes were transferred, this
247 : * function returns -EPROTO. Errors from the underlying AUX channel transfer
248 : * function, with the exception of -EBUSY (which causes the transaction to
249 : * be retried), are propagated to the caller.
250 : */
251 0 : ssize_t drm_dp_dpcd_read(struct drm_dp_aux *aux, unsigned int offset,
252 : void *buffer, size_t size)
253 : {
254 0 : return drm_dp_dpcd_access(aux, DP_AUX_NATIVE_READ, offset, buffer,
255 : size);
256 : }
257 : EXPORT_SYMBOL(drm_dp_dpcd_read);
258 :
259 : /**
260 : * drm_dp_dpcd_write() - write a series of bytes to the DPCD
261 : * @aux: DisplayPort AUX channel
262 : * @offset: address of the (first) register to write
263 : * @buffer: buffer containing the values to write
264 : * @size: number of bytes in @buffer
265 : *
266 : * Returns the number of bytes transferred on success, or a negative error
267 : * code on failure. -EIO is returned if the request was NAKed by the sink or
268 : * if the retry count was exceeded. If not all bytes were transferred, this
269 : * function returns -EPROTO. Errors from the underlying AUX channel transfer
270 : * function, with the exception of -EBUSY (which causes the transaction to
271 : * be retried), are propagated to the caller.
272 : */
273 0 : ssize_t drm_dp_dpcd_write(struct drm_dp_aux *aux, unsigned int offset,
274 : void *buffer, size_t size)
275 : {
276 0 : return drm_dp_dpcd_access(aux, DP_AUX_NATIVE_WRITE, offset, buffer,
277 : size);
278 : }
279 : EXPORT_SYMBOL(drm_dp_dpcd_write);
280 :
281 : /**
282 : * drm_dp_dpcd_read_link_status() - read DPCD link status (bytes 0x202-0x207)
283 : * @aux: DisplayPort AUX channel
284 : * @status: buffer to store the link status in (must be at least 6 bytes)
285 : *
286 : * Returns the number of bytes transferred on success or a negative error
287 : * code on failure.
288 : */
289 0 : int drm_dp_dpcd_read_link_status(struct drm_dp_aux *aux,
290 : u8 status[DP_LINK_STATUS_SIZE])
291 : {
292 0 : return drm_dp_dpcd_read(aux, DP_LANE0_1_STATUS, status,
293 : DP_LINK_STATUS_SIZE);
294 : }
295 : EXPORT_SYMBOL(drm_dp_dpcd_read_link_status);
296 :
297 : /**
298 : * drm_dp_link_probe() - probe a DisplayPort link for capabilities
299 : * @aux: DisplayPort AUX channel
300 : * @link: pointer to structure in which to return link capabilities
301 : *
302 : * The structure filled in by this function can usually be passed directly
303 : * into drm_dp_link_power_up() and drm_dp_link_configure() to power up and
304 : * configure the link based on the link's capabilities.
305 : *
306 : * Returns 0 on success or a negative error code on failure.
307 : */
308 0 : int drm_dp_link_probe(struct drm_dp_aux *aux, struct drm_dp_link *link)
309 : {
310 0 : u8 values[3];
311 : int err;
312 :
313 0 : memset(link, 0, sizeof(*link));
314 :
315 0 : err = drm_dp_dpcd_read(aux, DP_DPCD_REV, values, sizeof(values));
316 0 : if (err < 0)
317 0 : return err;
318 :
319 0 : link->revision = values[0];
320 0 : link->rate = drm_dp_bw_code_to_link_rate(values[1]);
321 0 : link->num_lanes = values[2] & DP_MAX_LANE_COUNT_MASK;
322 :
323 0 : if (values[2] & DP_ENHANCED_FRAME_CAP)
324 0 : link->capabilities |= DP_LINK_CAP_ENHANCED_FRAMING;
325 :
326 0 : return 0;
327 0 : }
328 : EXPORT_SYMBOL(drm_dp_link_probe);
329 :
330 : /**
331 : * drm_dp_link_power_up() - power up a DisplayPort link
332 : * @aux: DisplayPort AUX channel
333 : * @link: pointer to a structure containing the link configuration
334 : *
335 : * Returns 0 on success or a negative error code on failure.
336 : */
337 0 : int drm_dp_link_power_up(struct drm_dp_aux *aux, struct drm_dp_link *link)
338 : {
339 0 : u8 value;
340 : int err;
341 :
342 : /* DP_SET_POWER register is only available on DPCD v1.1 and later */
343 0 : if (link->revision < 0x11)
344 0 : return 0;
345 :
346 0 : err = drm_dp_dpcd_readb(aux, DP_SET_POWER, &value);
347 0 : if (err < 0)
348 0 : return err;
349 :
350 0 : value &= ~DP_SET_POWER_MASK;
351 0 : value |= DP_SET_POWER_D0;
352 :
353 0 : err = drm_dp_dpcd_writeb(aux, DP_SET_POWER, value);
354 0 : if (err < 0)
355 0 : return err;
356 :
357 : /*
358 : * According to the DP 1.1 specification, a "Sink Device must exit the
359 : * power saving state within 1 ms" (Section 2.5.3.1, Table 5-52, "Sink
360 : * Control Field" (register 0x600).
361 : */
362 0 : usleep_range(1000, 2000);
363 :
364 0 : return 0;
365 0 : }
366 : EXPORT_SYMBOL(drm_dp_link_power_up);
367 :
368 : /**
369 : * drm_dp_link_power_down() - power down a DisplayPort link
370 : * @aux: DisplayPort AUX channel
371 : * @link: pointer to a structure containing the link configuration
372 : *
373 : * Returns 0 on success or a negative error code on failure.
374 : */
375 0 : int drm_dp_link_power_down(struct drm_dp_aux *aux, struct drm_dp_link *link)
376 : {
377 0 : u8 value;
378 : int err;
379 :
380 : /* DP_SET_POWER register is only available on DPCD v1.1 and later */
381 0 : if (link->revision < 0x11)
382 0 : return 0;
383 :
384 0 : err = drm_dp_dpcd_readb(aux, DP_SET_POWER, &value);
385 0 : if (err < 0)
386 0 : return err;
387 :
388 0 : value &= ~DP_SET_POWER_MASK;
389 0 : value |= DP_SET_POWER_D3;
390 :
391 0 : err = drm_dp_dpcd_writeb(aux, DP_SET_POWER, value);
392 0 : if (err < 0)
393 0 : return err;
394 :
395 0 : return 0;
396 0 : }
397 : EXPORT_SYMBOL(drm_dp_link_power_down);
398 :
399 : /**
400 : * drm_dp_link_configure() - configure a DisplayPort link
401 : * @aux: DisplayPort AUX channel
402 : * @link: pointer to a structure containing the link configuration
403 : *
404 : * Returns 0 on success or a negative error code on failure.
405 : */
406 0 : int drm_dp_link_configure(struct drm_dp_aux *aux, struct drm_dp_link *link)
407 : {
408 0 : u8 values[2];
409 : int err;
410 :
411 0 : values[0] = drm_dp_link_rate_to_bw_code(link->rate);
412 0 : values[1] = link->num_lanes;
413 :
414 0 : if (link->capabilities & DP_LINK_CAP_ENHANCED_FRAMING)
415 0 : values[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
416 :
417 0 : err = drm_dp_dpcd_write(aux, DP_LINK_BW_SET, values, sizeof(values));
418 0 : if (err < 0)
419 0 : return err;
420 :
421 0 : return 0;
422 0 : }
423 : EXPORT_SYMBOL(drm_dp_link_configure);
424 :
425 : /*
426 : * I2C-over-AUX implementation
427 : */
428 :
429 0 : static u32 drm_dp_i2c_functionality(struct i2c_adapter *adapter)
430 : {
431 0 : return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL |
432 : I2C_FUNC_SMBUS_READ_BLOCK_DATA |
433 : I2C_FUNC_SMBUS_BLOCK_PROC_CALL |
434 : I2C_FUNC_10BIT_ADDR;
435 : }
436 :
437 0 : static void drm_dp_i2c_msg_write_status_update(struct drm_dp_aux_msg *msg)
438 : {
439 : /*
440 : * In case of i2c defer or short i2c ack reply to a write,
441 : * we need to switch to WRITE_STATUS_UPDATE to drain the
442 : * rest of the message
443 : */
444 0 : if ((msg->request & ~DP_AUX_I2C_MOT) == DP_AUX_I2C_WRITE) {
445 0 : msg->request &= DP_AUX_I2C_MOT;
446 0 : msg->request |= DP_AUX_I2C_WRITE_STATUS_UPDATE;
447 0 : }
448 0 : }
449 :
450 : #define AUX_PRECHARGE_LEN 10 /* 10 to 16 */
451 : #define AUX_SYNC_LEN (16 + 4) /* preamble + AUX_SYNC_END */
452 : #define AUX_STOP_LEN 4
453 : #define AUX_CMD_LEN 4
454 : #define AUX_ADDRESS_LEN 20
455 : #define AUX_REPLY_PAD_LEN 4
456 : #define AUX_LENGTH_LEN 8
457 :
458 : /*
459 : * Calculate the duration of the AUX request/reply in usec. Gives the
460 : * "best" case estimate, ie. successful while as short as possible.
461 : */
462 0 : static int drm_dp_aux_req_duration(const struct drm_dp_aux_msg *msg)
463 : {
464 : int len = AUX_PRECHARGE_LEN + AUX_SYNC_LEN + AUX_STOP_LEN +
465 : AUX_CMD_LEN + AUX_ADDRESS_LEN + AUX_LENGTH_LEN;
466 :
467 0 : if ((msg->request & DP_AUX_I2C_READ) == 0)
468 0 : len += msg->size * 8;
469 :
470 0 : return len;
471 : }
472 :
473 0 : static int drm_dp_aux_reply_duration(const struct drm_dp_aux_msg *msg)
474 : {
475 : int len = AUX_PRECHARGE_LEN + AUX_SYNC_LEN + AUX_STOP_LEN +
476 : AUX_CMD_LEN + AUX_REPLY_PAD_LEN;
477 :
478 : /*
479 : * For read we expect what was asked. For writes there will
480 : * be 0 or 1 data bytes. Assume 0 for the "best" case.
481 : */
482 0 : if (msg->request & DP_AUX_I2C_READ)
483 0 : len += msg->size * 8;
484 :
485 0 : return len;
486 : }
487 :
488 : #define I2C_START_LEN 1
489 : #define I2C_STOP_LEN 1
490 : #define I2C_ADDR_LEN 9 /* ADDRESS + R/W + ACK/NACK */
491 : #define I2C_DATA_LEN 9 /* DATA + ACK/NACK */
492 :
493 : /*
494 : * Calculate the length of the i2c transfer in usec, assuming
495 : * the i2c bus speed is as specified. Gives the the "worst"
496 : * case estimate, ie. successful while as long as possible.
497 : * Doesn't account the the "MOT" bit, and instead assumes each
498 : * message includes a START, ADDRESS and STOP. Neither does it
499 : * account for additional random variables such as clock stretching.
500 : */
501 0 : static int drm_dp_i2c_msg_duration(const struct drm_dp_aux_msg *msg,
502 : int i2c_speed_khz)
503 : {
504 : /* AUX bitrate is 1MHz, i2c bitrate as specified */
505 0 : return DIV_ROUND_UP((I2C_START_LEN + I2C_ADDR_LEN +
506 : msg->size * I2C_DATA_LEN +
507 : I2C_STOP_LEN) * 1000, i2c_speed_khz);
508 : }
509 :
510 : /*
511 : * Deterine how many retries should be attempted to successfully transfer
512 : * the specified message, based on the estimated durations of the
513 : * i2c and AUX transfers.
514 : */
515 0 : static int drm_dp_i2c_retry_count(const struct drm_dp_aux_msg *msg,
516 : int i2c_speed_khz)
517 : {
518 0 : int aux_time_us = drm_dp_aux_req_duration(msg) +
519 0 : drm_dp_aux_reply_duration(msg);
520 0 : int i2c_time_us = drm_dp_i2c_msg_duration(msg, i2c_speed_khz);
521 :
522 0 : return DIV_ROUND_UP(i2c_time_us, aux_time_us + AUX_RETRY_INTERVAL);
523 : }
524 :
525 : /*
526 : * FIXME currently assumes 10 kHz as some real world devices seem
527 : * to require it. We should query/set the speed via DPCD if supported.
528 : */
529 : static int dp_aux_i2c_speed_khz __read_mostly = 10;
530 : module_param_unsafe(dp_aux_i2c_speed_khz, int, 0644);
531 : MODULE_PARM_DESC(dp_aux_i2c_speed_khz,
532 : "Assumed speed of the i2c bus in kHz, (1-400, default 10)");
533 :
534 : /*
535 : * Transfer a single I2C-over-AUX message and handle various error conditions,
536 : * retrying the transaction as appropriate. It is assumed that the
537 : * aux->transfer function does not modify anything in the msg other than the
538 : * reply field.
539 : *
540 : * Returns bytes transferred on success, or a negative error code on failure.
541 : */
542 0 : static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
543 : {
544 : unsigned int retry, defer_i2c;
545 : int ret;
546 : /*
547 : * DP1.2 sections 2.7.7.1.5.6.1 and 2.7.7.1.6.6.1: A DP Source device
548 : * is required to retry at least seven times upon receiving AUX_DEFER
549 : * before giving up the AUX transaction.
550 : *
551 : * We also try to account for the i2c bus speed.
552 : */
553 0 : int max_retries = max(7, drm_dp_i2c_retry_count(msg, dp_aux_i2c_speed_khz));
554 :
555 0 : for (retry = 0, defer_i2c = 0; retry < (max_retries + defer_i2c); retry++) {
556 0 : ret = aux->transfer(aux, msg);
557 0 : if (ret < 0) {
558 0 : if (ret == -EBUSY)
559 : continue;
560 :
561 : DRM_DEBUG_KMS("transaction failed: %d\n", ret);
562 0 : return ret;
563 : }
564 :
565 :
566 0 : switch (msg->reply & DP_AUX_NATIVE_REPLY_MASK) {
567 : case DP_AUX_NATIVE_REPLY_ACK:
568 : /*
569 : * For I2C-over-AUX transactions this isn't enough, we
570 : * need to check for the I2C ACK reply.
571 : */
572 : break;
573 :
574 : case DP_AUX_NATIVE_REPLY_NACK:
575 : DRM_DEBUG_KMS("native nack (result=%d, size=%zu)\n", ret, msg->size);
576 0 : return -EREMOTEIO;
577 :
578 : case DP_AUX_NATIVE_REPLY_DEFER:
579 : DRM_DEBUG_KMS("native defer\n");
580 : /*
581 : * We could check for I2C bit rate capabilities and if
582 : * available adjust this interval. We could also be
583 : * more careful with DP-to-legacy adapters where a
584 : * long legacy cable may force very low I2C bit rates.
585 : *
586 : * For now just defer for long enough to hopefully be
587 : * safe for all use-cases.
588 : */
589 0 : usleep_range(AUX_RETRY_INTERVAL, AUX_RETRY_INTERVAL + 100);
590 0 : continue;
591 :
592 : default:
593 0 : DRM_ERROR("invalid native reply %#04x\n", msg->reply);
594 0 : return -EREMOTEIO;
595 : }
596 :
597 0 : switch (msg->reply & DP_AUX_I2C_REPLY_MASK) {
598 : case DP_AUX_I2C_REPLY_ACK:
599 : /*
600 : * Both native ACK and I2C ACK replies received. We
601 : * can assume the transfer was successful.
602 : */
603 0 : if (ret != msg->size)
604 0 : drm_dp_i2c_msg_write_status_update(msg);
605 0 : return ret;
606 :
607 : case DP_AUX_I2C_REPLY_NACK:
608 : DRM_DEBUG_KMS("I2C nack (result=%d, size=%zu\n", ret, msg->size);
609 0 : aux->i2c_nack_count++;
610 0 : return -EREMOTEIO;
611 :
612 : case DP_AUX_I2C_REPLY_DEFER:
613 : DRM_DEBUG_KMS("I2C defer\n");
614 : /* DP Compliance Test 4.2.2.5 Requirement:
615 : * Must have at least 7 retries for I2C defers on the
616 : * transaction to pass this test
617 : */
618 0 : aux->i2c_defer_count++;
619 0 : if (defer_i2c < 7)
620 0 : defer_i2c++;
621 0 : usleep_range(AUX_RETRY_INTERVAL, AUX_RETRY_INTERVAL + 100);
622 0 : drm_dp_i2c_msg_write_status_update(msg);
623 :
624 0 : continue;
625 :
626 : default:
627 0 : DRM_ERROR("invalid I2C reply %#04x\n", msg->reply);
628 0 : return -EREMOTEIO;
629 : }
630 : }
631 :
632 : DRM_DEBUG_KMS("too many retries, giving up\n");
633 0 : return -EREMOTEIO;
634 0 : }
635 :
636 0 : static void drm_dp_i2c_msg_set_request(struct drm_dp_aux_msg *msg,
637 : const struct i2c_msg *i2c_msg)
638 : {
639 0 : msg->request = (i2c_msg->flags & I2C_M_RD) ?
640 : DP_AUX_I2C_READ : DP_AUX_I2C_WRITE;
641 0 : msg->request |= DP_AUX_I2C_MOT;
642 0 : }
643 :
644 : /*
645 : * Keep retrying drm_dp_i2c_do_msg until all data has been transferred.
646 : *
647 : * Returns an error code on failure, or a recommended transfer size on success.
648 : */
649 0 : static int drm_dp_i2c_drain_msg(struct drm_dp_aux *aux, struct drm_dp_aux_msg *orig_msg)
650 : {
651 0 : int err, ret = orig_msg->size;
652 0 : struct drm_dp_aux_msg msg = *orig_msg;
653 :
654 0 : while (msg.size > 0) {
655 0 : err = drm_dp_i2c_do_msg(aux, &msg);
656 0 : if (err <= 0)
657 0 : return err == 0 ? -EPROTO : err;
658 :
659 0 : if (err < msg.size && err < ret) {
660 : DRM_DEBUG_KMS("Partial I2C reply: requested %zu bytes got %d bytes\n",
661 : msg.size, err);
662 : ret = err;
663 0 : }
664 :
665 0 : msg.size -= err;
666 0 : msg.buffer += err;
667 : }
668 :
669 0 : return ret;
670 0 : }
671 :
672 : /*
673 : * Bizlink designed DP->DVI-D Dual Link adapters require the I2C over AUX
674 : * packets to be as large as possible. If not, the I2C transactions never
675 : * succeed. Hence the default is maximum.
676 : */
677 : static int dp_aux_i2c_transfer_size __read_mostly = DP_AUX_MAX_PAYLOAD_BYTES;
678 : module_param_unsafe(dp_aux_i2c_transfer_size, int, 0644);
679 : MODULE_PARM_DESC(dp_aux_i2c_transfer_size,
680 : "Number of bytes to transfer in a single I2C over DP AUX CH message, (1-16, default 16)");
681 :
682 0 : static int drm_dp_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs,
683 : int num)
684 : {
685 0 : struct drm_dp_aux *aux = adapter->algo_data;
686 : unsigned int i, j;
687 : unsigned transfer_size;
688 0 : struct drm_dp_aux_msg msg;
689 : int err = 0;
690 :
691 0 : dp_aux_i2c_transfer_size = clamp(dp_aux_i2c_transfer_size, 1, DP_AUX_MAX_PAYLOAD_BYTES);
692 :
693 0 : memset(&msg, 0, sizeof(msg));
694 :
695 0 : mutex_lock(&aux->hw_mutex);
696 :
697 0 : for (i = 0; i < num; i++) {
698 0 : msg.address = msgs[i].addr;
699 0 : drm_dp_i2c_msg_set_request(&msg, &msgs[i]);
700 : /* Send a bare address packet to start the transaction.
701 : * Zero sized messages specify an address only (bare
702 : * address) transaction.
703 : */
704 0 : msg.buffer = NULL;
705 0 : msg.size = 0;
706 0 : err = drm_dp_i2c_do_msg(aux, &msg);
707 :
708 : /*
709 : * Reset msg.request in case in case it got
710 : * changed into a WRITE_STATUS_UPDATE.
711 : */
712 0 : drm_dp_i2c_msg_set_request(&msg, &msgs[i]);
713 :
714 0 : if (err < 0)
715 : break;
716 : /* We want each transaction to be as large as possible, but
717 : * we'll go to smaller sizes if the hardware gives us a
718 : * short reply.
719 : */
720 0 : transfer_size = dp_aux_i2c_transfer_size;
721 0 : for (j = 0; j < msgs[i].len; j += msg.size) {
722 0 : msg.buffer = msgs[i].buf + j;
723 0 : msg.size = min(transfer_size, msgs[i].len - j);
724 :
725 0 : err = drm_dp_i2c_drain_msg(aux, &msg);
726 :
727 : /*
728 : * Reset msg.request in case in case it got
729 : * changed into a WRITE_STATUS_UPDATE.
730 : */
731 0 : drm_dp_i2c_msg_set_request(&msg, &msgs[i]);
732 :
733 0 : if (err < 0)
734 : break;
735 : transfer_size = err;
736 : }
737 0 : if (err < 0)
738 : break;
739 : }
740 0 : if (err >= 0)
741 0 : err = num;
742 : /* Send a bare address packet to close out the transaction.
743 : * Zero sized messages specify an address only (bare
744 : * address) transaction.
745 : */
746 0 : msg.request &= ~DP_AUX_I2C_MOT;
747 0 : msg.buffer = NULL;
748 0 : msg.size = 0;
749 0 : (void)drm_dp_i2c_do_msg(aux, &msg);
750 :
751 0 : mutex_unlock(&aux->hw_mutex);
752 :
753 0 : return err;
754 0 : }
755 :
756 : static const struct i2c_algorithm drm_dp_i2c_algo = {
757 : .functionality = drm_dp_i2c_functionality,
758 : .master_xfer = drm_dp_i2c_xfer,
759 : };
760 :
761 : /**
762 : * drm_dp_aux_register() - initialise and register aux channel
763 : * @aux: DisplayPort AUX channel
764 : *
765 : * Returns 0 on success or a negative error code on failure.
766 : */
767 0 : int drm_dp_aux_register(struct drm_dp_aux *aux)
768 : {
769 0 : rw_init(&aux->hw_mutex, "drmdp");
770 :
771 0 : aux->ddc.algo = &drm_dp_i2c_algo;
772 0 : aux->ddc.algo_data = aux;
773 0 : aux->ddc.retries = 3;
774 :
775 : #ifdef __linux__
776 : aux->ddc.class = I2C_CLASS_DDC;
777 : aux->ddc.owner = THIS_MODULE;
778 : aux->ddc.dev.parent = aux->dev;
779 : aux->ddc.dev.of_node = aux->dev->of_node;
780 : #endif
781 :
782 0 : strlcpy(aux->ddc.name, aux->name ? aux->name : dev_name(aux->dev),
783 : sizeof(aux->ddc.name));
784 :
785 0 : return i2c_add_adapter(&aux->ddc);
786 : }
787 : EXPORT_SYMBOL(drm_dp_aux_register);
788 :
789 : /**
790 : * drm_dp_aux_unregister() - unregister an AUX adapter
791 : * @aux: DisplayPort AUX channel
792 : */
793 0 : void drm_dp_aux_unregister(struct drm_dp_aux *aux)
794 : {
795 : i2c_del_adapter(&aux->ddc);
796 0 : }
797 : EXPORT_SYMBOL(drm_dp_aux_unregister);
|