summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/display/intel_dp.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_dp.c')
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp.c57
1 files changed, 50 insertions, 7 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 795498382254..1fa6f50213e9 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -347,7 +347,7 @@ int intel_dp_max_common_rate(struct intel_dp *intel_dp)
return intel_dp_common_rate(intel_dp, intel_dp->num_common_rates - 1);
}
-static int intel_dp_max_source_lane_count(struct intel_digital_port *dig_port)
+int intel_dp_max_source_lane_count(struct intel_digital_port *dig_port)
{
int vbt_max_lanes = intel_bios_dp_max_lane_count(dig_port->base.devdata);
int max_lanes = dig_port->max_lanes;
@@ -373,19 +373,39 @@ int intel_dp_max_common_lane_count(struct intel_dp *intel_dp)
return min3(source_max, sink_max, lane_max);
}
+static int forced_lane_count(struct intel_dp *intel_dp)
+{
+ return clamp(intel_dp->link.force_lane_count, 1, intel_dp_max_common_lane_count(intel_dp));
+}
+
int intel_dp_max_lane_count(struct intel_dp *intel_dp)
{
- switch (intel_dp->link.max_lane_count) {
+ int lane_count;
+
+ if (intel_dp->link.force_lane_count)
+ lane_count = forced_lane_count(intel_dp);
+ else
+ lane_count = intel_dp->link.max_lane_count;
+
+ switch (lane_count) {
case 1:
case 2:
case 4:
- return intel_dp->link.max_lane_count;
+ return lane_count;
default:
- MISSING_CASE(intel_dp->link.max_lane_count);
+ MISSING_CASE(lane_count);
return 1;
}
}
+static int intel_dp_min_lane_count(struct intel_dp *intel_dp)
+{
+ if (intel_dp->link.force_lane_count)
+ return forced_lane_count(intel_dp);
+
+ return 1;
+}
+
/*
* The required data bandwidth for a mode with given pixel clock and bpp. This
* is the required net bandwidth independent of the data bandwidth efficiency.
@@ -1308,16 +1328,38 @@ static void intel_dp_print_rates(struct intel_dp *intel_dp)
drm_dbg_kms(&i915->drm, "common rates: %s\n", str);
}
+static int forced_link_rate(struct intel_dp *intel_dp)
+{
+ int len = intel_dp_common_len_rate_limit(intel_dp, intel_dp->link.force_rate);
+
+ if (len == 0)
+ return intel_dp_common_rate(intel_dp, 0);
+
+ return intel_dp_common_rate(intel_dp, len - 1);
+}
+
int
intel_dp_max_link_rate(struct intel_dp *intel_dp)
{
int len;
+ if (intel_dp->link.force_rate)
+ return forced_link_rate(intel_dp);
+
len = intel_dp_common_len_rate_limit(intel_dp, intel_dp->link.max_rate);
return intel_dp_common_rate(intel_dp, len - 1);
}
+static int
+intel_dp_min_link_rate(struct intel_dp *intel_dp)
+{
+ if (intel_dp->link.force_rate)
+ return forced_link_rate(intel_dp);
+
+ return intel_dp_common_rate(intel_dp, 0);
+}
+
int intel_dp_rate_select(struct intel_dp *intel_dp, int rate)
{
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
@@ -2287,13 +2329,14 @@ intel_dp_compute_config_limits(struct intel_dp *intel_dp,
bool dsc,
struct link_config_limits *limits)
{
- limits->min_rate = intel_dp_common_rate(intel_dp, 0);
+ limits->min_rate = intel_dp_min_link_rate(intel_dp);
limits->max_rate = intel_dp_max_link_rate(intel_dp);
/* FIXME 128b/132b SST support missing */
limits->max_rate = min(limits->max_rate, 810000);
+ limits->min_rate = min(limits->min_rate, limits->max_rate);
- limits->min_lane_count = 1;
+ limits->min_lane_count = intel_dp_min_lane_count(intel_dp);
limits->max_lane_count = intel_dp_max_lane_count(intel_dp);
limits->pipe.min_bpp = intel_dp_min_bpp(crtc_state->output_format);
@@ -2962,7 +3005,7 @@ void intel_dp_set_link_params(struct intel_dp *intel_dp,
intel_dp->lane_count = lane_count;
}
-static void intel_dp_reset_link_params(struct intel_dp *intel_dp)
+void intel_dp_reset_link_params(struct intel_dp *intel_dp)
{
intel_dp->link.max_lane_count = intel_dp_max_common_lane_count(intel_dp);
intel_dp->link.max_rate = intel_dp_max_common_rate(intel_dp);