* [PATCH v3 drm-dp 00/11] Fix hibmc driver bugs
@ 2025-07-18 6:51 Yongbang Shi
2025-07-18 6:51 ` [PATCH v3 drm-dp 01/11] drm/hisilicon/hibmc: fix the i2c device resource leak when vdac init failed Yongbang Shi
` (11 more replies)
0 siblings, 12 replies; 24+ messages in thread
From: Yongbang Shi @ 2025-07-18 6:51 UTC (permalink / raw)
To: xinliang.liu, tiantao6, maarten.lankhorst, mripard, tzimmermann,
airlied, daniel, kong.kongxinwei, dmitry.baryshkov
Cc: liangjian010, chenjianmin, fengsheng5, shiyongbang, libaihan,
shenjian15, shaojijie, jani.nikula, dri-devel, linux-kernel
From: Baihan Li <libaihan@huawei.com>
There are some bugfix for hibmc-drm driver.
---
ChangeLog:
v2 -> v3:
- fix hibmc_connector_get_modes() and hibmc_vdac_detect() to realize BMC KVM, suggested by Dmitry Baryshkov.
- fix the issue commit ID, suggested by Dmitry Baryshkov.
- split into 2 commits, suggested by Dmitry Baryshkov.
- add more comments in commit log, suggested by Dmitry Baryshkov.
---
Baihan Li (11):
drm/hisilicon/hibmc: fix the i2c device resource leak when vdac init
failed
drm/hisilicon/hibmc: fix dp probabilistical detect errors after HPD
irq
drm/hisilicon/hibmc: fix irq_request()'s irq name variable is local
drm/hisilicon/hibmc: fix the hibmc loaded failed bug
drm/hisilicon/hibmc: fix rare monitors cannot display problem
drm/hisilicon/hibmc: add dp mode valid check
drm/hisilicon/hibmc: fix dp and vga cannot show together
drm/hisilicon/hibmc: fix no showing when no connectors connected
drm/hisilicon/hibmc: fix no showing problem with loading hibmc
manually
drm/hisilicon/hibmc: adapting modification for the former commit
drm/hisilicon/hibmc: modification for the former commit
drivers/gpu/drm/hisilicon/hibmc/dp/dp_comm.h | 4 +-
drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c | 51 ++++++++++----
drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.h | 8 +++
drivers/gpu/drm/hisilicon/hibmc/dp/dp_link.c | 33 +++++++---
.../gpu/drm/hisilicon/hibmc/dp/dp_serdes.c | 12 ----
.../gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c | 64 ++++++++++++++++--
.../gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c | 22 ++++---
.../gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h | 5 ++
.../gpu/drm/hisilicon/hibmc/hibmc_drm_i2c.c | 5 ++
.../gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c | 66 +++++++++++++------
10 files changed, 201 insertions(+), 69 deletions(-)
--
2.33.0
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v3 drm-dp 01/11] drm/hisilicon/hibmc: fix the i2c device resource leak when vdac init failed
2025-07-18 6:51 [PATCH v3 drm-dp 00/11] Fix hibmc driver bugs Yongbang Shi
@ 2025-07-18 6:51 ` Yongbang Shi
2025-07-18 6:51 ` [PATCH v3 drm-dp 02/11] drm/hisilicon/hibmc: fix dp probabilistical detect errors after HPD irq Yongbang Shi
` (10 subsequent siblings)
11 siblings, 0 replies; 24+ messages in thread
From: Yongbang Shi @ 2025-07-18 6:51 UTC (permalink / raw)
To: xinliang.liu, tiantao6, maarten.lankhorst, mripard, tzimmermann,
airlied, daniel, kong.kongxinwei, dmitry.baryshkov
Cc: liangjian010, chenjianmin, fengsheng5, shiyongbang, libaihan,
shenjian15, shaojijie, jani.nikula, dri-devel, linux-kernel
From: Baihan Li <libaihan@huawei.com>
Currently the driver missed to clean the i2c adapter when vdac init failed.
It may cause resource leak.
Fixes: a0d078d06e516 ("drm/hisilicon: Features to support reading resolutions from EDID")
Signed-off-by: Baihan Li <libaihan@huawei.com>
Signed-off-by: Yongbang Shi <shiyongbang@huawei.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h | 1 +
drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_i2c.c | 5 +++++
drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c | 11 ++++++++---
3 files changed, 14 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
index 274feabe7df0..ca8502e2760c 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
@@ -69,6 +69,7 @@ int hibmc_de_init(struct hibmc_drm_private *priv);
int hibmc_vdac_init(struct hibmc_drm_private *priv);
int hibmc_ddc_create(struct drm_device *drm_dev, struct hibmc_vdac *connector);
+void hibmc_ddc_del(struct hibmc_vdac *vdac);
int hibmc_dp_init(struct hibmc_drm_private *priv);
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_i2c.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_i2c.c
index 99b3b77b5445..44860011855e 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_i2c.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_i2c.c
@@ -95,3 +95,8 @@ int hibmc_ddc_create(struct drm_device *drm_dev, struct hibmc_vdac *vdac)
return i2c_bit_add_bus(&vdac->adapter);
}
+
+void hibmc_ddc_del(struct hibmc_vdac *vdac)
+{
+ i2c_del_adapter(&vdac->adapter);
+}
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
index e8a527ede854..841e81f47b68 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
@@ -53,7 +53,7 @@ static void hibmc_connector_destroy(struct drm_connector *connector)
{
struct hibmc_vdac *vdac = to_hibmc_vdac(connector);
- i2c_del_adapter(&vdac->adapter);
+ hibmc_ddc_del(vdac);
drm_connector_cleanup(connector);
}
@@ -110,7 +110,7 @@ int hibmc_vdac_init(struct hibmc_drm_private *priv)
ret = drmm_encoder_init(dev, encoder, NULL, DRM_MODE_ENCODER_DAC, NULL);
if (ret) {
drm_err(dev, "failed to init encoder: %d\n", ret);
- return ret;
+ goto err;
}
drm_encoder_helper_add(encoder, &hibmc_encoder_helper_funcs);
@@ -121,7 +121,7 @@ int hibmc_vdac_init(struct hibmc_drm_private *priv)
&vdac->adapter);
if (ret) {
drm_err(dev, "failed to init connector: %d\n", ret);
- return ret;
+ goto err;
}
drm_connector_helper_add(connector, &hibmc_connector_helper_funcs);
@@ -131,4 +131,9 @@ int hibmc_vdac_init(struct hibmc_drm_private *priv)
connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT;
return 0;
+
+err:
+ hibmc_ddc_del(vdac);
+
+ return ret;
}
--
2.33.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v3 drm-dp 02/11] drm/hisilicon/hibmc: fix dp probabilistical detect errors after HPD irq
2025-07-18 6:51 [PATCH v3 drm-dp 00/11] Fix hibmc driver bugs Yongbang Shi
2025-07-18 6:51 ` [PATCH v3 drm-dp 01/11] drm/hisilicon/hibmc: fix the i2c device resource leak when vdac init failed Yongbang Shi
@ 2025-07-18 6:51 ` Yongbang Shi
2025-07-26 15:03 ` Dmitry Baryshkov
2025-07-18 6:51 ` [PATCH v3 drm-dp 03/11] drm/hisilicon/hibmc: fix irq_request()'s irq name variable is local Yongbang Shi
` (9 subsequent siblings)
11 siblings, 1 reply; 24+ messages in thread
From: Yongbang Shi @ 2025-07-18 6:51 UTC (permalink / raw)
To: xinliang.liu, tiantao6, maarten.lankhorst, mripard, tzimmermann,
airlied, daniel, kong.kongxinwei, dmitry.baryshkov
Cc: liangjian010, chenjianmin, fengsheng5, shiyongbang, libaihan,
shenjian15, shaojijie, jani.nikula, dri-devel, linux-kernel
From: Baihan Li <libaihan@huawei.com>
The debouncing when HPD pulled out still remains sometimes, 200ms still can
not ensure helper_detect() is correct. Add hibmc_dp_detect_link() in
detect_ctx(), which is to try dp link training.
Fixes: 3c7623fb5bb6 ("drm/hisilicon/hibmc: Enable this hot plug detect of irq feature")
Signed-off-by: Baihan Li <libaihan@huawei.com>
Signed-off-by: Yongbang Shi <shiyongbang@huawei.com>
---
drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c | 27 +++++++++++++++----
drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.h | 2 ++
.../gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c | 10 ++++---
3 files changed, 30 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c
index 8f0daec7d174..2d2fb6e759c3 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"
@@ -162,6 +163,8 @@ int hibmc_dp_hw_init(struct hibmc_dp *dp)
mutex_init(&dp_dev->lock);
+ drmm_mutex_init(drm_dev, &dp->link_train_mutex);
+
dp->dp_dev = dp_dev;
dp_dev->dev = drm_dev;
@@ -238,19 +241,33 @@ void hibmc_dp_display_en(struct hibmc_dp *dp, bool enable)
msleep(50);
}
-int hibmc_dp_mode_set(struct hibmc_dp *dp, struct drm_display_mode *mode)
+int hibmc_dp_detect_link(struct hibmc_dp *dp)
{
struct hibmc_dp_dev *dp_dev = dp->dp_dev;
- int ret;
+ int ret = 0;
+
+ mutex_lock(&dp->link_train_mutex);
if (!dp_dev->link.status.channel_equalized) {
ret = hibmc_dp_link_training(dp_dev);
- if (ret) {
+ if (ret)
drm_err(dp->drm_dev, "dp link training failed, ret: %d\n", ret);
- return ret;
- }
}
+ mutex_unlock(&dp->link_train_mutex);
+
+ return ret;
+}
+
+int hibmc_dp_mode_set(struct hibmc_dp *dp, struct drm_display_mode *mode)
+{
+ struct hibmc_dp_dev *dp_dev = dp->dp_dev;
+ int ret;
+
+ ret = hibmc_dp_detect_link(dp);
+ if (ret)
+ return ret;
+
hibmc_dp_display_en(dp, false);
hibmc_dp_link_cfg(dp_dev, mode);
diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.h b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.h
index 665f5b166dfb..9b45e88e47e4 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.h
+++ b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.h
@@ -50,9 +50,11 @@ struct hibmc_dp {
struct drm_dp_aux aux;
struct hibmc_dp_cbar_cfg cfg;
u32 irq_status;
+ struct mutex link_train_mutex; /* link training mutex */
};
int hibmc_dp_hw_init(struct hibmc_dp *dp);
+int hibmc_dp_detect_link(struct hibmc_dp *dp);
int hibmc_dp_mode_set(struct hibmc_dp *dp, struct drm_display_mode *mode);
void hibmc_dp_display_en(struct hibmc_dp *dp, bool enable);
void hibmc_dp_set_cbar(struct hibmc_dp *dp, const struct hibmc_dp_cbar_cfg *cfg);
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c
index d06832e62e96..354e18bb2998 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c
@@ -34,9 +34,12 @@ static int hibmc_dp_connector_get_modes(struct drm_connector *connector)
static int hibmc_dp_detect(struct drm_connector *connector,
struct drm_modeset_acquire_ctx *ctx, bool force)
{
- mdelay(200);
+ struct hibmc_drm_private *priv = to_hibmc_drm_private(connector->dev);
- return drm_connector_helper_detect_from_ddc(connector, ctx, force);
+ if (!hibmc_dp_detect_link(&priv->dp))
+ return connector_status_connected;
+
+ return connector_status_disconnected;
}
static const struct drm_connector_helper_funcs hibmc_dp_conn_helper_funcs = {
@@ -128,8 +131,7 @@ irqreturn_t hibmc_dp_hpd_isr(int irq, void *arg)
hibmc_dp_reset_link(&priv->dp);
}
- if (dev->registered)
- drm_connector_helper_hpd_irq_event(&priv->dp.connector);
+ drm_connector_helper_hpd_irq_event(&priv->dp.connector);
drm_dev_exit(idx);
--
2.33.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v3 drm-dp 03/11] drm/hisilicon/hibmc: fix irq_request()'s irq name variable is local
2025-07-18 6:51 [PATCH v3 drm-dp 00/11] Fix hibmc driver bugs Yongbang Shi
2025-07-18 6:51 ` [PATCH v3 drm-dp 01/11] drm/hisilicon/hibmc: fix the i2c device resource leak when vdac init failed Yongbang Shi
2025-07-18 6:51 ` [PATCH v3 drm-dp 02/11] drm/hisilicon/hibmc: fix dp probabilistical detect errors after HPD irq Yongbang Shi
@ 2025-07-18 6:51 ` Yongbang Shi
2025-07-18 6:51 ` [PATCH v3 drm-dp 04/11] drm/hisilicon/hibmc: fix the hibmc loaded failed bug Yongbang Shi
` (8 subsequent siblings)
11 siblings, 0 replies; 24+ messages in thread
From: Yongbang Shi @ 2025-07-18 6:51 UTC (permalink / raw)
To: xinliang.liu, tiantao6, maarten.lankhorst, mripard, tzimmermann,
airlied, daniel, kong.kongxinwei, dmitry.baryshkov
Cc: liangjian010, chenjianmin, fengsheng5, shiyongbang, libaihan,
shenjian15, shaojijie, jani.nikula, dri-devel, linux-kernel
From: Baihan Li <libaihan@huawei.com>
The local variable is passed in request_irq (), and there will be use
after free problem, which will make request_irq failed. Using the global
irq name instead of it to fix.
Fixes: b11bc1ae4658 ("drm/hisilicon/hibmc: Add MSI irq getting and requesting for HPD")
Signed-off-by: Baihan Li <libaihan@huawei.com>
Signed-off-by: Yongbang Shi <shiyongbang@huawei.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
index 768b97f9e74a..4cdcc34070ee 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
@@ -32,7 +32,7 @@
DEFINE_DRM_GEM_FOPS(hibmc_fops);
-static const char *g_irqs_names_map[HIBMC_MAX_VECTORS] = { "vblank", "hpd" };
+static const char *g_irqs_names_map[HIBMC_MAX_VECTORS] = { "hibmc-vblank", "hibmc-hpd" };
static irqreturn_t hibmc_interrupt(int irq, void *arg)
{
@@ -277,7 +277,6 @@ static void hibmc_unload(struct drm_device *dev)
static int hibmc_msi_init(struct drm_device *dev)
{
struct pci_dev *pdev = to_pci_dev(dev->dev);
- char name[32] = {0};
int valid_irq_num;
int irq;
int ret;
@@ -292,9 +291,6 @@ static int hibmc_msi_init(struct drm_device *dev)
valid_irq_num = ret;
for (int i = 0; i < valid_irq_num; i++) {
- snprintf(name, ARRAY_SIZE(name) - 1, "%s-%s-%s",
- dev->driver->name, pci_name(pdev), g_irqs_names_map[i]);
-
irq = pci_irq_vector(pdev, i);
if (i)
@@ -302,10 +298,10 @@ static int hibmc_msi_init(struct drm_device *dev)
ret = devm_request_threaded_irq(&pdev->dev, irq,
hibmc_dp_interrupt,
hibmc_dp_hpd_isr,
- IRQF_SHARED, name, dev);
+ IRQF_SHARED, g_irqs_names_map[i], dev);
else
ret = devm_request_irq(&pdev->dev, irq, hibmc_interrupt,
- IRQF_SHARED, name, dev);
+ IRQF_SHARED, g_irqs_names_map[i], dev);
if (ret) {
drm_err(dev, "install irq failed: %d\n", ret);
return ret;
--
2.33.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v3 drm-dp 04/11] drm/hisilicon/hibmc: fix the hibmc loaded failed bug
2025-07-18 6:51 [PATCH v3 drm-dp 00/11] Fix hibmc driver bugs Yongbang Shi
` (2 preceding siblings ...)
2025-07-18 6:51 ` [PATCH v3 drm-dp 03/11] drm/hisilicon/hibmc: fix irq_request()'s irq name variable is local Yongbang Shi
@ 2025-07-18 6:51 ` Yongbang Shi
2025-07-18 6:51 ` [PATCH v3 drm-dp 05/11] drm/hisilicon/hibmc: fix rare monitors cannot display problem Yongbang Shi
` (7 subsequent siblings)
11 siblings, 0 replies; 24+ messages in thread
From: Yongbang Shi @ 2025-07-18 6:51 UTC (permalink / raw)
To: xinliang.liu, tiantao6, maarten.lankhorst, mripard, tzimmermann,
airlied, daniel, kong.kongxinwei, dmitry.baryshkov
Cc: liangjian010, chenjianmin, fengsheng5, shiyongbang, libaihan,
shenjian15, shaojijie, jani.nikula, dri-devel, linux-kernel
From: Baihan Li <libaihan@huawei.com>
When hibmc loaded failed, the driver use hibmc_unload to free the
resource, but the mutexes in mode.config are not init, which will
access an NULL pointer. Just change goto statement to return, because
hibnc_hw_init() doesn't need to free anything.
Fixes: b3df5e65cc03 ("drm/hibmc: Drop drm_vblank_cleanup")
Signed-off-by: Baihan Li <libaihan@huawei.com>
Signed-off-by: Yongbang Shi <shiyongbang@huawei.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
index 4cdcc34070ee..ac552c339671 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
@@ -319,13 +319,13 @@ static int hibmc_load(struct drm_device *dev)
ret = hibmc_hw_init(priv);
if (ret)
- goto err;
+ return ret;
ret = drmm_vram_helper_init(dev, pci_resource_start(pdev, 0),
pci_resource_len(pdev, 0));
if (ret) {
drm_err(dev, "Error initializing VRAM MM; %d\n", ret);
- goto err;
+ return ret;
}
ret = hibmc_kms_init(priv);
--
2.33.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v3 drm-dp 05/11] drm/hisilicon/hibmc: fix rare monitors cannot display problem
2025-07-18 6:51 [PATCH v3 drm-dp 00/11] Fix hibmc driver bugs Yongbang Shi
` (3 preceding siblings ...)
2025-07-18 6:51 ` [PATCH v3 drm-dp 04/11] drm/hisilicon/hibmc: fix the hibmc loaded failed bug Yongbang Shi
@ 2025-07-18 6:51 ` Yongbang Shi
2025-07-26 15:09 ` Dmitry Baryshkov
2025-07-18 6:51 ` [PATCH v3 drm-dp 06/11] drm/hisilicon/hibmc: add dp mode valid check Yongbang Shi
` (6 subsequent siblings)
11 siblings, 1 reply; 24+ messages in thread
From: Yongbang Shi @ 2025-07-18 6:51 UTC (permalink / raw)
To: xinliang.liu, tiantao6, maarten.lankhorst, mripard, tzimmermann,
airlied, daniel, kong.kongxinwei, dmitry.baryshkov
Cc: liangjian010, chenjianmin, fengsheng5, shiyongbang, libaihan,
shenjian15, shaojijie, jani.nikula, dri-devel, linux-kernel
From: Baihan Li <libaihan@huawei.com>
In some case, the dp link training success at 8.1Gbps, but the sink's
maximum supported rate is less than 8.1G. So change the default 8.1Gbps
link rate to the rate that reads from devices' capabilities.
Fixes: 54063d86e036 ("drm/hisilicon/hibmc: add dp link moduel in hibmc drivers")
Signed-off-by: Baihan Li <libaihan@huawei.com>
Signed-off-by: Yongbang Shi <shiyongbang@huawei.com>
---
drivers/gpu/drm/hisilicon/hibmc/dp/dp_comm.h | 4 ++-
drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c | 6 +---
drivers/gpu/drm/hisilicon/hibmc/dp/dp_link.c | 33 +++++++++++++------
.../gpu/drm/hisilicon/hibmc/dp/dp_serdes.c | 12 -------
4 files changed, 27 insertions(+), 28 deletions(-)
diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_comm.h b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_comm.h
index 4add05c7f161..18a961466ff0 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_comm.h
+++ b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_comm.h
@@ -25,6 +25,9 @@ struct hibmc_link_status {
struct hibmc_link_cap {
u8 link_rate;
u8 lanes;
+ int rx_dpcd_revision;
+ bool is_tps3;
+ bool is_tps4;
};
struct hibmc_dp_link {
@@ -62,7 +65,6 @@ struct hibmc_dp_dev {
void hibmc_dp_aux_init(struct hibmc_dp *dp);
int hibmc_dp_link_training(struct hibmc_dp_dev *dp);
-int hibmc_dp_serdes_init(struct hibmc_dp_dev *dp);
int hibmc_dp_serdes_rate_switch(u8 rate, struct hibmc_dp_dev *dp);
int hibmc_dp_serdes_set_tx_cfg(struct hibmc_dp_dev *dp, u8 train_set[HIBMC_DP_LANE_NUM_MAX]);
diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c
index 2d2fb6e759c3..b4d612047f36 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c
@@ -155,7 +155,6 @@ int hibmc_dp_hw_init(struct hibmc_dp *dp)
{
struct drm_device *drm_dev = dp->drm_dev;
struct hibmc_dp_dev *dp_dev;
- int ret;
dp_dev = devm_kzalloc(drm_dev->dev, sizeof(struct hibmc_dp_dev), GFP_KERNEL);
if (!dp_dev)
@@ -169,13 +168,10 @@ int hibmc_dp_hw_init(struct hibmc_dp *dp)
dp_dev->dev = drm_dev;
dp_dev->base = dp->mmio + HIBMC_DP_OFFSET;
+ dp_dev->serdes_base = dp_dev->base + HIBMC_DP_HOST_OFFSET;
hibmc_dp_aux_init(dp);
- ret = hibmc_dp_serdes_init(dp_dev);
- if (ret)
- return ret;
-
dp_dev->link.cap.lanes = 0x2;
dp_dev->link.cap.link_rate = DP_LINK_BW_8_1;
diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_link.c b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_link.c
index 74f7832ea53e..6c69fa2ae9cf 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_link.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_link.c
@@ -39,6 +39,14 @@ static int hibmc_dp_link_training_configure(struct hibmc_dp_dev *dp)
/* enhanced frame */
hibmc_dp_reg_write_field(dp, HIBMC_DP_VIDEO_CTRL, HIBMC_DP_CFG_STREAM_FRAME_MODE, 0x1);
+ ret = hibmc_dp_get_serdes_rate_cfg(dp);
+ if (ret < 0)
+ return ret;
+
+ ret = hibmc_dp_serdes_rate_switch(ret, dp);
+ if (ret)
+ return ret;
+
/* set rate and lane count */
buf[0] = dp->link.cap.link_rate;
buf[1] = DP_LANE_COUNT_ENHANCED_FRAME_EN | dp->link.cap.lanes;
@@ -325,6 +333,20 @@ static int hibmc_dp_link_downgrade_training_eq(struct hibmc_dp_dev *dp)
return hibmc_dp_link_reduce_rate(dp);
}
+static void hibmc_dp_update_caps(struct hibmc_dp_dev *dp)
+{
+ dp->link.cap.rx_dpcd_revision = dp->dpcd[DP_DPCD_REV];
+
+ dp->link.cap.is_tps3 = (dp->dpcd[DP_DPCD_REV] >= DP_DPCD_REV_13) &&
+ (dp->dpcd[DP_MAX_LANE_COUNT] & DP_TPS3_SUPPORTED);
+ dp->link.cap.is_tps4 = (dp->dpcd[DP_DPCD_REV] >= DP_DPCD_REV_14) &&
+ (dp->dpcd[DP_MAX_DOWNSPREAD] & DP_TPS4_SUPPORTED);
+ dp->link.cap.link_rate = dp->dpcd[DP_MAX_LINK_RATE];
+ dp->link.cap.lanes = dp->dpcd[DP_MAX_LANE_COUNT] & DP_MAX_LANE_COUNT_MASK;
+ if (dp->link.cap.lanes > HIBMC_DP_LANE_NUM_MAX)
+ dp->link.cap.lanes = HIBMC_DP_LANE_NUM_MAX;
+}
+
int hibmc_dp_link_training(struct hibmc_dp_dev *dp)
{
struct hibmc_dp_link *link = &dp->link;
@@ -334,16 +356,7 @@ int hibmc_dp_link_training(struct hibmc_dp_dev *dp)
if (ret)
drm_err(dp->dev, "dp aux read dpcd failed, ret: %d\n", ret);
- dp->link.cap.link_rate = dp->dpcd[DP_MAX_LINK_RATE];
- dp->link.cap.lanes = 0x2;
-
- ret = hibmc_dp_get_serdes_rate_cfg(dp);
- if (ret < 0)
- return ret;
-
- ret = hibmc_dp_serdes_rate_switch(ret, dp);
- if (ret)
- return ret;
+ hibmc_dp_update_caps(dp);
while (true) {
ret = hibmc_dp_link_training_cr_pre(dp);
diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_serdes.c b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_serdes.c
index 676059d4c1e6..8191233aa965 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_serdes.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_serdes.c
@@ -57,15 +57,3 @@ int hibmc_dp_serdes_rate_switch(u8 rate, struct hibmc_dp_dev *dp)
return 0;
}
-
-int hibmc_dp_serdes_init(struct hibmc_dp_dev *dp)
-{
- dp->serdes_base = dp->base + HIBMC_DP_HOST_OFFSET;
-
- writel(FIELD_PREP(HIBMC_DP_PMA_TXDEEMPH, DP_SERDES_VOL0_PRE0),
- dp->serdes_base + HIBMC_DP_PMA_LANE0_OFFSET);
- writel(FIELD_PREP(HIBMC_DP_PMA_TXDEEMPH, DP_SERDES_VOL0_PRE0),
- dp->serdes_base + HIBMC_DP_PMA_LANE1_OFFSET);
-
- return hibmc_dp_serdes_rate_switch(DP_SERDES_BW_8_1, dp);
-}
--
2.33.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v3 drm-dp 06/11] drm/hisilicon/hibmc: add dp mode valid check
2025-07-18 6:51 [PATCH v3 drm-dp 00/11] Fix hibmc driver bugs Yongbang Shi
` (4 preceding siblings ...)
2025-07-18 6:51 ` [PATCH v3 drm-dp 05/11] drm/hisilicon/hibmc: fix rare monitors cannot display problem Yongbang Shi
@ 2025-07-18 6:51 ` Yongbang Shi
2025-07-26 15:56 ` Dmitry Baryshkov
2025-07-18 6:51 ` [PATCH v3 drm-dp 07/11] drm/hisilicon/hibmc: fix dp and vga cannot show together Yongbang Shi
` (5 subsequent siblings)
11 siblings, 1 reply; 24+ messages in thread
From: Yongbang Shi @ 2025-07-18 6:51 UTC (permalink / raw)
To: xinliang.liu, tiantao6, maarten.lankhorst, mripard, tzimmermann,
airlied, daniel, kong.kongxinwei, dmitry.baryshkov
Cc: liangjian010, chenjianmin, fengsheng5, shiyongbang, libaihan,
shenjian15, shaojijie, jani.nikula, dri-devel, linux-kernel
From: Baihan Li <libaihan@huawei.com>
If DP is connected, add mode check and BW check in mode_valid_ctx() to
ensure DP's cfg is usable.
For example: Some DP's mode(1920x1080 60HZ 138.5 MHz) gives to drm,
however, the GPU is configured for 148MHz in display_ctrl_adjust() by
looking up the table of struct hibmc_pll_table{}. This difference will
cause the DP to not display because the clock the DP gets via drm frame
is 138MHz.
Fixes: f9698f802e50 ("drm/hisilicon/hibmc: Restructuring the header dp_reg.h")
Signed-off-by: Baihan Li <libaihan@huawei.com>
Signed-off-by: Yongbang Shi <shiyongbang@huawei.com>
---
drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c | 10 ++++
drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.h | 6 +++
.../gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c | 51 +++++++++++++++++++
3 files changed, 67 insertions(+)
diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c
index b4d612047f36..7fbd51ffd778 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c
@@ -276,6 +276,16 @@ void hibmc_dp_reset_link(struct hibmc_dp *dp)
dp->dp_dev->link.status.channel_equalized = false;
}
+u8 hibmc_dp_get_link_rate(struct hibmc_dp *dp)
+{
+ return dp->dp_dev->link.cap.link_rate;
+}
+
+u8 hibmc_dp_get_lanes(struct hibmc_dp *dp)
+{
+ return dp->dp_dev->link.cap.lanes;
+}
+
static const struct hibmc_dp_color_raw g_rgb_raw[] = {
{CBAR_COLOR_BAR, 0x000, 0x000, 0x000},
{CBAR_WHITE, 0xfff, 0xfff, 0xfff},
diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.h b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.h
index 9b45e88e47e4..0059a2648a38 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.h
+++ b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.h
@@ -12,6 +12,10 @@
#include <drm/drm_print.h>
#include <drm/display/drm_dp_helper.h>
+/* 27 * 10000000 * 80% = 216000000 */
+#define DP_MODE_VALI_CAL 216000000
+#define BPP_24 24
+
struct hibmc_dp_dev;
enum hibmc_dp_cbar_pattern {
@@ -62,5 +66,7 @@ void hibmc_dp_reset_link(struct hibmc_dp *dp);
void hibmc_dp_hpd_cfg(struct hibmc_dp *dp);
void hibmc_dp_enable_int(struct hibmc_dp *dp);
void hibmc_dp_disable_int(struct hibmc_dp *dp);
+u8 hibmc_dp_get_link_rate(struct hibmc_dp *dp);
+u8 hibmc_dp_get_lanes(struct hibmc_dp *dp);
#endif
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c
index 354e18bb2998..99b30a6c7e06 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c
@@ -15,6 +15,28 @@
#define DP_MASKED_SINK_HPD_PLUG_INT BIT(2)
+struct hibmc_dp_disp_clk {
+ u16 hdisplay;
+ u16 vdisplay;
+ u32 clock;
+};
+
+static const struct hibmc_dp_disp_clk hibmc_dp_clk_table[] = {
+ {640, 480, 25175}, /* 25175 khz */
+ {800, 600, 40000}, /* 40000 khz */
+ {1024, 768, 65000}, /* 65000 khz */
+ {1152, 864, 80000}, /* 80000 khz */
+ {1280, 768, 79500}, /* 79500 khz */
+ {1280, 720, 74250}, /* 74250 khz */
+ {1280, 960, 108000}, /* 108000 khz */
+ {1280, 1024, 108000}, /* 108000 khz */
+ {1440, 900, 106500}, /* 106500 khz */
+ {1600, 900, 108000}, /* 108000 khz */
+ {1600, 1200, 162000}, /* 162000 khz */
+ {1920, 1080, 148500}, /* 148500 khz */
+ {1920, 1200, 193250}, /* 193250 khz */
+};
+
static int hibmc_dp_connector_get_modes(struct drm_connector *connector)
{
const struct drm_edid *drm_edid;
@@ -42,9 +64,38 @@ static int hibmc_dp_detect(struct drm_connector *connector,
return connector_status_disconnected;
}
+static int hibmc_dp_mode_valid(struct drm_connector *connector,
+ const struct drm_display_mode *mode,
+ struct drm_modeset_acquire_ctx *ctx,
+ enum drm_mode_status *status)
+{
+ struct hibmc_dp *dp = to_hibmc_dp(connector);
+ u64 cur_val, max_val;
+
+ /* check DP link BW */
+ cur_val = (u64)mode->htotal * mode->vtotal * drm_mode_vrefresh(mode) * BPP_24;
+ max_val = (u64)hibmc_dp_get_link_rate(dp) * DP_MODE_VALI_CAL * hibmc_dp_get_lanes(dp);
+
+ *status = cur_val > max_val ? MODE_CLOCK_HIGH : MODE_OK;
+
+ /* check the clock */
+ for (size_t i = 0; i < ARRAY_SIZE(hibmc_dp_clk_table); i++) {
+ if (hibmc_dp_clk_table[i].hdisplay == mode->hdisplay &&
+ hibmc_dp_clk_table[i].vdisplay == mode->vdisplay) {
+ if (hibmc_dp_clk_table[i].clock != mode->clock) {
+ *status = MODE_CLOCK_RANGE;
+ return 0;
+ }
+ }
+ }
+
+ return 0;
+}
+
static const struct drm_connector_helper_funcs hibmc_dp_conn_helper_funcs = {
.get_modes = hibmc_dp_connector_get_modes,
.detect_ctx = hibmc_dp_detect,
+ .mode_valid_ctx = hibmc_dp_mode_valid,
};
static int hibmc_dp_late_register(struct drm_connector *connector)
--
2.33.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v3 drm-dp 07/11] drm/hisilicon/hibmc: fix dp and vga cannot show together
2025-07-18 6:51 [PATCH v3 drm-dp 00/11] Fix hibmc driver bugs Yongbang Shi
` (5 preceding siblings ...)
2025-07-18 6:51 ` [PATCH v3 drm-dp 06/11] drm/hisilicon/hibmc: add dp mode valid check Yongbang Shi
@ 2025-07-18 6:51 ` Yongbang Shi
2025-07-18 6:51 ` [PATCH v3 drm-dp 08/11] drm/hisilicon/hibmc: fix no showing when no connectors connected Yongbang Shi
` (4 subsequent siblings)
11 siblings, 0 replies; 24+ messages in thread
From: Yongbang Shi @ 2025-07-18 6:51 UTC (permalink / raw)
To: xinliang.liu, tiantao6, maarten.lankhorst, mripard, tzimmermann,
airlied, daniel, kong.kongxinwei, dmitry.baryshkov
Cc: liangjian010, chenjianmin, fengsheng5, shiyongbang, libaihan,
shenjian15, shaojijie, jani.nikula, dri-devel, linux-kernel
From: Baihan Li <libaihan@huawei.com>
If VGA and DP connected together, there will be only one can get crtc.
Add encoder possible_clones to support two connectors enable.
Fixes: 3c7623fb5bb6 ("drm/hisilicon/hibmc: Enable this hot plug detect of irq feature")
Signed-off-by: Baihan Li <libaihan@huawei.com>
Signed-off-by: Yongbang Shi <shiyongbang@huawei.com>
---
drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
index ac552c339671..289304500ab0 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
@@ -115,6 +115,8 @@ static const struct drm_mode_config_funcs hibmc_mode_funcs = {
static int hibmc_kms_init(struct hibmc_drm_private *priv)
{
struct drm_device *dev = &priv->dev;
+ struct drm_encoder *encoder;
+ u32 clone_mask = 0;
int ret;
ret = drmm_mode_config_init(dev);
@@ -154,6 +156,12 @@ static int hibmc_kms_init(struct hibmc_drm_private *priv)
return ret;
}
+ drm_for_each_encoder(encoder, dev)
+ clone_mask |= drm_encoder_mask(encoder);
+
+ drm_for_each_encoder(encoder, dev)
+ encoder->possible_clones = clone_mask;
+
return 0;
}
--
2.33.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v3 drm-dp 08/11] drm/hisilicon/hibmc: fix no showing when no connectors connected
2025-07-18 6:51 [PATCH v3 drm-dp 00/11] Fix hibmc driver bugs Yongbang Shi
` (6 preceding siblings ...)
2025-07-18 6:51 ` [PATCH v3 drm-dp 07/11] drm/hisilicon/hibmc: fix dp and vga cannot show together Yongbang Shi
@ 2025-07-18 6:51 ` Yongbang Shi
2025-07-26 16:03 ` Dmitry Baryshkov
2025-07-18 6:51 ` [PATCH v3 drm-dp 09/11] drm/hisilicon/hibmc: fix no showing problem with loading hibmc manually Yongbang Shi
` (3 subsequent siblings)
11 siblings, 1 reply; 24+ messages in thread
From: Yongbang Shi @ 2025-07-18 6:51 UTC (permalink / raw)
To: xinliang.liu, tiantao6, maarten.lankhorst, mripard, tzimmermann,
airlied, daniel, kong.kongxinwei, dmitry.baryshkov
Cc: liangjian010, chenjianmin, fengsheng5, shiyongbang, libaihan,
shenjian15, shaojijie, jani.nikula, dri-devel, linux-kernel
From: Baihan Li <libaihan@huawei.com>
Our chip support KVM over IP feature, so hibmc diiver need to support
displaying without any connectors plugged in. If no connectors connected,
set the vdac connector status to 'connected' to handle BMC KVM. Use
is_connected to check all physical outputs.
For get_modes: using BMC modes for connector if no display is attached to
phys VGA cable, otherwise use EDID modes by drm_connector_helper_get_modes.
Fixes: 4c962bc929f1 ("drm/hisilicon/hibmc: Add vga connector detect functions")
Signed-off-by: Baihan Li <libaihan@huawei.com>
Signed-off-by: Yongbang Shi <shiyongbang@huawei.com>
---
ChangeLog:
v2 -> v3:
- fix hibmc_connector_get_modes() and hibmc_vdac_detect() to realize BMC KVM, suggested by Dmitry Baryshkov.
---
.../gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c | 5 +-
.../gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h | 4 ++
.../gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c | 55 +++++++++++++------
3 files changed, 45 insertions(+), 19 deletions(-)
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c
index 99b30a6c7e06..262ebe6138f0 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c
@@ -58,9 +58,12 @@ static int hibmc_dp_detect(struct drm_connector *connector,
{
struct hibmc_drm_private *priv = to_hibmc_drm_private(connector->dev);
- if (!hibmc_dp_detect_link(&priv->dp))
+ if (!hibmc_dp_detect_link(&priv->dp)) {
+ priv->is_connected |= BIT(0);
return connector_status_connected;
+ }
+ priv->is_connected &= ~BIT(0);
return connector_status_disconnected;
}
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
index ca8502e2760c..d68588ecec9b 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
@@ -31,6 +31,7 @@ struct hibmc_vdac {
struct drm_connector connector;
struct i2c_adapter adapter;
struct i2c_algo_bit_data bit_data;
+ int phys_status;
};
struct hibmc_drm_private {
@@ -43,6 +44,9 @@ struct hibmc_drm_private {
struct drm_crtc crtc;
struct hibmc_vdac vdac;
struct hibmc_dp dp;
+
+ /* VGA and DP phys connect status, BIT(0) is DP, BIT(1) is VGA */
+ int is_connected;
};
static inline struct hibmc_vdac *to_hibmc_vdac(struct drm_connector *connector)
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
index 841e81f47b68..3cdf640d1785 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
@@ -25,27 +25,18 @@
static int hibmc_connector_get_modes(struct drm_connector *connector)
{
struct hibmc_vdac *vdac = to_hibmc_vdac(connector);
- const struct drm_edid *drm_edid;
int count;
- drm_edid = drm_edid_read_ddc(connector, &vdac->adapter);
-
- drm_edid_connector_update(connector, drm_edid);
-
- if (drm_edid) {
- count = drm_edid_connector_add_modes(connector);
- if (count)
- goto out;
+ if (vdac->phys_status == connector_status_connected) {
+ count = drm_connector_helper_get_modes(connector);
+ } else {
+ drm_edid_connector_update(connector, NULL);
+ count = drm_add_modes_noedid(connector,
+ connector->dev->mode_config.max_width,
+ connector->dev->mode_config.max_height);
+ drm_set_preferred_mode(connector, 1024, 768); // 1024x768
}
- count = drm_add_modes_noedid(connector,
- connector->dev->mode_config.max_width,
- connector->dev->mode_config.max_height);
- drm_set_preferred_mode(connector, 1024, 768);
-
-out:
- drm_edid_free(drm_edid);
-
return count;
}
@@ -57,10 +48,38 @@ static void hibmc_connector_destroy(struct drm_connector *connector)
drm_connector_cleanup(connector);
}
+static int hibmc_vdac_detect(struct drm_connector *connector,
+ struct drm_modeset_acquire_ctx *ctx,
+ bool force)
+{
+ struct hibmc_drm_private *priv = to_hibmc_drm_private(connector->dev);
+ struct hibmc_vdac *vdac = to_hibmc_vdac(connector);
+ enum drm_connector_status status;
+
+ status = drm_connector_helper_detect_from_ddc(connector, ctx, force);
+
+ vdac->phys_status = status;
+
+ if (status == connector_status_connected) {
+ priv->is_connected |= BIT(1);
+ return connector_status_connected;
+ }
+
+ priv->is_connected &= ~BIT(1);
+
+ /* if all connectors are disconnected,
+ * return connected to support BMC KVM display.
+ */
+ if (!priv->is_connected)
+ return connector_status_connected;
+
+ return connector_status_disconnected;
+}
+
static const struct drm_connector_helper_funcs
hibmc_connector_helper_funcs = {
.get_modes = hibmc_connector_get_modes,
- .detect_ctx = drm_connector_helper_detect_from_ddc,
+ .detect_ctx = hibmc_vdac_detect,
};
static const struct drm_connector_funcs hibmc_connector_funcs = {
--
2.33.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v3 drm-dp 09/11] drm/hisilicon/hibmc: fix no showing problem with loading hibmc manually
2025-07-18 6:51 [PATCH v3 drm-dp 00/11] Fix hibmc driver bugs Yongbang Shi
` (7 preceding siblings ...)
2025-07-18 6:51 ` [PATCH v3 drm-dp 08/11] drm/hisilicon/hibmc: fix no showing when no connectors connected Yongbang Shi
@ 2025-07-18 6:51 ` Yongbang Shi
2025-07-26 16:04 ` Dmitry Baryshkov
2025-07-18 6:51 ` [PATCH v3 drm-dp 10/11] drm/hisilicon/hibmc: adapting modification for the former commit Yongbang Shi
` (2 subsequent siblings)
11 siblings, 1 reply; 24+ messages in thread
From: Yongbang Shi @ 2025-07-18 6:51 UTC (permalink / raw)
To: xinliang.liu, tiantao6, maarten.lankhorst, mripard, tzimmermann,
airlied, daniel, kong.kongxinwei, dmitry.baryshkov
Cc: liangjian010, chenjianmin, fengsheng5, shiyongbang, libaihan,
shenjian15, shaojijie, jani.nikula, dri-devel, linux-kernel
From: Baihan Li <libaihan@huawei.com>
When using command rmmod and insmod, there is no showing in second time
insmoding. Because DP controller won't send HPD signals, if connection
doesn't change or controller isn't reset. So add reset before unreset
in hibmc_dp_hw_init().
Fixes: 3c7623fb5bb6 ("drm/hisilicon/hibmc: Enable this hot plug detect of irq feature")
Signed-off-by: Baihan Li <libaihan@huawei.com>
Signed-off-by: Yongbang Shi <shiyongbang@huawei.com>
---
ChangeLog:
v2 -> v3:
- fix the issue commit ID, suggested by Dmitry Baryshkov.
---
drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c
index 7fbd51ffd778..36daf7542d40 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c
@@ -181,6 +181,8 @@ int hibmc_dp_hw_init(struct hibmc_dp *dp)
writel(0, dp_dev->base + HIBMC_DP_INTR_ENABLE);
writel(HIBMC_DP_INT_RST, dp_dev->base + HIBMC_DP_INTR_ORIGINAL_STATUS);
/* rst */
+ writel(0, dp_dev->base + HIBMC_DP_DPTX_RST_CTRL);
+ usleep_range(30, 50);
writel(HIBMC_DP_DPTX_RST, dp_dev->base + HIBMC_DP_DPTX_RST_CTRL);
/* clock enable */
writel(HIBMC_DP_CLK_EN, dp_dev->base + HIBMC_DP_DPTX_CLK_CTRL);
--
2.33.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v3 drm-dp 10/11] drm/hisilicon/hibmc: adapting modification for the former commit
2025-07-18 6:51 [PATCH v3 drm-dp 00/11] Fix hibmc driver bugs Yongbang Shi
` (8 preceding siblings ...)
2025-07-18 6:51 ` [PATCH v3 drm-dp 09/11] drm/hisilicon/hibmc: fix no showing problem with loading hibmc manually Yongbang Shi
@ 2025-07-18 6:51 ` Yongbang Shi
2025-07-26 16:05 ` Dmitry Baryshkov
2025-07-18 6:51 ` [PATCH v3 drm-dp 11/11] drm/hisilicon/hibmc: " Yongbang Shi
2025-07-25 9:16 ` [PATCH v3 drm-dp 00/11] Fix hibmc driver bugs Yongbang Shi
11 siblings, 1 reply; 24+ messages in thread
From: Yongbang Shi @ 2025-07-18 6:51 UTC (permalink / raw)
To: xinliang.liu, tiantao6, maarten.lankhorst, mripard, tzimmermann,
airlied, daniel, kong.kongxinwei, dmitry.baryshkov
Cc: liangjian010, chenjianmin, fengsheng5, shiyongbang, libaihan,
shenjian15, shaojijie, jani.nikula, dri-devel, linux-kernel
From: Baihan Li <libaihan@huawei.com>
Add colorbar disable operation before reset chontroller, to make sure
colorbar status is clear in the DP init, so if rmmod the driver and the
previous colorbar configuration will not affect the next time insmod the
driver.
Fixes: 3c7623fb5bb6 ("drm/hisilicon/hibmc: Enable this hot plug detect of irq feature")
Signed-off-by: Baihan Li <libaihan@huawei.com>
Signed-off-by: Yongbang Shi <shiyongbang@huawei.com>
---
ChangeLog:
v2 -> v3:
- fix the issue commit ID, suggested by Dmitry Baryshkov.
- split into 2 commits, suggested by Dmitry Baryshkov.
- add more comments in commit log, suggested by Dmitry Baryshkov.
---
drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c
index 36daf7542d40..85499f1ace8b 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c
@@ -180,6 +180,8 @@ int hibmc_dp_hw_init(struct hibmc_dp *dp)
/* int init */
writel(0, dp_dev->base + HIBMC_DP_INTR_ENABLE);
writel(HIBMC_DP_INT_RST, dp_dev->base + HIBMC_DP_INTR_ORIGINAL_STATUS);
+ /* clr colorbar */
+ writel(0, dp_dev->base + HIBMC_DP_COLOR_BAR_CTRL);
/* rst */
writel(0, dp_dev->base + HIBMC_DP_DPTX_RST_CTRL);
usleep_range(30, 50);
--
2.33.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v3 drm-dp 11/11] drm/hisilicon/hibmc: modification for the former commit
2025-07-18 6:51 [PATCH v3 drm-dp 00/11] Fix hibmc driver bugs Yongbang Shi
` (9 preceding siblings ...)
2025-07-18 6:51 ` [PATCH v3 drm-dp 10/11] drm/hisilicon/hibmc: adapting modification for the former commit Yongbang Shi
@ 2025-07-18 6:51 ` Yongbang Shi
2025-07-25 9:16 ` [PATCH v3 drm-dp 00/11] Fix hibmc driver bugs Yongbang Shi
11 siblings, 0 replies; 24+ messages in thread
From: Yongbang Shi @ 2025-07-18 6:51 UTC (permalink / raw)
To: xinliang.liu, tiantao6, maarten.lankhorst, mripard, tzimmermann,
airlied, daniel, kong.kongxinwei, dmitry.baryshkov
Cc: liangjian010, chenjianmin, fengsheng5, shiyongbang, libaihan,
shenjian15, shaojijie, jani.nikula, dri-devel, linux-kernel
From: Baihan Li <libaihan@huawei.com>
The DP reset was adding in the former commit, and move HDCP cfg after DP
controller deresets, so that configuration takes effect.
Fixes: 3c7623fb5bb6 ("drm/hisilicon/hibmc: Enable this hot plug detect of irq feature")
Signed-off-by: Baihan Li <libaihan@huawei.com>
Signed-off-by: Yongbang Shi <shiyongbang@huawei.com>
---
ChangeLog:
v2 -> v3:
- split into 2 commits, suggested by Dmitry Baryshkov.
---
drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c
index 85499f1ace8b..7ba01e7901d3 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c
@@ -175,8 +175,6 @@ int hibmc_dp_hw_init(struct hibmc_dp *dp)
dp_dev->link.cap.lanes = 0x2;
dp_dev->link.cap.link_rate = DP_LINK_BW_8_1;
- /* hdcp data */
- writel(HIBMC_DP_HDCP, dp_dev->base + HIBMC_DP_HDCP_CFG);
/* int init */
writel(0, dp_dev->base + HIBMC_DP_INTR_ENABLE);
writel(HIBMC_DP_INT_RST, dp_dev->base + HIBMC_DP_INTR_ORIGINAL_STATUS);
@@ -186,6 +184,8 @@ int hibmc_dp_hw_init(struct hibmc_dp *dp)
writel(0, dp_dev->base + HIBMC_DP_DPTX_RST_CTRL);
usleep_range(30, 50);
writel(HIBMC_DP_DPTX_RST, dp_dev->base + HIBMC_DP_DPTX_RST_CTRL);
+ /* hdcp data */
+ writel(HIBMC_DP_HDCP, dp_dev->base + HIBMC_DP_HDCP_CFG);
/* clock enable */
writel(HIBMC_DP_CLK_EN, dp_dev->base + HIBMC_DP_DPTX_CLK_CTRL);
--
2.33.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [PATCH v3 drm-dp 00/11] Fix hibmc driver bugs
2025-07-18 6:51 [PATCH v3 drm-dp 00/11] Fix hibmc driver bugs Yongbang Shi
` (10 preceding siblings ...)
2025-07-18 6:51 ` [PATCH v3 drm-dp 11/11] drm/hisilicon/hibmc: " Yongbang Shi
@ 2025-07-25 9:16 ` Yongbang Shi
11 siblings, 0 replies; 24+ messages in thread
From: Yongbang Shi @ 2025-07-25 9:16 UTC (permalink / raw)
To: xinliang.liu, tiantao6, maarten.lankhorst, mripard, tzimmermann,
airlied, daniel, kong.kongxinwei, dmitry.baryshkov
Cc: liangjian010, chenjianmin, fengsheng5, libaihan, shenjian15,
shaojijie, jani.nikula, dri-devel, linux-kernel, shiyongbang
Gentle ping for review !
> From: Baihan Li <libaihan@huawei.com>
>
> There are some bugfix for hibmc-drm driver.
> ---
> ChangeLog:
> v2 -> v3:
> - fix hibmc_connector_get_modes() and hibmc_vdac_detect() to realize BMC KVM, suggested by Dmitry Baryshkov.
> - fix the issue commit ID, suggested by Dmitry Baryshkov.
> - split into 2 commits, suggested by Dmitry Baryshkov.
> - add more comments in commit log, suggested by Dmitry Baryshkov.
> ---
>
> Baihan Li (11):
> drm/hisilicon/hibmc: fix the i2c device resource leak when vdac init
> failed
> drm/hisilicon/hibmc: fix dp probabilistical detect errors after HPD
> irq
> drm/hisilicon/hibmc: fix irq_request()'s irq name variable is local
> drm/hisilicon/hibmc: fix the hibmc loaded failed bug
> drm/hisilicon/hibmc: fix rare monitors cannot display problem
> drm/hisilicon/hibmc: add dp mode valid check
> drm/hisilicon/hibmc: fix dp and vga cannot show together
> drm/hisilicon/hibmc: fix no showing when no connectors connected
> drm/hisilicon/hibmc: fix no showing problem with loading hibmc
> manually
> drm/hisilicon/hibmc: adapting modification for the former commit
> drm/hisilicon/hibmc: modification for the former commit
>
> drivers/gpu/drm/hisilicon/hibmc/dp/dp_comm.h | 4 +-
> drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c | 51 ++++++++++----
> drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.h | 8 +++
> drivers/gpu/drm/hisilicon/hibmc/dp/dp_link.c | 33 +++++++---
> .../gpu/drm/hisilicon/hibmc/dp/dp_serdes.c | 12 ----
> .../gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c | 64 ++++++++++++++++--
> .../gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c | 22 ++++---
> .../gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h | 5 ++
> .../gpu/drm/hisilicon/hibmc/hibmc_drm_i2c.c | 5 ++
> .../gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c | 66 +++++++++++++------
> 10 files changed, 201 insertions(+), 69 deletions(-)
>
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v3 drm-dp 02/11] drm/hisilicon/hibmc: fix dp probabilistical detect errors after HPD irq
2025-07-18 6:51 ` [PATCH v3 drm-dp 02/11] drm/hisilicon/hibmc: fix dp probabilistical detect errors after HPD irq Yongbang Shi
@ 2025-07-26 15:03 ` Dmitry Baryshkov
2025-08-01 9:21 ` Yongbang Shi
0 siblings, 1 reply; 24+ messages in thread
From: Dmitry Baryshkov @ 2025-07-26 15:03 UTC (permalink / raw)
To: Yongbang Shi
Cc: xinliang.liu, tiantao6, maarten.lankhorst, mripard, tzimmermann,
airlied, daniel, kong.kongxinwei, liangjian010, chenjianmin,
fengsheng5, libaihan, shenjian15, shaojijie, jani.nikula,
dri-devel, linux-kernel
On Fri, Jul 18, 2025 at 02:51:16PM +0800, Yongbang Shi wrote:
> From: Baihan Li <libaihan@huawei.com>
>
> The debouncing when HPD pulled out still remains sometimes, 200ms still can
> not ensure helper_detect() is correct. Add hibmc_dp_detect_link() in
> detect_ctx(), which is to try dp link training.
I'm not sure if I follow the commit message. Anyway, link training
should be a part of atomic_(pre)_enable, not a detect_ctx.
>
> Fixes: 3c7623fb5bb6 ("drm/hisilicon/hibmc: Enable this hot plug detect of irq feature")
> Signed-off-by: Baihan Li <libaihan@huawei.com>
> Signed-off-by: Yongbang Shi <shiyongbang@huawei.com>
> ---
> drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c | 27 +++++++++++++++----
> drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.h | 2 ++
> .../gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c | 10 ++++---
> 3 files changed, 30 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c
> index 8f0daec7d174..2d2fb6e759c3 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"
> @@ -162,6 +163,8 @@ int hibmc_dp_hw_init(struct hibmc_dp *dp)
>
> mutex_init(&dp_dev->lock);
>
> + drmm_mutex_init(drm_dev, &dp->link_train_mutex);
> +
> dp->dp_dev = dp_dev;
>
> dp_dev->dev = drm_dev;
> @@ -238,19 +241,33 @@ void hibmc_dp_display_en(struct hibmc_dp *dp, bool enable)
> msleep(50);
> }
>
> -int hibmc_dp_mode_set(struct hibmc_dp *dp, struct drm_display_mode *mode)
> +int hibmc_dp_detect_link(struct hibmc_dp *dp)
> {
> struct hibmc_dp_dev *dp_dev = dp->dp_dev;
> - int ret;
> + int ret = 0;
> +
> + mutex_lock(&dp->link_train_mutex);
>
> if (!dp_dev->link.status.channel_equalized) {
> ret = hibmc_dp_link_training(dp_dev);
> - if (ret) {
> + if (ret)
> drm_err(dp->drm_dev, "dp link training failed, ret: %d\n", ret);
> - return ret;
> - }
> }
>
> + mutex_unlock(&dp->link_train_mutex);
> +
> + return ret;
> +}
> +
> +int hibmc_dp_mode_set(struct hibmc_dp *dp, struct drm_display_mode *mode)
> +{
> + struct hibmc_dp_dev *dp_dev = dp->dp_dev;
> + int ret;
> +
> + ret = hibmc_dp_detect_link(dp);
> + if (ret)
> + return ret;
> +
> hibmc_dp_display_en(dp, false);
> hibmc_dp_link_cfg(dp_dev, mode);
>
> diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.h b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.h
> index 665f5b166dfb..9b45e88e47e4 100644
> --- a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.h
> +++ b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.h
> @@ -50,9 +50,11 @@ struct hibmc_dp {
> struct drm_dp_aux aux;
> struct hibmc_dp_cbar_cfg cfg;
> u32 irq_status;
> + struct mutex link_train_mutex; /* link training mutex */
> };
>
> int hibmc_dp_hw_init(struct hibmc_dp *dp);
> +int hibmc_dp_detect_link(struct hibmc_dp *dp);
> int hibmc_dp_mode_set(struct hibmc_dp *dp, struct drm_display_mode *mode);
> void hibmc_dp_display_en(struct hibmc_dp *dp, bool enable);
> void hibmc_dp_set_cbar(struct hibmc_dp *dp, const struct hibmc_dp_cbar_cfg *cfg);
> diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c
> index d06832e62e96..354e18bb2998 100644
> --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c
> +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c
> @@ -34,9 +34,12 @@ static int hibmc_dp_connector_get_modes(struct drm_connector *connector)
> static int hibmc_dp_detect(struct drm_connector *connector,
> struct drm_modeset_acquire_ctx *ctx, bool force)
> {
> - mdelay(200);
> + struct hibmc_drm_private *priv = to_hibmc_drm_private(connector->dev);
>
> - return drm_connector_helper_detect_from_ddc(connector, ctx, force);
> + if (!hibmc_dp_detect_link(&priv->dp))
> + return connector_status_connected;
> +
> + return connector_status_disconnected;
> }
>
> static const struct drm_connector_helper_funcs hibmc_dp_conn_helper_funcs = {
> @@ -128,8 +131,7 @@ irqreturn_t hibmc_dp_hpd_isr(int irq, void *arg)
> hibmc_dp_reset_link(&priv->dp);
> }
>
> - if (dev->registered)
> - drm_connector_helper_hpd_irq_event(&priv->dp.connector);
> + drm_connector_helper_hpd_irq_event(&priv->dp.connector);
>
> drm_dev_exit(idx);
>
> --
> 2.33.0
>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v3 drm-dp 05/11] drm/hisilicon/hibmc: fix rare monitors cannot display problem
2025-07-18 6:51 ` [PATCH v3 drm-dp 05/11] drm/hisilicon/hibmc: fix rare monitors cannot display problem Yongbang Shi
@ 2025-07-26 15:09 ` Dmitry Baryshkov
2025-08-01 9:22 ` Yongbang Shi
0 siblings, 1 reply; 24+ messages in thread
From: Dmitry Baryshkov @ 2025-07-26 15:09 UTC (permalink / raw)
To: Yongbang Shi
Cc: xinliang.liu, tiantao6, maarten.lankhorst, mripard, tzimmermann,
airlied, daniel, kong.kongxinwei, liangjian010, chenjianmin,
fengsheng5, libaihan, shenjian15, shaojijie, jani.nikula,
dri-devel, linux-kernel
On Fri, Jul 18, 2025 at 02:51:19PM +0800, Yongbang Shi wrote:
> From: Baihan Li <libaihan@huawei.com>
>
> In some case, the dp link training success at 8.1Gbps, but the sink's
> maximum supported rate is less than 8.1G. So change the default 8.1Gbps
> link rate to the rate that reads from devices' capabilities.
You are doing more than changing default link rate. Please split away
non-related changes. This is especially imporant for Fixes commits.
>
> Fixes: 54063d86e036 ("drm/hisilicon/hibmc: add dp link moduel in hibmc drivers")
> Signed-off-by: Baihan Li <libaihan@huawei.com>
> Signed-off-by: Yongbang Shi <shiyongbang@huawei.com>
> ---
> drivers/gpu/drm/hisilicon/hibmc/dp/dp_comm.h | 4 ++-
> drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c | 6 +---
> drivers/gpu/drm/hisilicon/hibmc/dp/dp_link.c | 33 +++++++++++++------
> .../gpu/drm/hisilicon/hibmc/dp/dp_serdes.c | 12 -------
> 4 files changed, 27 insertions(+), 28 deletions(-)
>
> diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_comm.h b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_comm.h
> index 4add05c7f161..18a961466ff0 100644
> --- a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_comm.h
> +++ b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_comm.h
> @@ -25,6 +25,9 @@ struct hibmc_link_status {
> struct hibmc_link_cap {
> u8 link_rate;
> u8 lanes;
> + int rx_dpcd_revision;
> + bool is_tps3;
> + bool is_tps4;
> };
>
> struct hibmc_dp_link {
> @@ -62,7 +65,6 @@ struct hibmc_dp_dev {
>
> void hibmc_dp_aux_init(struct hibmc_dp *dp);
> int hibmc_dp_link_training(struct hibmc_dp_dev *dp);
> -int hibmc_dp_serdes_init(struct hibmc_dp_dev *dp);
> int hibmc_dp_serdes_rate_switch(u8 rate, struct hibmc_dp_dev *dp);
> int hibmc_dp_serdes_set_tx_cfg(struct hibmc_dp_dev *dp, u8 train_set[HIBMC_DP_LANE_NUM_MAX]);
>
> diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c
> index 2d2fb6e759c3..b4d612047f36 100644
> --- a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c
> +++ b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c
> @@ -155,7 +155,6 @@ int hibmc_dp_hw_init(struct hibmc_dp *dp)
> {
> struct drm_device *drm_dev = dp->drm_dev;
> struct hibmc_dp_dev *dp_dev;
> - int ret;
>
> dp_dev = devm_kzalloc(drm_dev->dev, sizeof(struct hibmc_dp_dev), GFP_KERNEL);
> if (!dp_dev)
> @@ -169,13 +168,10 @@ int hibmc_dp_hw_init(struct hibmc_dp *dp)
>
> dp_dev->dev = drm_dev;
> dp_dev->base = dp->mmio + HIBMC_DP_OFFSET;
> + dp_dev->serdes_base = dp_dev->base + HIBMC_DP_HOST_OFFSET;
>
> hibmc_dp_aux_init(dp);
>
> - ret = hibmc_dp_serdes_init(dp_dev);
> - if (ret)
> - return ret;
> -
> dp_dev->link.cap.lanes = 0x2;
> dp_dev->link.cap.link_rate = DP_LINK_BW_8_1;
>
> diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_link.c b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_link.c
> index 74f7832ea53e..6c69fa2ae9cf 100644
> --- a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_link.c
> +++ b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_link.c
> @@ -39,6 +39,14 @@ static int hibmc_dp_link_training_configure(struct hibmc_dp_dev *dp)
> /* enhanced frame */
> hibmc_dp_reg_write_field(dp, HIBMC_DP_VIDEO_CTRL, HIBMC_DP_CFG_STREAM_FRAME_MODE, 0x1);
>
> + ret = hibmc_dp_get_serdes_rate_cfg(dp);
> + if (ret < 0)
> + return ret;
> +
> + ret = hibmc_dp_serdes_rate_switch(ret, dp);
> + if (ret)
> + return ret;
> +
> /* set rate and lane count */
> buf[0] = dp->link.cap.link_rate;
> buf[1] = DP_LANE_COUNT_ENHANCED_FRAME_EN | dp->link.cap.lanes;
> @@ -325,6 +333,20 @@ static int hibmc_dp_link_downgrade_training_eq(struct hibmc_dp_dev *dp)
> return hibmc_dp_link_reduce_rate(dp);
> }
>
> +static void hibmc_dp_update_caps(struct hibmc_dp_dev *dp)
> +{
> + dp->link.cap.rx_dpcd_revision = dp->dpcd[DP_DPCD_REV];
> +
> + dp->link.cap.is_tps3 = (dp->dpcd[DP_DPCD_REV] >= DP_DPCD_REV_13) &&
> + (dp->dpcd[DP_MAX_LANE_COUNT] & DP_TPS3_SUPPORTED);
> + dp->link.cap.is_tps4 = (dp->dpcd[DP_DPCD_REV] >= DP_DPCD_REV_14) &&
> + (dp->dpcd[DP_MAX_DOWNSPREAD] & DP_TPS4_SUPPORTED);
> + dp->link.cap.link_rate = dp->dpcd[DP_MAX_LINK_RATE];
> + dp->link.cap.lanes = dp->dpcd[DP_MAX_LANE_COUNT] & DP_MAX_LANE_COUNT_MASK;
> + if (dp->link.cap.lanes > HIBMC_DP_LANE_NUM_MAX)
> + dp->link.cap.lanes = HIBMC_DP_LANE_NUM_MAX;
> +}
> +
> int hibmc_dp_link_training(struct hibmc_dp_dev *dp)
> {
> struct hibmc_dp_link *link = &dp->link;
> @@ -334,16 +356,7 @@ int hibmc_dp_link_training(struct hibmc_dp_dev *dp)
> if (ret)
> drm_err(dp->dev, "dp aux read dpcd failed, ret: %d\n", ret);
>
> - dp->link.cap.link_rate = dp->dpcd[DP_MAX_LINK_RATE];
> - dp->link.cap.lanes = 0x2;
> -
> - ret = hibmc_dp_get_serdes_rate_cfg(dp);
> - if (ret < 0)
> - return ret;
> -
> - ret = hibmc_dp_serdes_rate_switch(ret, dp);
> - if (ret)
> - return ret;
> + hibmc_dp_update_caps(dp);
>
> while (true) {
> ret = hibmc_dp_link_training_cr_pre(dp);
> diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_serdes.c b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_serdes.c
> index 676059d4c1e6..8191233aa965 100644
> --- a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_serdes.c
> +++ b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_serdes.c
> @@ -57,15 +57,3 @@ int hibmc_dp_serdes_rate_switch(u8 rate, struct hibmc_dp_dev *dp)
>
> return 0;
> }
> -
> -int hibmc_dp_serdes_init(struct hibmc_dp_dev *dp)
> -{
> - dp->serdes_base = dp->base + HIBMC_DP_HOST_OFFSET;
> -
> - writel(FIELD_PREP(HIBMC_DP_PMA_TXDEEMPH, DP_SERDES_VOL0_PRE0),
> - dp->serdes_base + HIBMC_DP_PMA_LANE0_OFFSET);
> - writel(FIELD_PREP(HIBMC_DP_PMA_TXDEEMPH, DP_SERDES_VOL0_PRE0),
> - dp->serdes_base + HIBMC_DP_PMA_LANE1_OFFSET);
> -
> - return hibmc_dp_serdes_rate_switch(DP_SERDES_BW_8_1, dp);
> -}
> --
> 2.33.0
>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v3 drm-dp 06/11] drm/hisilicon/hibmc: add dp mode valid check
2025-07-18 6:51 ` [PATCH v3 drm-dp 06/11] drm/hisilicon/hibmc: add dp mode valid check Yongbang Shi
@ 2025-07-26 15:56 ` Dmitry Baryshkov
2025-08-01 9:22 ` Yongbang Shi
0 siblings, 1 reply; 24+ messages in thread
From: Dmitry Baryshkov @ 2025-07-26 15:56 UTC (permalink / raw)
To: Yongbang Shi
Cc: xinliang.liu, tiantao6, maarten.lankhorst, mripard, tzimmermann,
airlied, daniel, kong.kongxinwei, liangjian010, chenjianmin,
fengsheng5, libaihan, shenjian15, shaojijie, jani.nikula,
dri-devel, linux-kernel
On Fri, Jul 18, 2025 at 02:51:20PM +0800, Yongbang Shi wrote:
> From: Baihan Li <libaihan@huawei.com>
>
> If DP is connected, add mode check and BW check in mode_valid_ctx() to
> ensure DP's cfg is usable.
>
> For example: Some DP's mode(1920x1080 60HZ 138.5 MHz) gives to drm,
> however, the GPU is configured for 148MHz in display_ctrl_adjust() by
> looking up the table of struct hibmc_pll_table{}. This difference will
> cause the DP to not display because the clock the DP gets via drm frame
> is 138MHz.
>
> Fixes: f9698f802e50 ("drm/hisilicon/hibmc: Restructuring the header dp_reg.h")
> Signed-off-by: Baihan Li <libaihan@huawei.com>
> Signed-off-by: Yongbang Shi <shiyongbang@huawei.com>
> ---
> drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c | 10 ++++
> drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.h | 6 +++
> .../gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c | 51 +++++++++++++++++++
> 3 files changed, 67 insertions(+)
>
> diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c
> index b4d612047f36..7fbd51ffd778 100644
> --- a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c
> +++ b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c
> @@ -276,6 +276,16 @@ void hibmc_dp_reset_link(struct hibmc_dp *dp)
> dp->dp_dev->link.status.channel_equalized = false;
> }
>
> +u8 hibmc_dp_get_link_rate(struct hibmc_dp *dp)
> +{
> + return dp->dp_dev->link.cap.link_rate;
> +}
> +
> +u8 hibmc_dp_get_lanes(struct hibmc_dp *dp)
> +{
> + return dp->dp_dev->link.cap.lanes;
> +}
> +
> static const struct hibmc_dp_color_raw g_rgb_raw[] = {
> {CBAR_COLOR_BAR, 0x000, 0x000, 0x000},
> {CBAR_WHITE, 0xfff, 0xfff, 0xfff},
> diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.h b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.h
> index 9b45e88e47e4..0059a2648a38 100644
> --- a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.h
> +++ b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.h
> @@ -12,6 +12,10 @@
> #include <drm/drm_print.h>
> #include <drm/display/drm_dp_helper.h>
>
> +/* 27 * 10000000 * 80% = 216000000 */
> +#define DP_MODE_VALI_CAL 216000000
> +#define BPP_24 24
> +
> struct hibmc_dp_dev;
>
> enum hibmc_dp_cbar_pattern {
> @@ -62,5 +66,7 @@ void hibmc_dp_reset_link(struct hibmc_dp *dp);
> void hibmc_dp_hpd_cfg(struct hibmc_dp *dp);
> void hibmc_dp_enable_int(struct hibmc_dp *dp);
> void hibmc_dp_disable_int(struct hibmc_dp *dp);
> +u8 hibmc_dp_get_link_rate(struct hibmc_dp *dp);
> +u8 hibmc_dp_get_lanes(struct hibmc_dp *dp);
>
> #endif
> diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c
> index 354e18bb2998..99b30a6c7e06 100644
> --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c
> +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c
> @@ -15,6 +15,28 @@
>
> #define DP_MASKED_SINK_HPD_PLUG_INT BIT(2)
>
> +struct hibmc_dp_disp_clk {
> + u16 hdisplay;
> + u16 vdisplay;
> + u32 clock;
> +};
> +
> +static const struct hibmc_dp_disp_clk hibmc_dp_clk_table[] = {
> + {640, 480, 25175}, /* 25175 khz */
> + {800, 600, 40000}, /* 40000 khz */
> + {1024, 768, 65000}, /* 65000 khz */
> + {1152, 864, 80000}, /* 80000 khz */
> + {1280, 768, 79500}, /* 79500 khz */
> + {1280, 720, 74250}, /* 74250 khz */
> + {1280, 960, 108000}, /* 108000 khz */
> + {1280, 1024, 108000}, /* 108000 khz */
> + {1440, 900, 106500}, /* 106500 khz */
> + {1600, 900, 108000}, /* 108000 khz */
> + {1600, 1200, 162000}, /* 162000 khz */
> + {1920, 1080, 148500}, /* 148500 khz */
> + {1920, 1200, 193250}, /* 193250 khz */
> +};
I generally think that these kind of tables are too limiting. Please try
to achieve the same by checking the clock with the PLL code instead of
checking the modes against the table.
> +
> static int hibmc_dp_connector_get_modes(struct drm_connector *connector)
> {
> const struct drm_edid *drm_edid;
> @@ -42,9 +64,38 @@ static int hibmc_dp_detect(struct drm_connector *connector,
> return connector_status_disconnected;
> }
>
> +static int hibmc_dp_mode_valid(struct drm_connector *connector,
> + const struct drm_display_mode *mode,
> + struct drm_modeset_acquire_ctx *ctx,
> + enum drm_mode_status *status)
> +{
> + struct hibmc_dp *dp = to_hibmc_dp(connector);
> + u64 cur_val, max_val;
> +
> + /* check DP link BW */
> + cur_val = (u64)mode->htotal * mode->vtotal * drm_mode_vrefresh(mode) * BPP_24;
> + max_val = (u64)hibmc_dp_get_link_rate(dp) * DP_MODE_VALI_CAL * hibmc_dp_get_lanes(dp);
> +
> + *status = cur_val > max_val ? MODE_CLOCK_HIGH : MODE_OK;
> +
> + /* check the clock */
> + for (size_t i = 0; i < ARRAY_SIZE(hibmc_dp_clk_table); i++) {
> + if (hibmc_dp_clk_table[i].hdisplay == mode->hdisplay &&
> + hibmc_dp_clk_table[i].vdisplay == mode->vdisplay) {
> + if (hibmc_dp_clk_table[i].clock != mode->clock) {
> + *status = MODE_CLOCK_RANGE;
> + return 0;
> + }
> + }
> + }
> +
> + return 0;
> +}
> +
> static const struct drm_connector_helper_funcs hibmc_dp_conn_helper_funcs = {
> .get_modes = hibmc_dp_connector_get_modes,
> .detect_ctx = hibmc_dp_detect,
> + .mode_valid_ctx = hibmc_dp_mode_valid,
> };
>
> static int hibmc_dp_late_register(struct drm_connector *connector)
> --
> 2.33.0
>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v3 drm-dp 08/11] drm/hisilicon/hibmc: fix no showing when no connectors connected
2025-07-18 6:51 ` [PATCH v3 drm-dp 08/11] drm/hisilicon/hibmc: fix no showing when no connectors connected Yongbang Shi
@ 2025-07-26 16:03 ` Dmitry Baryshkov
2025-08-01 9:24 ` Yongbang Shi
0 siblings, 1 reply; 24+ messages in thread
From: Dmitry Baryshkov @ 2025-07-26 16:03 UTC (permalink / raw)
To: Yongbang Shi
Cc: xinliang.liu, tiantao6, maarten.lankhorst, mripard, tzimmermann,
airlied, daniel, kong.kongxinwei, liangjian010, chenjianmin,
fengsheng5, libaihan, shenjian15, shaojijie, jani.nikula,
dri-devel, linux-kernel
On Fri, Jul 18, 2025 at 02:51:22PM +0800, Yongbang Shi wrote:
> From: Baihan Li <libaihan@huawei.com>
>
> Our chip support KVM over IP feature, so hibmc diiver need to support
I assume that KVM-over-IP doesnt provide EDID reads. This needs to be
stated in the commit message.
> displaying without any connectors plugged in. If no connectors connected,
> set the vdac connector status to 'connected' to handle BMC KVM. Use
> is_connected to check all physical outputs.
> For get_modes: using BMC modes for connector if no display is attached to
> phys VGA cable, otherwise use EDID modes by drm_connector_helper_get_modes.
>
> Fixes: 4c962bc929f1 ("drm/hisilicon/hibmc: Add vga connector detect functions")
> Signed-off-by: Baihan Li <libaihan@huawei.com>
> Signed-off-by: Yongbang Shi <shiyongbang@huawei.com>
> ---
> ChangeLog:
> v2 -> v3:
> - fix hibmc_connector_get_modes() and hibmc_vdac_detect() to realize BMC KVM, suggested by Dmitry Baryshkov.
> ---
> .../gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c | 5 +-
> .../gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h | 4 ++
> .../gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c | 55 +++++++++++++------
> 3 files changed, 45 insertions(+), 19 deletions(-)
>
> diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c
> index 99b30a6c7e06..262ebe6138f0 100644
> --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c
> +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c
> @@ -58,9 +58,12 @@ static int hibmc_dp_detect(struct drm_connector *connector,
> {
> struct hibmc_drm_private *priv = to_hibmc_drm_private(connector->dev);
>
> - if (!hibmc_dp_detect_link(&priv->dp))
> + if (!hibmc_dp_detect_link(&priv->dp)) {
> + priv->is_connected |= BIT(0);
Magic value BIT(0)
> return connector_status_connected;
> + }
>
> + priv->is_connected &= ~BIT(0);
> return connector_status_disconnected;
> }
>
> diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
> index ca8502e2760c..d68588ecec9b 100644
> --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
> +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
> @@ -31,6 +31,7 @@ struct hibmc_vdac {
> struct drm_connector connector;
> struct i2c_adapter adapter;
> struct i2c_algo_bit_data bit_data;
> + int phys_status;
> };
>
> struct hibmc_drm_private {
> @@ -43,6 +44,9 @@ struct hibmc_drm_private {
> struct drm_crtc crtc;
> struct hibmc_vdac vdac;
> struct hibmc_dp dp;
> +
> + /* VGA and DP phys connect status, BIT(0) is DP, BIT(1) is VGA */
#define those.
> + int is_connected;
And you need a lock around this one, otherwise you might get a race
between DP's and VGA's code setting and clearing bits here.
> };
>
> static inline struct hibmc_vdac *to_hibmc_vdac(struct drm_connector *connector)
> diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
> index 841e81f47b68..3cdf640d1785 100644
> --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
> +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
> @@ -25,27 +25,18 @@
> static int hibmc_connector_get_modes(struct drm_connector *connector)
> {
> struct hibmc_vdac *vdac = to_hibmc_vdac(connector);
> - const struct drm_edid *drm_edid;
> int count;
>
> - drm_edid = drm_edid_read_ddc(connector, &vdac->adapter);
> -
> - drm_edid_connector_update(connector, drm_edid);
> -
> - if (drm_edid) {
> - count = drm_edid_connector_add_modes(connector);
> - if (count)
> - goto out;
> + if (vdac->phys_status == connector_status_connected) {
> + count = drm_connector_helper_get_modes(connector);
> + } else {
> + drm_edid_connector_update(connector, NULL);
> + count = drm_add_modes_noedid(connector,
> + connector->dev->mode_config.max_width,
> + connector->dev->mode_config.max_height);
> + drm_set_preferred_mode(connector, 1024, 768); // 1024x768
> }
>
> - count = drm_add_modes_noedid(connector,
> - connector->dev->mode_config.max_width,
> - connector->dev->mode_config.max_height);
> - drm_set_preferred_mode(connector, 1024, 768);
> -
> -out:
> - drm_edid_free(drm_edid);
> -
> return count;
> }
>
> @@ -57,10 +48,38 @@ static void hibmc_connector_destroy(struct drm_connector *connector)
> drm_connector_cleanup(connector);
> }
>
> +static int hibmc_vdac_detect(struct drm_connector *connector,
> + struct drm_modeset_acquire_ctx *ctx,
> + bool force)
> +{
> + struct hibmc_drm_private *priv = to_hibmc_drm_private(connector->dev);
> + struct hibmc_vdac *vdac = to_hibmc_vdac(connector);
> + enum drm_connector_status status;
> +
> + status = drm_connector_helper_detect_from_ddc(connector, ctx, force);
> +
> + vdac->phys_status = status;
> +
> + if (status == connector_status_connected) {
> + priv->is_connected |= BIT(1);
> + return connector_status_connected;
> + }
> +
> + priv->is_connected &= ~BIT(1);
> +
> + /* if all connectors are disconnected,
> + * return connected to support BMC KVM display.
> + */
> + if (!priv->is_connected)
> + return connector_status_connected;
> +
> + return connector_status_disconnected;
> +}
> +
> static const struct drm_connector_helper_funcs
> hibmc_connector_helper_funcs = {
> .get_modes = hibmc_connector_get_modes,
> - .detect_ctx = drm_connector_helper_detect_from_ddc,
> + .detect_ctx = hibmc_vdac_detect,
> };
>
> static const struct drm_connector_funcs hibmc_connector_funcs = {
> --
> 2.33.0
>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v3 drm-dp 09/11] drm/hisilicon/hibmc: fix no showing problem with loading hibmc manually
2025-07-18 6:51 ` [PATCH v3 drm-dp 09/11] drm/hisilicon/hibmc: fix no showing problem with loading hibmc manually Yongbang Shi
@ 2025-07-26 16:04 ` Dmitry Baryshkov
0 siblings, 0 replies; 24+ messages in thread
From: Dmitry Baryshkov @ 2025-07-26 16:04 UTC (permalink / raw)
To: Yongbang Shi
Cc: xinliang.liu, tiantao6, maarten.lankhorst, mripard, tzimmermann,
airlied, daniel, kong.kongxinwei, liangjian010, chenjianmin,
fengsheng5, libaihan, shenjian15, shaojijie, jani.nikula,
dri-devel, linux-kernel
On Fri, Jul 18, 2025 at 02:51:23PM +0800, Yongbang Shi wrote:
> From: Baihan Li <libaihan@huawei.com>
>
> When using command rmmod and insmod, there is no showing in second time
> insmoding. Because DP controller won't send HPD signals, if connection
> doesn't change or controller isn't reset. So add reset before unreset
> in hibmc_dp_hw_init().
>
> Fixes: 3c7623fb5bb6 ("drm/hisilicon/hibmc: Enable this hot plug detect of irq feature")
> Signed-off-by: Baihan Li <libaihan@huawei.com>
> Signed-off-by: Yongbang Shi <shiyongbang@huawei.com>
> ---
> ChangeLog:
> v2 -> v3:
> - fix the issue commit ID, suggested by Dmitry Baryshkov.
> ---
> drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c | 2 ++
> 1 file changed, 2 insertions(+)
>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v3 drm-dp 10/11] drm/hisilicon/hibmc: adapting modification for the former commit
2025-07-18 6:51 ` [PATCH v3 drm-dp 10/11] drm/hisilicon/hibmc: adapting modification for the former commit Yongbang Shi
@ 2025-07-26 16:05 ` Dmitry Baryshkov
2025-08-01 9:25 ` Yongbang Shi
0 siblings, 1 reply; 24+ messages in thread
From: Dmitry Baryshkov @ 2025-07-26 16:05 UTC (permalink / raw)
To: Yongbang Shi
Cc: xinliang.liu, tiantao6, maarten.lankhorst, mripard, tzimmermann,
airlied, daniel, kong.kongxinwei, liangjian010, chenjianmin,
fengsheng5, libaihan, shenjian15, shaojijie, jani.nikula,
dri-devel, linux-kernel
On Fri, Jul 18, 2025 at 02:51:24PM +0800, Yongbang Shi wrote:
> From: Baihan Li <libaihan@huawei.com>
>
> Add colorbar disable operation before reset chontroller, to make sure
> colorbar status is clear in the DP init, so if rmmod the driver and the
> previous colorbar configuration will not affect the next time insmod the
> driver.
In this one and in the next one please fix commit subjects. Can't parse
them.
>
> Fixes: 3c7623fb5bb6 ("drm/hisilicon/hibmc: Enable this hot plug detect of irq feature")
> Signed-off-by: Baihan Li <libaihan@huawei.com>
> Signed-off-by: Yongbang Shi <shiyongbang@huawei.com>
> ---
> ChangeLog:
> v2 -> v3:
> - fix the issue commit ID, suggested by Dmitry Baryshkov.
> - split into 2 commits, suggested by Dmitry Baryshkov.
> - add more comments in commit log, suggested by Dmitry Baryshkov.
> ---
> drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c
> index 36daf7542d40..85499f1ace8b 100644
> --- a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c
> +++ b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c
> @@ -180,6 +180,8 @@ int hibmc_dp_hw_init(struct hibmc_dp *dp)
> /* int init */
> writel(0, dp_dev->base + HIBMC_DP_INTR_ENABLE);
> writel(HIBMC_DP_INT_RST, dp_dev->base + HIBMC_DP_INTR_ORIGINAL_STATUS);
> + /* clr colorbar */
> + writel(0, dp_dev->base + HIBMC_DP_COLOR_BAR_CTRL);
> /* rst */
> writel(0, dp_dev->base + HIBMC_DP_DPTX_RST_CTRL);
> usleep_range(30, 50);
> --
> 2.33.0
>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v3 drm-dp 02/11] drm/hisilicon/hibmc: fix dp probabilistical detect errors after HPD irq
2025-07-26 15:03 ` Dmitry Baryshkov
@ 2025-08-01 9:21 ` Yongbang Shi
0 siblings, 0 replies; 24+ messages in thread
From: Yongbang Shi @ 2025-08-01 9:21 UTC (permalink / raw)
To: Dmitry Baryshkov
Cc: xinliang.liu, tiantao6, maarten.lankhorst, mripard, tzimmermann,
airlied, daniel, kong.kongxinwei, liangjian010, chenjianmin,
fengsheng5, libaihan, shenjian15, shaojijie, jani.nikula,
dri-devel, linux-kernel, shiyongbang
> On Fri, Jul 18, 2025 at 02:51:16PM +0800, Yongbang Shi wrote:
>> From: Baihan Li <libaihan@huawei.com>
>>
>> The debouncing when HPD pulled out still remains sometimes, 200ms still can
>> not ensure helper_detect() is correct. Add hibmc_dp_detect_link() in
>> detect_ctx(), which is to try dp link training.
> I'm not sure if I follow the commit message. Anyway, link training
> should be a part of atomic_(pre)_enable, not a detect_ctx.
Okay, I will change it. thanks for your advice!
The problem is that when I unpluged the connector, sometimes the drm_connector_helper_detect_from_ddc()
return connected in dp's detect_ctx().
>> Fixes: 3c7623fb5bb6 ("drm/hisilicon/hibmc: Enable this hot plug detect of irq feature")
>> Signed-off-by: Baihan Li <libaihan@huawei.com>
>> Signed-off-by: Yongbang Shi <shiyongbang@huawei.com>
>> ---
>> drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c | 27 +++++++++++++++----
>> drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.h | 2 ++
>> .../gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c | 10 ++++---
>> 3 files changed, 30 insertions(+), 9 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c
>> index 8f0daec7d174..2d2fb6e759c3 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"
>> @@ -162,6 +163,8 @@ int hibmc_dp_hw_init(struct hibmc_dp *dp)
>>
>> mutex_init(&dp_dev->lock);
>>
>> + drmm_mutex_init(drm_dev, &dp->link_train_mutex);
>> +
>> dp->dp_dev = dp_dev;
>>
>> dp_dev->dev = drm_dev;
>> @@ -238,19 +241,33 @@ void hibmc_dp_display_en(struct hibmc_dp *dp, bool enable)
>> msleep(50);
>> }
>>
>> -int hibmc_dp_mode_set(struct hibmc_dp *dp, struct drm_display_mode *mode)
>> +int hibmc_dp_detect_link(struct hibmc_dp *dp)
>> {
>> struct hibmc_dp_dev *dp_dev = dp->dp_dev;
>> - int ret;
>> + int ret = 0;
>> +
>> + mutex_lock(&dp->link_train_mutex);
>>
>> if (!dp_dev->link.status.channel_equalized) {
>> ret = hibmc_dp_link_training(dp_dev);
>> - if (ret) {
>> + if (ret)
>> drm_err(dp->drm_dev, "dp link training failed, ret: %d\n", ret);
>> - return ret;
>> - }
>> }
>>
>> + mutex_unlock(&dp->link_train_mutex);
>> +
>> + return ret;
>> +}
>> +
>> +int hibmc_dp_mode_set(struct hibmc_dp *dp, struct drm_display_mode *mode)
>> +{
>> + struct hibmc_dp_dev *dp_dev = dp->dp_dev;
>> + int ret;
>> +
>> + ret = hibmc_dp_detect_link(dp);
>> + if (ret)
>> + return ret;
>> +
>> hibmc_dp_display_en(dp, false);
>> hibmc_dp_link_cfg(dp_dev, mode);
>>
>> diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.h b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.h
>> index 665f5b166dfb..9b45e88e47e4 100644
>> --- a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.h
>> +++ b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.h
>> @@ -50,9 +50,11 @@ struct hibmc_dp {
>> struct drm_dp_aux aux;
>> struct hibmc_dp_cbar_cfg cfg;
>> u32 irq_status;
>> + struct mutex link_train_mutex; /* link training mutex */
>> };
>>
>> int hibmc_dp_hw_init(struct hibmc_dp *dp);
>> +int hibmc_dp_detect_link(struct hibmc_dp *dp);
>> int hibmc_dp_mode_set(struct hibmc_dp *dp, struct drm_display_mode *mode);
>> void hibmc_dp_display_en(struct hibmc_dp *dp, bool enable);
>> void hibmc_dp_set_cbar(struct hibmc_dp *dp, const struct hibmc_dp_cbar_cfg *cfg);
>> diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c
>> index d06832e62e96..354e18bb2998 100644
>> --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c
>> +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c
>> @@ -34,9 +34,12 @@ static int hibmc_dp_connector_get_modes(struct drm_connector *connector)
>> static int hibmc_dp_detect(struct drm_connector *connector,
>> struct drm_modeset_acquire_ctx *ctx, bool force)
>> {
>> - mdelay(200);
>> + struct hibmc_drm_private *priv = to_hibmc_drm_private(connector->dev);
>>
>> - return drm_connector_helper_detect_from_ddc(connector, ctx, force);
>> + if (!hibmc_dp_detect_link(&priv->dp))
>> + return connector_status_connected;
>> +
>> + return connector_status_disconnected;
>> }
>>
>> static const struct drm_connector_helper_funcs hibmc_dp_conn_helper_funcs = {
>> @@ -128,8 +131,7 @@ irqreturn_t hibmc_dp_hpd_isr(int irq, void *arg)
>> hibmc_dp_reset_link(&priv->dp);
>> }
>>
>> - if (dev->registered)
>> - drm_connector_helper_hpd_irq_event(&priv->dp.connector);
>> + drm_connector_helper_hpd_irq_event(&priv->dp.connector);
>>
>> drm_dev_exit(idx);
>>
>> --
>> 2.33.0
>>
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v3 drm-dp 05/11] drm/hisilicon/hibmc: fix rare monitors cannot display problem
2025-07-26 15:09 ` Dmitry Baryshkov
@ 2025-08-01 9:22 ` Yongbang Shi
0 siblings, 0 replies; 24+ messages in thread
From: Yongbang Shi @ 2025-08-01 9:22 UTC (permalink / raw)
To: Dmitry Baryshkov
Cc: xinliang.liu, tiantao6, maarten.lankhorst, mripard, tzimmermann,
airlied, daniel, kong.kongxinwei, liangjian010, chenjianmin,
fengsheng5, libaihan, shenjian15, shaojijie, jani.nikula,
dri-devel, linux-kernel, shiyongbang
> On Fri, Jul 18, 2025 at 02:51:19PM +0800, Yongbang Shi wrote:
>> From: Baihan Li <libaihan@huawei.com>
>>
>> In some case, the dp link training success at 8.1Gbps, but the sink's
>> maximum supported rate is less than 8.1G. So change the default 8.1Gbps
>> link rate to the rate that reads from devices' capabilities.
> You are doing more than changing default link rate. Please split away
> non-related changes. This is especially imporant for Fixes commits.
OKay! I got it. I will move these to the next feature series。
>> Fixes: 54063d86e036 ("drm/hisilicon/hibmc: add dp link moduel in hibmc drivers")
>> Signed-off-by: Baihan Li <libaihan@huawei.com>
>> Signed-off-by: Yongbang Shi <shiyongbang@huawei.com>
>> ---
>> drivers/gpu/drm/hisilicon/hibmc/dp/dp_comm.h | 4 ++-
>> drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c | 6 +---
>> drivers/gpu/drm/hisilicon/hibmc/dp/dp_link.c | 33 +++++++++++++------
>> .../gpu/drm/hisilicon/hibmc/dp/dp_serdes.c | 12 -------
>> 4 files changed, 27 insertions(+), 28 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_comm.h b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_comm.h
>> index 4add05c7f161..18a961466ff0 100644
>> --- a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_comm.h
>> +++ b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_comm.h
>> @@ -25,6 +25,9 @@ struct hibmc_link_status {
>> struct hibmc_link_cap {
>> u8 link_rate;
>> u8 lanes;
>> + int rx_dpcd_revision;
>> + bool is_tps3;
>> + bool is_tps4;
>> };
>>
>> struct hibmc_dp_link {
>> @@ -62,7 +65,6 @@ struct hibmc_dp_dev {
>>
>> void hibmc_dp_aux_init(struct hibmc_dp *dp);
>> int hibmc_dp_link_training(struct hibmc_dp_dev *dp);
>> -int hibmc_dp_serdes_init(struct hibmc_dp_dev *dp);
>> int hibmc_dp_serdes_rate_switch(u8 rate, struct hibmc_dp_dev *dp);
>> int hibmc_dp_serdes_set_tx_cfg(struct hibmc_dp_dev *dp, u8 train_set[HIBMC_DP_LANE_NUM_MAX]);
>>
>> diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c
>> index 2d2fb6e759c3..b4d612047f36 100644
>> --- a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c
>> +++ b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c
>> @@ -155,7 +155,6 @@ int hibmc_dp_hw_init(struct hibmc_dp *dp)
>> {
>> struct drm_device *drm_dev = dp->drm_dev;
>> struct hibmc_dp_dev *dp_dev;
>> - int ret;
>>
>> dp_dev = devm_kzalloc(drm_dev->dev, sizeof(struct hibmc_dp_dev), GFP_KERNEL);
>> if (!dp_dev)
>> @@ -169,13 +168,10 @@ int hibmc_dp_hw_init(struct hibmc_dp *dp)
>>
>> dp_dev->dev = drm_dev;
>> dp_dev->base = dp->mmio + HIBMC_DP_OFFSET;
>> + dp_dev->serdes_base = dp_dev->base + HIBMC_DP_HOST_OFFSET;
>>
>> hibmc_dp_aux_init(dp);
>>
>> - ret = hibmc_dp_serdes_init(dp_dev);
>> - if (ret)
>> - return ret;
>> -
>> dp_dev->link.cap.lanes = 0x2;
>> dp_dev->link.cap.link_rate = DP_LINK_BW_8_1;
>>
>> diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_link.c b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_link.c
>> index 74f7832ea53e..6c69fa2ae9cf 100644
>> --- a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_link.c
>> +++ b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_link.c
>> @@ -39,6 +39,14 @@ static int hibmc_dp_link_training_configure(struct hibmc_dp_dev *dp)
>> /* enhanced frame */
>> hibmc_dp_reg_write_field(dp, HIBMC_DP_VIDEO_CTRL, HIBMC_DP_CFG_STREAM_FRAME_MODE, 0x1);
>>
>> + ret = hibmc_dp_get_serdes_rate_cfg(dp);
>> + if (ret < 0)
>> + return ret;
>> +
>> + ret = hibmc_dp_serdes_rate_switch(ret, dp);
>> + if (ret)
>> + return ret;
>> +
>> /* set rate and lane count */
>> buf[0] = dp->link.cap.link_rate;
>> buf[1] = DP_LANE_COUNT_ENHANCED_FRAME_EN | dp->link.cap.lanes;
>> @@ -325,6 +333,20 @@ static int hibmc_dp_link_downgrade_training_eq(struct hibmc_dp_dev *dp)
>> return hibmc_dp_link_reduce_rate(dp);
>> }
>>
>> +static void hibmc_dp_update_caps(struct hibmc_dp_dev *dp)
>> +{
>> + dp->link.cap.rx_dpcd_revision = dp->dpcd[DP_DPCD_REV];
>> +
>> + dp->link.cap.is_tps3 = (dp->dpcd[DP_DPCD_REV] >= DP_DPCD_REV_13) &&
>> + (dp->dpcd[DP_MAX_LANE_COUNT] & DP_TPS3_SUPPORTED);
>> + dp->link.cap.is_tps4 = (dp->dpcd[DP_DPCD_REV] >= DP_DPCD_REV_14) &&
>> + (dp->dpcd[DP_MAX_DOWNSPREAD] & DP_TPS4_SUPPORTED);
>> + dp->link.cap.link_rate = dp->dpcd[DP_MAX_LINK_RATE];
>> + dp->link.cap.lanes = dp->dpcd[DP_MAX_LANE_COUNT] & DP_MAX_LANE_COUNT_MASK;
>> + if (dp->link.cap.lanes > HIBMC_DP_LANE_NUM_MAX)
>> + dp->link.cap.lanes = HIBMC_DP_LANE_NUM_MAX;
>> +}
>> +
>> int hibmc_dp_link_training(struct hibmc_dp_dev *dp)
>> {
>> struct hibmc_dp_link *link = &dp->link;
>> @@ -334,16 +356,7 @@ int hibmc_dp_link_training(struct hibmc_dp_dev *dp)
>> if (ret)
>> drm_err(dp->dev, "dp aux read dpcd failed, ret: %d\n", ret);
>>
>> - dp->link.cap.link_rate = dp->dpcd[DP_MAX_LINK_RATE];
>> - dp->link.cap.lanes = 0x2;
>> -
>> - ret = hibmc_dp_get_serdes_rate_cfg(dp);
>> - if (ret < 0)
>> - return ret;
>> -
>> - ret = hibmc_dp_serdes_rate_switch(ret, dp);
>> - if (ret)
>> - return ret;
>> + hibmc_dp_update_caps(dp);
>>
>> while (true) {
>> ret = hibmc_dp_link_training_cr_pre(dp);
>> diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_serdes.c b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_serdes.c
>> index 676059d4c1e6..8191233aa965 100644
>> --- a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_serdes.c
>> +++ b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_serdes.c
>> @@ -57,15 +57,3 @@ int hibmc_dp_serdes_rate_switch(u8 rate, struct hibmc_dp_dev *dp)
>>
>> return 0;
>> }
>> -
>> -int hibmc_dp_serdes_init(struct hibmc_dp_dev *dp)
>> -{
>> - dp->serdes_base = dp->base + HIBMC_DP_HOST_OFFSET;
>> -
>> - writel(FIELD_PREP(HIBMC_DP_PMA_TXDEEMPH, DP_SERDES_VOL0_PRE0),
>> - dp->serdes_base + HIBMC_DP_PMA_LANE0_OFFSET);
>> - writel(FIELD_PREP(HIBMC_DP_PMA_TXDEEMPH, DP_SERDES_VOL0_PRE0),
>> - dp->serdes_base + HIBMC_DP_PMA_LANE1_OFFSET);
>> -
>> - return hibmc_dp_serdes_rate_switch(DP_SERDES_BW_8_1, dp);
>> -}
>> --
>> 2.33.0
>>
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v3 drm-dp 06/11] drm/hisilicon/hibmc: add dp mode valid check
2025-07-26 15:56 ` Dmitry Baryshkov
@ 2025-08-01 9:22 ` Yongbang Shi
0 siblings, 0 replies; 24+ messages in thread
From: Yongbang Shi @ 2025-08-01 9:22 UTC (permalink / raw)
To: Dmitry Baryshkov
Cc: xinliang.liu, tiantao6, maarten.lankhorst, mripard, tzimmermann,
airlied, daniel, kong.kongxinwei, liangjian010, chenjianmin,
fengsheng5, libaihan, shenjian15, shaojijie, jani.nikula,
dri-devel, linux-kernel, shiyongbang
> On Fri, Jul 18, 2025 at 02:51:20PM +0800, Yongbang Shi wrote:
>> From: Baihan Li <libaihan@huawei.com>
>>
>> If DP is connected, add mode check and BW check in mode_valid_ctx() to
>> ensure DP's cfg is usable.
>>
>> For example: Some DP's mode(1920x1080 60HZ 138.5 MHz) gives to drm,
>> however, the GPU is configured for 148MHz in display_ctrl_adjust() by
>> looking up the table of struct hibmc_pll_table{}. This difference will
>> cause the DP to not display because the clock the DP gets via drm frame
>> is 138MHz.
>>
>> Fixes: f9698f802e50 ("drm/hisilicon/hibmc: Restructuring the header dp_reg.h")
>> Signed-off-by: Baihan Li <libaihan@huawei.com>
>> Signed-off-by: Yongbang Shi <shiyongbang@huawei.com>
>> ---
>> drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c | 10 ++++
>> drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.h | 6 +++
>> .../gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c | 51 +++++++++++++++++++
>> 3 files changed, 67 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c
>> index b4d612047f36..7fbd51ffd778 100644
>> --- a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c
>> +++ b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c
>> @@ -276,6 +276,16 @@ void hibmc_dp_reset_link(struct hibmc_dp *dp)
>> dp->dp_dev->link.status.channel_equalized = false;
>> }
>>
>> +u8 hibmc_dp_get_link_rate(struct hibmc_dp *dp)
>> +{
>> + return dp->dp_dev->link.cap.link_rate;
>> +}
>> +
>> +u8 hibmc_dp_get_lanes(struct hibmc_dp *dp)
>> +{
>> + return dp->dp_dev->link.cap.lanes;
>> +}
>> +
>> static const struct hibmc_dp_color_raw g_rgb_raw[] = {
>> {CBAR_COLOR_BAR, 0x000, 0x000, 0x000},
>> {CBAR_WHITE, 0xfff, 0xfff, 0xfff},
>> diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.h b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.h
>> index 9b45e88e47e4..0059a2648a38 100644
>> --- a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.h
>> +++ b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.h
>> @@ -12,6 +12,10 @@
>> #include <drm/drm_print.h>
>> #include <drm/display/drm_dp_helper.h>
>>
>> +/* 27 * 10000000 * 80% = 216000000 */
>> +#define DP_MODE_VALI_CAL 216000000
>> +#define BPP_24 24
>> +
>> struct hibmc_dp_dev;
>>
>> enum hibmc_dp_cbar_pattern {
>> @@ -62,5 +66,7 @@ void hibmc_dp_reset_link(struct hibmc_dp *dp);
>> void hibmc_dp_hpd_cfg(struct hibmc_dp *dp);
>> void hibmc_dp_enable_int(struct hibmc_dp *dp);
>> void hibmc_dp_disable_int(struct hibmc_dp *dp);
>> +u8 hibmc_dp_get_link_rate(struct hibmc_dp *dp);
>> +u8 hibmc_dp_get_lanes(struct hibmc_dp *dp);
>>
>> #endif
>> diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c
>> index 354e18bb2998..99b30a6c7e06 100644
>> --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c
>> +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c
>> @@ -15,6 +15,28 @@
>>
>> #define DP_MASKED_SINK_HPD_PLUG_INT BIT(2)
>>
>> +struct hibmc_dp_disp_clk {
>> + u16 hdisplay;
>> + u16 vdisplay;
>> + u32 clock;
>> +};
>> +
>> +static const struct hibmc_dp_disp_clk hibmc_dp_clk_table[] = {
>> + {640, 480, 25175}, /* 25175 khz */
>> + {800, 600, 40000}, /* 40000 khz */
>> + {1024, 768, 65000}, /* 65000 khz */
>> + {1152, 864, 80000}, /* 80000 khz */
>> + {1280, 768, 79500}, /* 79500 khz */
>> + {1280, 720, 74250}, /* 74250 khz */
>> + {1280, 960, 108000}, /* 108000 khz */
>> + {1280, 1024, 108000}, /* 108000 khz */
>> + {1440, 900, 106500}, /* 106500 khz */
>> + {1600, 900, 108000}, /* 108000 khz */
>> + {1600, 1200, 162000}, /* 162000 khz */
>> + {1920, 1080, 148500}, /* 148500 khz */
>> + {1920, 1200, 193250}, /* 193250 khz */
>> +};
> I generally think that these kind of tables are too limiting. Please try
> to achieve the same by checking the clock with the PLL code instead of
> checking the modes against the table.
Okay!
>> +
>> static int hibmc_dp_connector_get_modes(struct drm_connector *connector)
>> {
>> const struct drm_edid *drm_edid;
>> @@ -42,9 +64,38 @@ static int hibmc_dp_detect(struct drm_connector *connector,
>> return connector_status_disconnected;
>> }
>>
>> +static int hibmc_dp_mode_valid(struct drm_connector *connector,
>> + const struct drm_display_mode *mode,
>> + struct drm_modeset_acquire_ctx *ctx,
>> + enum drm_mode_status *status)
>> +{
>> + struct hibmc_dp *dp = to_hibmc_dp(connector);
>> + u64 cur_val, max_val;
>> +
>> + /* check DP link BW */
>> + cur_val = (u64)mode->htotal * mode->vtotal * drm_mode_vrefresh(mode) * BPP_24;
>> + max_val = (u64)hibmc_dp_get_link_rate(dp) * DP_MODE_VALI_CAL * hibmc_dp_get_lanes(dp);
>> +
>> + *status = cur_val > max_val ? MODE_CLOCK_HIGH : MODE_OK;
>> +
>> + /* check the clock */
>> + for (size_t i = 0; i < ARRAY_SIZE(hibmc_dp_clk_table); i++) {
>> + if (hibmc_dp_clk_table[i].hdisplay == mode->hdisplay &&
>> + hibmc_dp_clk_table[i].vdisplay == mode->vdisplay) {
>> + if (hibmc_dp_clk_table[i].clock != mode->clock) {
>> + *status = MODE_CLOCK_RANGE;
>> + return 0;
>> + }
>> + }
>> + }
>> +
>> + return 0;
>> +}
>> +
>> static const struct drm_connector_helper_funcs hibmc_dp_conn_helper_funcs = {
>> .get_modes = hibmc_dp_connector_get_modes,
>> .detect_ctx = hibmc_dp_detect,
>> + .mode_valid_ctx = hibmc_dp_mode_valid,
>> };
>>
>> static int hibmc_dp_late_register(struct drm_connector *connector)
>> --
>> 2.33.0
>>
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v3 drm-dp 08/11] drm/hisilicon/hibmc: fix no showing when no connectors connected
2025-07-26 16:03 ` Dmitry Baryshkov
@ 2025-08-01 9:24 ` Yongbang Shi
0 siblings, 0 replies; 24+ messages in thread
From: Yongbang Shi @ 2025-08-01 9:24 UTC (permalink / raw)
To: Dmitry Baryshkov
Cc: xinliang.liu, tiantao6, maarten.lankhorst, mripard, tzimmermann,
airlied, daniel, kong.kongxinwei, liangjian010, chenjianmin,
fengsheng5, libaihan, shenjian15, shaojijie, jani.nikula,
dri-devel, linux-kernel, shiyongbang
> On Fri, Jul 18, 2025 at 02:51:22PM +0800, Yongbang Shi wrote:
>> From: Baihan Li <libaihan@huawei.com>
>>
>> Our chip support KVM over IP feature, so hibmc diiver need to support
> I assume that KVM-over-IP doesnt provide EDID reads. This needs to be
> stated in the commit message.
Okay!
>> displaying without any connectors plugged in. If no connectors connected,
>> set the vdac connector status to 'connected' to handle BMC KVM. Use
>> is_connected to check all physical outputs.
>> For get_modes: using BMC modes for connector if no display is attached to
>> phys VGA cable, otherwise use EDID modes by drm_connector_helper_get_modes.
>>
>> Fixes: 4c962bc929f1 ("drm/hisilicon/hibmc: Add vga connector detect functions")
>> Signed-off-by: Baihan Li <libaihan@huawei.com>
>> Signed-off-by: Yongbang Shi <shiyongbang@huawei.com>
>> ---
>> ChangeLog:
>> v2 -> v3:
>> - fix hibmc_connector_get_modes() and hibmc_vdac_detect() to realize BMC KVM, suggested by Dmitry Baryshkov.
>> ---
>> .../gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c | 5 +-
>> .../gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h | 4 ++
>> .../gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c | 55 +++++++++++++------
>> 3 files changed, 45 insertions(+), 19 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c
>> index 99b30a6c7e06..262ebe6138f0 100644
>> --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c
>> +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c
>> @@ -58,9 +58,12 @@ static int hibmc_dp_detect(struct drm_connector *connector,
>> {
>> struct hibmc_drm_private *priv = to_hibmc_drm_private(connector->dev);
>>
>> - if (!hibmc_dp_detect_link(&priv->dp))
>> + if (!hibmc_dp_detect_link(&priv->dp)) {
>> + priv->is_connected |= BIT(0);
> Magic value BIT(0)
>
>> return connector_status_connected;
>> + }
>>
>> + priv->is_connected &= ~BIT(0);
>> return connector_status_disconnected;
>> }
>>
>> diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
>> index ca8502e2760c..d68588ecec9b 100644
>> --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
>> +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
>> @@ -31,6 +31,7 @@ struct hibmc_vdac {
>> struct drm_connector connector;
>> struct i2c_adapter adapter;
>> struct i2c_algo_bit_data bit_data;
>> + int phys_status;
>> };
>>
>> struct hibmc_drm_private {
>> @@ -43,6 +44,9 @@ struct hibmc_drm_private {
>> struct drm_crtc crtc;
>> struct hibmc_vdac vdac;
>> struct hibmc_dp dp;
>> +
>> + /* VGA and DP phys connect status, BIT(0) is DP, BIT(1) is VGA */
> #define those.
>
>> + int is_connected;
> And you need a lock around this one, otherwise you might get a race
> between DP's and VGA's code setting and clearing bits here.
Okay, thanks for your advice!
I will modify all of the above issues.
>> };
>>
>> static inline struct hibmc_vdac *to_hibmc_vdac(struct drm_connector *connector)
>> diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
>> index 841e81f47b68..3cdf640d1785 100644
>> --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
>> +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
>> @@ -25,27 +25,18 @@
>> static int hibmc_connector_get_modes(struct drm_connector *connector)
>> {
>> struct hibmc_vdac *vdac = to_hibmc_vdac(connector);
>> - const struct drm_edid *drm_edid;
>> int count;
>>
>> - drm_edid = drm_edid_read_ddc(connector, &vdac->adapter);
>> -
>> - drm_edid_connector_update(connector, drm_edid);
>> -
>> - if (drm_edid) {
>> - count = drm_edid_connector_add_modes(connector);
>> - if (count)
>> - goto out;
>> + if (vdac->phys_status == connector_status_connected) {
>> + count = drm_connector_helper_get_modes(connector);
>> + } else {
>> + drm_edid_connector_update(connector, NULL);
>> + count = drm_add_modes_noedid(connector,
>> + connector->dev->mode_config.max_width,
>> + connector->dev->mode_config.max_height);
>> + drm_set_preferred_mode(connector, 1024, 768); // 1024x768
>> }
>>
>> - count = drm_add_modes_noedid(connector,
>> - connector->dev->mode_config.max_width,
>> - connector->dev->mode_config.max_height);
>> - drm_set_preferred_mode(connector, 1024, 768);
>> -
>> -out:
>> - drm_edid_free(drm_edid);
>> -
>> return count;
>> }
>>
>> @@ -57,10 +48,38 @@ static void hibmc_connector_destroy(struct drm_connector *connector)
>> drm_connector_cleanup(connector);
>> }
>>
>> +static int hibmc_vdac_detect(struct drm_connector *connector,
>> + struct drm_modeset_acquire_ctx *ctx,
>> + bool force)
>> +{
>> + struct hibmc_drm_private *priv = to_hibmc_drm_private(connector->dev);
>> + struct hibmc_vdac *vdac = to_hibmc_vdac(connector);
>> + enum drm_connector_status status;
>> +
>> + status = drm_connector_helper_detect_from_ddc(connector, ctx, force);
>> +
>> + vdac->phys_status = status;
>> +
>> + if (status == connector_status_connected) {
>> + priv->is_connected |= BIT(1);
>> + return connector_status_connected;
>> + }
>> +
>> + priv->is_connected &= ~BIT(1);
>> +
>> + /* if all connectors are disconnected,
>> + * return connected to support BMC KVM display.
>> + */
>> + if (!priv->is_connected)
>> + return connector_status_connected;
>> +
>> + return connector_status_disconnected;
>> +}
>> +
>> static const struct drm_connector_helper_funcs
>> hibmc_connector_helper_funcs = {
>> .get_modes = hibmc_connector_get_modes,
>> - .detect_ctx = drm_connector_helper_detect_from_ddc,
>> + .detect_ctx = hibmc_vdac_detect,
>> };
>>
>> static const struct drm_connector_funcs hibmc_connector_funcs = {
>> --
>> 2.33.0
>>
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v3 drm-dp 10/11] drm/hisilicon/hibmc: adapting modification for the former commit
2025-07-26 16:05 ` Dmitry Baryshkov
@ 2025-08-01 9:25 ` Yongbang Shi
0 siblings, 0 replies; 24+ messages in thread
From: Yongbang Shi @ 2025-08-01 9:25 UTC (permalink / raw)
To: Dmitry Baryshkov
Cc: xinliang.liu, tiantao6, maarten.lankhorst, mripard, tzimmermann,
airlied, daniel, kong.kongxinwei, liangjian010, chenjianmin,
fengsheng5, libaihan, shenjian15, shaojijie, jani.nikula,
dri-devel, linux-kernel, shiyongbang
> On Fri, Jul 18, 2025 at 02:51:24PM +0800, Yongbang Shi wrote:
>> From: Baihan Li <libaihan@huawei.com>
>>
>> Add colorbar disable operation before reset chontroller, to make sure
>> colorbar status is clear in the DP init, so if rmmod the driver and the
>> previous colorbar configuration will not affect the next time insmod the
>> driver.
> In this one and in the next one please fix commit subjects. Can't parse
> them.
Sorry about that, I will fix them!
>> Fixes: 3c7623fb5bb6 ("drm/hisilicon/hibmc: Enable this hot plug detect of irq feature")
>> Signed-off-by: Baihan Li <libaihan@huawei.com>
>> Signed-off-by: Yongbang Shi <shiyongbang@huawei.com>
>> ---
>> ChangeLog:
>> v2 -> v3:
>> - fix the issue commit ID, suggested by Dmitry Baryshkov.
>> - split into 2 commits, suggested by Dmitry Baryshkov.
>> - add more comments in commit log, suggested by Dmitry Baryshkov.
>> ---
>> drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c | 2 ++
>> 1 file changed, 2 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c
>> index 36daf7542d40..85499f1ace8b 100644
>> --- a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c
>> +++ b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c
>> @@ -180,6 +180,8 @@ int hibmc_dp_hw_init(struct hibmc_dp *dp)
>> /* int init */
>> writel(0, dp_dev->base + HIBMC_DP_INTR_ENABLE);
>> writel(HIBMC_DP_INT_RST, dp_dev->base + HIBMC_DP_INTR_ORIGINAL_STATUS);
>> + /* clr colorbar */
>> + writel(0, dp_dev->base + HIBMC_DP_COLOR_BAR_CTRL);
>> /* rst */
>> writel(0, dp_dev->base + HIBMC_DP_DPTX_RST_CTRL);
>> usleep_range(30, 50);
>> --
>> 2.33.0
>>
^ permalink raw reply [flat|nested] 24+ messages in thread
end of thread, other threads:[~2025-08-01 9:25 UTC | newest]
Thread overview: 24+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-18 6:51 [PATCH v3 drm-dp 00/11] Fix hibmc driver bugs Yongbang Shi
2025-07-18 6:51 ` [PATCH v3 drm-dp 01/11] drm/hisilicon/hibmc: fix the i2c device resource leak when vdac init failed Yongbang Shi
2025-07-18 6:51 ` [PATCH v3 drm-dp 02/11] drm/hisilicon/hibmc: fix dp probabilistical detect errors after HPD irq Yongbang Shi
2025-07-26 15:03 ` Dmitry Baryshkov
2025-08-01 9:21 ` Yongbang Shi
2025-07-18 6:51 ` [PATCH v3 drm-dp 03/11] drm/hisilicon/hibmc: fix irq_request()'s irq name variable is local Yongbang Shi
2025-07-18 6:51 ` [PATCH v3 drm-dp 04/11] drm/hisilicon/hibmc: fix the hibmc loaded failed bug Yongbang Shi
2025-07-18 6:51 ` [PATCH v3 drm-dp 05/11] drm/hisilicon/hibmc: fix rare monitors cannot display problem Yongbang Shi
2025-07-26 15:09 ` Dmitry Baryshkov
2025-08-01 9:22 ` Yongbang Shi
2025-07-18 6:51 ` [PATCH v3 drm-dp 06/11] drm/hisilicon/hibmc: add dp mode valid check Yongbang Shi
2025-07-26 15:56 ` Dmitry Baryshkov
2025-08-01 9:22 ` Yongbang Shi
2025-07-18 6:51 ` [PATCH v3 drm-dp 07/11] drm/hisilicon/hibmc: fix dp and vga cannot show together Yongbang Shi
2025-07-18 6:51 ` [PATCH v3 drm-dp 08/11] drm/hisilicon/hibmc: fix no showing when no connectors connected Yongbang Shi
2025-07-26 16:03 ` Dmitry Baryshkov
2025-08-01 9:24 ` Yongbang Shi
2025-07-18 6:51 ` [PATCH v3 drm-dp 09/11] drm/hisilicon/hibmc: fix no showing problem with loading hibmc manually Yongbang Shi
2025-07-26 16:04 ` Dmitry Baryshkov
2025-07-18 6:51 ` [PATCH v3 drm-dp 10/11] drm/hisilicon/hibmc: adapting modification for the former commit Yongbang Shi
2025-07-26 16:05 ` Dmitry Baryshkov
2025-08-01 9:25 ` Yongbang Shi
2025-07-18 6:51 ` [PATCH v3 drm-dp 11/11] drm/hisilicon/hibmc: " Yongbang Shi
2025-07-25 9:16 ` [PATCH v3 drm-dp 00/11] Fix hibmc driver bugs Yongbang Shi
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).