Skip to content

Commit 68f357c

Browse files
committed
drm/i915/dp: generate and cache sink rate array for all DP, not just eDP 1.4
There is some conflation related to sink rates, making this change more complicated than it would otherwise have to be. There are three changes here that are rather difficult to split up: 1) Use the intel_dp->sink_rates array for all DP, not just eDP 1.4. We initialize it from DPCD on eDP 1.4 like before, but generate it based on DP_MAX_LINK_RATE on others. This reduces code complexity when we need to use the sink rates; they are all always in the sink_rates array. 2) Update the sink rate array whenever we read DPCD, and use the information from there. This increases code readability when we need the sink rates. 3) Disentangle fallback rate limiting from sink rates. In the code, the max rate is a dynamic property of the *link*, not of the *sink*. Do the limiting after intersecting the source and sink rates, which are static properties of the devices. This paves the way for follow-up refactoring that I've refrained from doing here to keep this change as simple as it possibly can. v2: introduce use_rate_select and handle non-confirming eDP (Ville) v3: don't clobber cached eDP rates on short pulse (Ville) Cc: Manasi Navare <manasi.d.navare@intel.com> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Manasi Navare <manasi.d.navare@intel.com> Signed-off-by: Jani Nikula <jani.nikula@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/071bad76467f8ab2e73f3f61ad52d5a468004c71.1490712890.git.jani.nikula@intel.com
1 parent 55cfc58 commit 68f357c

File tree

3 files changed

+61
-28
lines changed

3 files changed

+61
-28
lines changed

drivers/gpu/drm/i915/intel_dp.c

Lines changed: 56 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,34 @@ static void vlv_steal_power_sequencer(struct drm_device *dev,
133133
enum pipe pipe);
134134
static void intel_dp_unset_edid(struct intel_dp *intel_dp);
135135

136+
static int intel_dp_num_rates(u8 link_bw_code)
137+
{
138+
switch (link_bw_code) {
139+
default:
140+
WARN(1, "invalid max DP link bw val %x, using 1.62Gbps\n",
141+
link_bw_code);
142+
case DP_LINK_BW_1_62:
143+
return 1;
144+
case DP_LINK_BW_2_7:
145+
return 2;
146+
case DP_LINK_BW_5_4:
147+
return 3;
148+
}
149+
}
150+
151+
/* update sink rates from dpcd */
152+
static void intel_dp_set_sink_rates(struct intel_dp *intel_dp)
153+
{
154+
int i, num_rates;
155+
156+
num_rates = intel_dp_num_rates(intel_dp->dpcd[DP_MAX_LINK_RATE]);
157+
158+
for (i = 0; i < num_rates; i++)
159+
intel_dp->sink_rates[i] = default_rates[i];
160+
161+
intel_dp->num_sink_rates = num_rates;
162+
}
163+
136164
static int
137165
intel_dp_max_link_bw(struct intel_dp *intel_dp)
138166
{
@@ -205,19 +233,6 @@ intel_dp_downstream_max_dotclock(struct intel_dp *intel_dp)
205233
return max_dotclk;
206234
}
207235

208-
static int
209-
intel_dp_sink_rates(struct intel_dp *intel_dp, const int **sink_rates)
210-
{
211-
if (intel_dp->num_sink_rates) {
212-
*sink_rates = intel_dp->sink_rates;
213-
return intel_dp->num_sink_rates;
214-
}
215-
216-
*sink_rates = default_rates;
217-
218-
return (intel_dp->max_sink_link_bw >> 3) + 1;
219-
}
220-
221236
static void
222237
intel_dp_set_source_rates(struct intel_dp *intel_dp)
223238
{
@@ -286,15 +301,22 @@ static int intel_dp_rate_index(const int *rates, int len, int rate)
286301
static int intel_dp_common_rates(struct intel_dp *intel_dp,
287302
int *common_rates)
288303
{
289-
const int *sink_rates;
290-
int sink_len;
304+
int max_rate = drm_dp_bw_code_to_link_rate(intel_dp->max_sink_link_bw);
305+
int i, common_len;
291306

292-
sink_len = intel_dp_sink_rates(intel_dp, &sink_rates);
307+
common_len = intersect_rates(intel_dp->source_rates,
308+
intel_dp->num_source_rates,
309+
intel_dp->sink_rates,
310+
intel_dp->num_sink_rates,
311+
common_rates);
312+
313+
/* Limit results by potentially reduced max rate */
314+
for (i = 0; i < common_len; i++) {
315+
if (common_rates[common_len - i - 1] <= max_rate)
316+
return common_len - i;
317+
}
293318

294-
return intersect_rates(intel_dp->source_rates,
295-
intel_dp->num_source_rates,
296-
sink_rates, sink_len,
297-
common_rates);
319+
return 0;
298320
}
299321

300322
static int intel_dp_link_rate_index(struct intel_dp *intel_dp,
@@ -1498,8 +1520,7 @@ static void snprintf_int_array(char *str, size_t len,
14981520

14991521
static void intel_dp_print_rates(struct intel_dp *intel_dp)
15001522
{
1501-
const int *sink_rates;
1502-
int sink_len, common_len;
1523+
int common_len;
15031524
int common_rates[DP_MAX_SUPPORTED_RATES];
15041525
char str[128]; /* FIXME: too big for stack? */
15051526

@@ -1510,8 +1531,8 @@ static void intel_dp_print_rates(struct intel_dp *intel_dp)
15101531
intel_dp->source_rates, intel_dp->num_source_rates);
15111532
DRM_DEBUG_KMS("source rates: %s\n", str);
15121533

1513-
sink_len = intel_dp_sink_rates(intel_dp, &sink_rates);
1514-
snprintf_int_array(str, sizeof(str), sink_rates, sink_len);
1534+
snprintf_int_array(str, sizeof(str),
1535+
intel_dp->sink_rates, intel_dp->num_sink_rates);
15151536
DRM_DEBUG_KMS("sink rates: %s\n", str);
15161537

15171538
common_len = intel_dp_common_rates(intel_dp, common_rates);
@@ -1577,7 +1598,8 @@ int intel_dp_rate_select(struct intel_dp *intel_dp, int rate)
15771598
void intel_dp_compute_rate(struct intel_dp *intel_dp, int port_clock,
15781599
uint8_t *link_bw, uint8_t *rate_select)
15791600
{
1580-
if (intel_dp->num_sink_rates) {
1601+
/* eDP 1.4 rate select method. */
1602+
if (intel_dp->use_rate_select) {
15811603
*link_bw = 0;
15821604
*rate_select =
15831605
intel_dp_rate_select(intel_dp, port_clock);
@@ -3702,6 +3724,11 @@ intel_edp_init_dpcd(struct intel_dp *intel_dp)
37023724
intel_dp->num_sink_rates = i;
37033725
}
37043726

3727+
if (intel_dp->num_sink_rates)
3728+
intel_dp->use_rate_select = true;
3729+
else
3730+
intel_dp_set_sink_rates(intel_dp);
3731+
37053732
return true;
37063733
}
37073734

@@ -3712,6 +3739,10 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp)
37123739
if (!intel_dp_read_dpcd(intel_dp))
37133740
return false;
37143741

3742+
/* Don't clobber cached eDP rates. */
3743+
if (!is_edp(intel_dp))
3744+
intel_dp_set_sink_rates(intel_dp);
3745+
37153746
if (drm_dp_dpcd_read(&intel_dp->aux, DP_SINK_COUNT,
37163747
&intel_dp->sink_count, 1) < 0)
37173748
return false;

drivers/gpu/drm/i915/intel_dp_link_training.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,8 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
146146
link_config[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
147147
drm_dp_dpcd_write(&intel_dp->aux, DP_LINK_BW_SET, link_config, 2);
148148

149-
if (intel_dp->num_sink_rates)
149+
/* eDP 1.4 rate select method. */
150+
if (!link_bw)
150151
drm_dp_dpcd_write(&intel_dp->aux, DP_LINK_RATE_SET,
151152
&rate_select, 1);
152153

drivers/gpu/drm/i915/intel_drv.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -952,9 +952,10 @@ struct intel_dp {
952952
/* source rates */
953953
int num_source_rates;
954954
const int *source_rates;
955-
/* sink rates as reported by DP_SUPPORTED_LINK_RATES */
956-
uint8_t num_sink_rates;
955+
/* sink rates as reported by DP_MAX_LINK_RATE/DP_SUPPORTED_LINK_RATES */
956+
int num_sink_rates;
957957
int sink_rates[DP_MAX_SUPPORTED_RATES];
958+
bool use_rate_select;
958959
/* Max lane count for the sink as per DPCD registers */
959960
uint8_t max_sink_lane_count;
960961
/* Max link BW for the sink as per DPCD registers */

0 commit comments

Comments
 (0)