From 1543e317f1da31b75942316931e8f491a8920811 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Thu, 04 Jan 2024 10:08:02 +0000
Subject: [PATCH] disable FB
---
kernel/drivers/gpu/drm/rockchip/cdn-dp-reg.c | 100 ++++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 89 insertions(+), 11 deletions(-)
diff --git a/kernel/drivers/gpu/drm/rockchip/cdn-dp-reg.c b/kernel/drivers/gpu/drm/rockchip/cdn-dp-reg.c
index 33fb4d0..2a54486 100644
--- a/kernel/drivers/gpu/drm/rockchip/cdn-dp-reg.c
+++ b/kernel/drivers/gpu/drm/rockchip/cdn-dp-reg.c
@@ -181,7 +181,7 @@
return 0;
}
-static int cdn_dp_reg_write(struct cdn_dp_device *dp, u16 addr, u32 val)
+int cdn_dp_reg_write(struct cdn_dp_device *dp, u16 addr, u32 val)
{
u8 msg[6];
@@ -213,7 +213,12 @@
sizeof(field), field);
}
-int cdn_dp_dpcd_read(struct cdn_dp_device *dp, u32 addr, u8 *data, u16 len)
+/*
+ * Returns the number of bytes transferred on success, or a negative
+ * error code on failure. -ETIMEDOUT is returned if mailbox message was
+ * not send successfully;
+ */
+ssize_t cdn_dp_dpcd_read(struct cdn_dp_device *dp, u32 addr, u8 *data, u16 len)
{
u8 msg[5], reg[5];
int ret;
@@ -239,24 +244,41 @@
goto err_dpcd_read;
ret = cdn_dp_mailbox_read_receive(dp, data, len);
+ if (!ret)
+ return len;
err_dpcd_read:
+ DRM_DEV_ERROR(dp->dev, "dpcd read failed: %d\n", ret);
return ret;
}
-int cdn_dp_dpcd_write(struct cdn_dp_device *dp, u32 addr, u8 value)
+#define CDN_AUX_HEADER_SIZE 5
+#define CDN_AUX_MSG_SIZE 20
+/*
+ * Returns the number of bytes transferred on success, or a negative error
+ * code on failure. -ETIMEDOUT is returned if mailbox message was not send
+ * success; -EINVAL is returned if get the wrong data size after message
+ * is sent
+ */
+ssize_t cdn_dp_dpcd_write(struct cdn_dp_device *dp, u32 addr, u8 *data, u16 len)
{
- u8 msg[6], reg[5];
+ u8 msg[CDN_AUX_MSG_SIZE + CDN_AUX_HEADER_SIZE];
+ u8 reg[CDN_AUX_HEADER_SIZE];
int ret;
- msg[0] = 0;
- msg[1] = 1;
+ if (WARN_ON(len > CDN_AUX_MSG_SIZE) || WARN_ON(len <= 0))
+ return -EINVAL;
+
+ msg[0] = (len >> 8) & 0xff;
+ msg[1] = len & 0xff;
msg[2] = (addr >> 16) & 0xff;
msg[3] = (addr >> 8) & 0xff;
msg[4] = addr & 0xff;
- msg[5] = value;
+
+ memcpy(msg + CDN_AUX_HEADER_SIZE, data, len);
+
ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_WRITE_DPCD,
- sizeof(msg), msg);
+ CDN_AUX_HEADER_SIZE + len, msg);
if (ret)
goto err_dpcd_write;
@@ -269,12 +291,43 @@
if (ret)
goto err_dpcd_write;
- if (addr != (reg[2] << 16 | reg[3] << 8 | reg[4]))
+ if ((len != (reg[0] << 8 | reg[1])) ||
+ (addr != (reg[2] << 16 | reg[3] << 8 | reg[4]))) {
ret = -EINVAL;
+ } else {
+ return len;
+ }
err_dpcd_write:
if (ret)
DRM_DEV_ERROR(dp->dev, "dpcd write failed: %d\n", ret);
+ return ret;
+}
+
+int cdn_dp_get_aux_status(struct cdn_dp_device *dp)
+{
+ u8 status;
+ int ret;
+
+ ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX,
+ DPTX_GET_LAST_AUX_STAUS, 0, NULL);
+ if (ret)
+ goto err_get_hpd;
+
+ ret = cdn_dp_mailbox_validate_receive(dp, MB_MODULE_ID_DP_TX,
+ DPTX_GET_LAST_AUX_STAUS,
+ sizeof(status));
+ if (ret)
+ goto err_get_hpd;
+
+ ret = cdn_dp_mailbox_read_receive(dp, &status, sizeof(status));
+ if (ret)
+ goto err_get_hpd;
+
+ return status;
+
+err_get_hpd:
+ DRM_DEV_ERROR(dp->dev, "get aux status failed: %d\n", ret);
return ret;
}
@@ -535,7 +588,7 @@
if (ret)
goto err_get_training_status;
- dp->max_rate = drm_dp_bw_code_to_link_rate(status[0]);
+ dp->max_rate = status[0];
dp->max_lanes = status[1];
err_get_training_status:
@@ -548,6 +601,31 @@
{
int ret;
+ /*
+ * DP firmware uses fixed phy config values to do training, but some
+ * boards need to adjust these values to fit for their unique hardware
+ * design. So if the phy is using custom config values, do software
+ * link training instead of relying on firmware, if software training
+ * fail, keep firmware training as a fallback if sw training fails.
+ */
+ ret = cdn_dp_software_train_link(dp);
+ if (ret) {
+ DRM_DEV_ERROR(dp->dev,
+ "Failed to do software training %d\n", ret);
+ goto do_fw_training;
+ }
+ ret = cdn_dp_reg_write(dp, SOURCE_HDTX_CAR, 0xf);
+ if (ret) {
+ DRM_DEV_ERROR(dp->dev,
+ "Failed to write SOURCE_HDTX_CAR register %d\n", ret);
+ goto do_fw_training;
+ }
+ dp->use_fw_training = false;
+ return 0;
+
+do_fw_training:
+ dp->use_fw_training = true;
+ DRM_DEV_DEBUG_KMS(dp->dev, "use fw training\n");
ret = cdn_dp_training_start(dp);
if (ret) {
DRM_DEV_ERROR(dp->dev, "Failed to start training %d\n", ret);
@@ -639,7 +717,7 @@
bit_per_pix = (video->color_fmt == YCBCR_4_2_2) ?
(video->color_depth * 2) : (video->color_depth * 3);
- link_rate = dp->max_rate / 1000;
+ link_rate = drm_dp_bw_code_to_link_rate(dp->max_rate) / 1000;
ret = cdn_dp_reg_write(dp, BND_HSYNC2VSYNC, VIF_BYPASS_INTERLACE);
if (ret)
--
Gitblit v1.6.2