xref: /linux/drivers/gpu/drm/i915/display/intel_dp_link_caps.h (revision 4e69c1856bfd9ffb7e9d335a25842fa211628929)
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