[PATCH 1/2] drm/i915: Make link training state machine code use function pointers

Ander Conselvan de Oliveira
2015-09-15T13:12:37Z

Create a series of function pointers in intel_dp for the consumption of
the link training state machine, instead of calling the functions from
intel_dp.c direcly. This creates the insertion points for a link
training unit test, that will be added in the next patch.
---
drivers/gpu/drm/i915/intel_dp.c | 36 ++++++++++++++++++++-------
drivers/gpu/drm/i915/intel_dp_link_training.c | 36 +++++++++++++--------------
drivers/gpu/drm/i915/intel_drv.h | 29 ++++++++++-----------
3 files changed, 58 insertions(+), 43 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index d914f95..6422b8a 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -1189,7 +1189,7 @@ intel_dp_sink_rates(struct intel_dp *intel_dp, const int **sink_rates)
return (intel_dp_max_link_bw(intel_dp) >> 3) + 1;
}

-bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp)
+static bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp)
{
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
struct drm_device *dev = dig_port->base.base.dev;
@@ -1368,8 +1368,8 @@ int intel_dp_rate_select(struct intel_dp *intel_dp, int rate)
return rate_to_index(rate, intel_dp->sink_rates);
}

-void intel_dp_compute_rate(struct intel_dp *intel_dp, int port_clock,
- uint8_t *link_bw, uint8_t *rate_select)
+static void intel_dp_compute_rate(struct intel_dp *intel_dp, int port_clock,
+ uint8_t *link_bw, uint8_t *rate_select)
{
if (intel_dp->num_sink_rates) {
*link_bw = 0;
@@ -3049,7 +3049,7 @@ intel_dp_dpcd_read_wake(struct drm_dp_aux *aux, unsigned int offset,
* Fetch AUX CH registers 0x202 - 0x207 which contain
* link status information
*/
-bool
+static bool
intel_dp_get_link_status(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_STATUS_SIZE])
{
return intel_dp_dpcd_read_wake(&intel_dp->aux,
@@ -3059,7 +3059,7 @@ intel_dp_get_link_status(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_
}

/* These are source-specific values. */
-uint8_t
+static uint8_t
intel_dp_voltage_max(struct intel_dp *intel_dp)
{
struct drm_device *dev = intel_dp_to_dev(intel_dp);
@@ -3082,7 +3082,7 @@ intel_dp_voltage_max(struct intel_dp *intel_dp)
return DP_TRAIN_VOLTAGE_SWING_LEVEL_2;
}

-uint8_t
+static uint8_t
intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing)
{
struct drm_device *dev = intel_dp_to_dev(intel_dp);
@@ -3570,7 +3570,7 @@ intel_dp_set_signal_levels(struct intel_dp *intel_dp, uint32_t *DP)
*DP = (*DP & ~mask) | signal_levels;
}

-void
+static void
intel_dp_program_link_training_pattern(struct intel_dp *intel_dp,
uint8_t dp_train_pat)
{
@@ -3584,7 +3584,7 @@ intel_dp_program_link_training_pattern(struct intel_dp *intel_dp,
POSTING_READ(intel_dp->output_reg);
}

-void
+static void
intel_dp_update_signal_levels(struct intel_dp *intel_dp)
{
struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
@@ -3597,7 +3597,14 @@ intel_dp_update_signal_levels(struct intel_dp *intel_dp)
POSTING_READ(intel_dp->output_reg);
}

-void intel_dp_set_idle_link_train(struct intel_dp *intel_dp)
+static ssize_t
+intel_dp_dpcd_write(struct intel_dp *intel_dp, unsigned int offset,
+ void *buffer, size_t size)
+{
+ return drm_dp_dpcd_write(&intel_dp->aux, offset, buffer, size);
+}
+
+static void intel_dp_set_idle_link_train(struct intel_dp *intel_dp)
{
struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
struct drm_device *dev = intel_dig_port->base.base.dev;
@@ -5742,6 +5749,17 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
if (HAS_DDI(dev))
intel_dp->prepare_link_retrain = intel_ddi_prepare_link_retrain;

+ intel_dp->get_link_status = intel_dp_get_link_status;
+ intel_dp->update_signal_levels = intel_dp_update_signal_levels;
+ intel_dp->compute_rate = intel_dp_compute_rate;
+ intel_dp->program_link_training_pattern =
+ intel_dp_program_link_training_pattern;
+ intel_dp->set_idle_link_train = intel_dp_set_idle_link_train;
+ intel_dp->voltage_max = intel_dp_voltage_max;
+ intel_dp->pre_emphasis_max = intel_dp_pre_emphasis_max;
+ intel_dp->dpcd_write = intel_dp_dpcd_write;
+ intel_dp->source_supports_hbr2 = intel_dp_source_supports_hbr2;
+
/* Preserve the current hw state. */
intel_dp->DP = I915_READ(intel_dp->output_reg);
intel_dp->attached_connector = intel_connector;
diff --git a/drivers/gpu/drm/i915/intel_dp_link_training.c b/drivers/gpu/drm/i915/intel_dp_link_training.c
index 4d2bdc0..c2982f8 100644
--- a/drivers/gpu/drm/i915/intel_dp_link_training.c
+++ b/drivers/gpu/drm/i915/intel_dp_link_training.c
@@ -43,11 +43,11 @@ intel_get_adjust_train(struct intel_dp *intel_dp,
p = this_p;
}

- voltage_max = intel_dp_voltage_max(intel_dp);
+ voltage_max = intel_dp->voltage_max(intel_dp);
if (v >= voltage_max)
v = voltage_max | DP_TRAIN_MAX_SWING_REACHED;

- preemph_max = intel_dp_pre_emphasis_max(intel_dp, v);
+ preemph_max = intel_dp->pre_emphasis_max(intel_dp, v);
if (p >= preemph_max)
p = preemph_max | DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;

@@ -62,7 +62,7 @@ intel_dp_set_link_train(struct intel_dp *intel_dp,
uint8_t buf[sizeof(intel_dp->train_set) + 1];
int ret, len;

- intel_dp_program_link_training_pattern(intel_dp, dp_train_pat);
+ intel_dp->program_link_training_pattern(intel_dp, dp_train_pat);

buf[0] = dp_train_pat;
if ((dp_train_pat & DP_TRAINING_PATTERN_MASK) ==
@@ -75,8 +75,8 @@ intel_dp_set_link_train(struct intel_dp *intel_dp,
len = intel_dp->lane_count + 1;
}

- ret = drm_dp_dpcd_write(&intel_dp->aux, DP_TRAINING_PATTERN_SET,
- buf, len);
+ ret = intel_dp->dpcd_write(intel_dp, DP_TRAINING_PATTERN_SET,
+ buf, len);

return ret == len;
}
@@ -87,7 +87,7 @@ intel_dp_reset_link_train(struct intel_dp *intel_dp,
{
if (!intel_dp->train_set_valid)
memset(intel_dp->train_set, 0, sizeof(intel_dp->train_set));
- intel_dp_update_signal_levels(intel_dp);
+ intel_dp->update_signal_levels(intel_dp);
return intel_dp_set_link_train(intel_dp, dp_train_pat);
}

@@ -96,10 +96,10 @@ intel_dp_update_link_train(struct intel_dp *intel_dp)
{
int ret;

- intel_dp_update_signal_levels(intel_dp);
+ intel_dp->update_signal_levels(intel_dp);

- ret = drm_dp_dpcd_write(&intel_dp->aux, DP_TRAINING_LANE0_SET,
- intel_dp->train_set, intel_dp->lane_count);
+ ret = intel_dp->dpcd_write(intel_dp, DP_TRAINING_LANE0_SET,
+ intel_dp->train_set, intel_dp->lane_count);

return ret == intel_dp->lane_count;
}
@@ -118,22 +118,22 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
if (intel_dp->prepare_link_retrain)
intel_dp->prepare_link_retrain(intel_dp);

- intel_dp_compute_rate(intel_dp, intel_dp->link_rate,
- &link_bw, &rate_select);
+ intel_dp->compute_rate(intel_dp, intel_dp->link_rate,
+ &link_bw, &rate_select);

/* Write the link configuration data */
link_config[0] = link_bw;
link_config[1] = intel_dp->lane_count;
if (drm_dp_enhanced_frame_cap(intel_dp->dpcd))
link_config[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
- drm_dp_dpcd_write(&intel_dp->aux, DP_LINK_BW_SET, link_config, 2);
+ intel_dp->dpcd_write(intel_dp, DP_LINK_BW_SET, link_config, 2);
if (intel_dp->num_sink_rates)
- drm_dp_dpcd_write(&intel_dp->aux, DP_LINK_RATE_SET,
+ intel_dp->dpcd_write(intel_dp, DP_LINK_RATE_SET,
&rate_select, 1);

link_config[0] = 0;
link_config[1] = DP_SET_ANSI_8B10B;
- drm_dp_dpcd_write(&intel_dp->aux, DP_DOWNSPREAD_CTRL, link_config, 2);
+ intel_dp->dpcd_write(intel_dp, DP_DOWNSPREAD_CTRL, link_config, 2);

intel_dp->DP |= DP_PORT_EN;

@@ -150,7 +150,7 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
loop_tries = 0;
for (;;) {
drm_dp_link_train_clock_recovery_delay(intel_dp->dpcd);
- if (!intel_dp_get_link_status(intel_dp, link_status)) {
+ if (!intel_dp->get_link_status(intel_dp, link_status)) {
DRM_ERROR("failed to get link status\n");
break;
}
@@ -232,7 +232,7 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
* Due to WaDisableHBR2 SKL < B0 is the only exception where TPS3 is
* supported but still not enabled.
*/
- if (intel_dp_source_supports_hbr2(intel_dp) &&
+ if (intel_dp->source_supports_hbr2(intel_dp) &&
drm_dp_tps3_supported(intel_dp->dpcd))
training_pattern = DP_TRAINING_PATTERN_3;
else if (intel_dp->link_rate == 540000)
@@ -258,7 +258,7 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
}

drm_dp_link_train_channel_eq_delay(intel_dp->dpcd);
- if (!intel_dp_get_link_status(intel_dp, link_status)) {
+ if (!intel_dp->get_link_status(intel_dp, link_status)) {
DRM_ERROR("failed to get link status\n");
break;
}
@@ -302,7 +302,7 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
++tries;
}

- intel_dp_set_idle_link_train(intel_dp);
+ intel_dp->set_idle_link_train(intel_dp);

if (channel_eq) {
intel_dp->train_set_valid = true;
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 35ffe27e..bc0de6c 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -771,6 +771,19 @@ struct intel_dp {

/* This is called before a link training is starterd */
void (*prepare_link_retrain)(struct intel_dp *intel_dp);
+ bool (*get_link_status)(struct intel_dp *intel_dp,
+ uint8_t link_status[DP_LINK_STATUS_SIZE]);
+ void (*update_signal_levels)(struct intel_dp *intel_dp);
+ void (*compute_rate)(struct intel_dp *intel_dp, int port_clock,
+ uint8_t *link_bw, uint8_t *rate_select);
+ void (*program_link_training_pattern)(struct intel_dp *intel_dp,
+ uint8_t dp_train_pat);
+ void (*set_idle_link_train)(struct intel_dp *intel_dp);
+ uint8_t (*voltage_max)(struct intel_dp *intel_dp);
+ uint8_t (*pre_emphasis_max)(struct intel_dp *intel_dp, uint8_t voltage);
+ ssize_t (*dpcd_write)(struct intel_dp *intel_dp, unsigned int offset,
+ void *buffer, size_t size);
+ bool (*source_supports_hbr2)(struct intel_dp *intel_dp);

bool train_set_valid;

@@ -1217,22 +1230,6 @@ void intel_edp_drrs_invalidate(struct drm_device *dev,
void intel_edp_drrs_flush(struct drm_device *dev, unsigned frontbuffer_bits);
void hsw_dp_set_ddi_pll_sel(struct intel_crtc_state *pipe_config);

-void
-intel_dp_program_link_training_pattern(struct intel_dp *intel_dp,
- uint8_t dp_train_pat);
-void
-intel_dp_update_signal_levels(struct intel_dp *intel_dp);
-void intel_dp_set_idle_link_train(struct intel_dp *intel_dp);
-uint8_t
-intel_dp_voltage_max(struct intel_dp *intel_dp);
-uint8_t
-intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing);
-void intel_dp_compute_rate(struct intel_dp *intel_dp, int port_clock,
- uint8_t *link_bw, uint8_t *rate_select);
-bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp);
-bool
-intel_dp_get_link_status(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_STATUS_SIZE]);
-
/* intel_dp_mst.c */
int intel_dp_mst_encoder_init(struct intel_digital_port *intel_dig_port, int conn_id);
void intel_dp_mst_encoder_cleanup(struct intel_digital_port *intel_dig_port);
--
2.4.3