/* SPDX-License-Identifier: MIT */
/* Copyright © 2026 Intel Corporation */
#ifndef __INTEL_DP_LINK_CAPS_H__
#define __INTEL_DP_LINK_CAPS_H__
#include <linux/bitops.h>
#include <linux/types.h>
struct intel_connector;
struct intel_dp;
struct intel_dp_link_caps;
struct intel_dp_link_config;
/**
* enum intel_dp_link_caps_order_key - key used to order configurations
* @INTEL_DP_LINK_CAPS_ORDER_KEY_BW:
* Order configurations by bandwidth, then by link rate.
* @INTEL_DP_LINK_CAPS_ORDER_KEY_RATE_LANE:
* Order configurations by link rate, then by lane count.
* @INTEL_DP_LINK_CAPS_ORDER_KEY_LANE_RATE:
* Order configurations by lane count, then by link rate.
* @INTEL_DP_LINK_CAPS_ORDER_KEY_NUM:
* Number of ordering keys.
*
* Selects how a caller wants the configuration table to be ordered,
* together with an &enum intel_dp_link_caps_order_direction, for
* iteration queries.
*
* See also:
* - &struct intel_dp_link_caps_order
* - intel_dp_link_caps_get_max_config()
*/
enum intel_dp_link_caps_order_key {
INTEL_DP_LINK_CAPS_ORDER_KEY_BW,
INTEL_DP_LINK_CAPS_ORDER_KEY_RATE_LANE,
INTEL_DP_LINK_CAPS_ORDER_KEY_LANE_RATE,
INTEL_DP_LINK_CAPS_ORDER_KEY_NUM
};
/**
* enum intel_dp_link_caps_order_direction - iteration direction
* @INTEL_DP_LINK_CAPS_ORDER_DIR_ASC:
* Iterate in ascending order according to the selected ordering key.
* @INTEL_DP_LINK_CAPS_ORDER_DIR_DESC:
* Iterate in descending order according to the selected ordering key.
* @INTEL_DP_LINK_CAPS_ORDER_DIR_NUM:
* Number of ordering directions.
*
* Selects the direction associated with an
* &enum intel_dp_link_caps_order_key for iteration queries.
*
* See also:
* - &struct intel_dp_link_caps_order
*/
enum intel_dp_link_caps_order_direction {
INTEL_DP_LINK_CAPS_ORDER_DIR_ASC,
INTEL_DP_LINK_CAPS_ORDER_DIR_DESC,
INTEL_DP_LINK_CAPS_ORDER_DIR_NUM
};
/**
* struct intel_dp_link_caps_order - configuration ordering
* @key:
* Key used to order configurations.
* @dir:
* Direction of the selected ordering.
*
* Describes an iteration order for link configurations.
*
* See also:
* - for_each_dp_link_config()
*/
struct intel_dp_link_caps_order {
enum intel_dp_link_caps_order_key key;
enum intel_dp_link_caps_order_direction dir;
};
struct intel_dp_link_caps_filter {
u32 config_mask;
};
#define INTEL_DP_LINK_CAPS_FILTER_NONE \
((struct intel_dp_link_caps_filter){ .config_mask = 0 })
#define INTEL_DP_LINK_CAPS_FILTER_ALL \
((struct intel_dp_link_caps_filter){ .config_mask = (u32)-1 })
struct intel_dp_link_caps_iter {
struct intel_dp_link_caps *link_caps;
int pos;
struct intel_dp_link_caps_order order;
struct intel_dp_link_caps_filter filter;
bool (*get_next_config)(struct intel_dp_link_caps_iter *iter,
struct intel_dp_link_config *config);
};
/**
* for_each_dp_link_config - iterate allowed link configurations
* @__iter:
* &struct intel_dp_link_caps_iter being iterated
* @__config:
* pointer to &struct intel_dp_link_config filled for each match
*/
#define for_each_dp_link_config(__iter, __config) \
while ((__iter)->get_next_config((__iter), (__config)))
void intel_dp_link_caps_iter_start(struct intel_dp_link_caps_iter *iter,
struct intel_dp_link_caps *link_caps,
struct intel_dp_link_caps_order order,
struct intel_dp_link_caps_filter filter);
void intel_dp_link_caps_iter_end(struct intel_dp_link_caps_iter *iter);
struct intel_dp_link_caps_order
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);
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);
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);
bool intel_dp_link_caps_get_max_config(struct intel_dp_link_caps *link_caps,
enum intel_dp_link_caps_order_key order_key,
struct intel_dp_link_caps_filter filter,
struct intel_dp_link_config *max_config);
void intel_dp_link_caps_get_max_bw_config(struct intel_dp_link_caps *link_caps,
struct intel_dp_link_config *max_config);
bool intel_dp_link_caps_disable_config(struct intel_dp_link_caps *link_caps,
const struct intel_dp_link_config *config);
void intel_dp_link_caps_get_max_limits(struct intel_dp_link_caps *link_caps,
struct intel_dp_link_config *max_link_limits);
bool intel_dp_link_caps_set_max_limits(struct intel_dp_link_caps *link_caps,
const struct intel_dp_link_config *max_link_limits);
void intel_dp_link_caps_reset_max_limits(struct intel_dp_link_caps *link_caps);
bool intel_dp_link_caps_update(struct intel_dp_link_caps *link_caps,
const int *rates, int num_rates, int max_lane_count,
bool reset);
void intel_dp_link_caps_reset(struct intel_dp_link_caps *link_caps);
void intel_dp_link_caps_debugfs_add(struct intel_connector *connector);
struct intel_dp_link_caps *intel_dp_link_caps_init(struct intel_dp *intel_dp);
void intel_dp_link_caps_cleanup(struct intel_dp_link_caps *link_caps);
#if IS_ENABLED(CONFIG_KUNIT)
#define INTEL_DP_LINK_CAPS_TEST_OPS_MEMBERS(__X) \
__X(connector_compute_order, intel_dp_link_caps_connector_compute_order) \
__X(connector_fallback_order, intel_dp_link_caps_connector_fallback_order) \
__X(iter_start, intel_dp_link_caps_iter_start) \
__X(iter_end, intel_dp_link_caps_iter_end) \
__X(set_max_limits, intel_dp_link_caps_set_max_limits) \
__X(get_max_limits, intel_dp_link_caps_get_max_limits) \
__X(get_max_bw_config, intel_dp_link_caps_get_max_bw_config) \
__X(reset_max_limits, intel_dp_link_caps_reset_max_limits) \
__X(disable_config, intel_dp_link_caps_disable_config) \
__X(update, intel_dp_link_caps_update) \
__X(init, intel_dp_link_caps_init) \
__X(cleanup, intel_dp_link_caps_cleanup)
#define __DECLARE_MEMBER(__name, __fn) \
typeof(__fn) *__name;
#define INTEL_DP_LINK_CAPS_TEST_OPS_DECLARE \
INTEL_DP_LINK_CAPS_TEST_OPS_MEMBERS(__DECLARE_MEMBER)
struct intel_dp_link_caps_test_ops {
INTEL_DP_LINK_CAPS_TEST_OPS_DECLARE
};
#undef INTEL_DP_LINK_CAPS_TEST_OPS_DECLARE
#undef __DECLARE_MEMBER
#ifdef I915
extern const struct intel_dp_link_caps_test_ops i915_display_dp_link_caps_test_ops;
#else
extern const struct intel_dp_link_caps_test_ops intel_display_dp_link_caps_test_ops;
#endif /* I915 */
#endif /* CONFIG_KUNIT */
#endif /* __INTEL_DP_LINK_CAPS_H__ */