1ebf5ad5cSImre Deak /* SPDX-License-Identifier: MIT */ 2ebf5ad5cSImre Deak /* Copyright © 2026 Intel Corporation */ 3ebf5ad5cSImre Deak 4ebf5ad5cSImre Deak #ifndef __INTEL_DP_LINK_CAPS_H__ 5ebf5ad5cSImre Deak #define __INTEL_DP_LINK_CAPS_H__ 6ebf5ad5cSImre Deak 739e30bdfSImre Deak #include <linux/bitops.h> 87aa14e73SImre Deak #include <linux/types.h> 97aa14e73SImre Deak 10fdd4b01bSImre Deak struct intel_connector; 11ebf5ad5cSImre Deak struct intel_dp; 12690e3194SImre Deak struct intel_dp_link_caps; 13690e3194SImre Deak struct intel_dp_link_config; 14ebf5ad5cSImre Deak 1539e30bdfSImre Deak /** 1639e30bdfSImre Deak * enum intel_dp_link_caps_order_key - key used to order configurations 1739e30bdfSImre Deak * @INTEL_DP_LINK_CAPS_ORDER_KEY_BW: 1839e30bdfSImre Deak * Order configurations by bandwidth, then by link rate. 1939e30bdfSImre Deak * @INTEL_DP_LINK_CAPS_ORDER_KEY_RATE_LANE: 2039e30bdfSImre Deak * Order configurations by link rate, then by lane count. 2139e30bdfSImre Deak * @INTEL_DP_LINK_CAPS_ORDER_KEY_LANE_RATE: 2239e30bdfSImre Deak * Order configurations by lane count, then by link rate. 2339e30bdfSImre Deak * @INTEL_DP_LINK_CAPS_ORDER_KEY_NUM: 2439e30bdfSImre Deak * Number of ordering keys. 2539e30bdfSImre Deak * 2639e30bdfSImre Deak * Selects how a caller wants the configuration table to be ordered, 2739e30bdfSImre Deak * together with an &enum intel_dp_link_caps_order_direction, for 2839e30bdfSImre Deak * iteration queries. 2939e30bdfSImre Deak * 3039e30bdfSImre Deak * See also: 3139e30bdfSImre Deak * - &struct intel_dp_link_caps_order 3269505f3fSImre Deak * - intel_dp_link_caps_get_max_config() 3339e30bdfSImre Deak */ 3439e30bdfSImre Deak enum intel_dp_link_caps_order_key { 3539e30bdfSImre Deak INTEL_DP_LINK_CAPS_ORDER_KEY_BW, 3639e30bdfSImre Deak INTEL_DP_LINK_CAPS_ORDER_KEY_RATE_LANE, 3739e30bdfSImre Deak INTEL_DP_LINK_CAPS_ORDER_KEY_LANE_RATE, 3839e30bdfSImre Deak 3939e30bdfSImre Deak INTEL_DP_LINK_CAPS_ORDER_KEY_NUM 4039e30bdfSImre Deak }; 4139e30bdfSImre Deak 4239e30bdfSImre Deak /** 4339e30bdfSImre Deak * enum intel_dp_link_caps_order_direction - iteration direction 4439e30bdfSImre Deak * @INTEL_DP_LINK_CAPS_ORDER_DIR_ASC: 4539e30bdfSImre Deak * Iterate in ascending order according to the selected ordering key. 4639e30bdfSImre Deak * @INTEL_DP_LINK_CAPS_ORDER_DIR_DESC: 4739e30bdfSImre Deak * Iterate in descending order according to the selected ordering key. 4839e30bdfSImre Deak * @INTEL_DP_LINK_CAPS_ORDER_DIR_NUM: 4939e30bdfSImre Deak * Number of ordering directions. 5039e30bdfSImre Deak * 5139e30bdfSImre Deak * Selects the direction associated with an 5239e30bdfSImre Deak * &enum intel_dp_link_caps_order_key for iteration queries. 5339e30bdfSImre Deak * 5439e30bdfSImre Deak * See also: 5539e30bdfSImre Deak * - &struct intel_dp_link_caps_order 5639e30bdfSImre Deak */ 5739e30bdfSImre Deak enum intel_dp_link_caps_order_direction { 5839e30bdfSImre Deak INTEL_DP_LINK_CAPS_ORDER_DIR_ASC, 5939e30bdfSImre Deak INTEL_DP_LINK_CAPS_ORDER_DIR_DESC, 6039e30bdfSImre Deak 6139e30bdfSImre Deak INTEL_DP_LINK_CAPS_ORDER_DIR_NUM 6239e30bdfSImre Deak }; 6339e30bdfSImre Deak 6439e30bdfSImre Deak /** 6539e30bdfSImre Deak * struct intel_dp_link_caps_order - configuration ordering 6639e30bdfSImre Deak * @key: 6739e30bdfSImre Deak * Key used to order configurations. 6839e30bdfSImre Deak * @dir: 6939e30bdfSImre Deak * Direction of the selected ordering. 7039e30bdfSImre Deak * 7139e30bdfSImre Deak * Describes an iteration order for link configurations. 7239e30bdfSImre Deak * 7339e30bdfSImre Deak * See also: 7439e30bdfSImre Deak * - for_each_dp_link_config() 7539e30bdfSImre Deak */ 7639e30bdfSImre Deak struct intel_dp_link_caps_order { 7739e30bdfSImre Deak enum intel_dp_link_caps_order_key key; 7839e30bdfSImre Deak enum intel_dp_link_caps_order_direction dir; 7939e30bdfSImre Deak }; 8039e30bdfSImre Deak 8139e30bdfSImre Deak struct intel_dp_link_caps_filter { 8239e30bdfSImre Deak u32 config_mask; 8339e30bdfSImre Deak }; 8439e30bdfSImre Deak 8539e30bdfSImre Deak #define INTEL_DP_LINK_CAPS_FILTER_NONE \ 8639e30bdfSImre Deak ((struct intel_dp_link_caps_filter){ .config_mask = 0 }) 8739e30bdfSImre Deak #define INTEL_DP_LINK_CAPS_FILTER_ALL \ 8839e30bdfSImre Deak ((struct intel_dp_link_caps_filter){ .config_mask = (u32)-1 }) 8939e30bdfSImre Deak 9039e30bdfSImre Deak struct intel_dp_link_caps_iter { 9139e30bdfSImre Deak struct intel_dp_link_caps *link_caps; 9239e30bdfSImre Deak int pos; 9339e30bdfSImre Deak struct intel_dp_link_caps_order order; 9439e30bdfSImre Deak struct intel_dp_link_caps_filter filter; 9539e30bdfSImre Deak 9639e30bdfSImre Deak bool (*get_next_config)(struct intel_dp_link_caps_iter *iter, 9739e30bdfSImre Deak struct intel_dp_link_config *config); 9839e30bdfSImre Deak }; 9939e30bdfSImre Deak 10039e30bdfSImre Deak /** 10139e30bdfSImre Deak * for_each_dp_link_config - iterate allowed link configurations 10239e30bdfSImre Deak * @__iter: 10339e30bdfSImre Deak * &struct intel_dp_link_caps_iter being iterated 10439e30bdfSImre Deak * @__config: 10539e30bdfSImre Deak * pointer to &struct intel_dp_link_config filled for each match 10639e30bdfSImre Deak */ 10739e30bdfSImre Deak #define for_each_dp_link_config(__iter, __config) \ 10839e30bdfSImre Deak while ((__iter)->get_next_config((__iter), (__config))) 10939e30bdfSImre Deak 11039e30bdfSImre Deak void intel_dp_link_caps_iter_start(struct intel_dp_link_caps_iter *iter, 11139e30bdfSImre Deak struct intel_dp_link_caps *link_caps, 11239e30bdfSImre Deak struct intel_dp_link_caps_order order, 11339e30bdfSImre Deak struct intel_dp_link_caps_filter filter); 11439e30bdfSImre Deak 11539e30bdfSImre Deak void intel_dp_link_caps_iter_end(struct intel_dp_link_caps_iter *iter); 11639e30bdfSImre Deak 1179d4bd665SImre Deak struct intel_dp_link_caps_order 1189d4bd665SImre Deak intel_dp_link_caps_connector_compute_order(struct intel_connector *connector); 1199d4bd665SImre Deak struct intel_dp_link_caps_order 1209d4bd665SImre Deak intel_dp_link_caps_connector_fallback_order(bool is_mst); 1219d4bd665SImre Deak 12296d07a10SImre Deak void intel_dp_link_caps_print_common_rates(struct intel_dp_link_caps *link_caps); 12396d07a10SImre Deak 124690e3194SImre Deak void intel_dp_link_caps_get_forced_params(struct intel_dp_link_caps *link_caps, 125690e3194SImre Deak struct intel_dp_link_config *forced_params); 126690e3194SImre Deak 12739e30bdfSImre Deak bool intel_dp_link_caps_filter_add(struct intel_dp_link_caps *link_caps, 12839e30bdfSImre Deak struct intel_dp_link_caps_filter *filter, 12939e30bdfSImre Deak const struct intel_dp_link_config *config); 13039e30bdfSImre Deak 13169505f3fSImre Deak bool intel_dp_link_caps_get_max_config(struct intel_dp_link_caps *link_caps, 13269505f3fSImre Deak enum intel_dp_link_caps_order_key order_key, 13369505f3fSImre Deak struct intel_dp_link_caps_filter filter, 13469505f3fSImre Deak struct intel_dp_link_config *max_config); 13569505f3fSImre Deak 1369791229bSImre Deak void intel_dp_link_caps_get_max_bw_config(struct intel_dp_link_caps *link_caps, 1379791229bSImre Deak struct intel_dp_link_config *max_config); 1389791229bSImre Deak 13955b131b3SImre Deak bool intel_dp_link_caps_disable_config(struct intel_dp_link_caps *link_caps, 14055b131b3SImre Deak const struct intel_dp_link_config *config); 14155b131b3SImre Deak 14245408c4cSImre Deak void intel_dp_link_caps_get_max_limits(struct intel_dp_link_caps *link_caps, 14345408c4cSImre Deak struct intel_dp_link_config *max_link_limits); 14417659f83SImre Deak bool intel_dp_link_caps_set_max_limits(struct intel_dp_link_caps *link_caps, 14517659f83SImre Deak const struct intel_dp_link_config *max_link_limits); 14613b1b0b9SImre Deak void intel_dp_link_caps_reset_max_limits(struct intel_dp_link_caps *link_caps); 14745408c4cSImre Deak 1483aa9d374SImre Deak bool intel_dp_link_caps_update(struct intel_dp_link_caps *link_caps, 149ae40784fSImre Deak const int *rates, int num_rates, int max_lane_count, 150ae40784fSImre Deak bool reset); 151cd0d2557SImre Deak void intel_dp_link_caps_reset(struct intel_dp_link_caps *link_caps); 152b9d98594SImre Deak 153fdd4b01bSImre Deak void intel_dp_link_caps_debugfs_add(struct intel_connector *connector); 154fdd4b01bSImre Deak 155ebf5ad5cSImre Deak struct intel_dp_link_caps *intel_dp_link_caps_init(struct intel_dp *intel_dp); 156ebf5ad5cSImre Deak void intel_dp_link_caps_cleanup(struct intel_dp_link_caps *link_caps); 157ebf5ad5cSImre Deak 158*2eb9982fSImre Deak #if IS_ENABLED(CONFIG_KUNIT) 159*2eb9982fSImre Deak 160*2eb9982fSImre Deak #define INTEL_DP_LINK_CAPS_TEST_OPS_MEMBERS(__X) \ 161*2eb9982fSImre Deak __X(connector_compute_order, intel_dp_link_caps_connector_compute_order) \ 162*2eb9982fSImre Deak __X(connector_fallback_order, intel_dp_link_caps_connector_fallback_order) \ 163*2eb9982fSImre Deak __X(iter_start, intel_dp_link_caps_iter_start) \ 164*2eb9982fSImre Deak __X(iter_end, intel_dp_link_caps_iter_end) \ 165*2eb9982fSImre Deak __X(set_max_limits, intel_dp_link_caps_set_max_limits) \ 166*2eb9982fSImre Deak __X(get_max_limits, intel_dp_link_caps_get_max_limits) \ 167*2eb9982fSImre Deak __X(get_max_bw_config, intel_dp_link_caps_get_max_bw_config) \ 168*2eb9982fSImre Deak __X(reset_max_limits, intel_dp_link_caps_reset_max_limits) \ 169*2eb9982fSImre Deak __X(disable_config, intel_dp_link_caps_disable_config) \ 170*2eb9982fSImre Deak __X(update, intel_dp_link_caps_update) \ 171*2eb9982fSImre Deak __X(init, intel_dp_link_caps_init) \ 172*2eb9982fSImre Deak __X(cleanup, intel_dp_link_caps_cleanup) 173*2eb9982fSImre Deak 174*2eb9982fSImre Deak #define __DECLARE_MEMBER(__name, __fn) \ 175*2eb9982fSImre Deak typeof(__fn) *__name; 176*2eb9982fSImre Deak 177*2eb9982fSImre Deak #define INTEL_DP_LINK_CAPS_TEST_OPS_DECLARE \ 178*2eb9982fSImre Deak INTEL_DP_LINK_CAPS_TEST_OPS_MEMBERS(__DECLARE_MEMBER) 179*2eb9982fSImre Deak 180*2eb9982fSImre Deak struct intel_dp_link_caps_test_ops { 181*2eb9982fSImre Deak INTEL_DP_LINK_CAPS_TEST_OPS_DECLARE 182*2eb9982fSImre Deak }; 183*2eb9982fSImre Deak 184*2eb9982fSImre Deak #undef INTEL_DP_LINK_CAPS_TEST_OPS_DECLARE 185*2eb9982fSImre Deak #undef __DECLARE_MEMBER 186*2eb9982fSImre Deak 187*2eb9982fSImre Deak #ifdef I915 188*2eb9982fSImre Deak extern const struct intel_dp_link_caps_test_ops i915_display_dp_link_caps_test_ops; 189*2eb9982fSImre Deak #else 190*2eb9982fSImre Deak extern const struct intel_dp_link_caps_test_ops intel_display_dp_link_caps_test_ops; 191*2eb9982fSImre Deak #endif /* I915 */ 192*2eb9982fSImre Deak 193*2eb9982fSImre Deak #endif /* CONFIG_KUNIT */ 194*2eb9982fSImre Deak 195ebf5ad5cSImre Deak #endif /* __INTEL_DP_LINK_CAPS_H__ */ 196