mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 04:34:03 +02:00
drm/i915/dp_link_training: Use config iterator for fallback
Switch the fallback loop to use the link configuration iterator to select a fallback configuration. This also allows unexporting and removing from the link caps interface all the common link rate query helpers and the helpers that accept or return a link configuration index. Reviewed-by: Luca Coelho <luciano.coelho@intel.com> Signed-off-by: Imre Deak <imre.deak@intel.com> Link: https://patch.msgid.link/20260701153204.4124150-25-imre.deak@intel.com
This commit is contained in:
parent
9cee806ef5
commit
86e664219a
|
|
@ -249,7 +249,7 @@ static int intel_dp_common_len_rate_limit(struct intel_dp_link_caps *link_caps,
|
|||
link_caps->num_rates, max_rate);
|
||||
}
|
||||
|
||||
int intel_dp_common_rate(struct intel_dp_link_caps *link_caps, int index)
|
||||
static int intel_dp_common_rate(struct intel_dp_link_caps *link_caps, int index)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(link_caps->dp);
|
||||
|
||||
|
|
@ -260,15 +260,8 @@ int intel_dp_common_rate(struct intel_dp_link_caps *link_caps, int index)
|
|||
return link_caps->rates[index];
|
||||
}
|
||||
|
||||
int intel_dp_link_caps_common_rate_idx(struct intel_dp_link_caps *link_caps, int rate)
|
||||
{
|
||||
return intel_dp_rate_index(link_caps->rates,
|
||||
link_caps->num_rates,
|
||||
rate);
|
||||
}
|
||||
|
||||
/* Theoretical max between source and sink */
|
||||
int intel_dp_max_common_rate(struct intel_dp_link_caps *link_caps)
|
||||
static int intel_dp_max_common_rate(struct intel_dp_link_caps *link_caps)
|
||||
{
|
||||
return intel_dp_common_rate(link_caps, link_caps->num_rates - 1);
|
||||
}
|
||||
|
|
@ -870,40 +863,6 @@ bool intel_dp_link_caps_update(struct intel_dp_link_caps *link_caps,
|
|||
return link_params_changed;
|
||||
}
|
||||
|
||||
void intel_dp_link_config_get(struct intel_dp_link_caps *link_caps,
|
||||
int idx, int *link_rate, int *lane_count)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(link_caps->dp);
|
||||
struct intel_dp_link_config config;
|
||||
|
||||
if (drm_WARN_ON(display->drm, idx < 0 || idx >= link_caps->num_configs))
|
||||
idx = 0;
|
||||
|
||||
to_intel_dp_link_config(link_caps, idx, &config);
|
||||
|
||||
*link_rate = config.rate;
|
||||
*lane_count = config.lane_count;
|
||||
}
|
||||
|
||||
int intel_dp_link_config_index(struct intel_dp_link_caps *link_caps,
|
||||
int link_rate, int lane_count)
|
||||
{
|
||||
int link_rate_idx = intel_dp_rate_index(link_caps->rates, link_caps->num_rates,
|
||||
link_rate);
|
||||
int lane_count_exp = ilog2(lane_count);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < link_caps->num_configs; i++) {
|
||||
const struct intel_dp_link_config_entry *lce = &link_caps->configs[i];
|
||||
|
||||
if (lce->lane_count_exp == lane_count_exp &&
|
||||
lce->link_rate_idx == link_rate_idx)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* intel_dp_link_caps_reset - reset link capability restrictions
|
||||
* @link_caps: link capabilities state
|
||||
|
|
|
|||
|
|
@ -119,20 +119,11 @@ intel_dp_link_caps_connector_compute_order(struct intel_connector *connector);
|
|||
struct intel_dp_link_caps_order
|
||||
intel_dp_link_caps_connector_fallback_order(bool is_mst);
|
||||
|
||||
int intel_dp_common_rate(struct intel_dp_link_caps *link_caps, int index);
|
||||
int intel_dp_link_caps_common_rate_idx(struct intel_dp_link_caps *link_caps, int rate);
|
||||
int intel_dp_max_common_rate(struct intel_dp_link_caps *link_caps);
|
||||
|
||||
void intel_dp_link_caps_print_common_rates(struct intel_dp_link_caps *link_caps);
|
||||
|
||||
void intel_dp_link_caps_get_forced_params(struct intel_dp_link_caps *link_caps,
|
||||
struct intel_dp_link_config *forced_params);
|
||||
|
||||
int intel_dp_link_config_index(struct intel_dp_link_caps *link_caps,
|
||||
int link_rate, int lane_count);
|
||||
void intel_dp_link_config_get(struct intel_dp_link_caps *link_caps,
|
||||
int idx, int *link_rate, int *lane_count);
|
||||
|
||||
bool intel_dp_link_caps_filter_add(struct intel_dp_link_caps *link_caps,
|
||||
struct intel_dp_link_caps_filter *filter,
|
||||
const struct intel_dp_link_config *config);
|
||||
|
|
|
|||
|
|
@ -1846,115 +1846,46 @@ static bool intel_dp_can_link_train_fallback_for_edp(struct intel_dp *intel_dp,
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool reduce_link_params_in_bw_order(struct intel_dp *intel_dp,
|
||||
const struct intel_crtc_state *crtc_state,
|
||||
int *new_link_rate, int *new_lane_count)
|
||||
{
|
||||
struct intel_dp_link_caps *link_caps = intel_dp->link.caps;
|
||||
struct intel_dp_link_config forced_params;
|
||||
int link_rate;
|
||||
int lane_count;
|
||||
int i;
|
||||
|
||||
intel_dp_link_caps_get_forced_params(link_caps, &forced_params);
|
||||
|
||||
i = intel_dp_link_config_index(intel_dp->link.caps,
|
||||
crtc_state->port_clock, crtc_state->lane_count);
|
||||
for (i--; i >= 0; i--) {
|
||||
intel_dp_link_config_get(intel_dp->link.caps, i, &link_rate, &lane_count);
|
||||
|
||||
if ((forced_params.rate &&
|
||||
forced_params.rate != link_rate) ||
|
||||
(forced_params.lane_count &&
|
||||
forced_params.lane_count != lane_count))
|
||||
continue;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (i < 0)
|
||||
return false;
|
||||
|
||||
*new_link_rate = link_rate;
|
||||
*new_lane_count = lane_count;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int reduce_link_rate(struct intel_dp *intel_dp, int current_rate)
|
||||
{
|
||||
struct intel_dp_link_caps *link_caps = intel_dp->link.caps;
|
||||
struct intel_dp_link_config forced_params;
|
||||
int rate_index;
|
||||
int new_rate;
|
||||
|
||||
intel_dp_link_caps_get_forced_params(link_caps, &forced_params);
|
||||
if (forced_params.rate)
|
||||
return -1;
|
||||
|
||||
rate_index = intel_dp_link_caps_common_rate_idx(link_caps,
|
||||
current_rate);
|
||||
|
||||
if (rate_index <= 0)
|
||||
return -1;
|
||||
|
||||
new_rate = intel_dp_common_rate(link_caps, rate_index - 1);
|
||||
|
||||
/* TODO: Make switching from UHBR to non-UHBR rates work. */
|
||||
if (drm_dp_is_uhbr_rate(current_rate) != drm_dp_is_uhbr_rate(new_rate))
|
||||
return -1;
|
||||
|
||||
return new_rate;
|
||||
}
|
||||
|
||||
static int reduce_lane_count(struct intel_dp *intel_dp, int current_lane_count)
|
||||
{
|
||||
struct intel_dp_link_config forced_params;
|
||||
|
||||
intel_dp_link_caps_get_forced_params(intel_dp->link.caps, &forced_params);
|
||||
if (forced_params.lane_count)
|
||||
return -1;
|
||||
|
||||
if (current_lane_count == 1)
|
||||
return -1;
|
||||
|
||||
return current_lane_count >> 1;
|
||||
}
|
||||
|
||||
static bool reduce_link_params_in_rate_lane_order(struct intel_dp *intel_dp,
|
||||
const struct intel_crtc_state *crtc_state,
|
||||
int *new_link_rate, int *new_lane_count)
|
||||
{
|
||||
struct intel_dp_link_caps *link_caps = intel_dp->link.caps;
|
||||
int link_rate;
|
||||
int lane_count;
|
||||
|
||||
lane_count = crtc_state->lane_count;
|
||||
link_rate = reduce_link_rate(intel_dp, crtc_state->port_clock);
|
||||
if (link_rate < 0) {
|
||||
lane_count = reduce_lane_count(intel_dp, crtc_state->lane_count);
|
||||
link_rate = intel_dp_max_common_rate(link_caps);
|
||||
}
|
||||
|
||||
if (lane_count < 0)
|
||||
return false;
|
||||
|
||||
*new_link_rate = link_rate;
|
||||
*new_lane_count = lane_count;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool reduce_link_params(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state,
|
||||
int *new_link_rate, int *new_lane_count)
|
||||
{
|
||||
/* TODO: Use the same fallback logic on SST as on MST. */
|
||||
if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST))
|
||||
return reduce_link_params_in_bw_order(intel_dp, crtc_state,
|
||||
new_link_rate, new_lane_count);
|
||||
else
|
||||
return reduce_link_params_in_rate_lane_order(intel_dp, crtc_state,
|
||||
new_link_rate, new_lane_count);
|
||||
struct intel_dp_link_caps *link_caps = intel_dp->link.caps;
|
||||
bool is_mst = intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST);
|
||||
struct intel_dp_link_caps_order order =
|
||||
intel_dp_link_caps_connector_fallback_order(is_mst);
|
||||
struct intel_dp_link_config old_config = {
|
||||
.rate = crtc_state->port_clock,
|
||||
.lane_count = crtc_state->lane_count,
|
||||
};
|
||||
struct intel_dp_link_caps_iter iter;
|
||||
struct intel_dp_link_config config;
|
||||
bool old_found = false;
|
||||
bool new_found = false;
|
||||
|
||||
intel_dp_link_caps_iter_start(&iter, link_caps, order, INTEL_DP_LINK_CAPS_FILTER_ALL);
|
||||
for_each_dp_link_config(&iter, &config) {
|
||||
if (!old_found) {
|
||||
if (config.rate == old_config.rate &&
|
||||
config.lane_count == old_config.lane_count)
|
||||
old_found = true;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!is_mst &&
|
||||
drm_dp_is_uhbr_rate(config.rate) !=
|
||||
drm_dp_is_uhbr_rate(old_config.rate))
|
||||
continue;
|
||||
|
||||
*new_link_rate = config.rate;
|
||||
*new_lane_count = config.lane_count;
|
||||
new_found = true;
|
||||
|
||||
break;
|
||||
}
|
||||
intel_dp_link_caps_iter_end(&iter);
|
||||
|
||||
return new_found;
|
||||
}
|
||||
|
||||
static int intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user