aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2015-09-10 20:52:37 -0400
committerDave Airlie <airlied@redhat.com>2015-09-10 20:52:37 -0400
commitd1031d576d7398ab2e2fce53796d733c5be13d64 (patch)
tree6745db05344b0d961d3f90388618d2f1a64b6526 /drivers
parent91b6fc02a258422bf342992add24cfe70a029eca (diff)
parentf36203be608a38a5b5523a7aa52cc72f757b9679 (diff)
Merge tag 'topic/drm-fixes-2015-09-09' of git://anongit.freedesktop.org/drm-intel into drm-next
bunch of drm fixes. * tag 'topic/drm-fixes-2015-09-09' of git://anongit.freedesktop.org/drm-intel: drm/dp: Add dp_aux_i2c_speed_khz module param to set the assume i2c bus speed drm/dp: Adjust i2c-over-aux retry count based on message size and i2c bus speed drm/dp: Define AUX_RETRY_INTERVAL as 500 us drm/atomic: Fix bookkeeping with TEST_ONLY, v3.
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/drm_atomic.c39
-rw-r--r--drivers/gpu/drm/drm_dp_helper.c99
2 files changed, 117 insertions, 21 deletions
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 434915448ea0..f7d5166f89b2 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -1515,7 +1515,8 @@ retry:
1515 copied_props++; 1515 copied_props++;
1516 } 1516 }
1517 1517
1518 if (obj->type == DRM_MODE_OBJECT_PLANE && count_props) { 1518 if (obj->type == DRM_MODE_OBJECT_PLANE && count_props &&
1519 !(arg->flags & DRM_MODE_ATOMIC_TEST_ONLY)) {
1519 plane = obj_to_plane(obj); 1520 plane = obj_to_plane(obj);
1520 plane_mask |= (1 << drm_plane_index(plane)); 1521 plane_mask |= (1 << drm_plane_index(plane));
1521 plane->old_fb = plane->fb; 1522 plane->old_fb = plane->fb;
@@ -1537,10 +1538,11 @@ retry:
1537 } 1538 }
1538 1539
1539 if (arg->flags & DRM_MODE_ATOMIC_TEST_ONLY) { 1540 if (arg->flags & DRM_MODE_ATOMIC_TEST_ONLY) {
1541 /*
1542 * Unlike commit, check_only does not clean up state.
1543 * Below we call drm_atomic_state_free for it.
1544 */
1540 ret = drm_atomic_check_only(state); 1545 ret = drm_atomic_check_only(state);
1541 /* _check_only() does not free state, unlike _commit() */
1542 if (!ret)
1543 drm_atomic_state_free(state);
1544 } else if (arg->flags & DRM_MODE_ATOMIC_NONBLOCK) { 1546 } else if (arg->flags & DRM_MODE_ATOMIC_NONBLOCK) {
1545 ret = drm_atomic_async_commit(state); 1547 ret = drm_atomic_async_commit(state);
1546 } else { 1548 } else {
@@ -1567,25 +1569,30 @@ out:
1567 plane->old_fb = NULL; 1569 plane->old_fb = NULL;
1568 } 1570 }
1569 1571
1572 if (ret && arg->flags & DRM_MODE_PAGE_FLIP_EVENT) {
1573 /*
1574 * TEST_ONLY and PAGE_FLIP_EVENT are mutually exclusive,
1575 * if they weren't, this code should be called on success
1576 * for TEST_ONLY too.
1577 */
1578
1579 for_each_crtc_in_state(state, crtc, crtc_state, i) {
1580 if (!crtc_state->event)
1581 continue;
1582
1583 destroy_vblank_event(dev, file_priv,
1584 crtc_state->event);
1585 }
1586 }
1587
1570 if (ret == -EDEADLK) { 1588 if (ret == -EDEADLK) {
1571 drm_atomic_state_clear(state); 1589 drm_atomic_state_clear(state);
1572 drm_modeset_backoff(&ctx); 1590 drm_modeset_backoff(&ctx);
1573 goto retry; 1591 goto retry;
1574 } 1592 }
1575 1593
1576 if (ret) { 1594 if (ret || arg->flags & DRM_MODE_ATOMIC_TEST_ONLY)
1577 if (arg->flags & DRM_MODE_PAGE_FLIP_EVENT) {
1578 for_each_crtc_in_state(state, crtc, crtc_state, i) {
1579 if (!crtc_state->event)
1580 continue;
1581
1582 destroy_vblank_event(dev, file_priv,
1583 crtc_state->event);
1584 }
1585 }
1586
1587 drm_atomic_state_free(state); 1595 drm_atomic_state_free(state);
1588 }
1589 1596
1590 drm_modeset_drop_locks(&ctx); 1597 drm_modeset_drop_locks(&ctx);
1591 drm_modeset_acquire_fini(&ctx); 1598 drm_modeset_acquire_fini(&ctx);
diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index 80a02a412607..291734e87fca 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -159,6 +159,8 @@ int drm_dp_bw_code_to_link_rate(u8 link_bw)
159} 159}
160EXPORT_SYMBOL(drm_dp_bw_code_to_link_rate); 160EXPORT_SYMBOL(drm_dp_bw_code_to_link_rate);
161 161
162#define AUX_RETRY_INTERVAL 500 /* us */
163
162/** 164/**
163 * DOC: dp helpers 165 * DOC: dp helpers
164 * 166 *
@@ -213,7 +215,7 @@ static int drm_dp_dpcd_access(struct drm_dp_aux *aux, u8 request,
213 return -EIO; 215 return -EIO;
214 216
215 case DP_AUX_NATIVE_REPLY_DEFER: 217 case DP_AUX_NATIVE_REPLY_DEFER:
216 usleep_range(400, 500); 218 usleep_range(AUX_RETRY_INTERVAL, AUX_RETRY_INTERVAL + 100);
217 break; 219 break;
218 } 220 }
219 } 221 }
@@ -422,6 +424,90 @@ static u32 drm_dp_i2c_functionality(struct i2c_adapter *adapter)
422 I2C_FUNC_10BIT_ADDR; 424 I2C_FUNC_10BIT_ADDR;
423} 425}
424 426
427#define AUX_PRECHARGE_LEN 10 /* 10 to 16 */
428#define AUX_SYNC_LEN (16 + 4) /* preamble + AUX_SYNC_END */
429#define AUX_STOP_LEN 4
430#define AUX_CMD_LEN 4
431#define AUX_ADDRESS_LEN 20
432#define AUX_REPLY_PAD_LEN 4
433#define AUX_LENGTH_LEN 8
434
435/*
436 * Calculate the duration of the AUX request/reply in usec. Gives the
437 * "best" case estimate, ie. successful while as short as possible.
438 */
439static int drm_dp_aux_req_duration(const struct drm_dp_aux_msg *msg)
440{
441 int len = AUX_PRECHARGE_LEN + AUX_SYNC_LEN + AUX_STOP_LEN +
442 AUX_CMD_LEN + AUX_ADDRESS_LEN + AUX_LENGTH_LEN;
443
444 if ((msg->request & DP_AUX_I2C_READ) == 0)
445 len += msg->size * 8;
446
447 return len;
448}
449
450static int drm_dp_aux_reply_duration(const struct drm_dp_aux_msg *msg)
451{
452 int len = AUX_PRECHARGE_LEN + AUX_SYNC_LEN + AUX_STOP_LEN +
453 AUX_CMD_LEN + AUX_REPLY_PAD_LEN;
454
455 /*
456 * For read we expect what was asked. For writes there will
457 * be 0 or 1 data bytes. Assume 0 for the "best" case.
458 */
459 if (msg->request & DP_AUX_I2C_READ)
460 len += msg->size * 8;
461
462 return len;
463}
464
465#define I2C_START_LEN 1
466#define I2C_STOP_LEN 1
467#define I2C_ADDR_LEN 9 /* ADDRESS + R/W + ACK/NACK */
468#define I2C_DATA_LEN 9 /* DATA + ACK/NACK */
469
470/*
471 * Calculate the length of the i2c transfer in usec, assuming
472 * the i2c bus speed is as specified. Gives the the "worst"
473 * case estimate, ie. successful while as long as possible.
474 * Doesn't account the the "MOT" bit, and instead assumes each
475 * message includes a START, ADDRESS and STOP. Neither does it
476 * account for additional random variables such as clock stretching.
477 */
478static int drm_dp_i2c_msg_duration(const struct drm_dp_aux_msg *msg,
479 int i2c_speed_khz)
480{
481 /* AUX bitrate is 1MHz, i2c bitrate as specified */
482 return DIV_ROUND_UP((I2C_START_LEN + I2C_ADDR_LEN +
483 msg->size * I2C_DATA_LEN +
484 I2C_STOP_LEN) * 1000, i2c_speed_khz);
485}
486
487/*
488 * Deterine how many retries should be attempted to successfully transfer
489 * the specified message, based on the estimated durations of the
490 * i2c and AUX transfers.
491 */
492static int drm_dp_i2c_retry_count(const struct drm_dp_aux_msg *msg,
493 int i2c_speed_khz)
494{
495 int aux_time_us = drm_dp_aux_req_duration(msg) +
496 drm_dp_aux_reply_duration(msg);
497 int i2c_time_us = drm_dp_i2c_msg_duration(msg, i2c_speed_khz);
498
499 return DIV_ROUND_UP(i2c_time_us, aux_time_us + AUX_RETRY_INTERVAL);
500}
501
502/*
503 * FIXME currently assumes 10 kHz as some real world devices seem
504 * to require it. We should query/set the speed via DPCD if supported.
505 */
506static int dp_aux_i2c_speed_khz __read_mostly = 10;
507module_param_unsafe(dp_aux_i2c_speed_khz, int, 0644);
508MODULE_PARM_DESC(dp_aux_i2c_speed_khz,
509 "Assumed speed of the i2c bus in kHz, (1-400, default 10)");
510
425/* 511/*
426 * Transfer a single I2C-over-AUX message and handle various error conditions, 512 * Transfer a single I2C-over-AUX message and handle various error conditions,
427 * retrying the transaction as appropriate. It is assumed that the 513 * retrying the transaction as appropriate. It is assumed that the
@@ -434,13 +520,16 @@ static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
434{ 520{
435 unsigned int retry, defer_i2c; 521 unsigned int retry, defer_i2c;
436 int ret; 522 int ret;
437
438 /* 523 /*
439 * DP1.2 sections 2.7.7.1.5.6.1 and 2.7.7.1.6.6.1: A DP Source device 524 * DP1.2 sections 2.7.7.1.5.6.1 and 2.7.7.1.6.6.1: A DP Source device
440 * is required to retry at least seven times upon receiving AUX_DEFER 525 * is required to retry at least seven times upon receiving AUX_DEFER
441 * before giving up the AUX transaction. 526 * before giving up the AUX transaction.
527 *
528 * We also try to account for the i2c bus speed.
442 */ 529 */
443 for (retry = 0, defer_i2c = 0; retry < (7 + defer_i2c); retry++) { 530 int max_retries = max(7, drm_dp_i2c_retry_count(msg, dp_aux_i2c_speed_khz));
531
532 for (retry = 0, defer_i2c = 0; retry < (max_retries + defer_i2c); retry++) {
444 mutex_lock(&aux->hw_mutex); 533 mutex_lock(&aux->hw_mutex);
445 ret = aux->transfer(aux, msg); 534 ret = aux->transfer(aux, msg);
446 mutex_unlock(&aux->hw_mutex); 535 mutex_unlock(&aux->hw_mutex);
@@ -476,7 +565,7 @@ static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
476 * For now just defer for long enough to hopefully be 565 * For now just defer for long enough to hopefully be
477 * safe for all use-cases. 566 * safe for all use-cases.
478 */ 567 */
479 usleep_range(500, 600); 568 usleep_range(AUX_RETRY_INTERVAL, AUX_RETRY_INTERVAL + 100);
480 continue; 569 continue;
481 570
482 default: 571 default:
@@ -506,7 +595,7 @@ static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
506 aux->i2c_defer_count++; 595 aux->i2c_defer_count++;
507 if (defer_i2c < 7) 596 if (defer_i2c < 7)
508 defer_i2c++; 597 defer_i2c++;
509 usleep_range(400, 500); 598 usleep_range(AUX_RETRY_INTERVAL, AUX_RETRY_INTERVAL + 100);
510 continue; 599 continue;
511 600
512 default: 601 default: