summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/tegra
diff options
context:
space:
mode:
authorThierry Reding <treding@nvidia.com>2015-07-07 21:01:26 +0200
committerThierry Reding <treding@nvidia.com>2019-10-28 11:18:52 +0100
commitad7f2dda38911698deb2cc9ea45362f9a127e3f4 (patch)
tree5abfecdb2db327c54ce5bb7a47d7694af9350a48 /drivers/gpu/drm/tegra
parent7aa3cc540d00b0be7d225202fa5c2d0c8e99f3f1 (diff)
downloadlinux-ad7f2dda38911698deb2cc9ea45362f9a127e3f4.tar.bz2
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')
-rw-r--r--drivers/gpu/drm/tegra/dp.c31
-rw-r--r--drivers/gpu/drm/tegra/dp.h11
2 files changed, 42 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;
diff --git a/drivers/gpu/drm/tegra/dp.h b/drivers/gpu/drm/tegra/dp.h
index 681cbd0a0094..1fe2d4f45ba3 100644
--- a/drivers/gpu/drm/tegra/dp.h
+++ b/drivers/gpu/drm/tegra/dp.h
@@ -60,6 +60,7 @@ void drm_dp_link_caps_copy(struct drm_dp_link_caps *dest,
* @max_rate: maximum clock rate supported on the link
* @max_lanes: maximum number of lanes supported on the link
* @caps: capabilities supported on the link (see &drm_dp_link_caps)
+ * @aux_rd_interval: AUX read interval to use for training (in microseconds)
* @edp: eDP revision (0x11: eDP 1.1, 0x12: eDP 1.2, ...)
* @rate: currently configured link rate
* @lanes: currently configured number of lanes
@@ -70,6 +71,16 @@ struct drm_dp_link {
unsigned int max_lanes;
struct drm_dp_link_caps caps;
+
+ /**
+ * @cr: clock recovery read interval
+ * @ce: channel equalization read interval
+ */
+ struct {
+ unsigned int cr;
+ unsigned int ce;
+ } aux_rd_interval;
+
unsigned char edp;
unsigned int rate;