]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/hisilicon/hibmc: add dp mode valid check
authorBaihan Li <libaihan@huawei.com>
Wed, 10 Dec 2025 02:37:57 +0000 (10:37 +0800)
committerDmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Tue, 20 Jan 2026 08:53:14 +0000 (10:53 +0200)
If DP is connected, check the DP BW in mode_valid_ctx() to ensure
that DP's link rate supports high-resolution data transmission.

Fixes: 0ab6ea261c1f ("drm/hisilicon/hibmc: add dp module in hibmc")
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>
Reviewed-by: Tao Tian <tiantao6@hisilicon.com>
Link: https://patch.msgid.link/20251210023759.3944834-3-shiyongbang@huawei.com
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
drivers/gpu/drm/hisilicon/hibmc/dp/dp_config.h
drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c
drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.h
drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c

index 08f9e1caf7fcbb16842a594498d8e94c2ae4781b..efb30a7584758c8b90c555cc8b0ae248aae15546 100644 (file)
@@ -17,5 +17,7 @@
 #define HIBMC_DP_LINK_RATE_CAL         27
 #define HIBMC_DP_SYNC_DELAY(lanes)     ((lanes) == 0x2 ? 86 : 46)
 #define HIBMC_DP_INT_ENABLE            0xc
+/* HIBMC_DP_LINK_RATE_CAL * 10000 * 80% = 216000 */
+#define DP_MODE_VALI_CAL               216000
 
 #endif
index 0ec6ace2d082285686939bac086b49227ea529f6..37549dafa06caf4f33876b60178c214f7cf1c0e9 100644 (file)
@@ -264,6 +264,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},
index 59c1eae153c55d82d8651be02c2c0ea42bf4e490..31316fe1ea8dbfea6fae0b8f3c6f18ac4ed1820d 100644 (file)
@@ -66,5 +66,7 @@ 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);
 bool hibmc_dp_check_hpd_status(struct hibmc_dp *dp, int exp_status);
+u8 hibmc_dp_get_link_rate(struct hibmc_dp *dp);
+u8 hibmc_dp_get_lanes(struct hibmc_dp *dp);
 
 #endif
index 4a66a107900a10c33b554dbab8ed67760392fc7e..616821e3c933bcd9ac5dbe42c950ac542df86485 100644 (file)
@@ -13,6 +13,7 @@
 #include "hibmc_drm_drv.h"
 #include "dp/dp_hw.h"
 #include "dp/dp_comm.h"
+#include "dp/dp_config.h"
 
 #define DP_MASKED_SINK_HPD_PLUG_INT    BIT(2)
 
@@ -81,9 +82,27 @@ 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->clock * HIBMC_DP_BPP;
+       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;
+
+       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)