From: Alexander Graf <agraf@csgraf.de>
To: u-boot@lists.denx.de
Cc: Tuomas Tynkkynen <tuomas.tynkkynen@iki.fi>,
Simon Glass <sjg@chromium.org>,
Mark Kettenis <mark.kettenis@xs4all.nl>,
Bin Meng <bmeng.cn@gmail.com>, Asherah Connor <ashe@kivikakk.ee>,
Heinrich Schuchardt <xypron.glpk@gmx.de>,
Anatolij Gustschin <agust@denx.de>
Subject: [PATCH 2/4] ramfb: Add driver for ramfb display
Date: Sun, 27 Feb 2022 15:40:41 +0100 [thread overview]
Message-ID: <20220227144043.37359-3-agraf@csgraf.de> (raw)
In-Reply-To: <20220227144043.37359-1-agraf@csgraf.de>
QEMU implements multiple ways to expose graphics output to the virt
machine, but most of them are incompatible with hardware virtualization.
The one that does work reliably is ramfb. It's a very simple mechanism
in which the guest reserves a memory region for the frame buffer and then
notifies the host about its location and properties. The host then just
displays the contents of the frame buffer on screen.
This patch implements a trivial version of a ramfb driver - hard coded
to a single resolution.
Signed-off-by: Alexander Graf <agraf@csgraf.de>
---
drivers/video/Kconfig | 8 +++
drivers/video/MAINTAINERS | 4 ++
drivers/video/Makefile | 1 +
drivers/video/ramfb.c | 104 ++++++++++++++++++++++++++++++++++++++
4 files changed, 117 insertions(+)
create mode 100644 drivers/video/MAINTAINERS
create mode 100644 drivers/video/ramfb.c
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index ff8e11f648..73a9e20534 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -871,6 +871,14 @@ config VIDEO_MCDE_SIMPLE
before u-boot starts, and u-boot will simply render to the pre-
allocated frame buffer surface.
+config VIDEO_RAMFB
+ bool "QEMU ramfb display driver for in-RAM display"
+ depends on EFI_LOADER && DM_VIDEO && QFW
+ help
+ Enables a RAM based simple frame buffer driver which uses qfw to
+ notify the hypervisor about the location of a Frame Buffer allocated
+ in guest RAM as well as its properties.
+
config OSD
bool "Enable OSD support"
depends on DM
diff --git a/drivers/video/MAINTAINERS b/drivers/video/MAINTAINERS
new file mode 100644
index 0000000000..74c258a314
--- /dev/null
+++ b/drivers/video/MAINTAINERS
@@ -0,0 +1,4 @@
+QEMU RAMFB VIDEO DRIVER
+M: Alexander Graf <agraf@csgraf.de>
+S: Maintained
+F: drivers/video/ramfb.c
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 4038395b12..6cfec17072 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -74,6 +74,7 @@ obj-$(CONFIG_VIDEO_TEGRA20) += tegra.o
obj-$(CONFIG_VIDEO_VCXK) += bus_vcxk.o
obj-$(CONFIG_VIDEO_VESA) += vesa.o
obj-$(CONFIG_VIDEO_SEPS525) += seps525.o
+obj-$(CONFIG_VIDEO_RAMFB) += ramfb.o
obj-y += bridge/
obj-y += sunxi/
diff --git a/drivers/video/ramfb.c b/drivers/video/ramfb.c
new file mode 100644
index 0000000000..c46bfa3baa
--- /dev/null
+++ b/drivers/video/ramfb.c
@@ -0,0 +1,104 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2022 Alexander Graf
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <log.h>
+#include <video.h>
+#include <asm/global_data.h>
+#include <efi_loader.h>
+#include <qfw.h>
+
+#define fourcc_code(a, b, c, d) ((u32)(a) | ((u32)(b) << 8) | \
+ ((u32)(c) << 16) | ((u32)(d) << 24))
+#define DRM_FORMAT_XRGB8888 fourcc_code('X', 'R', '2', '4')
+
+#define DEFAULT_WIDTH 1280
+#define DEFAULT_HEIGHT 900
+#define DEFAULT_BPIX VIDEO_BPP32
+#define DEFAULT_FORMAT VIDEO_X8R8G8B8
+
+struct ramfb_cfg {
+ u64 addr;
+ u32 fourcc;
+ u32 flags;
+ u32 width;
+ u32 height;
+ u32 stride;
+} __packed;
+
+static int ramfb_probe(struct udevice *dev)
+{
+ struct video_uc_plat *plat = dev_get_uclass_plat(dev);
+ struct video_priv *uc_priv = dev_get_uclass_priv(dev);
+ u32 selector;
+ u64 base;
+ u64 size;
+ efi_status_t ret;
+ struct fw_file *file;
+ struct udevice *qfw;
+ struct dm_qfw_ops *ops;
+ struct qfw_dma dma = {};
+ struct ramfb_cfg cfg = {
+ .addr = 0,
+ .fourcc = cpu_to_be32(DRM_FORMAT_XRGB8888),
+ .flags = 0,
+ .width = cpu_to_be32(DEFAULT_WIDTH),
+ .height = cpu_to_be32(DEFAULT_HEIGHT),
+ .stride = 0,
+ };
+
+ ret = qfw_get_dev(&qfw);
+ if (ret)
+ return -EPROBE_DEFER;
+
+ ops = dm_qfw_get_ops(qfw);
+ if (!ops)
+ return -EPROBE_DEFER;
+
+ file = qfw_find_file(qfw, "etc/ramfb");
+ if (!file) {
+ /* No ramfb available. At least we tried. */
+ return -ENOENT;
+ }
+
+ size = DEFAULT_WIDTH * DEFAULT_HEIGHT * VNBYTES(DEFAULT_BPIX);
+ ret = efi_allocate_pages(EFI_ALLOCATE_ANY_PAGES,
+ EFI_RESERVED_MEMORY_TYPE,
+ efi_size_in_pages(size), &base);
+ if (ret != EFI_SUCCESS)
+ return -ENOMEM;
+
+ debug("%s: base=%llx, size=%llu\n", __func__, base, size);
+
+ cfg.addr = cpu_to_be64(base);
+ plat->base = base;
+ plat->size = size;
+ uc_priv->xsize = DEFAULT_WIDTH;
+ uc_priv->ysize = DEFAULT_HEIGHT;
+ uc_priv->bpix = DEFAULT_BPIX;
+ uc_priv->format = DEFAULT_FORMAT;
+ uc_priv->fb = (void *)base;
+ uc_priv->fb_size = size;
+
+ selector = be16_to_cpu(file->cfg.select);
+ dma.length = cpu_to_be32(sizeof(cfg));
+ dma.address = cpu_to_be64((uintptr_t)&cfg);
+ dma.control = cpu_to_be32(FW_CFG_DMA_WRITE | FW_CFG_DMA_SELECT |
+ (selector << 16));
+
+ barrier();
+
+ /* Send a DMA write request which enables the screen */
+ ops->read_entry_dma(qfw, &dma);
+
+ return 0;
+}
+
+U_BOOT_DRIVER(ramfb) = {
+ .name = "ramfb",
+ .id = UCLASS_VIDEO,
+ .probe = ramfb_probe,
+};
--
2.32.0
next prev parent reply other threads:[~2022-02-27 14:41 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-02-27 14:40 [PATCH 0/4] Add support for QEMU's ramfb display Alexander Graf
2022-02-27 14:40 ` [PATCH 1/4] qfw: Add WRITE definition Alexander Graf
2022-03-12 2:25 ` Simon Glass
2022-02-27 14:40 ` Alexander Graf [this message]
2022-03-12 2:25 ` [PATCH 2/4] ramfb: Add driver for ramfb display Simon Glass
2022-02-27 14:40 ` [PATCH 3/4] qfw: Spawn ramfb device if its file is present Alexander Graf
2022-02-27 14:40 ` [PATCH 4/4] qemu-arm*: Enable ramfb by default Alexander Graf
2022-02-27 15:35 ` [PATCH 0/4] Add support for QEMU's ramfb display Heinrich Schuchardt
2022-02-27 17:05 ` Alexander Graf
2022-02-27 17:03 ` [PATCH 5/5] qemu-riscv: Enable ramfb by default Alexander Graf
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=20220227144043.37359-3-agraf@csgraf.de \
--to=agraf@csgraf.de \
--cc=agust@denx.de \
--cc=ashe@kivikakk.ee \
--cc=bmeng.cn@gmail.com \
--cc=mark.kettenis@xs4all.nl \
--cc=sjg@chromium.org \
--cc=tuomas.tynkkynen@iki.fi \
--cc=u-boot@lists.denx.de \
--cc=xypron.glpk@gmx.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