All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/17] drm/dp: Miscellaneous improvements
@ 2018-02-05 19:38 Thierry Reding
  2018-02-05 19:38 ` [PATCH 01/17] drm/dp: Add missing kerneldoc for struct drm_dp_link Thierry Reding
                   ` (16 more replies)
  0 siblings, 17 replies; 20+ messages in thread
From: Thierry Reding @ 2018-02-05 19:38 UTC (permalink / raw)
  To: dri-devel

From: Thierry Reding <treding@nvidia.com>

Hi,

this set of patches is based on work that I had done some 2-3 years ago
to enable DP support on Pixel C. I never really got that to work, but I
recently got my hands on newer hardware with DP connectivity, so I went
to revive these patches.

I think this takes into account all review comments I was able to find
and adds a bit of kerneldoc here and there. I've got a couple of patches
on top of this that implement DP support (and make use of more of these
helpers in the existing eDP support) for Tegra.

Thierry

Thierry Reding (17):
  drm/dp: Add missing kerneldoc for struct drm_dp_link
  drm/dp: Add drm_dp_link_reset() implementation
  drm/dp: Track link capabilities alongside settings
  drm/dp: Turn link capabilities into booleans
  drm/dp: Probe link using existing parsing helpers
  drm/dp: Read fast training capability from link
  drm/dp: Read TPS3 capability from sink
  drm/dp: Read channel coding capability from sink
  drm/dp: Read alternate scrambler reset capability from sink
  drm/dp: Read eDP version from DPCD
  drm/dp: Read AUX read interval from DPCD
  drm/dp: Do not busy-loop during link training
  drm/dp: Use drm_dp_aux_rd_interval()
  drm/dp: Add helper to get post-cursor adjustments
  drm/dp: Set channel coding on link configuration
  drm/dp: Enable alternate scrambler reset when supported
  drm/dp: Add drm_dp_link_choose() helper

 drivers/gpu/drm/bridge/tc358767.c      |  20 ++--
 drivers/gpu/drm/drm_dp_helper.c        | 211 +++++++++++++++++++++++++++++----
 drivers/gpu/drm/msm/edp/edp_ctrl.c     |  12 +-
 drivers/gpu/drm/rockchip/cdn-dp-core.c |   8 +-
 drivers/gpu/drm/rockchip/cdn-dp-reg.c  |  13 +-
 drivers/gpu/drm/tegra/dpaux.c          |   8 +-
 drivers/gpu/drm/tegra/sor.c            |  32 ++---
 include/drm/drm_dp_helper.h            |  95 ++++++++++++++-
 8 files changed, 328 insertions(+), 71 deletions(-)

-- 
2.15.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 01/17] drm/dp: Add missing kerneldoc for struct drm_dp_link
  2018-02-05 19:38 [PATCH 00/17] drm/dp: Miscellaneous improvements Thierry Reding
@ 2018-02-05 19:38 ` Thierry Reding
  2018-02-05 19:38 ` [PATCH 02/17] drm/dp: Add drm_dp_link_reset() implementation Thierry Reding
                   ` (15 subsequent siblings)
  16 siblings, 0 replies; 20+ messages in thread
From: Thierry Reding @ 2018-02-05 19:38 UTC (permalink / raw)
  To: dri-devel

From: Thierry Reding <treding@nvidia.com>

The drm_dp_link structure tracks capabilities on the DP link. Add some
kerneldoc to explain what each of its fields means.

Signed-off-by: Thierry Reding <treding@nvidia.com>
---
 include/drm/drm_dp_helper.h | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index da58a428c8d7..6ced0bc6feb9 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -1099,6 +1099,13 @@ int drm_dp_dpcd_read_link_status(struct drm_dp_aux *aux,
  */
 #define DP_LINK_CAP_ENHANCED_FRAMING (1 << 0)
 
+/**
+ * struct drm_dp_link - DP link capabilities
+ * @revision: DP specification revision supported on the link
+ * @rate: maximum clock rate supported on the link
+ * @num_lanes: maximum number of lanes supported on the link
+ * @capabilities: bitmask of capabilities supported on the link
+ */
 struct drm_dp_link {
 	unsigned char revision;
 	unsigned int rate;
-- 
2.15.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 02/17] drm/dp: Add drm_dp_link_reset() implementation
  2018-02-05 19:38 [PATCH 00/17] drm/dp: Miscellaneous improvements Thierry Reding
  2018-02-05 19:38 ` [PATCH 01/17] drm/dp: Add missing kerneldoc for struct drm_dp_link Thierry Reding
@ 2018-02-05 19:38 ` Thierry Reding
  2018-02-05 19:38 ` [PATCH 03/17] drm/dp: Track link capabilities alongside settings Thierry Reding
                   ` (14 subsequent siblings)
  16 siblings, 0 replies; 20+ messages in thread
From: Thierry Reding @ 2018-02-05 19:38 UTC (permalink / raw)
  To: dri-devel

From: Thierry Reding <treding@nvidia.com>

Subsequent patches will add non-volatile fields to struct drm_dp_link,
so introduce a function to zero out only the volatile fields.

Signed-off-by: Thierry Reding <treding@nvidia.com>
---
 drivers/gpu/drm/drm_dp_helper.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index adf79be42c1e..1b8a471ec1b7 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -315,6 +315,17 @@ int drm_dp_dpcd_read_link_status(struct drm_dp_aux *aux,
 }
 EXPORT_SYMBOL(drm_dp_dpcd_read_link_status);
 
+static void drm_dp_link_reset(struct drm_dp_link *link)
+{
+	if (!link)
+		return;
+
+	link->revision = 0;
+	link->rate = 0;
+	link->num_lanes = 0;
+	link->capabilities = 0;
+}
+
 /**
  * drm_dp_link_probe() - probe a DisplayPort link for capabilities
  * @aux: DisplayPort AUX channel
@@ -331,7 +342,7 @@ int drm_dp_link_probe(struct drm_dp_aux *aux, struct drm_dp_link *link)
 	u8 values[3];
 	int err;
 
-	memset(link, 0, sizeof(*link));
+	drm_dp_link_reset(link);
 
 	err = drm_dp_dpcd_read(aux, DP_DPCD_REV, values, sizeof(values));
 	if (err < 0)
-- 
2.15.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 03/17] drm/dp: Track link capabilities alongside settings
  2018-02-05 19:38 [PATCH 00/17] drm/dp: Miscellaneous improvements Thierry Reding
  2018-02-05 19:38 ` [PATCH 01/17] drm/dp: Add missing kerneldoc for struct drm_dp_link Thierry Reding
  2018-02-05 19:38 ` [PATCH 02/17] drm/dp: Add drm_dp_link_reset() implementation Thierry Reding
@ 2018-02-05 19:38 ` Thierry Reding
  2018-02-05 19:38 ` [PATCH 04/17] drm/dp: Turn link capabilities into booleans Thierry Reding
                   ` (13 subsequent siblings)
  16 siblings, 0 replies; 20+ messages in thread
From: Thierry Reding @ 2018-02-05 19:38 UTC (permalink / raw)
  To: dri-devel

From: Thierry Reding <treding@nvidia.com>

Store capabilities in max_* fields and add separate fields for the
currently selected settings.

Signed-off-by: Thierry Reding <treding@nvidia.com>
---
 drivers/gpu/drm/bridge/tc358767.c      | 14 +++++++-------
 drivers/gpu/drm/drm_dp_helper.c        | 16 +++++++++++-----
 drivers/gpu/drm/msm/edp/edp_ctrl.c     |  8 ++++----
 drivers/gpu/drm/rockchip/cdn-dp-core.c |  8 ++++----
 drivers/gpu/drm/rockchip/cdn-dp-reg.c  | 13 ++++++-------
 drivers/gpu/drm/tegra/dpaux.c          |  8 ++++----
 drivers/gpu/drm/tegra/sor.c            | 28 ++++++++++++++--------------
 include/drm/drm_dp_helper.h            | 15 ++++++++++-----
 8 files changed, 60 insertions(+), 50 deletions(-)

diff --git a/drivers/gpu/drm/bridge/tc358767.c b/drivers/gpu/drm/bridge/tc358767.c
index 08ab7d6aea65..55037f999579 100644
--- a/drivers/gpu/drm/bridge/tc358767.c
+++ b/drivers/gpu/drm/bridge/tc358767.c
@@ -391,7 +391,7 @@ static u32 tc_srcctrl(struct tc_data *tc)
 		reg |= DP0_SRCCTRL_EN810B;
 	if (tc->link.spread)
 		reg |= DP0_SRCCTRL_SSCG;	/* Spread Spectrum Enable */
-	if (tc->link.base.num_lanes == 2)
+	if (tc->link.base.lanes == 2)
 		reg |= DP0_SRCCTRL_LANES_2;	/* Two Main Channel Lanes */
 	if (tc->link.base.rate != 162000)
 		reg |= DP0_SRCCTRL_BW27;	/* 2.7 Gbps link */
@@ -610,9 +610,9 @@ static int tc_get_display_props(struct tc_data *tc)
 		tc->link.base.rate = 270000;
 	}
 
-	if (tc->link.base.num_lanes > 2) {
+	if (tc->link.base.lanes > 2) {
 		dev_dbg(tc->dev, "Falling to 2 lanes\n");
-		tc->link.base.num_lanes = 2;
+		tc->link.base.lanes = 2;
 	}
 
 	ret = drm_dp_dpcd_readb(&tc->aux, DP_MAX_DOWNSPREAD, tmp);
@@ -634,7 +634,7 @@ static int tc_get_display_props(struct tc_data *tc)
 	dev_dbg(tc->dev, "DPCD rev: %d.%d, rate: %s, lanes: %d, framing: %s\n",
 		tc->link.base.revision >> 4, tc->link.base.revision & 0x0f,
 		(tc->link.base.rate == 162000) ? "1.62Gbps" : "2.7Gbps",
-		tc->link.base.num_lanes,
+		tc->link.base.lanes,
 		(tc->link.base.capabilities & DP_LINK_CAP_ENHANCED_FRAMING) ?
 		"enhanced" : "non-enhanced");
 	dev_dbg(tc->dev, "ANSI 8B/10B: %d\n", tc->link.coding8b10b);
@@ -788,13 +788,13 @@ static int tc_link_training(struct tc_data *tc, int pattern)
 					 LT_INTERLANE_ALIGN_DONE |
 					 LT_CHANNEL0_EQ_BITS;
 				/* in case of two lanes */
-				if ((tc->link.base.num_lanes == 2) &&
+				if ((tc->link.base.lanes == 2) &&
 				    (value == (LT_CHANNEL1_EQ_BITS |
 					       LT_INTERLANE_ALIGN_DONE |
 					       LT_CHANNEL0_EQ_BITS)))
 					break;
 				/* in case of one line */
-				if ((tc->link.base.num_lanes == 1) &&
+				if ((tc->link.base.lanes == 1) &&
 				    (value == (LT_INTERLANE_ALIGN_DONE |
 					       LT_CHANNEL0_EQ_BITS)))
 					break;
@@ -966,7 +966,7 @@ static int tc_main_link_setup(struct tc_data *tc)
 		if (ret < 0)
 			goto err_dpcd_read;
 	} while ((--timeout) &&
-		 !(drm_dp_channel_eq_ok(tmp + 2,  tc->link.base.num_lanes)));
+		 !(drm_dp_channel_eq_ok(tmp + 2,  tc->link.base.lanes)));
 
 	if (timeout == 0) {
 		/* Read DPCD 0x200-0x201 */
diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index 1b8a471ec1b7..f401377a199d 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -321,9 +321,12 @@ static void drm_dp_link_reset(struct drm_dp_link *link)
 		return;
 
 	link->revision = 0;
-	link->rate = 0;
-	link->num_lanes = 0;
+	link->max_rate = 0;
+	link->max_lanes = 0;
 	link->capabilities = 0;
+
+	link->rate = 0;
+	link->lanes = 0;
 }
 
 /**
@@ -349,12 +352,15 @@ int drm_dp_link_probe(struct drm_dp_aux *aux, struct drm_dp_link *link)
 		return err;
 
 	link->revision = values[0];
-	link->rate = drm_dp_bw_code_to_link_rate(values[1]);
-	link->num_lanes = values[2] & DP_MAX_LANE_COUNT_MASK;
+	link->max_rate = drm_dp_bw_code_to_link_rate(values[1]);
+	link->max_lanes = values[2] & DP_MAX_LANE_COUNT_MASK;
 
 	if (values[2] & DP_ENHANCED_FRAME_CAP)
 		link->capabilities |= DP_LINK_CAP_ENHANCED_FRAMING;
 
+	link->rate = link->max_rate;
+	link->lanes = link->max_lanes;
+
 	return 0;
 }
 EXPORT_SYMBOL(drm_dp_link_probe);
@@ -441,7 +447,7 @@ int drm_dp_link_configure(struct drm_dp_aux *aux, struct drm_dp_link *link)
 	int err;
 
 	values[0] = drm_dp_link_rate_to_bw_code(link->rate);
-	values[1] = link->num_lanes;
+	values[1] = link->lanes;
 
 	if (link->capabilities & DP_LINK_CAP_ENHANCED_FRAMING)
 		values[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
diff --git a/drivers/gpu/drm/msm/edp/edp_ctrl.c b/drivers/gpu/drm/msm/edp/edp_ctrl.c
index 7c72264101ff..71192a0656e3 100644
--- a/drivers/gpu/drm/msm/edp/edp_ctrl.c
+++ b/drivers/gpu/drm/msm/edp/edp_ctrl.c
@@ -411,7 +411,7 @@ static void edp_fill_link_cfg(struct edp_ctrl *ctrl)
 	u32 prate;
 	u32 lrate;
 	u32 bpp;
-	u8 max_lane = ctrl->dp_link.num_lanes;
+	u8 max_lane = ctrl->dp_link.max_lanes;
 	u8 lane;
 
 	prate = ctrl->pixel_rate;
@@ -421,7 +421,7 @@ static void edp_fill_link_cfg(struct edp_ctrl *ctrl)
 	 * By default, use the maximum link rate and minimum lane count,
 	 * so that we can do rate down shift during link training.
 	 */
-	ctrl->link_rate = drm_dp_link_rate_to_bw_code(ctrl->dp_link.rate);
+	ctrl->link_rate = drm_dp_link_rate_to_bw_code(ctrl->dp_link.max_rate);
 
 	prate *= bpp;
 	prate /= 8; /* in kByte */
@@ -709,7 +709,7 @@ static int edp_link_rate_down_shift(struct edp_ctrl *ctrl)
 
 	rate = ctrl->link_rate;
 	lane = ctrl->lane_cnt;
-	max_lane = ctrl->dp_link.num_lanes;
+	max_lane = ctrl->dp_link.max_lanes;
 
 	bpp = ctrl->color_depth * 3;
 	prate = ctrl->pixel_rate;
@@ -767,7 +767,7 @@ static int edp_do_link_train(struct edp_ctrl *ctrl)
 	 * Set the current link rate and lane cnt to panel. They may have been
 	 * adjusted and the values are different from them in DPCD CAP
 	 */
-	dp_link.num_lanes = ctrl->lane_cnt;
+	dp_link.lanes = ctrl->lane_cnt;
 	dp_link.rate = drm_dp_bw_code_to_link_rate(ctrl->link_rate);
 	dp_link.capabilities = ctrl->dp_link.capabilities;
 	if (drm_dp_link_configure(ctrl->drm_aux, &dp_link) < 0)
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index ec999d9f15f6..00298acf804b 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -494,7 +494,7 @@ static int cdn_dp_disable(struct cdn_dp_device *dp)
 	cdn_dp_clk_disable(dp);
 	dp->active = false;
 	dp->link.rate = 0;
-	dp->link.num_lanes = 0;
+	dp->link.lanes = 0;
 	if (!dp->connected) {
 		kfree(dp->edid);
 		dp->edid = NULL;
@@ -586,7 +586,7 @@ static bool cdn_dp_check_link_status(struct cdn_dp_device *dp)
 	struct cdn_dp_port *port = cdn_dp_connected_port(dp);
 	u8 sink_lanes = drm_dp_max_lane_count(dp->dpcd);
 
-	if (!port || !dp->link.rate || !dp->link.num_lanes)
+	if (!port || !dp->link.rate || !dp->link.lanes)
 		return false;
 
 	if (cdn_dp_dpcd_read(dp, DP_LANE0_1_STATUS, link_status,
@@ -969,7 +969,7 @@ static void cdn_dp_pd_event_work(struct work_struct *work)
 	/* Enabled and connected with a sink, re-train if requested */
 	} else if (!cdn_dp_check_link_status(dp)) {
 		unsigned int rate = dp->link.rate;
-		unsigned int lanes = dp->link.num_lanes;
+		unsigned int lanes = dp->link.lanes;
 		struct drm_display_mode *mode = &dp->mode;
 
 		DRM_DEV_INFO(dp->dev, "Connected with sink. Re-train link\n");
@@ -982,7 +982,7 @@ static void cdn_dp_pd_event_work(struct work_struct *work)
 
 		/* If training result is changed, update the video config */
 		if (mode->clock &&
-		    (rate != dp->link.rate || lanes != dp->link.num_lanes)) {
+		    (rate != dp->link.rate || lanes != dp->link.lanes)) {
 			ret = cdn_dp_config_video(dp);
 			if (ret) {
 				dp->connected = false;
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-reg.c b/drivers/gpu/drm/rockchip/cdn-dp-reg.c
index eb3042c6d1b2..14421be48c90 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-reg.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-reg.c
@@ -544,7 +544,7 @@ static int cdn_dp_get_training_status(struct cdn_dp_device *dp)
 		goto err_get_training_status;
 
 	dp->link.rate = status[0];
-	dp->link.num_lanes = status[1];
+	dp->link.lanes = status[1];
 
 err_get_training_status:
 	if (ret)
@@ -569,7 +569,7 @@ int cdn_dp_train_link(struct cdn_dp_device *dp)
 	}
 
 	DRM_DEV_DEBUG_KMS(dp->dev, "rate:0x%x, lanes:%d\n", dp->link.rate,
-			  dp->link.num_lanes);
+			  dp->link.lanes);
 	return ret;
 }
 
@@ -667,14 +667,13 @@ int cdn_dp_config_video(struct cdn_dp_device *dp)
 	do {
 		tu_size_reg += 2;
 		symbol = tu_size_reg * mode->clock * bit_per_pix;
-		do_div(symbol, dp->link.num_lanes * link_rate * 8);
+		do_div(symbol, dp->link.lanes * link_rate * 8);
 		rem = do_div(symbol, 1000);
 		if (tu_size_reg > 64) {
 			ret = -EINVAL;
 			DRM_DEV_ERROR(dp->dev,
 				      "tu error, clk:%d, lanes:%d, rate:%d\n",
-				      mode->clock, dp->link.num_lanes,
-				      link_rate);
+				      mode->clock, dp->link.lanes, link_rate);
 			goto err_config_video;
 		}
 	} while ((symbol <= 1) || (tu_size_reg - symbol < 4) ||
@@ -688,7 +687,7 @@ int cdn_dp_config_video(struct cdn_dp_device *dp)
 
 	/* set the FIFO Buffer size */
 	val = div_u64(mode->clock * (symbol + 1), 1000) + link_rate;
-	val /= (dp->link.num_lanes * link_rate);
+	val /= (dp->link.lanes * link_rate);
 	val = div_u64(8 * (symbol + 1), bit_per_pix) - val;
 	val += 2;
 	ret = cdn_dp_reg_write(dp, DP_VC_TABLE(15), val);
@@ -846,7 +845,7 @@ static void cdn_dp_audio_config_i2s(struct cdn_dp_device *dp,
 	u32 val;
 
 	if (audio->channels == 2) {
-		if (dp->link.num_lanes == 1)
+		if (dp->link.lanes == 1)
 			sub_pckt_num = 2;
 		else
 			sub_pckt_num = 4;
diff --git a/drivers/gpu/drm/tegra/dpaux.c b/drivers/gpu/drm/tegra/dpaux.c
index d84e81ff36ad..844fb946fb2e 100644
--- a/drivers/gpu/drm/tegra/dpaux.c
+++ b/drivers/gpu/drm/tegra/dpaux.c
@@ -788,14 +788,14 @@ int drm_dp_aux_train(struct drm_dp_aux *aux, struct drm_dp_link *link,
 	if (tp == DP_TRAINING_PATTERN_DISABLE)
 		return 0;
 
-	for (i = 0; i < link->num_lanes; i++)
+	for (i = 0; i < link->lanes; i++)
 		values[i] = DP_TRAIN_MAX_PRE_EMPHASIS_REACHED |
 			    DP_TRAIN_PRE_EMPH_LEVEL_0 |
 			    DP_TRAIN_MAX_SWING_REACHED |
 			    DP_TRAIN_VOLTAGE_SWING_LEVEL_0;
 
 	err = drm_dp_dpcd_write(aux, DP_TRAINING_LANE0_SET, values,
-				link->num_lanes);
+				link->lanes);
 	if (err < 0)
 		return err;
 
@@ -807,13 +807,13 @@ int drm_dp_aux_train(struct drm_dp_aux *aux, struct drm_dp_link *link,
 
 	switch (tp) {
 	case DP_TRAINING_PATTERN_1:
-		if (!drm_dp_clock_recovery_ok(status, link->num_lanes))
+		if (!drm_dp_clock_recovery_ok(status, link->lanes))
 			return -EAGAIN;
 
 		break;
 
 	case DP_TRAINING_PATTERN_2:
-		if (!drm_dp_channel_eq_ok(status, link->num_lanes))
+		if (!drm_dp_channel_eq_ok(status, link->lanes))
 			return -EAGAIN;
 
 		break;
diff --git a/drivers/gpu/drm/tegra/sor.c b/drivers/gpu/drm/tegra/sor.c
index 8c03ca870a09..e3c3f5add411 100644
--- a/drivers/gpu/drm/tegra/sor.c
+++ b/drivers/gpu/drm/tegra/sor.c
@@ -585,7 +585,7 @@ static int tegra_sor_dp_train_fast(struct tegra_sor *sor,
 	if (err < 0)
 		return err;
 
-	for (i = 0, value = 0; i < link->num_lanes; i++) {
+	for (i = 0, value = 0; i < link->lanes; i++) {
 		unsigned long lane = SOR_DP_TPG_CHANNEL_CODING |
 				     SOR_DP_TPG_SCRAMBLER_NONE |
 				     SOR_DP_TPG_PATTERN_TRAIN1;
@@ -606,7 +606,7 @@ static int tegra_sor_dp_train_fast(struct tegra_sor *sor,
 	value |= SOR_DP_SPARE_MACRO_SOR_CLK;
 	tegra_sor_writel(sor, value, SOR_DP_SPARE0);
 
-	for (i = 0, value = 0; i < link->num_lanes; i++) {
+	for (i = 0, value = 0; i < link->lanes; i++) {
 		unsigned long lane = SOR_DP_TPG_CHANNEL_CODING |
 				     SOR_DP_TPG_SCRAMBLER_NONE |
 				     SOR_DP_TPG_PATTERN_TRAIN2;
@@ -621,7 +621,7 @@ static int tegra_sor_dp_train_fast(struct tegra_sor *sor,
 	if (err < 0)
 		return err;
 
-	for (i = 0, value = 0; i < link->num_lanes; i++) {
+	for (i = 0, value = 0; i < link->lanes; i++) {
 		unsigned long lane = SOR_DP_TPG_CHANNEL_CODING |
 				     SOR_DP_TPG_SCRAMBLER_GALIOS |
 				     SOR_DP_TPG_PATTERN_NONE;
@@ -848,11 +848,11 @@ static int tegra_sor_compute_config(struct tegra_sor *sor,
 	u32 num_syms_per_line;
 	unsigned int i;
 
-	if (!link_rate || !link->num_lanes || !pclk || !config->bits_per_pixel)
+	if (!link_rate || !link->lanes || !pclk || !config->bits_per_pixel)
 		return -EINVAL;
 
-	output = link_rate * 8 * link->num_lanes;
 	input = pclk * config->bits_per_pixel;
+	output = link_rate * 8 * link->lanes;
 
 	if (input >= output)
 		return -ERANGE;
@@ -895,7 +895,7 @@ static int tegra_sor_compute_config(struct tegra_sor *sor,
 	watermark = div_u64(watermark + params.error, f);
 	config->watermark = watermark + (config->bits_per_pixel / 8) + 2;
 	num_syms_per_line = (mode->hdisplay * config->bits_per_pixel) *
-			    (link->num_lanes * 8);
+			    (link->lanes * 8);
 
 	if (config->watermark > 30) {
 		config->watermark = 30;
@@ -915,12 +915,12 @@ static int tegra_sor_compute_config(struct tegra_sor *sor,
 	if (link->capabilities & DP_LINK_CAP_ENHANCED_FRAMING)
 		config->hblank_symbols -= 3;
 
-	config->hblank_symbols -= 12 / link->num_lanes;
+	config->hblank_symbols -= 12 / link->lanes;
 
 	/* compute the number of symbols per vertical blanking interval */
 	num = (mode->hdisplay - 25) * link_rate;
 	config->vblank_symbols = div_u64(num, pclk);
-	config->vblank_symbols -= 36 / link->num_lanes + 4;
+	config->vblank_symbols -= 36 / link->lanes + 4;
 
 	dev_dbg(sor->dev, "blank symbols: H:%u V:%u\n", config->hblank_symbols,
 		config->vblank_symbols);
@@ -2004,17 +2004,17 @@ static void tegra_sor_edp_enable(struct drm_encoder *encoder)
 	/* power DP lanes */
 	value = tegra_sor_readl(sor, sor->soc->regs->dp_padctl0);
 
-	if (link.num_lanes <= 2)
+	if (link.lanes <= 2)
 		value &= ~(SOR_DP_PADCTL_PD_TXD_3 | SOR_DP_PADCTL_PD_TXD_2);
 	else
 		value |= SOR_DP_PADCTL_PD_TXD_3 | SOR_DP_PADCTL_PD_TXD_2;
 
-	if (link.num_lanes <= 1)
+	if (link.lanes <= 1)
 		value &= ~SOR_DP_PADCTL_PD_TXD_1;
 	else
 		value |= SOR_DP_PADCTL_PD_TXD_1;
 
-	if (link.num_lanes == 0)
+	if (link.lanes == 0)
 		value &= ~SOR_DP_PADCTL_PD_TXD_0;
 	else
 		value |= SOR_DP_PADCTL_PD_TXD_0;
@@ -2023,7 +2023,7 @@ static void tegra_sor_edp_enable(struct drm_encoder *encoder)
 
 	value = tegra_sor_readl(sor, SOR_DP_LINKCTL0);
 	value &= ~SOR_DP_LINKCTL_LANE_COUNT_MASK;
-	value |= SOR_DP_LINKCTL_LANE_COUNT(link.num_lanes);
+	value |= SOR_DP_LINKCTL_LANE_COUNT(link.lanes);
 	tegra_sor_writel(sor, value, SOR_DP_LINKCTL0);
 
 	/* start lane sequencer */
@@ -2080,7 +2080,7 @@ static void tegra_sor_edp_enable(struct drm_encoder *encoder)
 		dev_err(sor->dev, "failed to configure eDP link: %d\n", err);
 
 	rate = drm_dp_link_rate_to_bw_code(link.rate);
-	lanes = link.num_lanes;
+	lanes = link.lanes;
 
 	value = tegra_sor_readl(sor, SOR_CLK_CNTRL);
 	value &= ~SOR_CLK_CNTRL_DP_LINK_SPEED_MASK;
@@ -2098,7 +2098,7 @@ static void tegra_sor_edp_enable(struct drm_encoder *encoder)
 
 	/* disable training pattern generator */
 
-	for (i = 0; i < link.num_lanes; i++) {
+	for (i = 0; i < link.lanes; i++) {
 		unsigned long lane = SOR_DP_TPG_CHANNEL_CODING |
 				     SOR_DP_TPG_SCRAMBLER_GALIOS |
 				     SOR_DP_TPG_PATTERN_NONE;
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index 6ced0bc6feb9..216a388f467f 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -1100,17 +1100,22 @@ int drm_dp_dpcd_read_link_status(struct drm_dp_aux *aux,
 #define DP_LINK_CAP_ENHANCED_FRAMING (1 << 0)
 
 /**
- * struct drm_dp_link - DP link capabilities
+ * struct drm_dp_link - DP link capabilities and configuration
  * @revision: DP specification revision supported on the link
- * @rate: maximum clock rate supported on the link
- * @num_lanes: maximum number of lanes supported on the link
+ * @max_rate: maximum clock rate supported on the link
+ * @max_lanes: maximum number of lanes supported on the link
  * @capabilities: bitmask of capabilities supported on the link
+ * @rate: currently configured link rate
+ * @lanes: currently configured number of lanes
  */
 struct drm_dp_link {
 	unsigned char revision;
-	unsigned int rate;
-	unsigned int num_lanes;
+	unsigned int max_rate;
+	unsigned int max_lanes;
 	unsigned long capabilities;
+
+	unsigned int rate;
+	unsigned int lanes;
 };
 
 int drm_dp_link_probe(struct drm_dp_aux *aux, struct drm_dp_link *link);
-- 
2.15.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 04/17] drm/dp: Turn link capabilities into booleans
  2018-02-05 19:38 [PATCH 00/17] drm/dp: Miscellaneous improvements Thierry Reding
                   ` (2 preceding siblings ...)
  2018-02-05 19:38 ` [PATCH 03/17] drm/dp: Track link capabilities alongside settings Thierry Reding
@ 2018-02-05 19:38 ` Thierry Reding
  2018-02-05 19:38 ` [PATCH 05/17] drm/dp: Probe link using existing parsing helpers Thierry Reding
                   ` (12 subsequent siblings)
  16 siblings, 0 replies; 20+ messages in thread
From: Thierry Reding @ 2018-02-05 19:38 UTC (permalink / raw)
  To: dri-devel

From: Thierry Reding <treding@nvidia.com>

Rather than storing capabilities as flags in an integer, use a separate
boolean per capability. This simplifies the code that checks for these
capabilities.

Signed-off-by: Thierry Reding <treding@nvidia.com>
---
 drivers/gpu/drm/bridge/tc358767.c  |  6 +++---
 drivers/gpu/drm/drm_dp_helper.c    | 19 ++++++++++++++++---
 drivers/gpu/drm/msm/edp/edp_ctrl.c |  4 ++--
 drivers/gpu/drm/tegra/sor.c        |  4 ++--
 include/drm/drm_dp_helper.h        | 17 ++++++++++++++---
 5 files changed, 37 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/bridge/tc358767.c b/drivers/gpu/drm/bridge/tc358767.c
index 55037f999579..ad278a79feb3 100644
--- a/drivers/gpu/drm/bridge/tc358767.c
+++ b/drivers/gpu/drm/bridge/tc358767.c
@@ -635,8 +635,8 @@ static int tc_get_display_props(struct tc_data *tc)
 		tc->link.base.revision >> 4, tc->link.base.revision & 0x0f,
 		(tc->link.base.rate == 162000) ? "1.62Gbps" : "2.7Gbps",
 		tc->link.base.lanes,
-		(tc->link.base.capabilities & DP_LINK_CAP_ENHANCED_FRAMING) ?
-		"enhanced" : "non-enhanced");
+		(tc->link.base.caps.enhanced_framing) ? "enhanced" :
+		"non-enhanced");
 	dev_dbg(tc->dev, "ANSI 8B/10B: %d\n", tc->link.coding8b10b);
 	dev_dbg(tc->dev, "Display ASSR: %d, TC358767 ASSR: %d\n",
 		tc->link.assr, tc->assr);
@@ -1015,7 +1015,7 @@ static int tc_main_link_stream(struct tc_data *tc, int state)
 
 	if (state) {
 		value = VID_MN_GEN | DP_EN;
-		if (tc->link.base.capabilities & DP_LINK_CAP_ENHANCED_FRAMING)
+		if (tc->link.base.caps.enhanced_framing)
 			value |= EF_EN;
 		tc_write(DP0CTL, value);
 		/*
diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index f401377a199d..6fbce4554029 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -315,6 +315,18 @@ int drm_dp_dpcd_read_link_status(struct drm_dp_aux *aux,
 }
 EXPORT_SYMBOL(drm_dp_dpcd_read_link_status);
 
+static void drm_dp_link_caps_reset(struct drm_dp_link_caps *caps)
+{
+	caps->enhanced_framing = false;
+}
+
+void drm_dp_link_caps_copy(struct drm_dp_link_caps *dest,
+			   const struct drm_dp_link_caps *src)
+{
+	dest->enhanced_framing = src->enhanced_framing;
+}
+EXPORT_SYMBOL(drm_dp_link_caps_copy);
+
 static void drm_dp_link_reset(struct drm_dp_link *link)
 {
 	if (!link)
@@ -323,7 +335,8 @@ static void drm_dp_link_reset(struct drm_dp_link *link)
 	link->revision = 0;
 	link->max_rate = 0;
 	link->max_lanes = 0;
-	link->capabilities = 0;
+
+	drm_dp_link_caps_reset(&link->caps);
 
 	link->rate = 0;
 	link->lanes = 0;
@@ -356,7 +369,7 @@ int drm_dp_link_probe(struct drm_dp_aux *aux, struct drm_dp_link *link)
 	link->max_lanes = values[2] & DP_MAX_LANE_COUNT_MASK;
 
 	if (values[2] & DP_ENHANCED_FRAME_CAP)
-		link->capabilities |= DP_LINK_CAP_ENHANCED_FRAMING;
+		link->caps.enhanced_framing = true;
 
 	link->rate = link->max_rate;
 	link->lanes = link->max_lanes;
@@ -449,7 +462,7 @@ int drm_dp_link_configure(struct drm_dp_aux *aux, struct drm_dp_link *link)
 	values[0] = drm_dp_link_rate_to_bw_code(link->rate);
 	values[1] = link->lanes;
 
-	if (link->capabilities & DP_LINK_CAP_ENHANCED_FRAMING)
+	if (link->caps.enhanced_framing)
 		values[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
 
 	err = drm_dp_dpcd_write(aux, DP_LINK_BW_SET, values, sizeof(values));
diff --git a/drivers/gpu/drm/msm/edp/edp_ctrl.c b/drivers/gpu/drm/msm/edp/edp_ctrl.c
index 71192a0656e3..489fa81bb508 100644
--- a/drivers/gpu/drm/msm/edp/edp_ctrl.c
+++ b/drivers/gpu/drm/msm/edp/edp_ctrl.c
@@ -447,7 +447,7 @@ static void edp_config_ctrl(struct edp_ctrl *ctrl)
 
 	data = EDP_CONFIGURATION_CTRL_LANES(ctrl->lane_cnt - 1);
 
-	if (ctrl->dp_link.capabilities & DP_LINK_CAP_ENHANCED_FRAMING)
+	if (ctrl->dp_link.caps.enhanced_framing)
 		data |= EDP_CONFIGURATION_CTRL_ENHANCED_FRAMING;
 
 	depth = EDP_6BIT;
@@ -769,7 +769,7 @@ static int edp_do_link_train(struct edp_ctrl *ctrl)
 	 */
 	dp_link.lanes = ctrl->lane_cnt;
 	dp_link.rate = drm_dp_bw_code_to_link_rate(ctrl->link_rate);
-	dp_link.capabilities = ctrl->dp_link.capabilities;
+	drm_dp_link_caps_copy(&dp_link.caps, &ctrl->dp_link.caps);
 	if (drm_dp_link_configure(ctrl->drm_aux, &dp_link) < 0)
 		return EDP_TRAIN_FAIL;
 
diff --git a/drivers/gpu/drm/tegra/sor.c b/drivers/gpu/drm/tegra/sor.c
index e3c3f5add411..f24c012f1b41 100644
--- a/drivers/gpu/drm/tegra/sor.c
+++ b/drivers/gpu/drm/tegra/sor.c
@@ -912,7 +912,7 @@ static int tegra_sor_compute_config(struct tegra_sor *sor,
 	num = ((mode->htotal - mode->hdisplay) - 7) * link_rate;
 	config->hblank_symbols = div_u64(num, pclk);
 
-	if (link->capabilities & DP_LINK_CAP_ENHANCED_FRAMING)
+	if (link->caps.enhanced_framing)
 		config->hblank_symbols -= 3;
 
 	config->hblank_symbols -= 12 / link->lanes;
@@ -2091,7 +2091,7 @@ static void tegra_sor_edp_enable(struct drm_encoder *encoder)
 	value &= ~SOR_DP_LINKCTL_LANE_COUNT_MASK;
 	value |= SOR_DP_LINKCTL_LANE_COUNT(lanes);
 
-	if (link.capabilities & DP_LINK_CAP_ENHANCED_FRAMING)
+	if (link.caps.enhanced_framing)
 		value |= SOR_DP_LINKCTL_ENHANCED_FRAME;
 
 	tegra_sor_writel(sor, value, SOR_DP_LINKCTL0);
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index 216a388f467f..e3429abb03f9 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -1097,14 +1097,24 @@ int drm_dp_dpcd_read_link_status(struct drm_dp_aux *aux,
 /*
  * DisplayPort link
  */
-#define DP_LINK_CAP_ENHANCED_FRAMING (1 << 0)
+
+/**
+ * struct drm_dp_link_caps - DP link capabilities
+ * @enhanced_framing: enhanced framing capability (mandatory as of DP 1.2)
+ */
+struct drm_dp_link_caps {
+	bool enhanced_framing;
+};
+
+void drm_dp_link_caps_copy(struct drm_dp_link_caps *dest,
+			   const struct drm_dp_link_caps *src);
 
 /**
  * struct drm_dp_link - DP link capabilities and configuration
  * @revision: DP specification revision supported on the link
  * @max_rate: maximum clock rate supported on the link
  * @max_lanes: maximum number of lanes supported on the link
- * @capabilities: bitmask of capabilities supported on the link
+ * @caps: capabilities supported on the link (see &drm_dp_link_caps)
  * @rate: currently configured link rate
  * @lanes: currently configured number of lanes
  */
@@ -1112,7 +1122,8 @@ struct drm_dp_link {
 	unsigned char revision;
 	unsigned int max_rate;
 	unsigned int max_lanes;
-	unsigned long capabilities;
+
+	struct drm_dp_link_caps caps;
 
 	unsigned int rate;
 	unsigned int lanes;
-- 
2.15.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 05/17] drm/dp: Probe link using existing parsing helpers
  2018-02-05 19:38 [PATCH 00/17] drm/dp: Miscellaneous improvements Thierry Reding
                   ` (3 preceding siblings ...)
  2018-02-05 19:38 ` [PATCH 04/17] drm/dp: Turn link capabilities into booleans Thierry Reding
@ 2018-02-05 19:38 ` Thierry Reding
  2018-02-05 19:38 ` [PATCH 06/17] drm/dp: Read fast training capability from link Thierry Reding
                   ` (11 subsequent siblings)
  16 siblings, 0 replies; 20+ messages in thread
From: Thierry Reding @ 2018-02-05 19:38 UTC (permalink / raw)
  To: dri-devel

From: Thierry Reding <treding@nvidia.com>

Use existing parsing helpers to probe a DisplayPort link.

Signed-off-by: Thierry Reding <treding@nvidia.com>
---
 drivers/gpu/drm/drm_dp_helper.c | 29 ++++++++++++++++++++++-------
 include/drm/drm_dp_helper.h     |  2 ++
 2 files changed, 24 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index 6fbce4554029..982dd9febb1c 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -299,6 +299,22 @@ ssize_t drm_dp_dpcd_write(struct drm_dp_aux *aux, unsigned int offset,
 }
 EXPORT_SYMBOL(drm_dp_dpcd_write);
 
+/**
+ * drm_dp_dpcd_read_link_caps() - read DPCD link capabilities
+ * @aux: DisplayPort AUX channel
+ * @caps: buffer to store the link capabilities in
+ *
+ * Returns:
+ * The number of bytes transferred on success or a negative error code on
+ * failure.
+ */
+int drm_dp_dpcd_read_link_caps(struct drm_dp_aux *aux,
+			       u8 caps[DP_RECEIVER_CAP_SIZE])
+{
+	return drm_dp_dpcd_read(aux, DP_DPCD_REV, caps, DP_RECEIVER_CAP_SIZE);
+}
+EXPORT_SYMBOL(drm_dp_dpcd_read_link_caps);
+
 /**
  * drm_dp_dpcd_read_link_status() - read DPCD link status (bytes 0x202-0x207)
  * @aux: DisplayPort AUX channel
@@ -355,21 +371,20 @@ 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 values[3];
+	u8 values[DP_RECEIVER_CAP_SIZE];
 	int err;
 
 	drm_dp_link_reset(link);
 
-	err = drm_dp_dpcd_read(aux, DP_DPCD_REV, values, sizeof(values));
+	err = drm_dp_dpcd_read_link_caps(aux, values);
 	if (err < 0)
 		return err;
 
-	link->revision = values[0];
-	link->max_rate = drm_dp_bw_code_to_link_rate(values[1]);
-	link->max_lanes = values[2] & DP_MAX_LANE_COUNT_MASK;
+	link->revision = values[DP_DPCD_REV];
+	link->max_rate = drm_dp_max_link_rate(values);
+	link->max_lanes = drm_dp_max_lane_count(values);
 
-	if (values[2] & DP_ENHANCED_FRAME_CAP)
-		link->caps.enhanced_framing = true;
+	link->caps.enhanced_framing = drm_dp_enhanced_frame_cap(values);
 
 	link->rate = link->max_rate;
 	link->lanes = link->max_lanes;
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index e3429abb03f9..85ff67958875 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -1091,6 +1091,8 @@ static inline ssize_t drm_dp_dpcd_writeb(struct drm_dp_aux *aux,
 	return drm_dp_dpcd_write(aux, offset, &value, 1);
 }
 
+int drm_dp_dpcd_read_link_caps(struct drm_dp_aux *aux,
+			       u8 caps[DP_RECEIVER_CAP_SIZE]);
 int drm_dp_dpcd_read_link_status(struct drm_dp_aux *aux,
 				 u8 status[DP_LINK_STATUS_SIZE]);
 
-- 
2.15.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 06/17] drm/dp: Read fast training capability from link
  2018-02-05 19:38 [PATCH 00/17] drm/dp: Miscellaneous improvements Thierry Reding
                   ` (4 preceding siblings ...)
  2018-02-05 19:38 ` [PATCH 05/17] drm/dp: Probe link using existing parsing helpers Thierry Reding
@ 2018-02-05 19:38 ` Thierry Reding
  2018-02-05 19:38 ` [PATCH 07/17] drm/dp: Read TPS3 capability from sink Thierry Reding
                   ` (10 subsequent siblings)
  16 siblings, 0 replies; 20+ messages in thread
From: Thierry Reding @ 2018-02-05 19:38 UTC (permalink / raw)
  To: dri-devel

From: Thierry Reding <treding@nvidia.com>

While probing the DisplayPort link, query the fast training capability.
If supported, drivers can use the fast link training sequence instead of
the more involved full link training sequence.

Signed-off-by: Thierry Reding <treding@nvidia.com>
---
 drivers/gpu/drm/drm_dp_helper.c | 3 +++
 include/drm/drm_dp_helper.h     | 9 +++++++++
 2 files changed, 12 insertions(+)

diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index 982dd9febb1c..2d56aeda1b75 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -334,12 +334,14 @@ EXPORT_SYMBOL(drm_dp_dpcd_read_link_status);
 static void drm_dp_link_caps_reset(struct drm_dp_link_caps *caps)
 {
 	caps->enhanced_framing = false;
+	caps->fast_training = false;
 }
 
 void drm_dp_link_caps_copy(struct drm_dp_link_caps *dest,
 			   const struct drm_dp_link_caps *src)
 {
 	dest->enhanced_framing = src->enhanced_framing;
+	dest->fast_training = src->fast_training;
 }
 EXPORT_SYMBOL(drm_dp_link_caps_copy);
 
@@ -385,6 +387,7 @@ int drm_dp_link_probe(struct drm_dp_aux *aux, struct drm_dp_link *link)
 	link->max_lanes = drm_dp_max_lane_count(values);
 
 	link->caps.enhanced_framing = drm_dp_enhanced_frame_cap(values);
+	link->caps.fast_training = drm_dp_fast_training_cap(values);
 
 	link->rate = link->max_rate;
 	link->lanes = link->max_lanes;
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index 85ff67958875..680d6719d463 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -976,6 +976,13 @@ drm_dp_is_branch(const u8 dpcd[DP_RECEIVER_CAP_SIZE])
 	return dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_PRESENT;
 }
 
+static inline bool
+drm_dp_fast_training_cap(const u8 dpcd[DP_RECEIVER_CAP_SIZE])
+{
+	return dpcd[DP_DPCD_REV] >= 0x11 &&
+		(dpcd[DP_MAX_DOWNSPREAD] & DP_NO_AUX_HANDSHAKE_LINK_TRAINING);
+}
+
 /*
  * DisplayPort AUX channel
  */
@@ -1103,9 +1110,11 @@ int drm_dp_dpcd_read_link_status(struct drm_dp_aux *aux,
 /**
  * struct drm_dp_link_caps - DP link capabilities
  * @enhanced_framing: enhanced framing capability (mandatory as of DP 1.2)
+ * @fast_training: AUX CH handshake not required for link training
  */
 struct drm_dp_link_caps {
 	bool enhanced_framing;
+	bool fast_training;
 };
 
 void drm_dp_link_caps_copy(struct drm_dp_link_caps *dest,
-- 
2.15.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 07/17] drm/dp: Read TPS3 capability from sink
  2018-02-05 19:38 [PATCH 00/17] drm/dp: Miscellaneous improvements Thierry Reding
                   ` (5 preceding siblings ...)
  2018-02-05 19:38 ` [PATCH 06/17] drm/dp: Read fast training capability from link Thierry Reding
@ 2018-02-05 19:38 ` Thierry Reding
  2018-02-05 19:38 ` [PATCH 08/17] drm/dp: Read channel coding " Thierry Reding
                   ` (9 subsequent siblings)
  16 siblings, 0 replies; 20+ messages in thread
From: Thierry Reding @ 2018-02-05 19:38 UTC (permalink / raw)
  To: dri-devel

From: Thierry Reding <treding@nvidia.com>

The TPS3 capability can be exposed by DP 1.2 and later sinks if they
support the alternative training pattern for channel equalization.

Signed-off-by: Thierry Reding <treding@nvidia.com>
---
 drivers/gpu/drm/drm_dp_helper.c | 3 +++
 include/drm/drm_dp_helper.h     | 2 ++
 2 files changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index 2d56aeda1b75..664d814ab250 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -334,6 +334,7 @@ EXPORT_SYMBOL(drm_dp_dpcd_read_link_status);
 static void drm_dp_link_caps_reset(struct drm_dp_link_caps *caps)
 {
 	caps->enhanced_framing = false;
+	caps->tps3_supported = false;
 	caps->fast_training = false;
 }
 
@@ -341,6 +342,7 @@ void drm_dp_link_caps_copy(struct drm_dp_link_caps *dest,
 			   const struct drm_dp_link_caps *src)
 {
 	dest->enhanced_framing = src->enhanced_framing;
+	dest->tps3_supported = src->tps3_supported;
 	dest->fast_training = src->fast_training;
 }
 EXPORT_SYMBOL(drm_dp_link_caps_copy);
@@ -387,6 +389,7 @@ int drm_dp_link_probe(struct drm_dp_aux *aux, struct drm_dp_link *link)
 	link->max_lanes = drm_dp_max_lane_count(values);
 
 	link->caps.enhanced_framing = drm_dp_enhanced_frame_cap(values);
+	link->caps.tps3_supported = drm_dp_tps3_supported(values);
 	link->caps.fast_training = drm_dp_fast_training_cap(values);
 
 	link->rate = link->max_rate;
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index 680d6719d463..81af618c6b4a 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -1110,10 +1110,12 @@ int drm_dp_dpcd_read_link_status(struct drm_dp_aux *aux,
 /**
  * struct drm_dp_link_caps - DP link capabilities
  * @enhanced_framing: enhanced framing capability (mandatory as of DP 1.2)
+ * @tps3_supported: training pattern sequence 3 supported for equalization
  * @fast_training: AUX CH handshake not required for link training
  */
 struct drm_dp_link_caps {
 	bool enhanced_framing;
+	bool tps3_supported;
 	bool fast_training;
 };
 
-- 
2.15.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 08/17] drm/dp: Read channel coding capability from sink
  2018-02-05 19:38 [PATCH 00/17] drm/dp: Miscellaneous improvements Thierry Reding
                   ` (6 preceding siblings ...)
  2018-02-05 19:38 ` [PATCH 07/17] drm/dp: Read TPS3 capability from sink Thierry Reding
@ 2018-02-05 19:38 ` Thierry Reding
  2018-02-05 19:38 ` [PATCH 09/17] drm/dp: Read alternate scrambler reset " Thierry Reding
                   ` (8 subsequent siblings)
  16 siblings, 0 replies; 20+ messages in thread
From: Thierry Reding @ 2018-02-05 19:38 UTC (permalink / raw)
  To: dri-devel

From: Thierry Reding <treding@nvidia.com>

Parse from the sink capabilities whether or not it supports ANSI 8B/10B
channel coding as specified in ANSI X3.230-1994, clause 11.

Signed-off-by: Thierry Reding <treding@nvidia.com>
---
 drivers/gpu/drm/drm_dp_helper.c | 3 +++
 include/drm/drm_dp_helper.h     | 9 +++++++++
 2 files changed, 12 insertions(+)

diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index 664d814ab250..743343527bfa 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -336,6 +336,7 @@ static void drm_dp_link_caps_reset(struct drm_dp_link_caps *caps)
 	caps->enhanced_framing = false;
 	caps->tps3_supported = false;
 	caps->fast_training = false;
+	caps->channel_coding = false;
 }
 
 void drm_dp_link_caps_copy(struct drm_dp_link_caps *dest,
@@ -344,6 +345,7 @@ void drm_dp_link_caps_copy(struct drm_dp_link_caps *dest,
 	dest->enhanced_framing = src->enhanced_framing;
 	dest->tps3_supported = src->tps3_supported;
 	dest->fast_training = src->fast_training;
+	dest->channel_coding = src->channel_coding;
 }
 EXPORT_SYMBOL(drm_dp_link_caps_copy);
 
@@ -391,6 +393,7 @@ int drm_dp_link_probe(struct drm_dp_aux *aux, struct drm_dp_link *link)
 	link->caps.enhanced_framing = drm_dp_enhanced_frame_cap(values);
 	link->caps.tps3_supported = drm_dp_tps3_supported(values);
 	link->caps.fast_training = drm_dp_fast_training_cap(values);
+	link->caps.channel_coding = drm_dp_channel_coding_supported(values);
 
 	link->rate = link->max_rate;
 	link->lanes = link->max_lanes;
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index 81af618c6b4a..fe7aef2c0736 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -89,6 +89,7 @@
 # define DP_DETAILED_CAP_INFO_AVAILABLE	    (1 << 4) /* DPI */
 
 #define DP_MAIN_LINK_CHANNEL_CODING         0x006
+# define DP_CAP_ANSI_8B10B		    (1 << 0)
 
 #define DP_DOWN_STREAM_PORT_COUNT	    0x007
 # define DP_PORT_COUNT_MASK		    0x0f
@@ -983,6 +984,12 @@ drm_dp_fast_training_cap(const u8 dpcd[DP_RECEIVER_CAP_SIZE])
 		(dpcd[DP_MAX_DOWNSPREAD] & DP_NO_AUX_HANDSHAKE_LINK_TRAINING);
 }
 
+static inline bool
+drm_dp_channel_coding_supported(const u8 dpcd[DP_RECEIVER_CAP_SIZE])
+{
+	return dpcd[DP_MAIN_LINK_CHANNEL_CODING] & DP_CAP_ANSI_8B10B;
+}
+
 /*
  * DisplayPort AUX channel
  */
@@ -1112,11 +1119,13 @@ int drm_dp_dpcd_read_link_status(struct drm_dp_aux *aux,
  * @enhanced_framing: enhanced framing capability (mandatory as of DP 1.2)
  * @tps3_supported: training pattern sequence 3 supported for equalization
  * @fast_training: AUX CH handshake not required for link training
+ * @channel_coding: ANSI 8B/10B channel coding capability
  */
 struct drm_dp_link_caps {
 	bool enhanced_framing;
 	bool tps3_supported;
 	bool fast_training;
+	bool channel_coding;
 };
 
 void drm_dp_link_caps_copy(struct drm_dp_link_caps *dest,
-- 
2.15.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 09/17] drm/dp: Read alternate scrambler reset capability from sink
  2018-02-05 19:38 [PATCH 00/17] drm/dp: Miscellaneous improvements Thierry Reding
                   ` (7 preceding siblings ...)
  2018-02-05 19:38 ` [PATCH 08/17] drm/dp: Read channel coding " Thierry Reding
@ 2018-02-05 19:38 ` Thierry Reding
  2018-02-05 19:38 ` [PATCH 10/17] drm/dp: Read eDP version from DPCD Thierry Reding
                   ` (7 subsequent siblings)
  16 siblings, 0 replies; 20+ messages in thread
From: Thierry Reding @ 2018-02-05 19:38 UTC (permalink / raw)
  To: dri-devel

From: Thierry Reding <treding@nvidia.com>

Parse from the sink capabilities whether or not the eDP alternate
scrambler reset value of 0xfffe is supported.

Signed-off-by: Thierry Reding <treding@nvidia.com>
---
 drivers/gpu/drm/drm_dp_helper.c | 5 +++++
 include/drm/drm_dp_helper.h     | 9 +++++++++
 2 files changed, 14 insertions(+)

diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index 743343527bfa..23429a53452d 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -337,6 +337,7 @@ static void drm_dp_link_caps_reset(struct drm_dp_link_caps *caps)
 	caps->tps3_supported = false;
 	caps->fast_training = false;
 	caps->channel_coding = false;
+	caps->alternate_scrambler_reset = false;
 }
 
 void drm_dp_link_caps_copy(struct drm_dp_link_caps *dest,
@@ -346,6 +347,7 @@ void drm_dp_link_caps_copy(struct drm_dp_link_caps *dest,
 	dest->tps3_supported = src->tps3_supported;
 	dest->fast_training = src->fast_training;
 	dest->channel_coding = src->channel_coding;
+	dest->alternate_scrambler_reset = src->alternate_scrambler_reset;
 }
 EXPORT_SYMBOL(drm_dp_link_caps_copy);
 
@@ -395,6 +397,9 @@ int drm_dp_link_probe(struct drm_dp_aux *aux, struct drm_dp_link *link)
 	link->caps.fast_training = drm_dp_fast_training_cap(values);
 	link->caps.channel_coding = drm_dp_channel_coding_supported(values);
 
+	if (drm_dp_alternate_scrambler_reset_cap(values))
+		link->caps.alternate_scrambler_reset = true;
+
 	link->rate = link->max_rate;
 	link->lanes = link->max_lanes;
 
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index fe7aef2c0736..c52b6cf96a81 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -990,6 +990,13 @@ drm_dp_channel_coding_supported(const u8 dpcd[DP_RECEIVER_CAP_SIZE])
 	return dpcd[DP_MAIN_LINK_CHANNEL_CODING] & DP_CAP_ANSI_8B10B;
 }
 
+static inline bool
+drm_dp_alternate_scrambler_reset_cap(const u8 dpcd[DP_RECEIVER_CAP_SIZE])
+{
+	return dpcd[DP_EDP_CONFIGURATION_CAP] &
+			DP_ALTERNATE_SCRAMBLER_RESET_CAP;
+}
+
 /*
  * DisplayPort AUX channel
  */
@@ -1120,12 +1127,14 @@ int drm_dp_dpcd_read_link_status(struct drm_dp_aux *aux,
  * @tps3_supported: training pattern sequence 3 supported for equalization
  * @fast_training: AUX CH handshake not required for link training
  * @channel_coding: ANSI 8B/10B channel coding capability
+ * @alternate_scrambler_reset: eDP alternate scrambler reset capability
  */
 struct drm_dp_link_caps {
 	bool enhanced_framing;
 	bool tps3_supported;
 	bool fast_training;
 	bool channel_coding;
+	bool alternate_scrambler_reset;
 };
 
 void drm_dp_link_caps_copy(struct drm_dp_link_caps *dest,
-- 
2.15.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 10/17] drm/dp: Read eDP version from DPCD
  2018-02-05 19:38 [PATCH 00/17] drm/dp: Miscellaneous improvements Thierry Reding
                   ` (8 preceding siblings ...)
  2018-02-05 19:38 ` [PATCH 09/17] drm/dp: Read alternate scrambler reset " Thierry Reding
@ 2018-02-05 19:38 ` Thierry Reding
  2018-02-05 19:38 ` [PATCH 11/17] drm/dp: Read AUX read interval " Thierry Reding
                   ` (6 subsequent siblings)
  16 siblings, 0 replies; 20+ messages in thread
From: Thierry Reding @ 2018-02-05 19:38 UTC (permalink / raw)
  To: dri-devel

From: Thierry Reding <treding@nvidia.com>

If the sink supports eDP, read the eDP revision from it's DPCD.

Signed-off-by: Thierry Reding <treding@nvidia.com>
---
 drivers/gpu/drm/drm_dp_helper.c | 16 +++++++++++++++-
 include/drm/drm_dp_helper.h     |  2 ++
 2 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index 23429a53452d..c78cc62f149f 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -361,6 +361,7 @@ static void drm_dp_link_reset(struct drm_dp_link *link)
 	link->max_lanes = 0;
 
 	drm_dp_link_caps_reset(&link->caps);
+	link->edp = 0;
 
 	link->rate = 0;
 	link->lanes = 0;
@@ -397,9 +398,22 @@ int drm_dp_link_probe(struct drm_dp_aux *aux, struct drm_dp_link *link)
 	link->caps.fast_training = drm_dp_fast_training_cap(values);
 	link->caps.channel_coding = drm_dp_channel_coding_supported(values);
 
-	if (drm_dp_alternate_scrambler_reset_cap(values))
+	if (drm_dp_alternate_scrambler_reset_cap(values)) {
+		static const u8 edp_revs[] = { 0x11, 0x12, 0x13, 0x14 };
+		u8 value;
+
 		link->caps.alternate_scrambler_reset = true;
 
+		err = drm_dp_dpcd_readb(aux, DP_EDP_DPCD_REV, &value);
+		if (err < 0)
+			return err;
+
+		if (value >= ARRAY_SIZE(edp_revs))
+			DRM_ERROR("unsupported eDP version: %02x\n", value);
+		else
+			link->edp = edp_revs[value];
+	}
+
 	link->rate = link->max_rate;
 	link->lanes = link->max_lanes;
 
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index c52b6cf96a81..705c56ebe74d 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -1146,6 +1146,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)
+ * @edp: eDP revision (0x11: eDP 1.1, 0x12: eDP 1.2, ...)
  * @rate: currently configured link rate
  * @lanes: currently configured number of lanes
  */
@@ -1155,6 +1156,7 @@ struct drm_dp_link {
 	unsigned int max_lanes;
 
 	struct drm_dp_link_caps caps;
+	unsigned char edp;
 
 	unsigned int rate;
 	unsigned int lanes;
-- 
2.15.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 11/17] drm/dp: Read AUX read interval from DPCD
  2018-02-05 19:38 [PATCH 00/17] drm/dp: Miscellaneous improvements Thierry Reding
                   ` (9 preceding siblings ...)
  2018-02-05 19:38 ` [PATCH 10/17] drm/dp: Read eDP version from DPCD Thierry Reding
@ 2018-02-05 19:38 ` Thierry Reding
  2018-02-05 19:38 ` [PATCH 12/17] drm/dp: Do not busy-loop during link training Thierry Reding
                   ` (5 subsequent siblings)
  16 siblings, 0 replies; 20+ messages in thread
From: Thierry Reding @ 2018-02-05 19:38 UTC (permalink / raw)
  To: dri-devel

From: Thierry Reding <treding@nvidia.com>

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>
---
 drivers/gpu/drm/drm_dp_helper.c |  3 +++
 include/drm/drm_dp_helper.h     | 18 ++++++++++++++++++
 2 files changed, 21 insertions(+)

diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index c78cc62f149f..0d9d5360465c 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -361,6 +361,7 @@ 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 = 0;
 	link->edp = 0;
 
 	link->rate = 0;
@@ -414,6 +415,8 @@ int drm_dp_link_probe(struct drm_dp_aux *aux, struct drm_dp_link *link)
 			link->edp = edp_revs[value];
 	}
 
+	link->aux_rd_interval = drm_dp_aux_rd_interval(values);
+
 	link->rate = link->max_rate;
 	link->lanes = link->max_lanes;
 
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index 705c56ebe74d..8213f1c53f9b 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -997,6 +997,22 @@ drm_dp_alternate_scrambler_reset_cap(const u8 dpcd[DP_RECEIVER_CAP_SIZE])
 			DP_ALTERNATE_SCRAMBLER_RESET_CAP;
 }
 
+/**
+ * drm_dp_read_aux_interval() - read the AUX read interval from the DPCD
+ * @dpcd: receiver capacity buffer
+ *
+ * Reads the AUX read interval (in microseconds) from the DPCD. Note that the
+ * TRAINING_AUX_RD_INTERVAL stores the value in units of 4 milliseconds.
+ *
+ * Returns:
+ * The read AUX interval in microseconds.
+ */
+static inline unsigned int
+drm_dp_aux_rd_interval(const u8 dpcd[DP_RECEIVER_CAP_SIZE])
+{
+	return dpcd[DP_TRAINING_AUX_RD_INTERVAL] * 4000;
+}
+
 /*
  * DisplayPort AUX channel
  */
@@ -1146,6 +1162,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
@@ -1156,6 +1173,7 @@ struct drm_dp_link {
 	unsigned int max_lanes;
 
 	struct drm_dp_link_caps caps;
+	unsigned int aux_rd_interval;
 	unsigned char edp;
 
 	unsigned int rate;
-- 
2.15.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 12/17] drm/dp: Do not busy-loop during link training
  2018-02-05 19:38 [PATCH 00/17] drm/dp: Miscellaneous improvements Thierry Reding
                   ` (10 preceding siblings ...)
  2018-02-05 19:38 ` [PATCH 11/17] drm/dp: Read AUX read interval " Thierry Reding
@ 2018-02-05 19:38 ` Thierry Reding
  2018-02-05 19:38 ` [PATCH 13/17] drm/dp: Use drm_dp_aux_rd_interval() Thierry Reding
                   ` (4 subsequent siblings)
  16 siblings, 0 replies; 20+ messages in thread
From: Thierry Reding @ 2018-02-05 19:38 UTC (permalink / raw)
  To: dri-devel

From: Thierry Reding <treding@nvidia.com>

Use microsecond sleeps for the clock recovery and channel equalization
delays during link training. The duration of these delays can be from
100 us up to 16 ms. It is rude to busy-loop for that amount of time.

While at it, also convert to standard coding style by putting the
opening braces in a function definition on a new line.

Signed-off-by: Thierry Reding <treding@nvidia.com>
---
 drivers/gpu/drm/drm_dp_helper.c | 26 ++++++++++++++++++--------
 1 file changed, 18 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index 0d9d5360465c..0d9e66ea9667 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -118,19 +118,29 @@ u8 drm_dp_get_adjust_request_pre_emphasis(const u8 link_status[DP_LINK_STATUS_SI
 }
 EXPORT_SYMBOL(drm_dp_get_adjust_request_pre_emphasis);
 
-void drm_dp_link_train_clock_recovery_delay(const u8 dpcd[DP_RECEIVER_CAP_SIZE]) {
-	if (dpcd[DP_TRAINING_AUX_RD_INTERVAL] == 0)
-		udelay(100);
+void drm_dp_link_train_clock_recovery_delay(const u8 dpcd[DP_RECEIVER_CAP_SIZE])
+{
+	unsigned int min;
+
+	if (dpcd[DP_TRAINING_AUX_RD_INTERVAL] != 0)
+		min = dpcd[DP_TRAINING_AUX_RD_INTERVAL] * 4000;
 	else
-		mdelay(dpcd[DP_TRAINING_AUX_RD_INTERVAL] * 4);
+		min = 100;
+
+	usleep_range(min, min * 2);
 }
 EXPORT_SYMBOL(drm_dp_link_train_clock_recovery_delay);
 
-void drm_dp_link_train_channel_eq_delay(const u8 dpcd[DP_RECEIVER_CAP_SIZE]) {
-	if (dpcd[DP_TRAINING_AUX_RD_INTERVAL] == 0)
-		udelay(400);
+void drm_dp_link_train_channel_eq_delay(const u8 dpcd[DP_RECEIVER_CAP_SIZE])
+{
+	unsigned int min;
+
+	if (dpcd[DP_TRAINING_AUX_RD_INTERVAL] != 0)
+		min = dpcd[DP_TRAINING_AUX_RD_INTERVAL] * 4000;
 	else
-		mdelay(dpcd[DP_TRAINING_AUX_RD_INTERVAL] * 4);
+		min = 400;
+
+	usleep_range(min, min * 2);
 }
 EXPORT_SYMBOL(drm_dp_link_train_channel_eq_delay);
 
-- 
2.15.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 13/17] drm/dp: Use drm_dp_aux_rd_interval()
  2018-02-05 19:38 [PATCH 00/17] drm/dp: Miscellaneous improvements Thierry Reding
                   ` (11 preceding siblings ...)
  2018-02-05 19:38 ` [PATCH 12/17] drm/dp: Do not busy-loop during link training Thierry Reding
@ 2018-02-05 19:38 ` Thierry Reding
  2018-02-05 19:38 ` [PATCH 14/17] drm/dp: Add helper to get post-cursor adjustments Thierry Reding
                   ` (3 subsequent siblings)
  16 siblings, 0 replies; 20+ messages in thread
From: Thierry Reding @ 2018-02-05 19:38 UTC (permalink / raw)
  To: dri-devel

From: Thierry Reding <treding@nvidia.com>

Make use of the newly added drm_dp_aux_rd_interval() helper in existing
DP link training helpers and add comments about minimum required delays
mandated by the DP specification.

Signed-off-by: Thierry Reding <treding@nvidia.com>
---
 drivers/gpu/drm/drm_dp_helper.c | 20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index 0d9e66ea9667..dabac772dfc3 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -120,11 +120,13 @@ EXPORT_SYMBOL(drm_dp_get_adjust_request_pre_emphasis);
 
 void drm_dp_link_train_clock_recovery_delay(const u8 dpcd[DP_RECEIVER_CAP_SIZE])
 {
-	unsigned int min;
+	unsigned int min = drm_dp_aux_rd_interval(dpcd);
 
-	if (dpcd[DP_TRAINING_AUX_RD_INTERVAL] != 0)
-		min = dpcd[DP_TRAINING_AUX_RD_INTERVAL] * 4000;
-	else
+	/*
+	 * The DP specification mandates a delay of 100 us during clock
+	 * recovery if the sink doesn't report an AUX read interval.
+	 */
+	if (min == 0)
 		min = 100;
 
 	usleep_range(min, min * 2);
@@ -133,11 +135,13 @@ EXPORT_SYMBOL(drm_dp_link_train_clock_recovery_delay);
 
 void drm_dp_link_train_channel_eq_delay(const u8 dpcd[DP_RECEIVER_CAP_SIZE])
 {
-	unsigned int min;
+	unsigned int min = drm_dp_aux_rd_interval(dpcd);
 
-	if (dpcd[DP_TRAINING_AUX_RD_INTERVAL] != 0)
-		min = dpcd[DP_TRAINING_AUX_RD_INTERVAL] * 4000;
-	else
+	/*
+	 * The DP specification mandates a delay of 400 us during clock
+	 * recovery if the sink doesn't report an AUX read interval.
+	 */
+	if (min == 0)
 		min = 400;
 
 	usleep_range(min, min * 2);
-- 
2.15.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 14/17] drm/dp: Add helper to get post-cursor adjustments
  2018-02-05 19:38 [PATCH 00/17] drm/dp: Miscellaneous improvements Thierry Reding
                   ` (12 preceding siblings ...)
  2018-02-05 19:38 ` [PATCH 13/17] drm/dp: Use drm_dp_aux_rd_interval() Thierry Reding
@ 2018-02-05 19:38 ` Thierry Reding
  2018-02-05 19:38 ` [PATCH 15/17] drm/dp: Set channel coding on link configuration Thierry Reding
                   ` (2 subsequent siblings)
  16 siblings, 0 replies; 20+ messages in thread
From: Thierry Reding @ 2018-02-05 19:38 UTC (permalink / raw)
  To: dri-devel

From: Thierry Reding <treding@nvidia.com>

If the transmitter supports pre-emphasis post cursor2 the sink will
request adjustments in a similar way to how it requests adjustments to
the voltage swing and pre-emphasis settings.

Add a helper to extract these adjustments on a per-lane basis from the
DPCD link status.

Signed-off-by: Thierry Reding <treding@nvidia.com>
---
 drivers/gpu/drm/drm_dp_helper.c | 10 ++++++++++
 include/drm/drm_dp_helper.h     | 10 ++++++++++
 2 files changed, 20 insertions(+)

diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index dabac772dfc3..f1a7f18ab795 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -118,6 +118,16 @@ u8 drm_dp_get_adjust_request_pre_emphasis(const u8 link_status[DP_LINK_STATUS_SI
 }
 EXPORT_SYMBOL(drm_dp_get_adjust_request_pre_emphasis);
 
+u8 drm_dp_get_adjust_request_post_cursor(const u8 link_status[DP_LINK_STATUS_SIZE],
+					 unsigned int lane)
+{
+	unsigned int offset = DP_ADJUST_REQUEST_POST_CURSOR2;
+	u8 value = dp_link_status(link_status, offset);
+
+	return (value >> (lane << 1)) & 0x3;
+}
+EXPORT_SYMBOL(drm_dp_get_adjust_request_post_cursor);
+
 void drm_dp_link_train_clock_recovery_delay(const u8 dpcd[DP_RECEIVER_CAP_SIZE])
 {
 	unsigned int min = drm_dp_aux_rd_interval(dpcd);
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index 8213f1c53f9b..4c7badcde945 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -512,6 +512,14 @@
 # define DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT  6
 
 #define DP_ADJUST_REQUEST_POST_CURSOR2      0x20c
+# define DP_ADJUST_POST_CURSOR2_LANE0_MASK  0x03
+# define DP_ADJUST_POST_CURSOR2_LANE0_SHIFT 0
+# define DP_ADJUST_POST_CURSOR2_LANE1_MASK  0x0c
+# define DP_ADJUST_POST_CURSOR2_LANE1_SHIFT 2
+# define DP_ADJUST_POST_CURSOR2_LANE2_MASK  0x30
+# define DP_ADJUST_POST_CURSOR2_LANE2_SHIFT 4
+# define DP_ADJUST_POST_CURSOR2_LANE3_MASK  0xc0
+# define DP_ADJUST_POST_CURSOR2_LANE3_SHIFT 6
 
 #define DP_TEST_REQUEST			    0x218
 # define DP_TEST_LINK_TRAINING		    (1 << 0)
@@ -892,6 +900,8 @@ u8 drm_dp_get_adjust_request_voltage(const u8 link_status[DP_LINK_STATUS_SIZE],
 				     int lane);
 u8 drm_dp_get_adjust_request_pre_emphasis(const u8 link_status[DP_LINK_STATUS_SIZE],
 					  int lane);
+u8 drm_dp_get_adjust_request_post_cursor(const u8 link_status[DP_LINK_STATUS_SIZE],
+					 unsigned int lane);
 
 #define DP_BRANCH_OUI_HEADER_SIZE	0xc
 #define DP_RECEIVER_CAP_SIZE		0xf
-- 
2.15.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 15/17] drm/dp: Set channel coding on link configuration
  2018-02-05 19:38 [PATCH 00/17] drm/dp: Miscellaneous improvements Thierry Reding
                   ` (13 preceding siblings ...)
  2018-02-05 19:38 ` [PATCH 14/17] drm/dp: Add helper to get post-cursor adjustments Thierry Reding
@ 2018-02-05 19:38 ` Thierry Reding
  2018-02-05 19:38 ` [PATCH 16/17] drm/dp: Enable alternate scrambler reset when supported Thierry Reding
  2018-02-05 19:38 ` [PATCH 17/17] drm/dp: Add drm_dp_link_choose() helper Thierry Reding
  16 siblings, 0 replies; 20+ messages in thread
From: Thierry Reding @ 2018-02-05 19:38 UTC (permalink / raw)
  To: dri-devel

From: Thierry Reding <treding@nvidia.com>

Make use of ANSI 8B/10B channel coding if the DisplayPort sink supports
it.

Signed-off-by: Thierry Reding <treding@nvidia.com>
---
 drivers/gpu/drm/drm_dp_helper.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index f1a7f18ab795..828dc091b015 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -526,7 +526,7 @@ EXPORT_SYMBOL(drm_dp_link_power_down);
  */
 int drm_dp_link_configure(struct drm_dp_aux *aux, struct drm_dp_link *link)
 {
-	u8 values[2];
+	u8 values[2], value = 0;
 	int err;
 
 	values[0] = drm_dp_link_rate_to_bw_code(link->rate);
@@ -539,6 +539,13 @@ int drm_dp_link_configure(struct drm_dp_aux *aux, struct drm_dp_link *link)
 	if (err < 0)
 		return err;
 
+	if (link->caps.channel_coding)
+		value = DP_SET_ANSI_8B10B;
+
+	err = drm_dp_dpcd_writeb(aux, DP_MAIN_LINK_CHANNEL_CODING_SET, value);
+	if (err < 0)
+		return err;
+
 	return 0;
 }
 EXPORT_SYMBOL(drm_dp_link_configure);
-- 
2.15.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 16/17] drm/dp: Enable alternate scrambler reset when supported
  2018-02-05 19:38 [PATCH 00/17] drm/dp: Miscellaneous improvements Thierry Reding
                   ` (14 preceding siblings ...)
  2018-02-05 19:38 ` [PATCH 15/17] drm/dp: Set channel coding on link configuration Thierry Reding
@ 2018-02-05 19:38 ` Thierry Reding
  2018-02-05 19:38 ` [PATCH 17/17] drm/dp: Add drm_dp_link_choose() helper Thierry Reding
  16 siblings, 0 replies; 20+ messages in thread
From: Thierry Reding @ 2018-02-05 19:38 UTC (permalink / raw)
  To: dri-devel

From: Thierry Reding <treding@nvidia.com>

If the sink is eDP and supports the alternate scrambler reset, enable
it.

Signed-off-by: Thierry Reding <treding@nvidia.com>
---
 drivers/gpu/drm/drm_dp_helper.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index 828dc091b015..c8b18c0161d7 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -546,6 +546,13 @@ int drm_dp_link_configure(struct drm_dp_aux *aux, struct drm_dp_link *link)
 	if (err < 0)
 		return err;
 
+	if (link->caps.alternate_scrambler_reset) {
+		err = drm_dp_dpcd_writeb(aux, DP_EDP_CONFIGURATION_SET,
+					 DP_ALTERNATE_SCRAMBLER_RESET_ENABLE);
+		if (err < 0)
+			return err;
+	}
+
 	return 0;
 }
 EXPORT_SYMBOL(drm_dp_link_configure);
-- 
2.15.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 17/17] drm/dp: Add drm_dp_link_choose() helper
  2018-02-05 19:38 [PATCH 00/17] drm/dp: Miscellaneous improvements Thierry Reding
                   ` (15 preceding siblings ...)
  2018-02-05 19:38 ` [PATCH 16/17] drm/dp: Enable alternate scrambler reset when supported Thierry Reding
@ 2018-02-05 19:38 ` Thierry Reding
  2018-02-07 12:53   ` Jani Nikula
  16 siblings, 1 reply; 20+ messages in thread
From: Thierry Reding @ 2018-02-05 19:38 UTC (permalink / raw)
  To: dri-devel

From: Thierry Reding <treding@nvidia.com>

This helper chooses an appropriate configuration, according to the
bitrate requirements of the video mode and the capabilities of the
DisplayPort sink.

Signed-off-by: Thierry Reding <treding@nvidia.com>
---
 drivers/gpu/drm/drm_dp_helper.c | 55 +++++++++++++++++++++++++++++++++++++++++
 include/drm/drm_dp_helper.h     |  5 ++++
 2 files changed, 60 insertions(+)

diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index c8b18c0161d7..fb6ee3ebc37d 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -557,6 +557,61 @@ int drm_dp_link_configure(struct drm_dp_aux *aux, struct drm_dp_link *link)
 }
 EXPORT_SYMBOL(drm_dp_link_configure);
 
+/**
+ * drm_dp_link_choose() - choose the lowest possible configuration for a mode
+ * @link: DRM DP link object
+ * @mode: DRM display mode
+ * @info: DRM display information
+ *
+ * According to the eDP specification, a source should select a configuration
+ * with the lowest number of lanes and the lowest possible link rate that can
+ * match the bitrate requirements of a video mode. However it must ensure not
+ * to exceed the capabilities of the sink.
+ *
+ * Returns: 0 on success or a negative error code on failure.
+ */
+int drm_dp_link_choose(struct drm_dp_link *link,
+		       const struct drm_display_mode *mode,
+		       const struct drm_display_info *info)
+{
+	/* available link symbol clock rates */
+	static const unsigned int rates[3] = { 162000, 270000, 540000 };
+	/* available number of lanes */
+	static const unsigned int lanes[3] = { 1, 2, 4 };
+	unsigned long requirement, capacity;
+	unsigned int rate = link->max_rate;
+	unsigned int i, j;
+
+	/* bandwidth requirement */
+	requirement = mode->clock * info->bpc * 3;
+
+	for (i = 0; i < ARRAY_SIZE(lanes) && lanes[i] <= link->max_lanes; i++) {
+		for (j = 0; j < ARRAY_SIZE(rates) && rates[j] <= rate; j++) {
+			/*
+			 * Capacity for this combination of lanes and rate,
+			 * factoring in the ANSI 8B/10B encoding.
+			 *
+			 * Link rates in the DRM DP helpers are really link
+			 * symbol frequencies, so a tenth of the actual rate
+			 * of the link.
+			 */
+			capacity = lanes[i] * (rates[j] * 10) * 8 / 10;
+
+			if (capacity >= requirement) {
+				DRM_DEBUG_KMS("using %u lanes at %u kHz (%lu/%lu kbps)\n",
+					      lanes[i], rates[j], requirement,
+					      capacity);
+				link->lanes = lanes[i];
+				link->rate = rates[j];
+				return 0;
+			}
+		}
+	}
+
+	return -ERANGE;
+}
+EXPORT_SYMBOL(drm_dp_link_choose);
+
 /**
  * drm_dp_downstream_max_clock() - extract branch device max
  *                                 pixel rate for legacy VGA
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index 4c7badcde945..39d134f9a954 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -27,6 +27,8 @@
 #include <linux/i2c.h>
 #include <linux/delay.h>
 
+#include <drm/drm_crtc.h>
+
 /*
  * Unless otherwise noted, all values are from the DP 1.1a spec.  Note that
  * DP and DPCD versions are independent.  Differences from 1.0 are not noted,
@@ -1194,6 +1196,9 @@ int drm_dp_link_probe(struct drm_dp_aux *aux, struct drm_dp_link *link);
 int drm_dp_link_power_up(struct drm_dp_aux *aux, struct drm_dp_link *link);
 int drm_dp_link_power_down(struct drm_dp_aux *aux, struct drm_dp_link *link);
 int drm_dp_link_configure(struct drm_dp_aux *aux, struct drm_dp_link *link);
+int drm_dp_link_choose(struct drm_dp_link *link,
+		       const struct drm_display_mode *mode,
+		       const struct drm_display_info *info);
 int drm_dp_downstream_max_clock(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
 				const u8 port_cap[4]);
 int drm_dp_downstream_max_bpc(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
-- 
2.15.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: [PATCH 17/17] drm/dp: Add drm_dp_link_choose() helper
  2018-02-05 19:38 ` [PATCH 17/17] drm/dp: Add drm_dp_link_choose() helper Thierry Reding
@ 2018-02-07 12:53   ` Jani Nikula
  2018-03-13 12:36     ` Thierry Reding
  0 siblings, 1 reply; 20+ messages in thread
From: Jani Nikula @ 2018-02-07 12:53 UTC (permalink / raw)
  To: Thierry Reding, dri-devel

On Mon, 05 Feb 2018, Thierry Reding <thierry.reding@gmail.com> wrote:
> From: Thierry Reding <treding@nvidia.com>
>
> This helper chooses an appropriate configuration, according to the
> bitrate requirements of the video mode and the capabilities of the
> DisplayPort sink.
>
> Signed-off-by: Thierry Reding <treding@nvidia.com>
> ---
>  drivers/gpu/drm/drm_dp_helper.c | 55 +++++++++++++++++++++++++++++++++++++++++
>  include/drm/drm_dp_helper.h     |  5 ++++
>  2 files changed, 60 insertions(+)
>
> diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
> index c8b18c0161d7..fb6ee3ebc37d 100644
> --- a/drivers/gpu/drm/drm_dp_helper.c
> +++ b/drivers/gpu/drm/drm_dp_helper.c
> @@ -557,6 +557,61 @@ int drm_dp_link_configure(struct drm_dp_aux *aux, struct drm_dp_link *link)
>  }
>  EXPORT_SYMBOL(drm_dp_link_configure);
>  
> +/**
> + * drm_dp_link_choose() - choose the lowest possible configuration for a mode
> + * @link: DRM DP link object
> + * @mode: DRM display mode
> + * @info: DRM display information
> + *
> + * According to the eDP specification, a source should select a configuration
> + * with the lowest number of lanes and the lowest possible link rate that can
> + * match the bitrate requirements of a video mode. However it must ensure not
> + * to exceed the capabilities of the sink.

Just a couple of notes here:

Recent eDP allows more rates than just the ones mentioned. So you'll
actually have a number of source and sink rates, and you'll have to
intersect them to find the common rates. We have this in i915.

Although the spec says use the "smallest" link parameters possible,
we've found that many panels out in the wild only work at the maximum
sink parameters. Presumably the sink max rate and width correspond to
the native resolution, and not much testing happens using other
parameters. :(


BR,
Jani.


> + *
> + * Returns: 0 on success or a negative error code on failure.
> + */
> +int drm_dp_link_choose(struct drm_dp_link *link,
> +		       const struct drm_display_mode *mode,
> +		       const struct drm_display_info *info)
> +{
> +	/* available link symbol clock rates */
> +	static const unsigned int rates[3] = { 162000, 270000, 540000 };
> +	/* available number of lanes */
> +	static const unsigned int lanes[3] = { 1, 2, 4 };
> +	unsigned long requirement, capacity;
> +	unsigned int rate = link->max_rate;
> +	unsigned int i, j;
> +
> +	/* bandwidth requirement */
> +	requirement = mode->clock * info->bpc * 3;
> +
> +	for (i = 0; i < ARRAY_SIZE(lanes) && lanes[i] <= link->max_lanes; i++) {
> +		for (j = 0; j < ARRAY_SIZE(rates) && rates[j] <= rate; j++) {
> +			/*
> +			 * Capacity for this combination of lanes and rate,
> +			 * factoring in the ANSI 8B/10B encoding.
> +			 *
> +			 * Link rates in the DRM DP helpers are really link
> +			 * symbol frequencies, so a tenth of the actual rate
> +			 * of the link.
> +			 */
> +			capacity = lanes[i] * (rates[j] * 10) * 8 / 10;
> +
> +			if (capacity >= requirement) {
> +				DRM_DEBUG_KMS("using %u lanes at %u kHz (%lu/%lu kbps)\n",
> +					      lanes[i], rates[j], requirement,
> +					      capacity);
> +				link->lanes = lanes[i];
> +				link->rate = rates[j];
> +				return 0;
> +			}
> +		}
> +	}
> +
> +	return -ERANGE;
> +}
> +EXPORT_SYMBOL(drm_dp_link_choose);
> +
>  /**
>   * drm_dp_downstream_max_clock() - extract branch device max
>   *                                 pixel rate for legacy VGA
> diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
> index 4c7badcde945..39d134f9a954 100644
> --- a/include/drm/drm_dp_helper.h
> +++ b/include/drm/drm_dp_helper.h
> @@ -27,6 +27,8 @@
>  #include <linux/i2c.h>
>  #include <linux/delay.h>
>  
> +#include <drm/drm_crtc.h>
> +
>  /*
>   * Unless otherwise noted, all values are from the DP 1.1a spec.  Note that
>   * DP and DPCD versions are independent.  Differences from 1.0 are not noted,
> @@ -1194,6 +1196,9 @@ int drm_dp_link_probe(struct drm_dp_aux *aux, struct drm_dp_link *link);
>  int drm_dp_link_power_up(struct drm_dp_aux *aux, struct drm_dp_link *link);
>  int drm_dp_link_power_down(struct drm_dp_aux *aux, struct drm_dp_link *link);
>  int drm_dp_link_configure(struct drm_dp_aux *aux, struct drm_dp_link *link);
> +int drm_dp_link_choose(struct drm_dp_link *link,
> +		       const struct drm_display_mode *mode,
> +		       const struct drm_display_info *info);
>  int drm_dp_downstream_max_clock(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
>  				const u8 port_cap[4]);
>  int drm_dp_downstream_max_bpc(const u8 dpcd[DP_RECEIVER_CAP_SIZE],

-- 
Jani Nikula, Intel Open Source Technology Center
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 17/17] drm/dp: Add drm_dp_link_choose() helper
  2018-02-07 12:53   ` Jani Nikula
@ 2018-03-13 12:36     ` Thierry Reding
  0 siblings, 0 replies; 20+ messages in thread
From: Thierry Reding @ 2018-03-13 12:36 UTC (permalink / raw)
  To: Jani Nikula; +Cc: dri-devel


[-- Attachment #1.1: Type: text/plain, Size: 2652 bytes --]

On Wed, Feb 07, 2018 at 02:53:19PM +0200, Jani Nikula wrote:
> On Mon, 05 Feb 2018, Thierry Reding <thierry.reding@gmail.com> wrote:
> > From: Thierry Reding <treding@nvidia.com>
> >
> > This helper chooses an appropriate configuration, according to the
> > bitrate requirements of the video mode and the capabilities of the
> > DisplayPort sink.
> >
> > Signed-off-by: Thierry Reding <treding@nvidia.com>
> > ---
> >  drivers/gpu/drm/drm_dp_helper.c | 55 +++++++++++++++++++++++++++++++++++++++++
> >  include/drm/drm_dp_helper.h     |  5 ++++
> >  2 files changed, 60 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
> > index c8b18c0161d7..fb6ee3ebc37d 100644
> > --- a/drivers/gpu/drm/drm_dp_helper.c
> > +++ b/drivers/gpu/drm/drm_dp_helper.c
> > @@ -557,6 +557,61 @@ int drm_dp_link_configure(struct drm_dp_aux *aux, struct drm_dp_link *link)
> >  }
> >  EXPORT_SYMBOL(drm_dp_link_configure);
> >  
> > +/**
> > + * drm_dp_link_choose() - choose the lowest possible configuration for a mode
> > + * @link: DRM DP link object
> > + * @mode: DRM display mode
> > + * @info: DRM display information
> > + *
> > + * According to the eDP specification, a source should select a configuration
> > + * with the lowest number of lanes and the lowest possible link rate that can
> > + * match the bitrate requirements of a video mode. However it must ensure not
> > + * to exceed the capabilities of the sink.
> 
> Just a couple of notes here:

Sorry, this got burried under too much email.

> Recent eDP allows more rates than just the ones mentioned. So you'll
> actually have a number of source and sink rates, and you'll have to
> intersect them to find the common rates. We have this in i915.

I'm aware of this and I have a local patch to implement this. However I
currently don't have an eDP setup where I can test it, so I didn't think
it right to submit the patch.

> Although the spec says use the "smallest" link parameters possible,
> we've found that many panels out in the wild only work at the maximum
> sink parameters. Presumably the sink max rate and width correspond to
> the native resolution, and not much testing happens using other
> parameters. :(

I suppose I could just drop this helper. Or perhaps add a note about the
potential pitfalls. It works fine for my particular use-case, so I could
move it into the Tegra driver.

How about the other patches? It's getting really late for v4.17, but I'd
like to still get these in if possible so I can reduce my local patch
count and merge DP support for Tegra186.

Thierry

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2018-03-13 12:36 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-02-05 19:38 [PATCH 00/17] drm/dp: Miscellaneous improvements Thierry Reding
2018-02-05 19:38 ` [PATCH 01/17] drm/dp: Add missing kerneldoc for struct drm_dp_link Thierry Reding
2018-02-05 19:38 ` [PATCH 02/17] drm/dp: Add drm_dp_link_reset() implementation Thierry Reding
2018-02-05 19:38 ` [PATCH 03/17] drm/dp: Track link capabilities alongside settings Thierry Reding
2018-02-05 19:38 ` [PATCH 04/17] drm/dp: Turn link capabilities into booleans Thierry Reding
2018-02-05 19:38 ` [PATCH 05/17] drm/dp: Probe link using existing parsing helpers Thierry Reding
2018-02-05 19:38 ` [PATCH 06/17] drm/dp: Read fast training capability from link Thierry Reding
2018-02-05 19:38 ` [PATCH 07/17] drm/dp: Read TPS3 capability from sink Thierry Reding
2018-02-05 19:38 ` [PATCH 08/17] drm/dp: Read channel coding " Thierry Reding
2018-02-05 19:38 ` [PATCH 09/17] drm/dp: Read alternate scrambler reset " Thierry Reding
2018-02-05 19:38 ` [PATCH 10/17] drm/dp: Read eDP version from DPCD Thierry Reding
2018-02-05 19:38 ` [PATCH 11/17] drm/dp: Read AUX read interval " Thierry Reding
2018-02-05 19:38 ` [PATCH 12/17] drm/dp: Do not busy-loop during link training Thierry Reding
2018-02-05 19:38 ` [PATCH 13/17] drm/dp: Use drm_dp_aux_rd_interval() Thierry Reding
2018-02-05 19:38 ` [PATCH 14/17] drm/dp: Add helper to get post-cursor adjustments Thierry Reding
2018-02-05 19:38 ` [PATCH 15/17] drm/dp: Set channel coding on link configuration Thierry Reding
2018-02-05 19:38 ` [PATCH 16/17] drm/dp: Enable alternate scrambler reset when supported Thierry Reding
2018-02-05 19:38 ` [PATCH 17/17] drm/dp: Add drm_dp_link_choose() helper Thierry Reding
2018-02-07 12:53   ` Jani Nikula
2018-03-13 12:36     ` Thierry Reding

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.