summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/tegra/dp.c
diff options
context:
space:
mode:
authorThierry Reding <treding@nvidia.com>2015-07-07 22:01:26 +0300
committerThierry Reding <treding@nvidia.com>2019-10-28 13:18:52 +0300
commitad7f2dda38911698deb2cc9ea45362f9a127e3f4 (patch)
tree5abfecdb2db327c54ce5bb7a47d7694af9350a48 /drivers/gpu/drm/tegra/dp.c
parent7aa3cc540d00b0be7d225202fa5c2d0c8e99f3f1 (diff)
downloadlinux-ad7f2dda38911698deb2cc9ea45362f9a127e3f4.tar.xz
drm/tegra: dp: Read AUX read interval from DPCD
Store the AUX read interval from DPCD, so that it can be used to wait for the durations given in the specification during link training. Signed-off-by: Thierry Reding <treding@nvidia.com>
Diffstat (limited to 'drivers/gpu/drm/tegra/dp.c')
-rw-r--r--drivers/gpu/drm/tegra/dp.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/drivers/gpu/drm/tegra/dp.c b/drivers/gpu/drm/tegra/dp.c
index 2be0a47ecbec..757a0256592f 100644
--- a/drivers/gpu/drm/tegra/dp.c
+++ b/drivers/gpu/drm/tegra/dp.c
@@ -40,6 +40,8 @@ static void drm_dp_link_reset(struct drm_dp_link *link)
link->max_lanes = 0;
drm_dp_link_caps_reset(&link->caps);
+ link->aux_rd_interval.cr = 0;
+ link->aux_rd_interval.ce = 0;
link->edp = 0;
link->rate = 0;
@@ -60,6 +62,7 @@ static void drm_dp_link_reset(struct drm_dp_link *link)
int drm_dp_link_probe(struct drm_dp_aux *aux, struct drm_dp_link *link)
{
u8 dpcd[DP_RECEIVER_CAP_SIZE], value;
+ unsigned int rd_interval;
int err;
drm_dp_link_reset(link);
@@ -90,6 +93,34 @@ int drm_dp_link_probe(struct drm_dp_aux *aux, struct drm_dp_link *link)
link->edp = drm_dp_edp_revisions[value];
}
+ /*
+ * The DPCD stores the AUX read interval in units of 4 ms. There are
+ * two special cases:
+ *
+ * 1) if the TRAINING_AUX_RD_INTERVAL field is 0, the clock recovery
+ * and channel equalization should use 100 us or 400 us AUX read
+ * intervals, respectively
+ *
+ * 2) for DP v1.4 and above, clock recovery should always use 100 us
+ * AUX read intervals
+ */
+ rd_interval = dpcd[DP_TRAINING_AUX_RD_INTERVAL] &
+ DP_TRAINING_AUX_RD_MASK;
+
+ if (rd_interval > 4) {
+ DRM_DEBUG_KMS("AUX interval %u out of range (max. 4)\n",
+ rd_interval);
+ rd_interval = 4;
+ }
+
+ rd_interval *= 4 * USEC_PER_MSEC;
+
+ if (rd_interval == 0 || link->revision >= DP_DPCD_REV_14)
+ link->aux_rd_interval.cr = 100;
+
+ if (rd_interval == 0)
+ link->aux_rd_interval.ce = 400;
+
link->rate = link->max_rate;
link->lanes = link->max_lanes;