From: Paulo Zanoni <przanoni@gmail.com>
To: intel-gfx@lists.freedesktop.org
Cc: Paulo Zanoni <paulo.r.zanoni@intel.com>
Subject: [PATCH 2/3] drm/i915: extract intel_dp_compute_link_config
Date: Thu, 24 Apr 2014 18:22:58 -0300 [thread overview]
Message-ID: <1398374579-5697-2-git-send-email-przanoni@gmail.com> (raw)
In-Reply-To: <1398374579-5697-1-git-send-email-przanoni@gmail.com>
From: Paulo Zanoni <paulo.r.zanoni@intel.com>
Extract this function to make the input and output parameters more
clear to the code reader.
I also have plans to allow ways to change the current parameters, so
the code will get even more complicated without the refactor. I also
have plans to add alternative implementations to
intel_dp_compute_link_config() and, again, the refactor makes it
easier.
Another change worth noticing is that now we will print all our
"attempts" in dmesg (see the debug code at link_config_is_possible()).
This will allow us to quickly identify if the user is trying fast and
narrow, or wide and slow, and also identify the minimum and maximum BW
and lane count values used by the code.
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
drivers/gpu/drm/i915/intel_dp.c | 94 +++++++++++++++++++++++++++--------------
1 file changed, 63 insertions(+), 31 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 19537a6..884166b 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -768,6 +768,52 @@ intel_dp_set_m2_n2(struct intel_crtc *crtc, struct intel_link_m_n *m_n)
I915_WRITE(PIPE_LINK_N2(transcoder), m_n->link_n);
}
+static bool link_config_is_possible(int mode_rate, int lanes, int bw)
+{
+ int link_clock, link_avail;
+
+ link_clock = drm_dp_bw_code_to_link_rate(bw);
+ link_avail = intel_dp_max_data_rate(link_clock, lanes);
+
+ DRM_DEBUG_KMS("DP link avail with 0x%x bw and %d lanes: %d. Required: %d (%d%%)\n",
+ bw, lanes, link_avail, mode_rate,
+ mode_rate * 100 / link_avail);
+
+ return (mode_rate <= link_avail);
+}
+
+/*
+ * This function tries to find the minimal number of lanes and BW required based
+ * on the parameters given. If not possible, it returns false.
+ */
+static bool intel_dp_compute_link_config(int mode_clock, int bpp,
+ int min_lanes, int max_lanes,
+ int min_bw, int max_bw,
+ int *lanes_used, int *bw_used)
+{
+ /* Conveniently, the link BW constants become indices with a shift...*/
+ static int bws[] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7, DP_LINK_BW_5_4 };
+ int min_bw_index = min_bw >> 3;
+ int max_bw_index = max_bw >> 3;
+ int mode_rate;
+ int lanes, bw_it;
+
+ mode_rate = intel_dp_link_required(mode_clock, bpp);
+
+ for (lanes = min_lanes; lanes <= max_lanes; lanes <<= 1)
+ for (bw_it = min_bw_index; bw_it <= max_bw_index; bw_it++)
+ if (link_config_is_possible(mode_rate, lanes,
+ bws[bw_it]))
+ goto found;
+
+ return false;
+
+found:
+ *lanes_used = lanes;
+ *bw_used = bws[bw_it];
+ return true;
+}
+
bool
intel_dp_compute_config(struct intel_encoder *encoder,
struct intel_crtc_config *pipe_config)
@@ -779,13 +825,10 @@ intel_dp_compute_config(struct intel_encoder *encoder,
enum port port = dp_to_dig_port(intel_dp)->port;
struct intel_crtc *intel_crtc = encoder->new_crtc;
struct intel_connector *intel_connector = intel_dp->attached_connector;
- int lane_count, clock;
+ int lanes_used, bw_used;
int max_lane_count = intel_dp_max_lane_count(intel_dp);
- /* Conveniently, the link BW constants become indices with a shift...*/
- int max_clock = intel_dp_max_link_bw(intel_dp) >> 3;
- int bpp, mode_rate;
- static int bws[] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7, DP_LINK_BW_5_4 };
- int link_avail, link_clock;
+ int max_bw = intel_dp_max_link_bw(intel_dp);
+ int bpp;
if (HAS_PCH_SPLIT(dev) && !HAS_DDI(dev) && port != PORT_A)
pipe_config->has_pch_encoder = true;
@@ -808,7 +851,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
DRM_DEBUG_KMS("DP link computation with max lane count %i "
"max bw %02x pixel clock %iKHz\n",
- max_lane_count, bws[max_clock],
+ max_lane_count, max_bw,
adjusted_mode->crtc_clock);
/* Walk through all bpp values. Luckily they're all nicely spaced with 2
@@ -821,26 +864,17 @@ intel_dp_compute_config(struct intel_encoder *encoder,
bpp = dev_priv->vbt.edp_bpp;
}
- for (; bpp >= 6*3; bpp -= 2*3) {
- mode_rate = intel_dp_link_required(adjusted_mode->crtc_clock,
- bpp);
-
- for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) {
- for (clock = 0; clock <= max_clock; clock++) {
- link_clock = drm_dp_bw_code_to_link_rate(bws[clock]);
- link_avail = intel_dp_max_data_rate(link_clock,
- lane_count);
-
- if (mode_rate <= link_avail) {
- goto found;
- }
- }
- }
- }
+ for (; bpp >= 6*3; bpp -= 2*3)
+ if (intel_dp_compute_link_config(adjusted_mode->crtc_clock, bpp,
+ 1, max_lane_count,
+ DP_LINK_BW_1_62,
+ max_bw,
+ &lanes_used, &bw_used))
+ break;
- return false;
+ if (bpp < 6*3)
+ return false;
-found:
if (intel_dp->color_range_auto) {
/*
* See:
@@ -856,25 +890,23 @@ found:
if (intel_dp->color_range)
pipe_config->limited_color_range = true;
- intel_dp->link_bw = bws[clock];
- intel_dp->lane_count = lane_count;
+ intel_dp->link_bw = bw_used;
+ intel_dp->lane_count = lanes_used;
pipe_config->pipe_bpp = bpp;
pipe_config->port_clock = drm_dp_bw_code_to_link_rate(intel_dp->link_bw);
DRM_DEBUG_KMS("DP link bw %02x lane count %d clock %d bpp %d\n",
intel_dp->link_bw, intel_dp->lane_count,
pipe_config->port_clock, bpp);
- DRM_DEBUG_KMS("DP link bw required %i available %i\n",
- mode_rate, link_avail);
- intel_link_compute_m_n(bpp, lane_count,
+ intel_link_compute_m_n(bpp, lanes_used,
adjusted_mode->crtc_clock,
pipe_config->port_clock,
&pipe_config->dp_m_n);
if (intel_connector->panel.downclock_mode != NULL &&
intel_dp->drrs_state.type == SEAMLESS_DRRS_SUPPORT) {
- intel_link_compute_m_n(bpp, lane_count,
+ intel_link_compute_m_n(bpp, lanes_used,
intel_connector->panel.downclock_mode->clock,
pipe_config->port_clock,
&pipe_config->dp_m2_n2);
--
1.9.0
next prev parent reply other threads:[~2014-04-24 21:23 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-04-24 21:22 [PATCH 1/3] drm/i915: consider the source max DP lane count too Paulo Zanoni
2014-04-24 21:22 ` Paulo Zanoni [this message]
2014-04-24 21:22 ` [PATCH 3/3] drm/i915: add i915.dp_link_train_policy option Paulo Zanoni
2014-04-25 8:06 ` Daniel Vetter
2014-04-25 8:10 ` Daniel Vetter
2014-04-25 9:00 ` Jani Nikula
2014-04-25 9:18 ` Daniel Vetter
2014-04-25 10:32 ` Jani Nikula
2014-04-25 10:50 ` Barbalho, Rafael
2014-04-25 17:48 ` Paulo Zanoni
2014-04-25 20:02 ` Daniel Vetter
2014-04-25 10:48 ` Barbalho, Rafael
2014-04-25 7:16 ` [PATCH 1/3] drm/i915: consider the source max DP lane count too Jani Nikula
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1398374579-5697-2-git-send-email-przanoni@gmail.com \
--to=przanoni@gmail.com \
--cc=intel-gfx@lists.freedesktop.org \
--cc=paulo.r.zanoni@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox