Lines Matching full:dp
11 #include "cdn-dp-core.h"
12 #include "cdn-dp-reg.h"
14 static void cdn_dp_set_signal_levels(struct cdn_dp_device *dp) in cdn_dp_set_signal_levels() argument
16 struct cdn_dp_port *port = dp->port[dp->active_port]; in cdn_dp_set_signal_levels()
17 int rate = drm_dp_bw_code_to_link_rate(dp->link.rate); in cdn_dp_set_signal_levels()
18 u8 swing = (dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) >> in cdn_dp_set_signal_levels()
20 u8 pre_emphasis = (dp->train_set[0] & DP_TRAIN_PRE_EMPHASIS_MASK) in cdn_dp_set_signal_levels()
23 tcphy_dp_set_phy_config(port->phy, rate, dp->link.num_lanes, in cdn_dp_set_signal_levels()
27 static int cdn_dp_set_pattern(struct cdn_dp_device *dp, uint8_t dp_train_pat) in cdn_dp_set_pattern() argument
33 global_config = NUM_LANES(dp->link.num_lanes - 1) | SST_MODE | in cdn_dp_set_pattern()
52 ret = cdn_dp_reg_write(dp, DP_FRAMER_GLOBAL_CONFIG, global_config); in cdn_dp_set_pattern()
59 ret = cdn_dp_reg_write(dp, DP_TX_PHY_CONFIG_REG, phy_config); in cdn_dp_set_pattern()
66 ret = cdn_dp_reg_write(dp, DPTX_LANE_EN, BIT(dp->link.num_lanes) - 1); in cdn_dp_set_pattern()
72 if (drm_dp_enhanced_frame_cap(dp->dpcd) || in cdn_dp_set_pattern()
78 dp->dpcd[DP_EDP_CONFIGURATION_CAP] & DP_FRAMING_CHANGE_CAP) in cdn_dp_set_pattern()
79 ret = cdn_dp_reg_write(dp, DPTX_ENHNCD, 1); in cdn_dp_set_pattern()
81 ret = cdn_dp_reg_write(dp, DPTX_ENHNCD, 0); in cdn_dp_set_pattern()
102 static void cdn_dp_get_adjust_train(struct cdn_dp_device *dp, in cdn_dp_get_adjust_train() argument
109 for (i = 0; i < dp->link.num_lanes; i++) { in cdn_dp_get_adjust_train()
122 for (i = 0; i < dp->link.num_lanes; i++) in cdn_dp_get_adjust_train()
123 dp->train_set[i] = v | p; in cdn_dp_get_adjust_train()
130 static u32 cdn_dp_select_chaneq_pattern(struct cdn_dp_device *dp) in cdn_dp_select_chaneq_pattern() argument
135 * cdn dp support HBR2 also support TPS3. TPS3 support is also mandatory in cdn_dp_select_chaneq_pattern()
139 if (drm_dp_tps3_supported(dp->dpcd)) in cdn_dp_select_chaneq_pattern()
148 static bool cdn_dp_link_max_vswing_reached(struct cdn_dp_device *dp) in cdn_dp_link_max_vswing_reached() argument
152 for (lane = 0; lane < dp->link.num_lanes; lane++) in cdn_dp_link_max_vswing_reached()
153 if ((dp->train_set[lane] & DP_TRAIN_MAX_SWING_REACHED) == 0) in cdn_dp_link_max_vswing_reached()
159 static int cdn_dp_update_link_train(struct cdn_dp_device *dp) in cdn_dp_update_link_train() argument
163 cdn_dp_set_signal_levels(dp); in cdn_dp_update_link_train()
165 ret = drm_dp_dpcd_write(&dp->aux, DP_TRAINING_LANE0_SET, in cdn_dp_update_link_train()
166 dp->train_set, dp->link.num_lanes); in cdn_dp_update_link_train()
167 if (ret != dp->link.num_lanes) in cdn_dp_update_link_train()
173 static int cdn_dp_set_link_train(struct cdn_dp_device *dp, in cdn_dp_set_link_train() argument
176 uint8_t buf[sizeof(dp->train_set) + 1]; in cdn_dp_set_link_train()
186 memcpy(buf + 1, dp->train_set, dp->link.num_lanes); in cdn_dp_set_link_train()
187 len = dp->link.num_lanes + 1; in cdn_dp_set_link_train()
190 ret = drm_dp_dpcd_write(&dp->aux, DP_TRAINING_PATTERN_SET, in cdn_dp_set_link_train()
198 static int cdn_dp_reset_link_train(struct cdn_dp_device *dp, in cdn_dp_reset_link_train() argument
203 memset(dp->train_set, 0, sizeof(dp->train_set)); in cdn_dp_reset_link_train()
205 cdn_dp_set_signal_levels(dp); in cdn_dp_reset_link_train()
207 ret = cdn_dp_set_pattern(dp, dp_train_pat); in cdn_dp_reset_link_train()
211 return cdn_dp_set_link_train(dp, dp_train_pat); in cdn_dp_reset_link_train()
215 static int cdn_dp_link_training_clock_recovery(struct cdn_dp_device *dp) in cdn_dp_link_training_clock_recovery() argument
223 ret = cdn_dp_reset_link_train(dp, DP_TRAINING_PATTERN_1 | in cdn_dp_link_training_clock_recovery()
233 drm_dp_link_train_clock_recovery_delay(dp->dpcd); in cdn_dp_link_training_clock_recovery()
234 if (drm_dp_dpcd_read_link_status(&dp->aux, link_status) != in cdn_dp_link_training_clock_recovery()
240 if (drm_dp_clock_recovery_ok(link_status, dp->link.num_lanes)) { in cdn_dp_link_training_clock_recovery()
255 voltage = dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK; in cdn_dp_link_training_clock_recovery()
258 cdn_dp_get_adjust_train(dp, link_status); in cdn_dp_link_training_clock_recovery()
259 if (cdn_dp_update_link_train(dp)) { in cdn_dp_link_training_clock_recovery()
264 if ((dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == in cdn_dp_link_training_clock_recovery()
270 if (cdn_dp_link_max_vswing_reached(dp)) in cdn_dp_link_training_clock_recovery()
275 static int cdn_dp_link_training_channel_equalization(struct cdn_dp_device *dp) in cdn_dp_link_training_channel_equalization() argument
281 training_pattern = cdn_dp_select_chaneq_pattern(dp); in cdn_dp_link_training_channel_equalization()
284 ret = cdn_dp_set_pattern(dp, training_pattern); in cdn_dp_link_training_channel_equalization()
288 ret = cdn_dp_set_link_train(dp, training_pattern); in cdn_dp_link_training_channel_equalization()
295 drm_dp_link_train_channel_eq_delay(dp->dpcd); in cdn_dp_link_training_channel_equalization()
296 if (drm_dp_dpcd_read_link_status(&dp->aux, link_status) != in cdn_dp_link_training_channel_equalization()
304 dp->link.num_lanes)) { in cdn_dp_link_training_channel_equalization()
309 if (drm_dp_channel_eq_ok(link_status, dp->link.num_lanes)) { in cdn_dp_link_training_channel_equalization()
315 cdn_dp_get_adjust_train(dp, link_status); in cdn_dp_link_training_channel_equalization()
316 if (cdn_dp_update_link_train(dp)) { in cdn_dp_link_training_channel_equalization()
329 static int cdn_dp_stop_link_train(struct cdn_dp_device *dp) in cdn_dp_stop_link_train() argument
331 int ret = cdn_dp_set_pattern(dp, DP_TRAINING_PATTERN_DISABLE); in cdn_dp_stop_link_train()
336 return cdn_dp_set_link_train(dp, DP_TRAINING_PATTERN_DISABLE); in cdn_dp_stop_link_train()
339 static int cdn_dp_get_lower_link_rate(struct cdn_dp_device *dp) in cdn_dp_get_lower_link_rate() argument
341 switch (dp->link.rate) { in cdn_dp_get_lower_link_rate()
345 dp->link.rate = DP_LINK_BW_1_62; in cdn_dp_get_lower_link_rate()
348 dp->link.rate = DP_LINK_BW_2_7; in cdn_dp_get_lower_link_rate()
351 dp->link.rate = DP_LINK_BW_5_4; in cdn_dp_get_lower_link_rate()
358 int cdn_dp_software_train_link(struct cdn_dp_device *dp) in cdn_dp_software_train_link() argument
360 struct cdn_dp_port *port = dp->port[dp->active_port]; in cdn_dp_software_train_link()
366 ret = drm_dp_dpcd_read(&dp->aux, DP_DPCD_REV, dp->dpcd, in cdn_dp_software_train_link()
367 sizeof(dp->dpcd)); in cdn_dp_software_train_link()
369 DRM_DEV_ERROR(dp->dev, "Failed to get caps %d\n", ret); in cdn_dp_software_train_link()
373 source_max = dp->lanes; in cdn_dp_software_train_link()
374 sink_max = drm_dp_max_lane_count(dp->dpcd); in cdn_dp_software_train_link()
375 dp->link.num_lanes = min(source_max, sink_max); in cdn_dp_software_train_link()
378 sink_max = drm_dp_max_link_rate(dp->dpcd); in cdn_dp_software_train_link()
380 dp->link.rate = drm_dp_link_rate_to_bw_code(rate); in cdn_dp_software_train_link()
382 ssc_on = !!(dp->dpcd[DP_MAX_DOWNSPREAD] & DP_MAX_DOWNSPREAD_0_5); in cdn_dp_software_train_link()
385 if (dp->dpcd[DP_MAIN_LINK_CHANNEL_CODING] & 0x01) in cdn_dp_software_train_link()
387 drm_dp_dpcd_write(&dp->aux, DP_DOWNSPREAD_CTRL, link_config, 2); in cdn_dp_software_train_link()
391 drm_dp_bw_code_to_link_rate(dp->link.rate), in cdn_dp_software_train_link()
398 ret = tcphy_dp_set_lane_count(port->phy, dp->link.num_lanes); in cdn_dp_software_train_link()
405 link_config[0] = dp->link.rate; in cdn_dp_software_train_link()
406 link_config[1] = dp->link.num_lanes; in cdn_dp_software_train_link()
407 if (drm_dp_enhanced_frame_cap(dp->dpcd)) in cdn_dp_software_train_link()
409 drm_dp_dpcd_write(&dp->aux, DP_LINK_BW_SET, link_config, 2); in cdn_dp_software_train_link()
411 ret = cdn_dp_link_training_clock_recovery(dp); in cdn_dp_software_train_link()
413 if (!cdn_dp_get_lower_link_rate(dp)) in cdn_dp_software_train_link()
420 ret = cdn_dp_link_training_channel_equalization(dp); in cdn_dp_software_train_link()
422 if (!cdn_dp_get_lower_link_rate(dp)) in cdn_dp_software_train_link()
432 stop_err = cdn_dp_stop_link_train(dp); in cdn_dp_software_train_link()