1 // SPDX-License-Identifier: MIT
3 * Copyright (C) 2013-2019 NVIDIA Corporation
4 * Copyright (C) 2015 Rob Clark
7 #include <drm/drm_dp_helper.h>
11 static void drm_dp_link_reset(struct drm_dp_link *link)
19 link->capabilities = 0;
26 * drm_dp_link_probe() - probe a DisplayPort link for capabilities
27 * @aux: DisplayPort AUX channel
28 * @link: pointer to structure in which to return link capabilities
30 * The structure filled in by this function can usually be passed directly
31 * into drm_dp_link_power_up() and drm_dp_link_configure() to power up and
32 * configure the link based on the link's capabilities.
34 * Returns 0 on success or a negative error code on failure.
36 int drm_dp_link_probe(struct drm_dp_aux *aux, struct drm_dp_link *link)
41 drm_dp_link_reset(link);
43 err = drm_dp_dpcd_read(aux, DP_DPCD_REV, values, sizeof(values));
47 link->revision = values[0];
48 link->max_rate = drm_dp_bw_code_to_link_rate(values[1]);
49 link->max_lanes = values[2] & DP_MAX_LANE_COUNT_MASK;
51 if (values[2] & DP_ENHANCED_FRAME_CAP)
52 link->capabilities |= DP_LINK_CAP_ENHANCED_FRAMING;
54 link->rate = link->max_rate;
55 link->lanes = link->max_lanes;
61 * drm_dp_link_power_up() - power up a DisplayPort link
62 * @aux: DisplayPort AUX channel
63 * @link: pointer to a structure containing the link configuration
65 * Returns 0 on success or a negative error code on failure.
67 int drm_dp_link_power_up(struct drm_dp_aux *aux, struct drm_dp_link *link)
72 /* DP_SET_POWER register is only available on DPCD v1.1 and later */
73 if (link->revision < 0x11)
76 err = drm_dp_dpcd_readb(aux, DP_SET_POWER, &value);
80 value &= ~DP_SET_POWER_MASK;
81 value |= DP_SET_POWER_D0;
83 err = drm_dp_dpcd_writeb(aux, DP_SET_POWER, value);
88 * According to the DP 1.1 specification, a "Sink Device must exit the
89 * power saving state within 1 ms" (Section 2.5.3.1, Table 5-52, "Sink
90 * Control Field" (register 0x600).
92 usleep_range(1000, 2000);
98 * drm_dp_link_power_down() - power down a DisplayPort link
99 * @aux: DisplayPort AUX channel
100 * @link: pointer to a structure containing the link configuration
102 * Returns 0 on success or a negative error code on failure.
104 int drm_dp_link_power_down(struct drm_dp_aux *aux, struct drm_dp_link *link)
109 /* DP_SET_POWER register is only available on DPCD v1.1 and later */
110 if (link->revision < 0x11)
113 err = drm_dp_dpcd_readb(aux, DP_SET_POWER, &value);
117 value &= ~DP_SET_POWER_MASK;
118 value |= DP_SET_POWER_D3;
120 err = drm_dp_dpcd_writeb(aux, DP_SET_POWER, value);
128 * drm_dp_link_configure() - configure a DisplayPort link
129 * @aux: DisplayPort AUX channel
130 * @link: pointer to a structure containing the link configuration
132 * Returns 0 on success or a negative error code on failure.
134 int drm_dp_link_configure(struct drm_dp_aux *aux, struct drm_dp_link *link)
139 values[0] = drm_dp_link_rate_to_bw_code(link->rate);
140 values[1] = link->lanes;
142 if (link->capabilities & DP_LINK_CAP_ENHANCED_FRAMING)
143 values[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
145 err = drm_dp_dpcd_write(aux, DP_LINK_BW_SET, values, sizeof(values));