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
next prev 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