summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAhmad Fatoum <ahmad@a3f.at>2021-02-28 20:08:58 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2021-03-01 16:59:34 +0100
commit70ddcbcb352aeb50a3103dcdf7341e84d8accf74 (patch)
treeddd8fffc5d84cae4760b8faeaf5c839cb1422728
parentd124b1437fbce91d50395111d0eff4adbce0165c (diff)
downloadbarebox-70ddcbcb352aeb50a3103dcdf7341e84d8accf74.tar.gz
barebox-70ddcbcb352aeb50a3103dcdf7341e84d8accf74.tar.xz
video: add simplefb driver
barebox has support to fix up a framebuffer it has set up as simplefb into the device tree of a kernel it boots. Add the counterpart to this, so barebox itself can reuse an already set up frame buffer. This is done to support the framebuffer device on the tinyemu RISC-V machine. Signed-off-by: Ahmad Fatoum <ahmad@a3f.at> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
-rw-r--r--drivers/video/Kconfig8
-rw-r--r--drivers/video/Makefile3
-rw-r--r--drivers/video/simplefb-client.c149
-rw-r--r--drivers/video/simplefb-fixup.c (renamed from drivers/video/simplefb.c)0
-rw-r--r--include/linux/platform_data/simplefb.h46
5 files changed, 204 insertions, 2 deletions
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index b6d468c63c..95d993dde8 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -101,8 +101,14 @@ source "drivers/video/imx-ipu-v3/Kconfig"
source "drivers/video/bochs/Kconfig"
+config DRIVER_VIDEO_SIMPLEFB_CLIENT
+ bool "Simple framebuffer client support"
+ depends on OFTREE
+ help
+ Add support for reusing a previously set up simple framebuffer.
+
config DRIVER_VIDEO_SIMPLEFB
- bool "Simple framebuffer support"
+ bool "Simple framebuffer fixup support"
depends on OFTREE
help
Add support for setting up the kernel's simple framebuffer driver
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 28d0fe205b..2c002f7e53 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -19,7 +19,8 @@ obj-$(CONFIG_DRIVER_VIDEO_PXA) += pxa.o
obj-$(CONFIG_DRIVER_VIDEO_SDL) += sdl.o
obj-$(CONFIG_DRIVER_VIDEO_OMAP) += omap.o
obj-$(CONFIG_DRIVER_VIDEO_BCM283X) += bcm2835.o
-obj-$(CONFIG_DRIVER_VIDEO_SIMPLEFB) += simplefb.o
+obj-$(CONFIG_DRIVER_VIDEO_SIMPLEFB_CLIENT) += simplefb-client.o
+obj-$(CONFIG_DRIVER_VIDEO_SIMPLEFB) += simplefb-fixup.o
obj-$(CONFIG_DRIVER_VIDEO_IMX_IPUV3) += imx-ipu-v3/
obj-$(CONFIG_DRIVER_VIDEO_EFI_GOP) += efi_gop.o
obj-$(CONFIG_DRIVER_VIDEO_FB_SSD1307) += ssd1307fb.o
diff --git a/drivers/video/simplefb-client.c b/drivers/video/simplefb-client.c
new file mode 100644
index 0000000000..2d0495f616
--- /dev/null
+++ b/drivers/video/simplefb-client.c
@@ -0,0 +1,149 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Simplest possible simple frame-buffer driver, as a platform device
+ *
+ * Copyright (c) 2013, Stephen Warren
+ *
+ * Based on q40fb.c, which was:
+ * Copyright (C) 2001 Richard Zidlicky <rz@linux-m68k.org>
+ *
+ * Also based on offb.c, which was:
+ * Copyright (C) 1997 Geert Uytterhoeven
+ * Copyright (C) 1996 Paul Mackerras
+ */
+
+#include <common.h>
+#include <fb.h>
+#include <io.h>
+#include <linux/platform_data/simplefb.h>
+#include <driver.h>
+#include <of.h>
+
+static struct fb_ops simplefb_ops;
+
+static struct simplefb_format simplefb_formats[] = SIMPLEFB_FORMATS;
+
+struct simplefb_params {
+ u32 width;
+ u32 height;
+ u32 stride;
+ struct simplefb_format *format;
+};
+
+static int simplefb_parse_dt(struct device_d *dev,
+ struct simplefb_params *params)
+{
+ struct device_node *np = dev->device_node;
+ int ret;
+ const char *format;
+ int i;
+
+ ret = of_property_read_u32(np, "width", &params->width);
+ if (ret) {
+ dev_err(dev, "Can't parse width property\n");
+ return ret;
+ }
+
+ ret = of_property_read_u32(np, "height", &params->height);
+ if (ret) {
+ dev_err(dev, "Can't parse height property\n");
+ return ret;
+ }
+
+ ret = of_property_read_u32(np, "stride", &params->stride);
+ if (ret) {
+ dev_err(dev, "Can't parse stride property\n");
+ return ret;
+ }
+
+ ret = of_property_read_string(np, "format", &format);
+ if (ret) {
+ dev_err(dev, "Can't parse format property\n");
+ return ret;
+ }
+ params->format = NULL;
+ for (i = 0; i < ARRAY_SIZE(simplefb_formats); i++) {
+ if (strcmp(format, simplefb_formats[i].name))
+ continue;
+ params->format = &simplefb_formats[i];
+ break;
+ }
+ if (!params->format) {
+ dev_err(dev, "Invalid format value\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int simplefb_probe(struct device_d *dev)
+{
+ int ret;
+ struct simplefb_params params;
+ struct fb_info *info;
+ struct resource *mem;
+
+ ret = -ENODEV;
+ if (dev->device_node)
+ ret = simplefb_parse_dt(dev, &params);
+
+ if (ret)
+ return ret;
+
+ mem = dev_request_mem_resource(dev, 0);
+ if (IS_ERR(mem)) {
+ dev_err(dev, "No memory resource\n");
+ return PTR_ERR(mem);
+ }
+
+ info = xzalloc(sizeof(*info));
+ dev->priv = info;
+
+ info->xres = params.width;
+ info->yres = params.height;
+ info->bits_per_pixel = params.format->bits_per_pixel;
+ info->red = params.format->red;
+ info->green = params.format->green;
+ info->blue = params.format->blue;
+ info->transp = params.format->transp;
+ info->line_length = params.stride;
+
+ info->screen_base = (void *)mem->start;
+ info->screen_size = resource_size(mem);
+
+
+ info->fbops = &simplefb_ops;
+
+ dev_info(dev, "framebuffer at 0x%p, 0x%lx bytes\n",
+ info->screen_base, info->screen_size);
+ dev_info(dev, "format=%s, mode=%dx%dx%d, linelength=%d\n",
+ params.format->name,
+ info->xres, info->yres,
+ info->bits_per_pixel, info->line_length);
+
+ ret = register_framebuffer(info);
+ if (ret < 0) {
+ dev_err(dev, "Unable to register simplefb: %d\n", ret);
+ return ret;
+ }
+
+ dev_info(dev, "simplefb registered!\n");
+
+ return 0;
+}
+
+static const struct of_device_id simplefb_of_match[] = {
+ { .compatible = "simple-framebuffer", },
+ { },
+};
+
+static struct driver_d simplefb_driver = {
+ .name = "simple-framebuffer",
+ .of_compatible = simplefb_of_match,
+ .probe = simplefb_probe,
+};
+device_platform_driver(simplefb_driver);
+
+MODULE_AUTHOR("Stephen Warren <swarren@wwwdotorg.org>");
+MODULE_DESCRIPTION("Simple framebuffer driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/video/simplefb.c b/drivers/video/simplefb-fixup.c
index a2c59de364..a2c59de364 100644
--- a/drivers/video/simplefb.c
+++ b/drivers/video/simplefb-fixup.c
diff --git a/include/linux/platform_data/simplefb.h b/include/linux/platform_data/simplefb.h
new file mode 100644
index 0000000000..a4f07eccd8
--- /dev/null
+++ b/include/linux/platform_data/simplefb.h
@@ -0,0 +1,46 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * simplefb.h - Simple Framebuffer Device
+ *
+ * Copyright (C) 2013 David Herrmann <dh.herrmann@gmail.com>
+ */
+
+#ifndef __PLATFORM_DATA_SIMPLEFB_H__
+#define __PLATFORM_DATA_SIMPLEFB_H__
+
+#include <video/fourcc.h>
+#include <fb.h>
+#include <linux/types.h>
+
+/* format array, use it to initialize a "struct simplefb_format" array */
+#define SIMPLEFB_FORMATS \
+{ \
+ { "r5g6b5", 16, {11, 5}, {5, 6}, {0, 5}, {0, 0}, DRM_FORMAT_RGB565 }, \
+ { "x1r5g5b5", 16, {10, 5}, {5, 5}, {0, 5}, {0, 0}, DRM_FORMAT_XRGB1555 }, \
+ { "a1r5g5b5", 16, {10, 5}, {5, 5}, {0, 5}, {15, 1}, DRM_FORMAT_ARGB1555 }, \
+ { "r8g8b8", 24, {16, 8}, {8, 8}, {0, 8}, {0, 0}, DRM_FORMAT_RGB888 }, \
+ { "x8r8g8b8", 32, {16, 8}, {8, 8}, {0, 8}, {0, 0}, DRM_FORMAT_XRGB8888 }, \
+ { "a8r8g8b8", 32, {16, 8}, {8, 8}, {0, 8}, {24, 8}, DRM_FORMAT_ARGB8888 }, \
+ { "a8b8g8r8", 32, {0, 8}, {8, 8}, {16, 8}, {24, 8}, DRM_FORMAT_ABGR8888 }, \
+ { "x2r10g10b10", 32, {20, 10}, {10, 10}, {0, 10}, {0, 0}, DRM_FORMAT_XRGB2101010 }, \
+ { "a2r10g10b10", 32, {20, 10}, {10, 10}, {0, 10}, {30, 2}, DRM_FORMAT_ARGB2101010 }, \
+}
+
+/*
+ * Data-Format for Simple-Framebuffers
+ * @name: unique 0-terminated name that can be used to identify the mode
+ * @red,green,blue: Offsets and sizes of the single RGB parts
+ * @transp: Offset and size of the alpha bits. length=0 means no alpha
+ * @fourcc: 32bit DRM four-CC code (see drm_fourcc.h)
+ */
+struct simplefb_format {
+ const char *name;
+ u32 bits_per_pixel;
+ struct fb_bitfield red;
+ struct fb_bitfield green;
+ struct fb_bitfield blue;
+ struct fb_bitfield transp;
+ u32 fourcc;
+};
+
+#endif /* __PLATFORM_DATA_SIMPLEFB_H__ */