switch (pattern) { case DP_TRAINING_PATTERN_DISABLE:
val = 0; break; case DP_TRAINING_PATTERN_1:
val = 1; break; case DP_TRAINING_PATTERN_2:
val = 2; break; case DP_TRAINING_PATTERN_3:
val = 3; break; case DP_TRAINING_PATTERN_4:
val = 4; break; default: return -EINVAL;
}
ret = drm_dp_dpcd_write(dp->aux, DP_TRAINING_PATTERN_SET, &buf, sizeof(buf)); if (ret != sizeof(buf)) {
drm_dbg_dp(dp->dev, "dp aux write training pattern set failed\n"); return ret >= 0 ? -EIO : ret;
}
ret = hibmc_dp_link_training_configure(dp); if (ret) return ret;
ret = hibmc_dp_link_set_pattern(dp, DP_TRAINING_PATTERN_1); if (ret) return ret;
for (i = 0; i < dp->link.cap.lanes; i++)
train_set[i] = DP_TRAIN_VOLTAGE_SWING_LEVEL_0;
ret = hibmc_dp_serdes_set_tx_cfg(dp, dp->link.train_set); if (ret) return ret;
ret = drm_dp_dpcd_write(dp->aux, DP_TRAINING_LANE0_SET, train_set, dp->link.cap.lanes); if (ret != dp->link.cap.lanes) {
drm_dbg_dp(dp->dev, "dp aux write training lane set failed\n"); return ret >= 0 ? -EIO : ret;
}
for (lane = 0; lane < dp->link.cap.lanes; lane++)
train_set[lane] = drm_dp_get_adjust_request_voltage(lane_status, lane) |
drm_dp_get_adjust_request_pre_emphasis(lane_status, lane);
if (memcmp(dp->link.train_set, train_set, HIBMC_DP_LANE_NUM_MAX)) {
memcpy(dp->link.train_set, train_set, HIBMC_DP_LANE_NUM_MAX); returntrue;
}
returnfalse;
}
staticint hibmc_dp_link_reduce_rate(struct hibmc_dp_dev *dp)
{ int ret;
switch (dp->link.cap.link_rate) { case DP_LINK_BW_2_7:
dp->link.cap.link_rate = DP_LINK_BW_1_62; break; case DP_LINK_BW_5_4:
dp->link.cap.link_rate = DP_LINK_BW_2_7; break; case DP_LINK_BW_8_1:
dp->link.cap.link_rate = DP_LINK_BW_5_4; break; default: return -EINVAL;
}
ret = hibmc_dp_get_serdes_rate_cfg(dp); if (ret < 0) return ret;
return hibmc_dp_serdes_rate_switch(ret, dp);
}
staticinlineint hibmc_dp_link_reduce_lane(struct hibmc_dp_dev *dp)
{ switch (dp->link.cap.lanes) { case 0x2:
dp->link.cap.lanes--;
drm_dbg_dp(dp->dev, "dp link training reduce to 1 lane\n"); break; case 0x1:
drm_err(dp->dev, "dp link training reduce lane failed, already reach minimum\n"); return -EIO; default: return -EINVAL;
}
/* * DP 1.4 spec define 10 for maxtries value, for pre DP 1.4 version set a limit of 80 * (4 voltage levels x 4 preemphasis levels x 5 identical voltage retries)
*/
ret = hibmc_dp_serdes_set_tx_cfg(dp, dp->link.train_set); if (ret) return ret;
ret = drm_dp_dpcd_write(dp->aux, DP_TRAINING_LANE0_SET, dp->link.train_set,
dp->link.cap.lanes); if (ret != dp->link.cap.lanes) {
drm_dbg_dp(dp->dev, "Update link training failed\n"); return ret >= 0 ? -EIO : ret;
}
if (drm_dp_channel_eq_ok(lane_status, dp->link.cap.lanes)) {
dp->link.status.channel_equalized = true;
drm_dbg_dp(dp->dev, "dp link training eq done\n"); break;
}
hibmc_dp_link_get_adjust_train(dp, lane_status);
ret = hibmc_dp_serdes_set_tx_cfg(dp, dp->link.train_set); if (ret) return ret;
ret = drm_dp_dpcd_write(dp->aux, DP_TRAINING_LANE0_SET,
dp->link.train_set, dp->link.cap.lanes); if (ret != dp->link.cap.lanes) {
drm_dbg_dp(dp->dev, "Update link training failed\n");
ret = (ret >= 0) ? -EIO : ret; break;
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.