}
}
-static void exynos_dp_link_start(struct exynos_dp_device *dp)
+static int exynos_dp_link_start(struct exynos_dp_device *dp)
{
+ int ret;
u8 buf[5];
int lane;
int lane_count;
dp->link_train.cr_loop[lane] = 0;
/* Set sink to D0 (Sink Not Ready) mode. */
- exynos_dp_write_byte_to_dpcd(dp, DPCD_ADDR_SINK_POWER_STATE,
+ ret = exynos_dp_write_byte_to_dpcd(dp, DPCD_ADDR_SINK_POWER_STATE,
DPCD_SET_POWER_STATE_D0);
+ if (ret)
+ return ret;
/* Set link rate and count as you want to establish*/
exynos_dp_set_link_bandwidth(dp, dp->link_train.link_rate);
/* Setup RX configuration */
buf[0] = dp->link_train.link_rate;
buf[1] = dp->link_train.lane_count;
- exynos_dp_write_bytes_to_dpcd(dp, DPCD_ADDR_LINK_BW_SET,
+ ret = exynos_dp_write_bytes_to_dpcd(dp, DPCD_ADDR_LINK_BW_SET,
2, buf);
+ if (ret)
+ return ret;
/* Set TX pre-emphasis to minimum */
for (lane = 0; lane < lane_count; lane++)
for (lane = 1; lane <= lane_count; lane++)
buf[lane] = DPCD_PRE_EMPHASIS_PATTERN2_LEVEL0 |
DPCD_VOLTAGE_SWING_PATTERN1_LEVEL0;
- exynos_dp_write_bytes_to_dpcd(dp,
+ ret = exynos_dp_write_bytes_to_dpcd(dp,
DPCD_ADDR_TRAINING_PATTERN_SET,
lane_count + 1, buf);
+ if (ret)
+ return ret;
+
+ return ret;
}
static unsigned char exynos_dp_get_lane_status(u8 link_status[6], int lane)
static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
{
+ int ret;
u8 data;
u8 link_status[6];
int lane;
udelay(100);
- exynos_dp_read_bytes_from_dpcd(dp, DPCD_ADDR_LANE0_1_STATUS,
+ ret = exynos_dp_read_bytes_from_dpcd(dp, DPCD_ADDR_LANE0_1_STATUS,
6, link_status);
+ if (ret)
+ return ret;
+
lane_count = dp->link_train.lane_count;
adjust_request[0] = link_status[4];
buf[0] = DPCD_SCRAMBLING_DISABLED |
DPCD_TRAINING_PATTERN_2;
- exynos_dp_write_byte_to_dpcd(dp,
+ ret = exynos_dp_write_byte_to_dpcd(dp,
DPCD_ADDR_TRAINING_PATTERN_SET,
buf[0]);
+ if (ret)
+ return ret;
for (lane = 0; lane < lane_count; lane++) {
exynos_dp_set_lane_link_training(dp,
dp->link_train.training_lane[lane],
lane);
buf[lane] = dp->link_train.training_lane[lane];
- exynos_dp_write_byte_to_dpcd(dp,
+ ret = exynos_dp_write_byte_to_dpcd(dp,
DPCD_ADDR_TRAINING_LANE0_SET + lane,
buf[lane]);
+ if (ret)
+ return ret;
}
dp->link_train.lt_state = EQUALIZER_TRAINING;
} else {
dp->link_train.training_lane[lane],
lane);
buf[lane] = dp->link_train.training_lane[lane];
- exynos_dp_write_byte_to_dpcd(dp,
+ ret = exynos_dp_write_byte_to_dpcd(dp,
DPCD_ADDR_TRAINING_LANE0_SET + lane,
buf[lane]);
+ if (ret)
+ return ret;
}
}
}
- return 0;
+ return ret;
}
static int exynos_dp_process_equalizer_training(struct exynos_dp_device *dp)
{
+ int ret;
u8 link_status[6];
int lane;
int lane_count;
udelay(400);
- exynos_dp_read_bytes_from_dpcd(dp, DPCD_ADDR_LANE0_1_STATUS,
+ ret = exynos_dp_read_bytes_from_dpcd(dp, DPCD_ADDR_LANE0_1_STATUS,
6, link_status);
+ if (ret)
+ return ret;
lane_count = dp->link_train.lane_count;
if (exynos_dp_clock_recovery_ok(link_status, lane_count) == 0) {
dp->link_train.training_lane[lane],
lane);
buf[lane] = dp->link_train.training_lane[lane];
- exynos_dp_write_byte_to_dpcd(dp,
+ ret = exynos_dp_write_byte_to_dpcd(dp,
DPCD_ADDR_TRAINING_LANE0_SET + lane,
buf[lane]);
+ if (ret)
+ return ret;
}
}
}
exynos_dp_reduce_link_rate(dp);
}
- return 0;
+ return ret;
}
static void exynos_dp_get_max_rx_bandwidth(struct exynos_dp_device *dp,
static int exynos_dp_sw_link_training(struct exynos_dp_device *dp)
{
- int retval = 0;
- int training_finished;
+ int ret = 0, training_finished = 0;
/* Turn off unnecessary lane */
if (dp->link_train.lane_count == 1)
exynos_dp_set_analog_power_down(dp, CH3_BLOCK, 1);
}
- training_finished = 0;
-
dp->link_train.lt_state = START;
/* Process here */
- while (!training_finished) {
+ while (!ret && !training_finished) {
switch (dp->link_train.lt_state) {
case START:
- exynos_dp_link_start(dp);
+ ret = exynos_dp_link_start(dp);
break;
case CLOCK_RECOVERY:
- exynos_dp_process_clock_recovery(dp);
+ ret = exynos_dp_process_clock_recovery(dp);
break;
case EQUALIZER_TRAINING:
- exynos_dp_process_equalizer_training(dp);
+ ret = exynos_dp_process_equalizer_training(dp);
break;
case FINISHED:
training_finished = 1;
return -EREMOTEIO;
}
}
+ if (ret)
+ dev_err(dp->dev, "eDP link training failed (%d)\n", ret);
- return retval;
+ return ret;
}
static int exynos_dp_set_hw_link_train(struct exynos_dp_device *dp,