提交 1a644cd4 编写于 作者: D Daniel Vetter

drm: extract dp link train delay functions from radeon

This requires a few changes since that dpcd value is above the
range currently cached by radeon. I've check the dp specs, and
above 0xf there's a big gap and nothing that looks like we should
cache it while a given device is plugged in. It's also the same value
that i915.ko uses.

Hence extend the various dpcd arrays in the radeon driver, use
proper symbolic constants where applicable (one place overallocated
the dpcd array to 25 bytes). Then also drop the rd_interval cache -
radeon_dp_link_train_init re-reads the dpcd block, so the values we'll
consume in train_cr and train_ce will always be fresh.

To avoid needless diff-churn, #define the old size of dpcd as the new
one and keep it around.

v2: Alex Deucher noticed one place where I've forgotten to replace 8
with DP_RECEIVER_CAP_SIZE.
Reviewed-by: NAlex Deucher <alexander.deucher@amd.com>
Acked-by: NDave Airlie <airlied@gmail.com>
Signed-off-by: NDaniel Vetter <daniel.vetter@ffwll.ch>
上级 0f037bde
...@@ -282,3 +282,18 @@ u8 drm_dp_get_adjust_request_pre_emphasis(u8 link_status[DP_LINK_STATUS_SIZE], ...@@ -282,3 +282,18 @@ u8 drm_dp_get_adjust_request_pre_emphasis(u8 link_status[DP_LINK_STATUS_SIZE],
} }
EXPORT_SYMBOL(drm_dp_get_adjust_request_pre_emphasis); EXPORT_SYMBOL(drm_dp_get_adjust_request_pre_emphasis);
void drm_dp_link_train_clock_recovery_delay(u8 dpcd[DP_RECEIVER_CAP_SIZE]) {
if (dpcd[DP_TRAINING_AUX_RD_INTERVAL] == 0)
udelay(100);
else
mdelay(dpcd[DP_TRAINING_AUX_RD_INTERVAL] * 4);
}
EXPORT_SYMBOL(drm_dp_link_train_clock_recovery_delay);
void drm_dp_link_train_channel_eq_delay(u8 dpcd[DP_RECEIVER_CAP_SIZE]) {
if (dpcd[DP_TRAINING_AUX_RD_INTERVAL] == 0)
udelay(400);
else
mdelay(dpcd[DP_TRAINING_AUX_RD_INTERVAL] * 4);
}
EXPORT_SYMBOL(drm_dp_link_train_channel_eq_delay);
...@@ -36,7 +36,6 @@ ...@@ -36,7 +36,6 @@
#include <drm/i915_drm.h> #include <drm/i915_drm.h>
#include "i915_drv.h" #include "i915_drv.h"
#define DP_RECEIVER_CAP_SIZE 0xf
#define DP_LINK_CHECK_TIMEOUT (10 * 1000) #define DP_LINK_CHECK_TIMEOUT (10 * 1000)
/** /**
......
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
/* move these to drm_dp_helper.c/h */ /* move these to drm_dp_helper.c/h */
#define DP_LINK_CONFIGURATION_SIZE 9 #define DP_LINK_CONFIGURATION_SIZE 9
#define DP_DPCD_SIZE 8 #define DP_DPCD_SIZE DP_RECEIVER_CAP_SIZE
static char *voltage_names[] = { static char *voltage_names[] = {
"0.4V", "0.6V", "0.8V", "1.2V" "0.4V", "0.6V", "0.8V", "1.2V"
...@@ -478,14 +478,15 @@ static void radeon_dp_probe_oui(struct radeon_connector *radeon_connector) ...@@ -478,14 +478,15 @@ static void radeon_dp_probe_oui(struct radeon_connector *radeon_connector)
bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector) bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector)
{ {
struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv; struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
u8 msg[25]; u8 msg[DP_DPCD_SIZE];
int ret, i; int ret, i;
ret = radeon_dp_aux_native_read(radeon_connector, DP_DPCD_REV, msg, 8, 0); ret = radeon_dp_aux_native_read(radeon_connector, DP_DPCD_REV, msg,
DP_DPCD_SIZE, 0);
if (ret > 0) { if (ret > 0) {
memcpy(dig_connector->dpcd, msg, 8); memcpy(dig_connector->dpcd, msg, DP_DPCD_SIZE);
DRM_DEBUG_KMS("DPCD: "); DRM_DEBUG_KMS("DPCD: ");
for (i = 0; i < 8; i++) for (i = 0; i < DP_DPCD_SIZE; i++)
DRM_DEBUG_KMS("%02x ", msg[i]); DRM_DEBUG_KMS("%02x ", msg[i]);
DRM_DEBUG_KMS("\n"); DRM_DEBUG_KMS("\n");
...@@ -604,9 +605,8 @@ struct radeon_dp_link_train_info { ...@@ -604,9 +605,8 @@ struct radeon_dp_link_train_info {
int enc_id; int enc_id;
int dp_clock; int dp_clock;
int dp_lane_count; int dp_lane_count;
int rd_interval;
bool tp3_supported; bool tp3_supported;
u8 dpcd[8]; u8 dpcd[DP_RECEIVER_CAP_SIZE];
u8 train_set[4]; u8 train_set[4];
u8 link_status[DP_LINK_STATUS_SIZE]; u8 link_status[DP_LINK_STATUS_SIZE];
u8 tries; u8 tries;
...@@ -748,10 +748,7 @@ static int radeon_dp_link_train_cr(struct radeon_dp_link_train_info *dp_info) ...@@ -748,10 +748,7 @@ static int radeon_dp_link_train_cr(struct radeon_dp_link_train_info *dp_info)
dp_info->tries = 0; dp_info->tries = 0;
voltage = 0xff; voltage = 0xff;
while (1) { while (1) {
if (dp_info->rd_interval == 0) drm_dp_link_train_clock_recovery_delay(dp_info->dpcd);
udelay(100);
else
mdelay(dp_info->rd_interval * 4);
if (!radeon_dp_get_link_status(dp_info->radeon_connector, dp_info->link_status)) { if (!radeon_dp_get_link_status(dp_info->radeon_connector, dp_info->link_status)) {
DRM_ERROR("displayport link status failed\n"); DRM_ERROR("displayport link status failed\n");
...@@ -813,10 +810,7 @@ static int radeon_dp_link_train_ce(struct radeon_dp_link_train_info *dp_info) ...@@ -813,10 +810,7 @@ static int radeon_dp_link_train_ce(struct radeon_dp_link_train_info *dp_info)
dp_info->tries = 0; dp_info->tries = 0;
channel_eq = false; channel_eq = false;
while (1) { while (1) {
if (dp_info->rd_interval == 0) drm_dp_link_train_channel_eq_delay(dp_info->dpcd);
udelay(400);
else
mdelay(dp_info->rd_interval * 4);
if (!radeon_dp_get_link_status(dp_info->radeon_connector, dp_info->link_status)) { if (!radeon_dp_get_link_status(dp_info->radeon_connector, dp_info->link_status)) {
DRM_ERROR("displayport link status failed\n"); DRM_ERROR("displayport link status failed\n");
...@@ -901,14 +895,13 @@ void radeon_dp_link_train(struct drm_encoder *encoder, ...@@ -901,14 +895,13 @@ void radeon_dp_link_train(struct drm_encoder *encoder,
else else
dp_info.enc_id |= ATOM_DP_CONFIG_LINK_A; dp_info.enc_id |= ATOM_DP_CONFIG_LINK_A;
dp_info.rd_interval = radeon_read_dpcd_reg(radeon_connector, DP_TRAINING_AUX_RD_INTERVAL);
tmp = radeon_read_dpcd_reg(radeon_connector, DP_MAX_LANE_COUNT); tmp = radeon_read_dpcd_reg(radeon_connector, DP_MAX_LANE_COUNT);
if (ASIC_IS_DCE5(rdev) && (tmp & DP_TPS3_SUPPORTED)) if (ASIC_IS_DCE5(rdev) && (tmp & DP_TPS3_SUPPORTED))
dp_info.tp3_supported = true; dp_info.tp3_supported = true;
else else
dp_info.tp3_supported = false; dp_info.tp3_supported = false;
memcpy(dp_info.dpcd, dig_connector->dpcd, 8); memcpy(dp_info.dpcd, dig_connector->dpcd, DP_RECEIVER_CAP_SIZE);
dp_info.rdev = rdev; dp_info.rdev = rdev;
dp_info.encoder = encoder; dp_info.encoder = encoder;
dp_info.connector = connector; dp_info.connector = connector;
......
...@@ -427,7 +427,7 @@ struct radeon_connector_atom_dig { ...@@ -427,7 +427,7 @@ struct radeon_connector_atom_dig {
uint32_t igp_lane_info; uint32_t igp_lane_info;
/* displayport */ /* displayport */
struct radeon_i2c_chan *dp_i2c_bus; struct radeon_i2c_chan *dp_i2c_bus;
u8 dpcd[8]; u8 dpcd[DP_RECEIVER_CAP_SIZE];
u8 dp_sink_type; u8 dp_sink_type;
int dp_clock; int dp_clock;
int dp_lane_count; int dp_lane_count;
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/delay.h>
/* /*
* Unless otherwise noted, all values are from the DP 1.1a spec. Note that * Unless otherwise noted, all values are from the DP 1.1a spec. Note that
...@@ -333,4 +334,8 @@ u8 drm_dp_get_adjust_request_voltage(u8 link_status[DP_LINK_STATUS_SIZE], ...@@ -333,4 +334,8 @@ u8 drm_dp_get_adjust_request_voltage(u8 link_status[DP_LINK_STATUS_SIZE],
u8 drm_dp_get_adjust_request_pre_emphasis(u8 link_status[DP_LINK_STATUS_SIZE], u8 drm_dp_get_adjust_request_pre_emphasis(u8 link_status[DP_LINK_STATUS_SIZE],
int lane); int lane);
#define DP_RECEIVER_CAP_SIZE 0xf
void drm_dp_link_train_clock_recovery_delay(u8 dpcd[DP_RECEIVER_CAP_SIZE]);
void drm_dp_link_train_channel_eq_delay(u8 dpcd[DP_RECEIVER_CAP_SIZE]);
#endif /* _DRM_DP_HELPER_H_ */ #endif /* _DRM_DP_HELPER_H_ */
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册