From a2acb6fcd7fd125f43fe349b9d949150e275767e Mon Sep 17 00:00:00 2001 From: Qubot <1445788683@qq.com> Date: Fri, 5 Jun 2026 21:14:10 +0800 Subject: [PATCH] drm/sunxi-hdmi: keep forced connector connected --- bsp/drivers/drm/sunxi_drm_hdmi.c | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/bsp/drivers/drm/sunxi_drm_hdmi.c b/bsp/drivers/drm/sunxi_drm_hdmi.c index cb2e1e0a8..6036783f2 100644 --- a/bsp/drivers/drm/sunxi_drm_hdmi.c +++ b/bsp/drivers/drm/sunxi_drm_hdmi.c @@ -1479,6 +1479,21 @@ static int _sunxi_drv_hdmi_thread(void *parg) } else if (ret == 0x2) goto next_loop; + /* + * The kernel command line may force the connector on + * (video=HDMI-A-1:e). In that mode a transient HPD low after a + * modeset/DPMS transition must not be treated as a real unplug, + * otherwise the driver tears down HDMI and immediately modesets it + * again, which shows up as a periodic HDMI "jump" on screen. + */ + if (hdmi->hdmi_ctrl.drm_hpd_force == DRM_FORCE_ON) { + if (!_sunxi_drv_hdmi_hpd_get(hdmi)) { + temp_hpd = 1; + goto handle_change; + } + goto next_loop; + } + /* check physical hpd state */ temp_hpd = sunxi_hdmi_get_hpd(); if (temp_hpd == _sunxi_drv_hdmi_hpd_get(hdmi)) @@ -2664,7 +2679,8 @@ static int _sunxi_drm_hdmi_get_modes(struct drm_connector *connector) return -1; } - if (!_sunxi_drv_hdmi_hpd_get(hdmi)) + if (!_sunxi_drv_hdmi_hpd_get(hdmi) && + hdmi->hdmi_ctrl.drm_hpd_force != DRM_FORCE_ON) return -1; ret = _sunxi_drv_hdmi_read_edid(hdmi); @@ -2772,7 +2788,10 @@ _sunxi_drm_hdmi_detect(struct drm_connector *connector, bool force) return ret; } - ret = _sunxi_drv_hdmi_hpd_get(hdmi); + if (hdmi->hdmi_ctrl.drm_hpd_force == DRM_FORCE_ON) + ret = 1; + else + ret = _sunxi_drv_hdmi_hpd_get(hdmi); hdmi_inf("drm hdmi detect: %s\n", ret ? "connect" : "disconnect"); return ret == 1 ? connector_status_connected : connector_status_disconnected; } @@ -2789,10 +2808,13 @@ static void _sunxi_drm_hdmi_force(struct drm_connector *connector) hdmi->hdmi_ctrl.drm_hpd_force = (int)connector->force; - if (connector->force == DRM_FORCE_ON) + if (connector->force == DRM_FORCE_ON) { _sunxi_drv_hdmi_hpd_plugin(hdmi); - else if (connector->force == DRM_FORCE_OFF) + _sunxi_drv_hdmi_hpd_set(hdmi, 0x1); + } else if (connector->force == DRM_FORCE_OFF) { _sunxi_drv_hdmi_hpd_plugout(hdmi); + _sunxi_drv_hdmi_hpd_set(hdmi, 0x0); + } hdmi_inf("drm hdmi set force hpd: %s\n", force_string[connector->force]); }