/** * xilinx_drm_dp_adjust_train - Adjust train values * @dp: DisplayPort IP core structure * @link_status: link status from sink which contains requested training values */ static void xilinx_drm_dp_adjust_train(struct xilinx_drm_dp *dp, u8 link_status[DP_LINK_STATUS_SIZE]) { u8 *train_set = dp->train_set; u8 voltage = 0, preemphasis = 0; u8 i; for (i = 0; i < dp->mode.lane_cnt; i++) { u8 v = drm_dp_get_adjust_request_voltage(link_status, i); u8 p = drm_dp_get_adjust_request_pre_emphasis(link_status, i); if (v > voltage) voltage = v; if (p > preemphasis) preemphasis = p; } if (voltage >= DP_TRAIN_VOLTAGE_SWING_1200) voltage |= DP_TRAIN_MAX_SWING_REACHED; if (preemphasis >= DP_TRAIN_PRE_EMPHASIS_9_5) preemphasis |= DP_TRAIN_MAX_PRE_EMPHASIS_REACHED; for (i = 0; i < dp->mode.lane_cnt; i++) train_set[i] = voltage | preemphasis; }
static void edp_sink_train_set_adjust(struct edp_ctrl *ctrl, const u8 *link_status) { int i; u8 max = 0; u8 data; /* use the max level across lanes */ for (i = 0; i < ctrl->lane_cnt; i++) { data = drm_dp_get_adjust_request_voltage(link_status, i); DBG("lane=%d req_voltage_swing=0x%x", i, data); if (max < data) max = data; } ctrl->v_level = max >> DP_TRAIN_VOLTAGE_SWING_SHIFT; /* use the max level across lanes */ max = 0; for (i = 0; i < ctrl->lane_cnt; i++) { data = drm_dp_get_adjust_request_pre_emphasis(link_status, i); DBG("lane=%d req_pre_emphasis=0x%x", i, data); if (max < data) max = data; } ctrl->p_level = max >> DP_TRAIN_PRE_EMPHASIS_SHIFT; DBG("v_level=%d, p_level=%d", ctrl->v_level, ctrl->p_level); }
static void intel_get_adjust_train(struct intel_dp *intel_dp, const uint8_t link_status[DP_LINK_STATUS_SIZE]) { uint8_t v = 0; uint8_t p = 0; int lane; uint8_t voltage_max; uint8_t preemph_max; for (lane = 0; lane < intel_dp->lane_count; lane++) { uint8_t this_v = drm_dp_get_adjust_request_voltage(link_status, lane); uint8_t this_p = drm_dp_get_adjust_request_pre_emphasis(link_status, lane); if (this_v > v) v = this_v; if (this_p > p) p = this_p; } 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); if (p >= preemph_max) p = preemph_max | DP_TRAIN_MAX_PRE_EMPHASIS_REACHED; for (lane = 0; lane < 4; lane++) intel_dp->train_set[lane] = v | p; }
static void dp_get_adjust_train(u8 link_status[DP_LINK_STATUS_SIZE], int lane_count, u8 train_set[4]) { u8 v = 0; u8 p = 0; int lane; for (lane = 0; lane < lane_count; lane++) { u8 this_v = drm_dp_get_adjust_request_voltage(link_status, lane); u8 this_p = drm_dp_get_adjust_request_pre_emphasis(link_status, lane); DRM_DEBUG_KMS("requested signal parameters: lane %d voltage %s pre_emph %s\n", lane, voltage_names[this_v >> DP_TRAIN_VOLTAGE_SWING_SHIFT], pre_emph_names[this_p >> DP_TRAIN_PRE_EMPHASIS_SHIFT]); if (this_v > v) v = this_v; if (this_p > p) p = this_p; } if (v >= DP_VOLTAGE_MAX) v |= DP_TRAIN_MAX_SWING_REACHED; if (p >= DP_PRE_EMPHASIS_MAX) p |= DP_TRAIN_MAX_PRE_EMPHASIS_REACHED; DRM_DEBUG_KMS("using signal parameters: voltage %s pre_emph %s\n", voltage_names[(v & DP_TRAIN_VOLTAGE_SWING_MASK) >> DP_TRAIN_VOLTAGE_SWING_SHIFT], pre_emph_names[(p & DP_TRAIN_PRE_EMPHASIS_MASK) >> DP_TRAIN_PRE_EMPHASIS_SHIFT]); for (lane = 0; lane < 4; lane++) train_set[lane] = v | p; }