because we want completely to negotiation process, so we start with
the maximum rate and the electrical characteristic level is 0.
Signed-off-by: Baihan Li <libai...@huawei.com>
Signed-off-by: Yongbang Shi <shiyongb...@huawei.com>
---
ChangeLog:
v1 -> v2:
- splittting the patch and add more detailed the changes in the commit
message, suggested by Dmitry Baryshkov.
---
.../gpu/drm/hisilicon/hibmc/dp/dp_config.h | 1 +
drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c | 6 +++-
drivers/gpu/drm/hisilicon/hibmc/dp/dp_link.c | 33 ++++++++++++++++---
drivers/gpu/drm/hisilicon/hibmc/dp/dp_reg.h | 1 +
.../gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c | 8 ++---
5 files changed, 38 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_config.h
b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_config.h
index 74dd9956144e..c5feef8dc27d 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_config.h
+++ b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_config.h
@@ -15,5 +15,6 @@
#define HIBMC_DP_CLK_EN 0x7
#define HIBMC_DP_SYNC_EN_MASK 0x3
#define HIBMC_DP_LINK_RATE_CAL 27
+#define HIBMC_DP_SYNC_DELAY(lanes) ((lanes) == 0x2 ? 86 : 46)
#endif
diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c
b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c
index 39fd3687efca..ee1ff205ff56 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c
@@ -3,6 +3,7 @@
#include <linux/io.h>
#include <linux/delay.h>
+#include <drm/drm_managed.h>
#include "dp_config.h"
#include "dp_comm.h"
#include "dp_reg.h"
@@ -73,6 +74,9 @@ static void hibmc_dp_set_sst(struct hibmc_dp_dev *dp, struct
drm_display_mode *m
HIBMC_DP_CFG_STREAM_HTOTAL_SIZE, htotal_size);
hibmc_dp_reg_write_field(dp, HIBMC_DP_VIDEO_HORIZONTAL_SIZE,
HIBMC_DP_CFG_STREAM_HBLANK_SIZE, hblank_size);
+ hibmc_dp_reg_write_field(dp, HIBMC_DP_VIDEO_PACKET,
+ HIBMC_DP_CFG_STREAM_SYNC_CALIBRATION,
+ HIBMC_DP_SYNC_DELAY(dp->link.cap.lanes));
}
static void hibmc_dp_link_cfg(struct hibmc_dp_dev *dp, struct drm_display_mode *mode)
@@ -170,7 +174,7 @@ int hibmc_dp_hw_init(struct hibmc_dp *dp)
return -EAGAIN;
dp_dev->link.cap.lanes = 0x2;
- dp_dev->link.cap.link_rate = DP_LINK_BW_2_7;
+ dp_dev->link.cap.link_rate = DP_LINK_BW_8_1;
/* hdcp data */
writel(HIBMC_DP_HDCP, dp_dev->base + HIBMC_DP_HDCP_CFG);
diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_link.c
b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_link.c
index f6355c16cc0a..43a4b656493f 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_link.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_link.c
@@ -6,6 +6,7 @@
#include <drm/drm_print.h>
#include "dp_comm.h"
#include "dp_reg.h"
+#include "dp_serdes.h"
#define HIBMC_EQ_MAX_RETRY 5
@@ -108,7 +109,11 @@ static int hibmc_dp_link_training_cr_pre(struct hibmc_dp_dev *dp)
return ret;
for (i = 0; i < dp->link.cap.lanes; i++)
- train_set[i] = DP_TRAIN_VOLTAGE_SWING_LEVEL_2;
+ train_set[i] = DP_TRAIN_VOLTAGE_SWING_LEVEL_0;
+
+ ret = hibmc_dp_serdes_set_tx_cfg(dp, dp->link.train_set);
+ if (ret)
+ return ret;
ret = drm_dp_dpcd_write(&dp->aux, DP_TRAINING_LANE0_SET, train_set, dp->link.cap.lanes);
if (ret != dp->link.cap.lanes) {
@@ -137,21 +142,28 @@ static bool hibmc_dp_link_get_adjust_train(struct
hibmc_dp_dev *dp,
return false;
}
-static inline int hibmc_dp_link_reduce_rate(struct hibmc_dp_dev *dp)
+static int hibmc_dp_link_reduce_rate(struct hibmc_dp_dev *dp)
{
+ u8 rate = 0;
+
switch (dp->link.cap.link_rate) {
case DP_LINK_BW_2_7:
dp->link.cap.link_rate = DP_LINK_BW_1_62;
- return 0;
+ rate = DP_SERDES_BW_1_62;
+ break;
case DP_LINK_BW_5_4:
dp->link.cap.link_rate = DP_LINK_BW_2_7;
- return 0;
+ rate = DP_SERDES_BW_2_7;
+ break;
case DP_LINK_BW_8_1:
dp->link.cap.link_rate = DP_LINK_BW_5_4;
- return 0;
+ rate = DP_SERDES_BW_5_4;
+ break;
default:
return -EINVAL;
}
+
+ return hibmc_dp_serdes_rate_switch(rate, dp);