Index | Thread | Search

From:
Kirill A. Korinsky <kirill@korins.ky>
Subject:
sys/qcdpc: blank eDP panels during suspend
To:
OpenBSD tech <tech@openbsd.org>
Date:
Mon, 05 Oct 2026 02:53:43 +0200

Download raw body.

Thread
tech@,

My HONOR Snapdragon panel remains light up when AUX backlight enable is
cleared; also request black video during quiesce; save the original display
control register and restore it on wake, preserving brightness and the
firmware configured display link.

Ok?

Index: sys/dev/fdt/qcdpc.c
===================================================================
RCS file: /home/cvs/src/sys/dev/fdt/qcdpc.c,v
diff -u -p -r1.2 qcdpc.c
--- sys/dev/fdt/qcdpc.c	9 Mar 2026 23:57:53 -0000	1.2
+++ sys/dev/fdt/qcdpc.c	5 Oct 2026 00:50:24 -0000
@@ -71,15 +71,19 @@ struct qcdpc_softc {
 
 	struct drm_edp_backlight_info sc_bl;
 	uint32_t		sc_bl_level;
+	uint8_t			sc_bl_control;
+	int			sc_bl_suspended;
 };
 
 struct qcdpc_softc *qcdpc_bl;
 
 int	qcdpc_match(struct device *, void *, void *);
 void	qcdpc_attach(struct device *, struct device *, void *);
+int	qcdpc_activate(struct device *, int);
 
 const struct cfattach qcdpc_ca = {
-	sizeof(struct qcdpc_softc), qcdpc_match, qcdpc_attach
+	sizeof(struct qcdpc_softc), qcdpc_match, qcdpc_attach,
+	NULL, qcdpc_activate
 };
 
 struct cfdriver qcdpc_cd = {
@@ -174,6 +178,47 @@ qcdpc_attach(struct device *parent, stru
 		fa.fa_node = node;
 		config_found(self, &fa, qcdpc_print);
 	}
+}
+
+int
+qcdpc_activate(struct device *self, int act)
+{
+	struct qcdpc_softc *sc = (struct qcdpc_softc *)self;
+	int ret;
+
+	if (sc != qcdpc_bl || !sc->sc_bl.aux_enable)
+		return config_activate_children(self, act);
+
+	switch (act) {
+	case DVACT_QUIESCE:
+		ret = config_activate_children(self, act);
+		if (ret)
+			return ret;
+
+		if (!sc->sc_bl_suspended) {
+			ret = drm_dp_dpcd_read_byte(&sc->sc_aux,
+			    DP_EDP_DISPLAY_CONTROL_REGISTER, &sc->sc_bl_control);
+			if (ret < 0)
+				return ret;
+			sc->sc_bl_suspended = 1;
+		}
+
+		return drm_dp_dpcd_write_byte(&sc->sc_aux,
+		    DP_EDP_DISPLAY_CONTROL_REGISTER,
+		    (sc->sc_bl_control & ~DP_EDP_BACKLIGHT_ENABLE) |
+		    DP_EDP_BLACK_VIDEO_ENABLE);
+
+	case DVACT_WAKEUP:
+		if (sc->sc_bl_suspended) {
+			ret = drm_dp_dpcd_write_byte(&sc->sc_aux,
+			    DP_EDP_DISPLAY_CONTROL_REGISTER, sc->sc_bl_control);
+			if (ret == 0)
+				sc->sc_bl_suspended = 0;
+		}
+		break;
+	}
+
+	return config_activate_children(self, act);
 }
 
 int


-- 
wbr, Kirill