Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Maxime Ripard <mripard@kernel.org>
To: Neil Armstrong <neil.armstrong@linaro.org>,
	 Jessica Zhang <jesszhan0024@gmail.com>,
	David Airlie <airlied@gmail.com>,
	 Simona Vetter <simona@ffwll.ch>,
	 Maarten Lankhorst <maarten.lankhorst@linux.intel.com>,
	 Thomas Zimmermann <tzimmermann@suse.de>,
	Rob Herring <robh@kernel.org>,
	 Krzysztof Kozlowski <krzk+dt@kernel.org>,
	 Conor Dooley <conor+dt@kernel.org>,
	Nathan Chancellor <nathan@kernel.org>,
	 Nick Desaulniers <ndesaulniers@google.com>,
	 Bill Wendling <morbo@google.com>,
	Justin Stitt <justinstitt@google.com>,
	 Florian Fainelli <florian.fainelli@broadcom.com>,
	 Broadcom internal kernel review list
	<bcm-kernel-feedback-list@broadcom.com>
Cc: Andrzej Hajda <andrzej.hajda@intel.com>,
	 Neil Armstrong <neil.armstrong@linaro.org>,
	Robert Foss <rfoss@kernel.org>,
	 Laurent Pinchart <Laurent.pinchart@ideasonboard.com>,
	 Jonas Karlman <jonas@kwiboo.se>,
	Jernej Skrabec <jernej.skrabec@gmail.com>,
	 Luca Ceresoli <luca.ceresoli@bootlin.com>,
	 Albert Esteve <aesteve@redhat.com>,
	 Dave Stevenson <dave.stevenson@raspberrypi.com>,
	 Javier Martinez Canillas <javierm@redhat.com>,
	 dri-devel@lists.freedesktop.org, devicetree@vger.kernel.org,
	 linux-kernel@vger.kernel.org, bpf@vger.kernel.org,
	llvm@lists.linux.dev,  linux-rpi-kernel@lists.infradead.org,
	linux-arm-kernel@lists.infradead.org,
	 Maxime Ripard <mripard@kernel.org>,
	Benjamin Tissoires <bentiss@kernel.org>
Subject: [PATCH 3/6] drm/panel: dsi-bpf: Add BPF program build infrastructure and helper header
Date: Mon, 28 Sep 2026 18:22:03 +0200	[thread overview]
Message-ID: <20260928-drm-mipi-dsi-panel-ebpf-v1-3-5244926aace4@kernel.org> (raw)
In-Reply-To: <20260928-drm-mipi-dsi-panel-ebpf-v1-0-5244926aace4@kernel.org>

Add the BPF-side header panel-bpf-mipi-dsi.h and a standalone
Makefile for building panel BPF programs. The header provides
section name macros (PANEL_BPF_MIPI_DSI_PREPARE, etc.), the
PANEL_BPF_MIPI_DSI_OPS() struct_ops declaration macro, extern
declarations for all the kfuncs, and some convenience macros.

The Makefile follows the same pattern as drivers/hid/bpf/progs/.
It generates vmlinux.h from BTF, bootstraps bpftool and libbpf
from the kernel tools/ directory, then compiles every *.bpf.c
file into a stripped .bpf.o object. The resulting objects are
userspace artifacts loaded at runtime.

Signed-off-by: Maxime Ripard <mripard@kernel.org>
---
 drivers/gpu/drm/panel/bpf/progs/Makefile           | 93 +++++++++++++++++++++
 .../gpu/drm/panel/bpf/progs/panel-bpf-mipi-dsi.h   | 95 ++++++++++++++++++++++
 include/drm/drm_panel_dsi_bpf.h                    | 50 ------------
 3 files changed, 188 insertions(+), 50 deletions(-)

diff --git a/drivers/gpu/drm/panel/bpf/progs/Makefile b/drivers/gpu/drm/panel/bpf/progs/Makefile
new file mode 100644
index 000000000000..74190ee618ab
--- /dev/null
+++ b/drivers/gpu/drm/panel/bpf/progs/Makefile
@@ -0,0 +1,93 @@
+# SPDX-License-Identifier: GPL-2.0
+OUTPUT := .output
+abs_out := $(abspath $(OUTPUT))
+
+CLANG ?= clang
+LLC ?= llc
+LLVM_STRIP ?= llvm-strip
+
+TOOLS_PATH := $(abspath ../../../../../../tools)
+BPFTOOL_SRC := $(TOOLS_PATH)/bpf/bpftool
+BPFTOOL_OUTPUT := $(abs_out)/bpftool
+DEFAULT_BPFTOOL := $(BPFTOOL_OUTPUT)/bootstrap/bpftool
+BPFTOOL ?= $(DEFAULT_BPFTOOL)
+
+LIBBPF_SRC := $(TOOLS_PATH)/lib/bpf
+LIBBPF_OUTPUT := $(abs_out)/libbpf
+LIBBPF_DESTDIR := $(LIBBPF_OUTPUT)
+LIBBPF_INCLUDE := $(LIBBPF_DESTDIR)/include
+BPFOBJ := $(LIBBPF_OUTPUT)/libbpf.a
+
+INCLUDES := -I$(OUTPUT) -I$(LIBBPF_INCLUDE) -I$(TOOLS_PATH)/include/uapi
+CFLAGS := -g -Wall
+
+VMLINUX_BTF_PATHS ?= $(if $(O),$(O)/vmlinux)				\
+		     $(if $(KBUILD_OUTPUT),$(KBUILD_OUTPUT)/vmlinux)	\
+		     ../../../../../../vmlinux				\
+		     /sys/kernel/btf/vmlinux				\
+		     /boot/vmlinux-$(shell uname -r)
+VMLINUX_BTF ?= $(abspath $(firstword $(wildcard $(VMLINUX_BTF_PATHS))))
+ifeq ($(VMLINUX_BTF),)
+$(error Cannot find a vmlinux for VMLINUX_BTF at any of "$(VMLINUX_BTF_PATHS)")
+endif
+
+ifeq ($(V),1)
+Q =
+msg =
+else
+Q = @
+msg = @printf '  %-8s %s%s\n' "$(1)" "$(notdir $(2))" "$(if $(3), $(3))";
+MAKEFLAGS += --no-print-directory
+submake_extras := feature_display=0
+endif
+
+.DELETE_ON_ERROR:
+
+.PHONY: all clean
+
+SOURCES = $(wildcard *.bpf.c)
+TARGETS = $(SOURCES:.bpf.c=.bpf.o)
+
+all: $(TARGETS)
+
+clean:
+	$(call msg,CLEAN)
+	$(Q)rm -rf $(OUTPUT) $(TARGETS)
+
+%.bpf.o: %.bpf.c vmlinux.h $(BPFOBJ) | $(OUTPUT)
+	$(call msg,BPF,$@)
+	$(Q)$(CLANG) -g -O2 --target=bpf -Wall -Werror $(INCLUDES)		\
+		     -Wno-microsoft-anon-tag					\
+		     -fms-extensions						\
+		     -c $(filter %.c,$^) -o $@ &&				\
+	$(LLVM_STRIP) -g $@
+
+vmlinux.h: $(VMLINUX_BTF) $(BPFTOOL) | $(INCLUDE_DIR)
+ifeq ($(VMLINUX_H),)
+	$(call msg,GEN,,$@)
+	$(Q)$(BPFTOOL) btf dump file $(VMLINUX_BTF) format c > $@
+else
+	$(call msg,CP,,$@)
+	$(Q)cp "$(VMLINUX_H)" $@
+endif
+
+$(OUTPUT) $(LIBBPF_OUTPUT) $(BPFTOOL_OUTPUT):
+	$(call msg,MKDIR,$@)
+	$(Q)mkdir -p $@
+
+$(BPFOBJ): $(wildcard $(LIBBPF_SRC)/*.[ch] $(LIBBPF_SRC)/Makefile) | $(LIBBPF_OUTPUT)
+	$(Q)$(MAKE) $(submake_extras) -C $(LIBBPF_SRC)			       \
+		    OUTPUT=$(abspath $(dir $@))/ prefix=		       \
+		    DESTDIR=$(LIBBPF_DESTDIR) $(abspath $@) install_headers
+
+ifeq ($(CROSS_COMPILE),)
+$(DEFAULT_BPFTOOL): $(BPFOBJ) | $(BPFTOOL_OUTPUT)
+	$(Q)$(MAKE) $(submake_extras) -C $(BPFTOOL_SRC)			       \
+		    OUTPUT=$(BPFTOOL_OUTPUT)/				       \
+		    LIBBPF_BOOTSTRAP_OUTPUT=$(LIBBPF_OUTPUT)/		       \
+		    LIBBPF_BOOTSTRAP_DESTDIR=$(LIBBPF_DESTDIR)/ bootstrap
+else
+$(DEFAULT_BPFTOOL): | $(BPFTOOL_OUTPUT)
+	$(Q)$(MAKE) $(submake_extras) -C $(BPFTOOL_SRC)			       \
+		    OUTPUT=$(BPFTOOL_OUTPUT)/ bootstrap
+endif
diff --git a/drivers/gpu/drm/panel/bpf/progs/panel-bpf-mipi-dsi.h b/drivers/gpu/drm/panel/bpf/progs/panel-bpf-mipi-dsi.h
new file mode 100644
index 000000000000..e2b03afef2c8
--- /dev/null
+++ b/drivers/gpu/drm/panel/bpf/progs/panel-bpf-mipi-dsi.h
@@ -0,0 +1,95 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef ____PANEL_BPF_MIPI_DSI_BPF__H
+#define ____PANEL_BPF_MIPI_DSI_BPF__H
+
+#define PANEL_BPF_MIPI_DSI_PREPARE	"struct_ops.s/panel_prepare"
+#define PANEL_BPF_MIPI_DSI_UNPREPARE	"struct_ops.s/panel_unprepare"
+#define PANEL_BPF_MIPI_DSI_ENABLE	"struct_ops.s/panel_enable"
+#define PANEL_BPF_MIPI_DSI_DISABLE	"struct_ops.s/panel_disable"
+
+#define PANEL_BPF_MIPI_DSI_OPS(name) SEC(".struct_ops") \
+	struct drm_panel_dsi_bpf_ops name
+
+/* Mode flags — kernel #defines not exported through BTF */
+#define MIPI_DSI_MODE_VIDEO		(1 << 0)
+#define MIPI_DSI_MODE_VIDEO_BURST	(1 << 1)
+#define MIPI_DSI_MODE_VIDEO_SYNC_PULSE	(1 << 2)
+#define MIPI_DSI_MODE_NO_EOT_PACKET	(1 << 9)
+#define MIPI_DSI_CLOCK_NON_CONTINUOUS	(1 << 10)
+#define MIPI_DSI_MODE_LPM		(1 << 11)
+
+extern int panel_bpf_mipi_dsi_regulator_enable_and_wait(struct panel_bpf_mipi_dsi_ctx *ctx,
+							enum panel_bpf_mipi_dsi_supply supply,
+							__u32 settle_ms) __ksym;
+extern int panel_bpf_mipi_dsi_regulator_disable(struct panel_bpf_mipi_dsi_ctx *ctx,
+						enum panel_bpf_mipi_dsi_supply supply) __ksym;
+extern void panel_bpf_mipi_dsi_gpio_cycle_and_wait(struct panel_bpf_mipi_dsi_ctx *ctx,
+						   enum panel_bpf_mipi_dsi_gpio gpio,
+						   __u32 assert_ms,
+						   __u32 settle_ms) __ksym;
+extern void panel_bpf_mipi_dsi_gpio_enable(struct panel_bpf_mipi_dsi_ctx *ctx,
+					   enum panel_bpf_mipi_dsi_gpio gpio) __ksym;
+extern void panel_bpf_mipi_dsi_gpio_disable(struct panel_bpf_mipi_dsi_ctx *ctx,
+					   enum panel_bpf_mipi_dsi_gpio gpio) __ksym;
+extern int panel_bpf_mipi_dsi_dcs_write_and_wait(struct panel_bpf_mipi_dsi_ctx *ctx,
+						  __u8 cmd, const __u8 *data,
+						  __u32 data__sz,
+						  __u32 settle_ms) __ksym;
+extern int panel_bpf_mipi_dsi_generic_write_and_wait(struct panel_bpf_mipi_dsi_ctx *ctx,
+						     const __u8 *data,
+						     __u32 data__sz,
+						     __u32 settle_ms) __ksym;
+extern int panel_bpf_mipi_dsi_dcs_read(struct panel_bpf_mipi_dsi_ctx *ctx,
+				       __u8 cmd, __u8 *data,
+				       __u32 data__sz) __ksym;
+
+/*
+ * Convenience macros
+ *
+ * These wrap the _and_wait kfuncs with settle_ms = 0 for the common
+ * case where no post-operation delay is needed.
+ */
+
+/* Enable a supply without a post-enable delay. */
+#define panel_bpf_mipi_dsi_regulator_enable(ctx, supply)			\
+	panel_bpf_mipi_dsi_regulator_enable_and_wait((ctx), (supply), 0)
+
+/* Send a DCS command without a post-send delay. */
+#define panel_bpf_mipi_dsi_dcs_write(ctx, cmd, data, data__sz)		\
+	panel_bpf_mipi_dsi_dcs_write_and_wait((ctx), (cmd), (data), (data__sz), 0)
+
+/* Send a generic DSI write without a post-send delay. */
+#define panel_bpf_mipi_dsi_generic_write(ctx, data, data__sz)		\
+	panel_bpf_mipi_dsi_generic_write_and_wait((ctx), (data), (data__sz), 0)
+
+/* Send a DCS command with a single byte payload. */
+#define panel_bpf_mipi_dsi_dcs_write_byte(ctx, cmd, val)		\
+	do {								\
+		const __u8 _v = (val);					\
+		panel_bpf_mipi_dsi_dcs_write((ctx), (cmd), &_v, 1);	\
+	} while (0)
+
+/*
+ * Standard DCS command helpers
+ *
+ * exit_sleep_mode and enter_sleep_mode include the 120ms delay
+ * required by the MIPI DCS specification before the next command.
+ */
+
+/* Send MIPI_DCS_EXIT_SLEEP_MODE with a 120ms settling delay. */
+#define panel_bpf_mipi_dsi_exit_sleep_mode(ctx)				\
+	panel_bpf_mipi_dsi_dcs_write_and_wait((ctx), MIPI_DCS_EXIT_SLEEP_MODE, NULL, 0, 120)
+
+/* Send MIPI_DCS_ENTER_SLEEP_MODE with a 120ms settling delay. */
+#define panel_bpf_mipi_dsi_enter_sleep_mode(ctx)			\
+	panel_bpf_mipi_dsi_dcs_write_and_wait((ctx), MIPI_DCS_ENTER_SLEEP_MODE, NULL, 0, 120)
+
+/* Send MIPI_DCS_SET_DISPLAY_ON. */
+#define panel_bpf_mipi_dsi_set_display_on(ctx)				\
+	panel_bpf_mipi_dsi_dcs_write((ctx), MIPI_DCS_SET_DISPLAY_ON, NULL, 0)
+
+/* Send MIPI_DCS_SET_DISPLAY_OFF. */
+#define panel_bpf_mipi_dsi_set_display_off(ctx)				\
+	panel_bpf_mipi_dsi_dcs_write((ctx), MIPI_DCS_SET_DISPLAY_OFF, NULL, 0)
+
+#endif /* ____PANEL_BPF_MIPI_DSI_BPF__H */
diff --git a/include/drm/drm_panel_dsi_bpf.h b/include/drm/drm_panel_dsi_bpf.h
deleted file mode 100644
index 02d4707fd0a0..000000000000
--- a/include/drm/drm_panel_dsi_bpf.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __DRM_PANEL_DSI_BPF_H__
-#define __DRM_PANEL_DSI_BPF_H__
-
-#include <linux/bpf.h>
-
-struct mipi_dsi_device;
-struct drm_panel;
-
-#define DSI_BPF_PANEL_ID_LEN	64
-
-/**
- * struct dsi_bpf_ctx - Context passed to BPF panel programs
- * @panel: The drm_panel this callback operates on (private)
- */
-struct dsi_bpf_ctx {
-	struct drm_panel *panel;
-};
-
-/**
- * struct drm_panel_dsi_bpf_ops - BPF struct_ops for MIPI-DSI panels
- * @panel_id: Device identifier for matching. On DT systems this holds
- *	the panel's compatible string. Firmware-agnostic to allow future
- *	ACPI support. Written before load, immutable after.
- * @panel_prepare: Called to power on the panel and send init commands.
- *	Must enable regulators, toggle GPIOs, and send the DSI init
- *	sequence. Sleepable.
- * @panel_unprepare: Called to power off the panel. Must send shutdown
- *	commands, assert reset, and disable regulators. Sleepable.
- * @panel_enable: Optional. Called after video stream starts, for panels
- *	that need post-video-start DSI commands. Sleepable.
- * @panel_disable: Optional. Called before video stream stops. Sleepable.
- * @set_brightness: Optional. Called to set backlight brightness via DSI
- *	commands. Sleepable.
- */
-struct drm_panel_dsi_bpf_ops {
-	char			panel_id[DSI_BPF_PANEL_ID_LEN];
-
-	/* private: internal bookkeeping */
-	struct drm_panel	*panel;
-
-	/* public: */
-	int (*panel_prepare)(struct dsi_bpf_ctx *ctx);
-	int (*panel_unprepare)(struct dsi_bpf_ctx *ctx);
-	int (*panel_enable)(struct dsi_bpf_ctx *ctx);
-	int (*panel_disable)(struct dsi_bpf_ctx *ctx);
-	int (*set_brightness)(struct dsi_bpf_ctx *ctx, u32 brightness);
-};
-
-#endif /* __DRM_PANEL_DSI_BPF_H__ */

-- 
2.55.0



  parent reply	other threads:[~2026-09-28 16:22 UTC|newest]

Thread overview: 58+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-28 16:22 [PATCH 0/6] drm/bridge: Add a BPF-based MIPI-DSI panel driver Maxime Ripard
2026-09-28 16:22 ` [PATCH 1/6] dt-bindings: display: Add panel-mipi-dsi-bpf generic panel binding Maxime Ripard
2026-09-28 19:16   ` Neil Armstrong
2026-09-28 20:40   ` Rob Herring
2026-09-29  8:39     ` Maxime Ripard
2026-09-29 22:28       ` Rob Herring
2026-09-30  8:04         ` Maxime Ripard
2026-09-30 19:07           ` Rob Herring
2026-10-01  7:22             ` Maxime Ripard
2026-10-01 16:03               ` Rob Herring
2026-09-30 13:32       ` Neil Armstrong
2026-10-01  7:09         ` Maxime Ripard
2026-10-02  7:28           ` Neil Armstrong
2026-09-28 20:43   ` Rob Herring (Arm)
2026-09-29 23:44   ` bot+bpf-ci
2026-09-28 16:22 ` [PATCH 2/6] drm/panel: Add generic MIPI-DSI panel driver with BPF init sequences Maxime Ripard
2026-09-28 16:22 ` Maxime Ripard [this message]
2026-09-29 23:44   ` [PATCH 3/6] drm/panel: dsi-bpf: Add BPF program build infrastructure and helper header bot+bpf-ci
2026-09-28 16:22 ` [PATCH 4/6] drm/panel: dsi-bpf: Add Raspberry Pi 7-inch panel BPF program Maxime Ripard
2026-09-28 16:22 ` [PATCH 5/6] drm/panel: dsi-bpf: Add Raspberry Pi 5-inch " Maxime Ripard
2026-09-28 16:22 ` [PATCH DO NOT MERGE 6/6] arm64: dts: broadcom: Add Raspberry Pi ILI9881C DSI panel overlays Maxime Ripard
2026-09-28 16:37 ` [PATCH 0/6] drm/bridge: Add a BPF-based MIPI-DSI panel driver Laurent Pinchart
2026-09-28 17:31   ` Benjamin Tissoires
2026-09-28 18:12     ` Laurent Pinchart
2026-09-29  6:54   ` Maxime Ripard
2026-09-28 16:39 ` Neil Armstrong
2026-09-28 17:24   ` Benjamin Tissoires
2026-09-28 19:20     ` Neil Armstrong
2026-09-28 19:48       ` Benjamin Tissoires
2026-09-28 20:36         ` Neil Armstrong
2026-09-29  7:41           ` Maxime Ripard
2026-09-29  7:55             ` Javier Martinez Canillas
2026-09-30 13:37               ` Neil Armstrong
2026-10-01  6:50                 ` Maxime Ripard
2026-10-02  7:30                   ` Neil Armstrong
2026-10-02  7:37                     ` Javier Martinez Canillas
2026-10-02  7:53                       ` Neil Armstrong
2026-10-02  9:04                         ` Javier Martinez Canillas
2026-09-30 13:36             ` Neil Armstrong
2026-09-30 20:59               ` Kumar Kartikeya Dwivedi
2026-10-01  6:38               ` Maxime Ripard
2026-10-01 17:03               ` Maxime Ripard
2026-09-29  7:27       ` Maxime Ripard
2026-09-30 13:49         ` Neil Armstrong
2026-10-01  7:01           ` Maxime Ripard
2026-10-02  7:39             ` Neil Armstrong
2026-09-29  7:13   ` Maxime Ripard
2026-09-29  7:46     ` Benjamin Tissoires
2026-09-30 13:46     ` Neil Armstrong
2026-10-01  6:48       ` Maxime Ripard
2026-10-02  8:11         ` Neil Armstrong
2026-09-29  9:03 ` Jani Nikula
2026-09-29  9:32   ` Benjamin Tissoires
2026-09-29 10:16     ` Jani Nikula
2026-09-29 12:28       ` Maxime Ripard
2026-09-30 14:01   ` Neil Armstrong
2026-09-30 19:18     ` Jani Nikula
2026-10-01  7:05     ` Maxime Ripard

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260928-drm-mipi-dsi-panel-ebpf-v1-3-5244926aace4@kernel.org \
    --to=mripard@kernel.org \
    --cc=Laurent.pinchart@ideasonboard.com \
    --cc=aesteve@redhat.com \
    --cc=airlied@gmail.com \
    --cc=andrzej.hajda@intel.com \
    --cc=bcm-kernel-feedback-list@broadcom.com \
    --cc=bentiss@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=conor+dt@kernel.org \
    --cc=dave.stevenson@raspberrypi.com \
    --cc=devicetree@vger.kernel.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=florian.fainelli@broadcom.com \
    --cc=javierm@redhat.com \
    --cc=jernej.skrabec@gmail.com \
    --cc=jesszhan0024@gmail.com \
    --cc=jonas@kwiboo.se \
    --cc=justinstitt@google.com \
    --cc=krzk+dt@kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-rpi-kernel@lists.infradead.org \
    --cc=llvm@lists.linux.dev \
    --cc=luca.ceresoli@bootlin.com \
    --cc=maarten.lankhorst@linux.intel.com \
    --cc=morbo@google.com \
    --cc=nathan@kernel.org \
    --cc=ndesaulniers@google.com \
    --cc=neil.armstrong@linaro.org \
    --cc=rfoss@kernel.org \
    --cc=robh@kernel.org \
    --cc=simona@ffwll.ch \
    --cc=tzimmermann@suse.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox