This patchset explores the idea of adding a DRM text mode (like VGA text mode) to get an alternative to fbcon/fbdev.
David Hermann has done alot of work on a fbcon replacement: - drm: add kernel-log renderer (Mar 2014)[1] - kmscon: development started Nov 2011 added to systemd Oct 2014 removed from systemd Jul 2015[2]
Since this work seems to have stalled, I propose an alternative solution to this problem that will also give VT console support while we're waiting for a userspace console.
The idea is that the driver provides a modeset like with the fbdev emulation code, and from this a text buffer representation is made. The console code can now write to this text buffer and ask for the text buffer to be flushed/rendered to the pixel buffer.
In this hack/implementation of the idea, I have just hijacked a CMA backed fbdev framebuffer to keep it simple. I have reused the default buffer format that VT uses. Getting panic handling to actually work, seems to be a challenge as Daniel describes on the DRMJanitors page[3].
Is this idea of a DRM text mode worth developing further?
Noralf.
[1] https://lwn.net/Articles/589858/ [2] https://github.com/systemd/systemd/pull/747 [3] https://www.x.org/wiki/DRMJanitors/#makepanichandlingwork
Noralf Trønnes (3): drm: Add support for text framebuffer drm/text: Add panic and boot console support drm/text: Add VT console support
drivers/gpu/drm/Makefile | 1 + drivers/gpu/drm/drm-text/Makefile | 5 + drivers/gpu/drm/drm-text/drm-text-buffer.c | 340 ++++++++++++++++++++++++++++ drivers/gpu/drm/drm-text/drm-text-console.c | 205 +++++++++++++++++ drivers/gpu/drm/drm-text/drm-text-debugfs.c | 295 ++++++++++++++++++++++++ drivers/gpu/drm/drm-text/drm-text-vt.c | 197 ++++++++++++++++ drivers/gpu/drm/drm-text/drm-text.h | 99 ++++++++ 7 files changed, 1142 insertions(+) create mode 100644 drivers/gpu/drm/drm-text/Makefile create mode 100644 drivers/gpu/drm/drm-text/drm-text-buffer.c create mode 100644 drivers/gpu/drm/drm-text/drm-text-console.c create mode 100644 drivers/gpu/drm/drm-text/drm-text-debugfs.c create mode 100644 drivers/gpu/drm/drm-text/drm-text-vt.c create mode 100644 drivers/gpu/drm/drm-text/drm-text.h
-- 2.8.2
This adds a text representation of a drm_framebuffer with backing object.
Signed-off-by: Noralf Trønnes noralf@tronnes.org --- drivers/gpu/drm/Makefile | 1 + drivers/gpu/drm/drm-text/Makefile | 4 + drivers/gpu/drm/drm-text/drm-text-buffer.c | 336 ++++++++++++++++++++++++++++ drivers/gpu/drm/drm-text/drm-text-debugfs.c | 206 +++++++++++++++++ drivers/gpu/drm/drm-text/drm-text.h | 81 +++++++ 5 files changed, 628 insertions(+) create mode 100644 drivers/gpu/drm/drm-text/Makefile create mode 100644 drivers/gpu/drm/drm-text/drm-text-buffer.c create mode 100644 drivers/gpu/drm/drm-text/drm-text-debugfs.c create mode 100644 drivers/gpu/drm/drm-text/drm-text.h
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index e3dba6f..94a846d 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -83,3 +83,4 @@ obj-$(CONFIG_DRM_FSL_DCU) += fsl-dcu/ obj-$(CONFIG_DRM_ETNAVIV) += etnaviv/ obj-$(CONFIG_DRM_ARCPGU)+= arc/ obj-y += hisilicon/ +obj-y += drm-text/ diff --git a/drivers/gpu/drm/drm-text/Makefile b/drivers/gpu/drm/drm-text/Makefile new file mode 100644 index 0000000..48f55bc --- /dev/null +++ b/drivers/gpu/drm/drm-text/Makefile @@ -0,0 +1,4 @@ +drm-text-y := drm-text-buffer.o +drm-text-$(CONFIG_DEBUG_FS) += drm-text-debugfs.o + +obj-m += drm-text.o diff --git a/drivers/gpu/drm/drm-text/drm-text-buffer.c b/drivers/gpu/drm/drm-text/drm-text-buffer.c new file mode 100644 index 0000000..187dd4b --- /dev/null +++ b/drivers/gpu/drm/drm-text/drm-text-buffer.c @@ -0,0 +1,336 @@ +#define DEBUG +/* + * Copyright 2016 Noralf Trønnes + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include <drm/drmP.h> +#include <drm/drm_fb_cma_helper.h> +#include <drm/drm_fb_helper.h> +#include <drm/drm_gem_cma_helper.h> +#include <linux/font.h> +#include <linux/module.h> + +#include "drm-text.h" + +struct drm_text_buffer *drm_text_buffers[MAX_DRM_TEXT_BUFFERS]; + +/** + * DOC: overview + * + * Text buffer format 16-bit: 4-bit bg color, 4-bit fg color, 8-bit character + * The CGA color palette is used: 4-bit RGBI: intense red green blue + * + * drm_text_get(): get a text buffer for a dev->primary->index + * Clients can write directly to the text buffer + * drm_text_write(): write string to text buffer (handles wrapping) + * drm_text_scroll(): scroll text buffer + * drm_text_flush(): flush text buffer to pixel buffer (uses worker unless panic) + * drm_text_enable/disable(): enabled/disable text buffer (mode setting) + * + */ + +static const u32 drm_text_palette888[] = { + 0x00000000, /* 0 black */ + 0x000000aa, /* 1 blue */ + 0x0000aa00, /* 2 green */ + 0x0000aaaa, /* 3 cyan */ + 0x00aa0000, /* 4 red */ + 0x00aa00aa, /* 5 magenta */ + 0x00aa5500, /* 6 brown */ + 0x00aaaaaa, /* 7 light gray */ + 0x00555555, /* 8 dark gray */ + 0x005555ff, /* 9 bright blue */ + 0x0055ff55, /* 10 bright green */ + 0x0055ffff, /* 11 bright cyan */ + 0x00ff5555, /* 12 bright red */ + 0x00ff55ff, /* 13 bright magenta */ + 0x00ffff55, /* 14 yellow */ + 0x00ffffff /* 15 white */ +}; + +static const u16 drm_text_palette565[] = { + 0x0000, /* 0 black */ + 0x0015, /* 1 blue */ + 0x0540, /* 2 green */ + 0x0555, /* 3 cyan */ + 0xa800, /* 4 red */ + 0xa815, /* 5 magenta */ + 0xaaa0, /* 6 brown */ + 0xad55, /* 7 light gray */ + 0x52aa, /* 8 dark gray */ + 0x52bf, /* 9 bright blue */ + 0x57ea, /* 10 bright green */ + 0x57ff, /* 11 bright cyan */ + 0xfaaa, /* 12 bright red */ + 0xfabf, /* 13 bright magenta */ + 0xffea, /* 14 yellow */ + 0xffff /* 15 white */ +}; + +static void drm_text_render_char(struct drm_text_buffer *text, size_t x, size_t y) +{ + u16 cc = text->text_buf[x + (y * text->cols)]; + const struct font_desc *font = text->font; + u16 *vmem = text->pixel_buf; + char c = cc; + unsigned int h, w; + const u8 *src; + u16 fg_col = drm_text_palette565[(cc & 0x0f00) >> 8]; + u16 bg_col = drm_text_palette565[cc >> 12]; + + src = font->data + c * font->height; + + for (h = 0; h < font->height; h++) { + u8 fontline = *(src + h); + + for (w = 0; w < font->width; w++) { + size_t i = ((x * font->width) + w) + (((y * font->height) + h) * text->fb->width); + + vmem[i] = fontline & BIT(7 - w) ? fg_col : bg_col; + } + } +} + +static void drm_text_do_flush(struct drm_text_buffer *text) +{ + size_t x, y; + + drm_text_debug("%s - IN\n", __func__); + + for (y = 0; y < text->rows; y++) { + for (x = 0; x < text->cols; x++) { + /* + * TODO + * A copy of the previously rendered text_buf + * could help speed this up by skipping characters + * that haven't changed + */ + drm_text_render_char(text, x, y); + } + } + + drm_text_debug("%s - OUT\n", __func__); +} + +static void drm_text_flush_work(struct work_struct *work) +{ + struct drm_text_buffer *text = container_of(work, struct drm_text_buffer, + flush_work); + struct drm_framebuffer *fb = text->fb; + + drm_text_debug("%s\n", __func__); + drm_text_do_flush(text); + + if (fb->funcs->dirty) + fb->funcs->dirty(fb, NULL, 0, 0, NULL, 0); +} + +void drm_text_flush(struct drm_text_buffer *text, bool panic) +{ + + drm_text_debug("%s(panic=%u)\n", __func__, panic); + if (panic) + drm_text_do_flush(text); + else + schedule_work(&text->flush_work); +} + +void drm_text_write(struct drm_text_buffer *text, const char *str, + unsigned int num) +{ + unsigned int i; + + for (i = 0; i < num; i++) { + char c = *str++; + + if (text->y_pos == text->rows) { + drm_text_scroll(text, 0, text->rows, 1); + text->y_pos--; + } + + if (c == '\n') { + text->x_pos = 0; + text->y_pos++; + continue; + } + + text->text_buf[text->x_pos + (text->y_pos * text->cols)] = 0x0f00 | c; + text->x_pos++; + + if (text->x_pos == text->cols) { + text->x_pos = 0; + text->y_pos++; + } + } +} + +/* TODO: Is top and bottom necessary? From VT */ +void drm_text_scroll(struct drm_text_buffer *text, unsigned int top, + unsigned int bottom, int lines) +{ + size_t count; + + drm_text_debug("%s(top=%u, bottom=%u, lines=%d)\n", __func__, top, bottom, lines); + + if (lines > 0) { + count = text->cols * (text->rows - lines); + memmove(text->text_buf, text->text_buf + text->cols, count * sizeof(u16)); + memset(text->text_buf + count, 0, text->cols * lines * sizeof(u16)); + } else if (lines < 0) { + drm_text_log("%s: TODO\n", __func__); + } + +} + +int drm_text_enable(struct drm_text_buffer *text) +{ + int ret; + + ret = drm_fb_helper_set_par(text->fbi); + if (ret) + drm_text_log("%s: failed to enable %d\n", __func__, ret); + + return ret; +} + +int drm_text_disable(struct drm_text_buffer *text) +{ + int ret; + + ret = fb_blank(text->fbi, FB_BLANK_POWERDOWN); + if (ret) + drm_text_log("%s: failed to disable %d\n", __func__, ret); + + return ret; +} + +struct drm_text_buffer *drm_text_get(unsigned int index) +{ + if (index >= MAX_DRM_TEXT_BUFFERS) + return NULL; + + return drm_text_buffers[index]; +} + +static struct drm_text_buffer *drm_text_create_from_fb_helper(struct drm_fb_helper *fb_helper) +{ + struct drm_framebuffer *fb = fb_helper->fb; + struct drm_gem_cma_object *cma_obj; + struct drm_text_buffer *text; + int ret; + + switch (fb->pixel_format) { + case DRM_FORMAT_RGB565: + break; + default: + return ERR_PTR(-EINVAL); + } + + text = kzalloc(sizeof(*text), GFP_KERNEL); + if (!text) + return ERR_PTR(-ENOMEM); + + INIT_WORK(&text->flush_work, drm_text_flush_work); + text->fb = fb; + text->fbi = fb_helper->fbdev; + + DRM_DEBUG_KMS("DRM minor: %d\n", fb->dev->primary->index); + + cma_obj = drm_fb_cma_get_gem_obj(fb, 0); + text->pixel_buf = cma_obj->vaddr; + + DRM_DEBUG_KMS("[FB:%d] pixel_format: %s, vaddr=%p\n", fb->base.id, + drm_get_format_name(fb->pixel_format), cma_obj->vaddr); + + /* TODO: 10 and 12 width fonts are not supported */ + text->font = get_default_font(fb->width, fb->height, -1, -1); + if (!text->font) { + ret = -ENODEV; + goto err_free; + } + + DRM_DEBUG_KMS("font: %s\n", text->font->name); + text->cols = text->fb->width / text->font->width; + text->rows = text->fb->height / text->font->height; + DRM_DEBUG_KMS("cols=%zu, rows=%zu\n", text->cols, text->rows); + + text->text_buf = kcalloc(text->cols * text->rows, sizeof(*text->text_buf), GFP_KERNEL); + if (!text->text_buf) { + ret = -ENOMEM; + goto err_free; + } + + drm_text_debugfs_buffer_init(text); +/* REMOVE, helpful while testing on display that needs fb flushing */ +drm_text_flush(text, false); + + return text; + +err_free: + DRM_DEBUG_KMS("Error creating buffer %d\n", ret); + kfree(text->text_buf); + kfree(text); + + return ERR_PTR(ret); +} + +static void drm_text_scan_fbdev(void) +{ + struct drm_fb_helper *fb_helper; + struct drm_text_buffer *text; + unsigned int i; + + for (i = 0; i < FB_MAX; i++) { + struct fb_info *info = registered_fb[i]; + + if (!info) + continue; + + fb_helper = info->par; + if (fb_helper && fb_helper->fbdev == info) { + text = drm_text_create_from_fb_helper(fb_helper); + if (!IS_ERR(text)) + drm_text_buffers[text->fb->dev->primary->index] = text; + } + } +} + +static void drm_text_free(struct drm_text_buffer *text) +{ + kfree(text->text_buf); + kfree(text); +} + +static int __init drm_text_init(void) +{ + int ret = 0; + + ret = drm_text_debugfs_init(); + if (ret) + pr_err("Failed to create debugfs entry\n"); + + drm_text_scan_fbdev(); + + + return ret; +} +module_init(drm_text_init); + +static void __exit drm_text_exit(void) +{ + unsigned int i; + + drm_text_debugfs_exit(); + + for (i = 0; i < MAX_DRM_TEXT_BUFFERS; i++) + if (drm_text_buffers[i]) + drm_text_free(drm_text_buffers[i]); +} +module_exit(drm_text_exit); + +MODULE_LICENSE("GPL"); diff --git a/drivers/gpu/drm/drm-text/drm-text-debugfs.c b/drivers/gpu/drm/drm-text/drm-text-debugfs.c new file mode 100644 index 0000000..d01f995 --- /dev/null +++ b/drivers/gpu/drm/drm-text/drm-text-debugfs.c @@ -0,0 +1,206 @@ +/* + * Copyright 2016 Noralf Trønnes + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include <drm/drmP.h> +#include <linux/debugfs.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/seq_file.h> +#include <linux/slab.h> +#include <linux/uaccess.h> + +#include "drm-text.h" + +#define HACK_NEED_FLUSHING + +#define LOG_LINE 64 +#define LOG_ENTRIES PAGE_SIZE / LOG_LINE + +static char *log_buf; +static size_t log_pos; +static struct dentry *drm_text_debugfs_root; + +static void drm_text_vprintk(int level, const char *fmt, va_list args) +{ + u32 rem_nsec; + char *text; + size_t len; + u64 sec; + + if (log_pos >= LOG_ENTRIES) + log_pos = 0; + + text = log_buf + (log_pos++ * LOG_LINE); + if (log_pos == LOG_ENTRIES) + log_pos = 0; + + sec = div_u64_rem(local_clock(), 1000000000, &rem_nsec); + + len = scnprintf(text, LOG_LINE, "[%5llu.%06u] ", sec, rem_nsec / 1000); + + vscnprintf(text + len, LOG_LINE - len, fmt, args); + + /* Make sure to always have a newline in case of overflow */ + if (text[LOG_LINE - 2] != '\0') + text[LOG_LINE - 2] = '\n'; +} + +void drm_text_log(const char *fmt, ...) +{ + va_list args; + + if (!log_buf) + return; + + va_start(args, fmt); + drm_text_vprintk(LOGLEVEL_DEFAULT, fmt, args); + va_end(args); +} + +static int drm_text_log_show(struct seq_file *m, void *v) +{ + size_t pos = log_pos; + unsigned int i; + char *text; + + for (i = 0; i < LOG_ENTRIES; i++) { + text = log_buf + (pos++ * LOG_LINE); + if (pos == LOG_ENTRIES) + pos = 0; + if (*text == '\0') + continue; + seq_puts(m, text); + } + + return 0; +} + +static int drm_text_log_open(struct inode *inode, struct file *file) +{ + return single_open(file, drm_text_log_show, NULL); +} + +static const struct file_operations drm_text_log_ops = { + .owner = THIS_MODULE, + .open = drm_text_log_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int drm_text_buffer_show(struct seq_file *m, void *v) +{ + struct drm_text_buffer *text = m->private; + size_t x, y; + + for (y = 0; y < text->rows; y++) { + for (x = 0; x < text->cols; x++) { + char c = text->text_buf[x + (y * text->cols)]; + + if (c < 32 || c == 127 || c == 255) + c = ' '; + seq_putc(m, c); + } + seq_putc(m, '\n'); + } + + return 0; +} + +static int drm_text_buffer_open(struct inode *inode, struct file *file) +{ + struct drm_text_buffer *text = inode->i_private; + + return single_open(file, drm_text_buffer_show, text); +} + +static const struct file_operations drm_text_buffer_ops = { + .owner = THIS_MODULE, + .open = drm_text_buffer_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +void drm_text_debugfs_buffer_init(struct drm_text_buffer *text) +{ + char name[64]; + + snprintf(name, sizeof(name), "%d", text->fb->dev->primary->index); + debugfs_create_file(name, S_IRUGO, drm_text_debugfs_root, text, + &drm_text_buffer_ops); +} + +static ssize_t drm_text_flush_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct drm_text_buffer *text; + unsigned long long val; + char buf[24]; + ssize_t ret = 0; + size_t size; + + size = min(sizeof(buf) - 1, count); + if (copy_from_user(buf, user_buf, size)) + return -EFAULT; + + buf[size] = '\0'; + ret = kstrtoull(buf, 0, &val); + if (ret) + return ret; + + text = drm_text_get(val); + if (!text) + return -EINVAL; + + //drm_text_flush(text, false); + if (text->fb->funcs->dirty) + text->fb->funcs->dirty(text->fb, NULL, 0, 0, NULL, 0); + + return count; +} + +static const struct file_operations drm_text_flush_ops = { + .write = drm_text_flush_write, + .open = simple_open, + .llseek = default_llseek, +}; + +int drm_text_debugfs_init(void) +{ + drm_text_debugfs_root = debugfs_create_dir("drm-text", NULL); + if (!drm_text_debugfs_root) + return -ENOMEM; + + if (!debugfs_create_file("log", S_IRUGO, drm_text_debugfs_root, NULL, + &drm_text_log_ops)) + goto err_remove; + + log_buf = kzalloc(PAGE_SIZE, GFP_KERNEL); + if (!log_buf) + goto err_remove; + + debugfs_create_file("flush", S_IWUSR, drm_text_debugfs_root, NULL, + &drm_text_flush_ops); + + return 0; + +err_remove: + debugfs_remove_recursive(drm_text_debugfs_root); + + return -ENOMEM; +} + +void drm_text_debugfs_exit(void) +{ + debugfs_remove_recursive(drm_text_debugfs_root); + kfree(log_buf); + log_buf = NULL; +} diff --git a/drivers/gpu/drm/drm-text/drm-text.h b/drivers/gpu/drm/drm-text/drm-text.h new file mode 100644 index 0000000..77e7429 --- /dev/null +++ b/drivers/gpu/drm/drm-text/drm-text.h @@ -0,0 +1,81 @@ +/* + * Copyright 2016 Noralf Trønnes + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef __LINUX_DRM_TEXT_H +#define __LINUX_DRM_TEXT_H + +#include <linux/workqueue.h> + +#define MAX_DRM_TEXT_BUFFERS 64 + +extern struct drm_text_buffer *drm_text_buffers[]; + +struct drm_text_buffer { + struct fb_info *fbi; + + struct work_struct flush_work; + const struct font_desc *font; + struct drm_framebuffer *fb; + void *pixel_buf; + u16 *text_buf; + size_t rows; + size_t cols; + size_t x_pos; + size_t y_pos; +}; + +void drm_text_flush(struct drm_text_buffer *text, bool panic); +void drm_text_write(struct drm_text_buffer *text, const char *str, + unsigned int num); +void drm_text_scroll(struct drm_text_buffer *text, unsigned int top, + unsigned int bottom, int lines); +int drm_text_enable(struct drm_text_buffer *text); +int drm_text_disable(struct drm_text_buffer *text); +struct drm_text_buffer *drm_text_get(unsigned int index); + +#ifdef DEBUG +#define drm_text_debug(fmt, ...) \ + drm_text_log(fmt, ##__VA_ARGS__) +#else +#define drm_text_debug(fmt, ...) \ +do { \ + if (0) \ + drm_text_log(fmt, ##__VA_ARGS__); \ +} while (0) +#endif + +#ifdef CONFIG_DEBUG_FS + +void drm_text_log(const char *fmt, ...) __printf(1, 2); +void drm_text_debugfs_buffer_init(struct drm_text_buffer *text); +int drm_text_debugfs_init(void); +void drm_text_debugfs_exit(void); + +#else + +static inline void drm_text_log(const char *fmt, ...) __printf(1, 2) +{ +} + +void drm_text_debugfs_buffer_init(struct drm_text_buffer *text) +{ +} + +static inline int drm_text_debugfs_init(void) +{ + return 0; +} + +static inline void drm_text_debugfs_exit(void); +{ +} + +#endif + +#endif
This adds support for panic and boot console.
Signed-off-by: Noralf Trønnes noralf@tronnes.org --- drivers/gpu/drm/drm-text/Makefile | 2 +- drivers/gpu/drm/drm-text/drm-text-buffer.c | 4 +- drivers/gpu/drm/drm-text/drm-text-console.c | 205 ++++++++++++++++++++++++++++ drivers/gpu/drm/drm-text/drm-text-debugfs.c | 89 ++++++++++++ drivers/gpu/drm/drm-text/drm-text.h | 4 + 5 files changed, 302 insertions(+), 2 deletions(-) create mode 100644 drivers/gpu/drm/drm-text/drm-text-console.c
diff --git a/drivers/gpu/drm/drm-text/Makefile b/drivers/gpu/drm/drm-text/Makefile index 48f55bc..be042b0 100644 --- a/drivers/gpu/drm/drm-text/Makefile +++ b/drivers/gpu/drm/drm-text/Makefile @@ -1,4 +1,4 @@ -drm-text-y := drm-text-buffer.o +drm-text-y := drm-text-console.o drm-text-buffer.o drm-text-$(CONFIG_DEBUG_FS) += drm-text-debugfs.o
obj-m += drm-text.o diff --git a/drivers/gpu/drm/drm-text/drm-text-buffer.c b/drivers/gpu/drm/drm-text/drm-text-buffer.c index 187dd4b..91beb48 100644 --- a/drivers/gpu/drm/drm-text/drm-text-buffer.c +++ b/drivers/gpu/drm/drm-text/drm-text-buffer.c @@ -308,7 +308,7 @@ static void drm_text_free(struct drm_text_buffer *text)
static int __init drm_text_init(void) { - int ret = 0; + int ret;
ret = drm_text_debugfs_init(); if (ret) @@ -316,6 +316,7 @@ static int __init drm_text_init(void)
drm_text_scan_fbdev();
+ ret = drm_text_console_init();
return ret; } @@ -325,6 +326,7 @@ static void __exit drm_text_exit(void) { unsigned int i;
+ drm_text_console_exit(); drm_text_debugfs_exit();
for (i = 0; i < MAX_DRM_TEXT_BUFFERS; i++) diff --git a/drivers/gpu/drm/drm-text/drm-text-console.c b/drivers/gpu/drm/drm-text/drm-text-console.c new file mode 100644 index 0000000..e7ef244 --- /dev/null +++ b/drivers/gpu/drm/drm-text/drm-text-console.c @@ -0,0 +1,205 @@ +#define DEBUG +/* + * Copyright 2016 Noralf Trønnes + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include <linux/console.h> +#include <linux/slab.h> + +#include "drm-text.h" + +static bool drm_text_console_panic; + +/** + * DOC: message/boot console + * + * The kernel message &console is enabled by using console=drm[n] where n is + * the primary minor number. Only one console is supported. + */ + +static void drm_text_console_write(struct console *con, const char *str, + unsigned int num) +{ + struct drm_text_buffer *text; + + drm_text_debug("%s(num=%u)\n", __func__, num); + if (drm_text_console_panic) + return; + + text = drm_text_get(con->index); + if (!text) + return; + + drm_text_write(text, str, num); + drm_text_flush(text, false); +} + +static int drm_text_console_setup(struct console *con, char *options) +{ + struct drm_text_buffer *text; + + drm_text_debug("%s[%u](%s) data=%p\n", __func__, con->index, options, con->data); + + text = drm_text_get(con->index); + if (text) + drm_text_enable(text); + + return 0; +} + +/* TODO: test as a boot console */ +static struct console drm_text_console = { + .name = "drm", + .write = drm_text_console_write, + .setup = drm_text_console_setup, + .flags = CON_PRINTBUFFER, + .index = -1, +}; + +/** + * DOC: panic console + * + * The panic &console is always enabled and collects kernel messages in a + * buffer as they come in. + * When the kernel does panic(), a panic notifier enables all text buffers. + * On the next &console->write it replays the message buffer and starts + * writing to all text buffers. Flushing of the text buffer to the pixel + * buffer is done inline instead of using the worker. + */ + +#define DRM_TEXT_PANIC_KMSGS_MAX SZ_1K + +struct drm_text_panic_console { + char kmsgs[DRM_TEXT_PANIC_KMSGS_MAX]; + size_t kmsg_pos; +}; + +static void drm_text_panic_write(const char *str, unsigned int num) +{ + unsigned int i; + + drm_text_debug("%s(num=%u)\n", __func__, num); + + for (i = 0; i < MAX_DRM_TEXT_BUFFERS; i++) + if (drm_text_buffers[i]) + drm_text_write(drm_text_buffers[i], str, num); +} + +static void drm_text_panic_flush(void) +{ + unsigned int i; + + drm_text_debug("%s()\n", __func__); + + for (i = 0; i < MAX_DRM_TEXT_BUFFERS; i++) + if (drm_text_buffers[i]) + drm_text_flush(drm_text_buffers[i], true); +} + +static void drm_text_panic_console_write(struct console *con, const char *str, + unsigned int num) +{ + struct drm_text_panic_console *pcon = con->data; + unsigned int i; + + drm_text_debug("%s(num=%u)\n", __func__, num); + + if (!pcon) + return; + + /* Buffer up messages to be replayed on panic */ + if (!drm_text_console_panic) { + for (i = 0; i < num; i++) { + pcon->kmsgs[pcon->kmsg_pos++] = *str++; + if (pcon->kmsg_pos == DRM_TEXT_PANIC_KMSGS_MAX) + pcon->kmsg_pos = 0; + } + return; + } + + if (pcon->kmsgs[0]) { + /* replay messages, the first one might be partial */ + if (pcon->kmsgs[pcon->kmsg_pos]) { /* buffer wrap around */ + drm_text_panic_write(&pcon->kmsgs[pcon->kmsg_pos], + DRM_TEXT_PANIC_KMSGS_MAX - pcon->kmsg_pos); + drm_text_panic_write(pcon->kmsgs, pcon->kmsg_pos); + } else { + drm_text_panic_write(pcon->kmsgs, pcon->kmsg_pos); + } + pcon->kmsgs[0] = '\0'; + } + + drm_text_panic_write(str, num); + drm_text_panic_flush(); +} + +static struct console drm_text_panic_console = { + .name = "drmpanic", + .write = drm_text_panic_console_write, + .flags = CON_PRINTBUFFER | CON_ENABLED, + .index = 0, +}; + +static int drm_text_panic_console_setup(struct console *con) +{ + struct drm_text_panic_console *pcon; + + drm_text_debug("%s[%u]() data=%p\n", __func__, con->index, con->data); + + pcon = kzalloc(sizeof(*pcon), GFP_KERNEL); + if (!pcon) + return -ENOMEM; + + con->data = pcon; + + return 0; +} + +int drm_text_panic(struct notifier_block *this, unsigned long ev, void *ptr) +{ + unsigned int i; + + drm_text_console_panic = true; + for (i = 0; i < MAX_DRM_TEXT_BUFFERS; i++) + if (drm_text_buffers[i]) + drm_text_enable(drm_text_buffers[i]); + + return NOTIFY_DONE; +} + +static struct notifier_block drm_text_panic_block = { + .notifier_call = drm_text_panic, +}; + +int drm_text_console_init(void) +{ + drm_text_log("%s\n", __func__); + + register_console(&drm_text_panic_console); + drm_text_panic_console_setup(&drm_text_panic_console); + atomic_notifier_chain_register(&panic_notifier_list, + &drm_text_panic_block); + drm_text_debug("drm_text_panic_console: index=%d, flags=0x%x\n", + drm_text_panic_console.index, drm_text_panic_console.flags); + + register_console(&drm_text_console); + drm_text_debug("drm_text_console: index=%d, flags=0x%x\n", + drm_text_console.index, drm_text_console.flags); + + return 0; +} + +void drm_text_console_exit(void) +{ + atomic_notifier_chain_unregister(&panic_notifier_list, + &drm_text_panic_block); + unregister_console(&drm_text_panic_console); + kfree(drm_text_panic_console.data); + + unregister_console(&drm_text_console); +} diff --git a/drivers/gpu/drm/drm-text/drm-text-debugfs.c b/drivers/gpu/drm/drm-text/drm-text-debugfs.c index d01f995..542ccac 100644 --- a/drivers/gpu/drm/drm-text/drm-text-debugfs.c +++ b/drivers/gpu/drm/drm-text/drm-text-debugfs.c @@ -173,6 +173,93 @@ static const struct file_operations drm_text_flush_ops = { .llseek = default_llseek, };
+/* + * Fake/simulate panic() at different levels: + * 1: only trigger panic handling internally + * 2: local_irq_disable() + * 3: bust_spinlocks(); + * 100: don't fake it, do call panic() + */ +static int drm_text_fake_panic(unsigned int level) +{ +/* The console_* symbols are not exported */ +// int old_loglevel = console_loglevel; + + if (!level && level != 100 && level > 3) + return -EINVAL; + + if (level == 100) + panic("TESTING"); + + if (level > 1) + local_irq_disable(); + +// console_verbose(); + + if (level > 2) + bust_spinlocks(1); + + pr_emerg("Kernel panic - not syncing: TESTING\n"); + +#ifdef CONFIG_DEBUG_BUGVERBOSE + dump_stack(); +#endif + + /* simulate calling panic_notifier_list */ + drm_text_panic(NULL, 0 , NULL); + + if (level > 2) + bust_spinlocks(0); + +// console_flush_on_panic(); + + pr_emerg("---[ end Kernel panic - not syncing: TESTING\n"); + + if (level > 1) + local_irq_enable(); + +// console_loglevel = old_loglevel; + +#ifdef HACK_NEED_FLUSHING +{ + struct drm_text_buffer *text = drm_text_get(0); + + if (text && text->fb->funcs->dirty) + text->fb->funcs->dirty(text->fb, NULL, 0, 0, NULL, 0); +} +#endif + return 0; +} + +static ssize_t drm_text_panic_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + unsigned long long val; + char buf[24]; + ssize_t ret = 0; + size_t size; + + size = min(sizeof(buf) - 1, count); + if (copy_from_user(buf, user_buf, size)) + return -EFAULT; + + buf[size] = '\0'; + ret = kstrtoull(buf, 0, &val); + if (ret) + return ret; + + ret = drm_text_fake_panic(1); + + return ret < 0 ? ret : count; +} + +static const struct file_operations drm_text_panic_ops = { + .write = drm_text_panic_write, + .open = simple_open, + .llseek = default_llseek, +}; + int drm_text_debugfs_init(void) { drm_text_debugfs_root = debugfs_create_dir("drm-text", NULL); @@ -189,6 +276,8 @@ int drm_text_debugfs_init(void)
debugfs_create_file("flush", S_IWUSR, drm_text_debugfs_root, NULL, &drm_text_flush_ops); + debugfs_create_file("panic", S_IWUSR, drm_text_debugfs_root, NULL, + &drm_text_panic_ops);
return 0;
diff --git a/drivers/gpu/drm/drm-text/drm-text.h b/drivers/gpu/drm/drm-text/drm-text.h index 77e7429..43ba76c 100644 --- a/drivers/gpu/drm/drm-text/drm-text.h +++ b/drivers/gpu/drm/drm-text/drm-text.h @@ -39,6 +39,10 @@ int drm_text_enable(struct drm_text_buffer *text); int drm_text_disable(struct drm_text_buffer *text); struct drm_text_buffer *drm_text_get(unsigned int index);
+int drm_text_console_init(void); +void drm_text_console_exit(void); +int drm_text_panic(struct notifier_block *this, unsigned long ev, void *ptr); + #ifdef DEBUG #define drm_text_debug(fmt, ...) \ drm_text_log(fmt, ##__VA_ARGS__)
This adds VT console support.
Signed-off-by: Noralf Trønnes noralf@tronnes.org --- drivers/gpu/drm/drm-text/Makefile | 1 + drivers/gpu/drm/drm-text/drm-text-buffer.c | 2 + drivers/gpu/drm/drm-text/drm-text-vt.c | 197 +++++++++++++++++++++++++++++ drivers/gpu/drm/drm-text/drm-text.h | 14 ++ 4 files changed, 214 insertions(+) create mode 100644 drivers/gpu/drm/drm-text/drm-text-vt.c
diff --git a/drivers/gpu/drm/drm-text/Makefile b/drivers/gpu/drm/drm-text/Makefile index be042b0..4427522 100644 --- a/drivers/gpu/drm/drm-text/Makefile +++ b/drivers/gpu/drm/drm-text/Makefile @@ -1,4 +1,5 @@ drm-text-y := drm-text-console.o drm-text-buffer.o +drm-text-$(CONFIG_VT) += drm-text-vt.o drm-text-$(CONFIG_DEBUG_FS) += drm-text-debugfs.o
obj-m += drm-text.o diff --git a/drivers/gpu/drm/drm-text/drm-text-buffer.c b/drivers/gpu/drm/drm-text/drm-text-buffer.c index 91beb48..0f995d3 100644 --- a/drivers/gpu/drm/drm-text/drm-text-buffer.c +++ b/drivers/gpu/drm/drm-text/drm-text-buffer.c @@ -317,6 +317,7 @@ static int __init drm_text_init(void) drm_text_scan_fbdev();
ret = drm_text_console_init(); + ret = drm_text_vt_init();
return ret; } @@ -327,6 +328,7 @@ static void __exit drm_text_exit(void) unsigned int i;
drm_text_console_exit(); + drm_text_vt_exit(); drm_text_debugfs_exit();
for (i = 0; i < MAX_DRM_TEXT_BUFFERS; i++) diff --git a/drivers/gpu/drm/drm-text/drm-text-vt.c b/drivers/gpu/drm/drm-text/drm-text-vt.c new file mode 100644 index 0000000..a999a41 --- /dev/null +++ b/drivers/gpu/drm/drm-text/drm-text-vt.c @@ -0,0 +1,197 @@ +#define DEBUG +/* + * Copyright 2016 Noralf Trønnes + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include <linux/console.h> +#include <linux/err.h> +#include <linux/vt_buffer.h> +#include <linux/vt_kern.h> + +#include "drm-text.h" + +static unsigned int drm_text_vt_map[MAX_DRM_TEXT_BUFFERS]; + +/* TODO: Some kind of mapping might be needed */ +static inline struct drm_text_buffer *drm_text_vt_get(unsigned int index) +{ + return drm_text_get(drm_text_vt_map[index]); +} + +static const char *drm_text_con_startup(void) +{ + drm_text_debug("%s\n", __func__); + return "drm-vt"; +} + +static void drm_text_con_init(struct vc_data *vc, int init) +{ + struct drm_text_buffer *text = drm_text_vt_get(vc->vc_num); + + drm_text_log("%s[%u](init=%d)\n", __func__, vc->vc_num, init); + + vc->vc_can_do_color = 1; + + if (!text) { + drm_text_log("%s[%u] no DRM device\n", __func__, vc->vc_num); + return; + } + + if (init) { + vc->vc_cols = text->cols; + vc->vc_rows = text->rows; + } else { + vc_resize(vc, text->cols, text->rows); + } + + drm_text_enable(text); +} + +static void drm_text_con_deinit(struct vc_data *vc) +{ + drm_text_debug("%s[%u]\n", __func__, vc->vc_num); + pr_info("%s\n", __func__); +} + +static void drm_text_con_putcs(struct vc_data *vc, const unsigned short *s, + int count, int y, int x) +{ + struct drm_text_buffer *text = drm_text_vt_get(vc->vc_num); + u16 *dest; + + if (!text) + return; + + dest = &text->text_buf[x + (y * text->cols)]; + + for (; count > 0; count--) { + scr_writew(scr_readw(s++), dest++); + } + drm_text_flush(text, false); +} + +static void drm_text_con_putc(struct vc_data *vc, int ch, int y, int x) +{ + struct drm_text_buffer *text = drm_text_vt_get(vc->vc_num); + unsigned short chr; + + if (!text) + return; + + scr_writew(ch, &chr); + drm_text_con_putcs(vc, &chr, 1, y, x); +} + +/* TODO: How do I actually test this? */ +static void drm_text_con_clear(struct vc_data *vc, int y, int x, + int height, int width) +{ + struct drm_text_buffer *text = drm_text_vt_get(vc->vc_num); + + drm_text_debug("%s[%u]\n", __func__, vc->vc_num); + + if (!text) + return; + + scr_memcpyw(text->text_buf, (unsigned short *)vc->vc_pos, + vc->vc_cols * vc->vc_rows); + drm_text_flush(text, false); +} + +static int drm_text_con_switch(struct vc_data *vc) +{ + drm_text_debug("%s[%u] %ux%u\n", __func__, vc->vc_num, vc->vc_cols, vc->vc_rows); + + return 1; /* redrawing needed */ +} + +static void drm_text_con_set_palette(struct vc_data *vc, const unsigned char *table) +{ + drm_text_debug("%s[%u]\n", __func__, vc->vc_num); +} + +static int drm_text_con_blank(struct vc_data *vc, int blank, int mode_switch) +{ + struct drm_text_buffer *text = drm_text_vt_get(vc->vc_num); + int ret; + + drm_text_debug("%s[%u](blank=%d, mode_switch=%d)\n", __func__, vc->vc_num, blank, mode_switch); + + if (!text) + return 0; + + if (blank) + ret = drm_text_disable(text); + else + ret = drm_text_enable(text); + + return ret; +} + +static void drm_text_con_scrolldelta(struct vc_data *vc, int lines) +{ + drm_text_debug("%s[%u](lines=%d)\n", __func__, vc->vc_num, lines); +} + +static void drm_text_con_cursor(struct vc_data *vc, int mode) +{ + /* TODO: Do we need a blinking cursor? */ +} + +static int drm_text_con_scroll(struct vc_data *vc, int t, int b, int dir, int lines) +{ + struct drm_text_buffer *text = drm_text_vt_get(vc->vc_num); + + if (!text) + return 0; + + switch (dir) { + case SM_UP: + drm_text_scroll(text, t, b, lines); + break; + case SM_DOWN: + drm_text_scroll(text, t, b, -lines); + break; + } + + return 0; +} + +static const struct consw drm_text_vt = { + .owner = THIS_MODULE, + .con_startup = drm_text_con_startup, + .con_init = drm_text_con_init, + .con_deinit = drm_text_con_deinit, + .con_clear = drm_text_con_clear, + .con_putc = drm_text_con_putc, + .con_putcs = drm_text_con_putcs, + .con_cursor = drm_text_con_cursor, + .con_scroll = drm_text_con_scroll, + .con_switch = drm_text_con_switch, + .con_blank = drm_text_con_blank, + .con_set_palette = drm_text_con_set_palette, + .con_scrolldelta = drm_text_con_scrolldelta, +}; + +int drm_text_vt_init(void) +{ + int ret; + + drm_text_debug("%s\n", __func__); + + console_lock(); + ret = do_take_over_console(&drm_text_vt, 0, MAX_NR_CONSOLES - 1, 0); + console_unlock(); + + return ret; +} + +void drm_text_vt_exit(void) +{ + give_up_console(&drm_text_vt); +} diff --git a/drivers/gpu/drm/drm-text/drm-text.h b/drivers/gpu/drm/drm-text/drm-text.h index 43ba76c..a01c283 100644 --- a/drivers/gpu/drm/drm-text/drm-text.h +++ b/drivers/gpu/drm/drm-text/drm-text.h @@ -43,6 +43,20 @@ int drm_text_console_init(void); void drm_text_console_exit(void); int drm_text_panic(struct notifier_block *this, unsigned long ev, void *ptr);
+#ifdef CONFIG_VT +int drm_text_vt_init(void); +void drm_text_vt_exit(void); +#else +int drm_text_vt_init(void) +{ + return 0; +} + +void drm_text_vt_exit(void) +{ +} +#endif + #ifdef DEBUG #define drm_text_debug(fmt, ...) \ drm_text_log(fmt, ##__VA_ARGS__)
On Thu, Jul 28, 2016 at 04:15:04PM +0200, Noralf Trønnes wrote:
This patchset explores the idea of adding a DRM text mode (like VGA text mode) to get an alternative to fbcon/fbdev.
David Hermann has done alot of work on a fbcon replacement:
- drm: add kernel-log renderer (Mar 2014)[1]
- kmscon: development started Nov 2011 added to systemd Oct 2014 removed from systemd Jul 2015[2]
Since this work seems to have stalled, I propose an alternative solution to this problem that will also give VT console support while we're waiting for a userspace console.
The idea is that the driver provides a modeset like with the fbdev emulation code, and from this a text buffer representation is made. The console code can now write to this text buffer and ask for the text buffer to be flushed/rendered to the pixel buffer.
In this hack/implementation of the idea, I have just hijacked a CMA backed fbdev framebuffer to keep it simple. I have reused the default buffer format that VT uses. Getting panic handling to actually work, seems to be a challenge as Daniel describes on the DRMJanitors page[3].
Is this idea of a DRM text mode worth developing further?
I guess some simpler drm console with vt support which would allow us to get rid of fbdev could make sense. And there's definitely going to be a lot of overlap with a full userspace solution using something like kmscon.
But we can't just add a new drm text console, there's a pile of prep work needed that David started for either approach: - Nuking fbdev means no more fbdev drivers for firmware consoles (uboot, uefi, vga, ...). The simpledrm driver would cover this, would be great to get that landed (especially now that we have the simple pipe helpers!).
- One nice benefit of fbdev is that it automatically gets rid of these firmware-based display drivers when the real driver loads. Some drivers do this properly even when fbdev isn't enabled (see i915_kick_out_vgacon and i915_kick_out_firmware_fb), but pretty much all others fail in some way or the other. David also had some code (iirc as part of simpledrm) to solve this issue.
- I think we need more than rbg565 render support, iirc David also had some work in that area.
- None of these approaches has a good answer yet to the configuration question. For a full VT I think we definitely should share the setup logic with the fbdev emulation code to make it useful, but as describe in the DRMJanitors page handlings panics is an entierly different problem.
Definitely coordinate with David Herrmann here too, since if we do something in this area it should be widely supported.
Aside: Where's the pull request for your driver? ;-)
Cheers, Daniel
Noralf.
[1] https://lwn.net/Articles/589858/ [2] https://github.com/systemd/systemd/pull/747 [3] https://www.x.org/wiki/DRMJanitors/#makepanichandlingwork
Noralf Trønnes (3): drm: Add support for text framebuffer drm/text: Add panic and boot console support drm/text: Add VT console support
drivers/gpu/drm/Makefile | 1 + drivers/gpu/drm/drm-text/Makefile | 5 + drivers/gpu/drm/drm-text/drm-text-buffer.c | 340 ++++++++++++++++++++++++++++ drivers/gpu/drm/drm-text/drm-text-console.c | 205 +++++++++++++++++ drivers/gpu/drm/drm-text/drm-text-debugfs.c | 295 ++++++++++++++++++++++++ drivers/gpu/drm/drm-text/drm-text-vt.c | 197 ++++++++++++++++ drivers/gpu/drm/drm-text/drm-text.h | 99 ++++++++ 7 files changed, 1142 insertions(+) create mode 100644 drivers/gpu/drm/drm-text/Makefile create mode 100644 drivers/gpu/drm/drm-text/drm-text-buffer.c create mode 100644 drivers/gpu/drm/drm-text/drm-text-console.c create mode 100644 drivers/gpu/drm/drm-text/drm-text-debugfs.c create mode 100644 drivers/gpu/drm/drm-text/drm-text-vt.c create mode 100644 drivers/gpu/drm/drm-text/drm-text.h
-- 2.8.2
dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Actually adding David. -Daniel
On Fri, Jul 29, 2016 at 10:20:51AM +0200, Daniel Vetter wrote:
On Thu, Jul 28, 2016 at 04:15:04PM +0200, Noralf Trønnes wrote:
This patchset explores the idea of adding a DRM text mode (like VGA text mode) to get an alternative to fbcon/fbdev.
David Hermann has done alot of work on a fbcon replacement:
- drm: add kernel-log renderer (Mar 2014)[1]
- kmscon: development started Nov 2011 added to systemd Oct 2014 removed from systemd Jul 2015[2]
Since this work seems to have stalled, I propose an alternative solution to this problem that will also give VT console support while we're waiting for a userspace console.
The idea is that the driver provides a modeset like with the fbdev emulation code, and from this a text buffer representation is made. The console code can now write to this text buffer and ask for the text buffer to be flushed/rendered to the pixel buffer.
In this hack/implementation of the idea, I have just hijacked a CMA backed fbdev framebuffer to keep it simple. I have reused the default buffer format that VT uses. Getting panic handling to actually work, seems to be a challenge as Daniel describes on the DRMJanitors page[3].
Is this idea of a DRM text mode worth developing further?
I guess some simpler drm console with vt support which would allow us to get rid of fbdev could make sense. And there's definitely going to be a lot of overlap with a full userspace solution using something like kmscon.
But we can't just add a new drm text console, there's a pile of prep work needed that David started for either approach:
Nuking fbdev means no more fbdev drivers for firmware consoles (uboot, uefi, vga, ...). The simpledrm driver would cover this, would be great to get that landed (especially now that we have the simple pipe helpers!).
One nice benefit of fbdev is that it automatically gets rid of these firmware-based display drivers when the real driver loads. Some drivers do this properly even when fbdev isn't enabled (see i915_kick_out_vgacon and i915_kick_out_firmware_fb), but pretty much all others fail in some way or the other. David also had some code (iirc as part of simpledrm) to solve this issue.
I think we need more than rbg565 render support, iirc David also had some work in that area.
None of these approaches has a good answer yet to the configuration question. For a full VT I think we definitely should share the setup logic with the fbdev emulation code to make it useful, but as describe in the DRMJanitors page handlings panics is an entierly different problem.
Definitely coordinate with David Herrmann here too, since if we do something in this area it should be widely supported.
Aside: Where's the pull request for your driver? ;-)
Cheers, Daniel
Noralf.
[1] https://lwn.net/Articles/589858/ [2] https://github.com/systemd/systemd/pull/747 [3] https://www.x.org/wiki/DRMJanitors/#makepanichandlingwork
Noralf Trønnes (3): drm: Add support for text framebuffer drm/text: Add panic and boot console support drm/text: Add VT console support
drivers/gpu/drm/Makefile | 1 + drivers/gpu/drm/drm-text/Makefile | 5 + drivers/gpu/drm/drm-text/drm-text-buffer.c | 340 ++++++++++++++++++++++++++++ drivers/gpu/drm/drm-text/drm-text-console.c | 205 +++++++++++++++++ drivers/gpu/drm/drm-text/drm-text-debugfs.c | 295 ++++++++++++++++++++++++ drivers/gpu/drm/drm-text/drm-text-vt.c | 197 ++++++++++++++++ drivers/gpu/drm/drm-text/drm-text.h | 99 ++++++++ 7 files changed, 1142 insertions(+) create mode 100644 drivers/gpu/drm/drm-text/Makefile create mode 100644 drivers/gpu/drm/drm-text/drm-text-buffer.c create mode 100644 drivers/gpu/drm/drm-text/drm-text-console.c create mode 100644 drivers/gpu/drm/drm-text/drm-text-debugfs.c create mode 100644 drivers/gpu/drm/drm-text/drm-text-vt.c create mode 100644 drivers/gpu/drm/drm-text/drm-text.h
-- 2.8.2
dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
-- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch
Den 29.07.2016 10:23, skrev Daniel Vetter:
Actually adding David. -Daniel
On Fri, Jul 29, 2016 at 10:20:51AM +0200, Daniel Vetter wrote:
On Thu, Jul 28, 2016 at 04:15:04PM +0200, Noralf Trønnes wrote:
This patchset explores the idea of adding a DRM text mode (like VGA text mode) to get an alternative to fbcon/fbdev.
David Hermann has done alot of work on a fbcon replacement:
- drm: add kernel-log renderer (Mar 2014)[1]
- kmscon: development started Nov 2011 added to systemd Oct 2014 removed from systemd Jul 2015[2]
Since this work seems to have stalled, I propose an alternative solution to this problem that will also give VT console support while we're waiting for a userspace console.
The idea is that the driver provides a modeset like with the fbdev emulation code, and from this a text buffer representation is made. The console code can now write to this text buffer and ask for the text buffer to be flushed/rendered to the pixel buffer.
In this hack/implementation of the idea, I have just hijacked a CMA backed fbdev framebuffer to keep it simple. I have reused the default buffer format that VT uses. Getting panic handling to actually work, seems to be a challenge as Daniel describes on the DRMJanitors page[3].
Is this idea of a DRM text mode worth developing further?
I guess some simpler drm console with vt support which would allow us to get rid of fbdev could make sense. And there's definitely going to be a lot of overlap with a full userspace solution using something like kmscon.
But we can't just add a new drm text console, there's a pile of prep work needed that David started for either approach:
- Nuking fbdev means no more fbdev drivers for firmware consoles (uboot, uefi, vga, ...). The simpledrm driver would cover this, would be great to get that landed (especially now that we have the simple pipe helpers!).
I have rebased simpledrm on drm_simple_display_pipe and have it working on a Raspberry Pi. modetest gives me a wrong picture, but that is probably because of some wrong format conversion since fbdev using the native rgb565 format works fine.
I could finish this up and send a patch unless David is working on something?
I have used this version of simpledrm: [PATCH 09/11] drm: add SimpleDRM driver https://lists.freedesktop.org/archives/dri-devel/2014-January/052594.html
One nice benefit of fbdev is that it automatically gets rid of these firmware-based display drivers when the real driver loads. Some drivers do this properly even when fbdev isn't enabled (see i915_kick_out_vgacon and i915_kick_out_firmware_fb), but pretty much all others fail in some way or the other. David also had some code (iirc as part of simpledrm) to solve this issue.
I think we need more than rbg565 render support, iirc David also had some work in that area.
None of these approaches has a good answer yet to the configuration question. For a full VT I think we definitely should share the setup logic with the fbdev emulation code to make it useful, but as describe in the DRMJanitors page handlings panics is an entierly different problem.
Definitely coordinate with David Herrmann here too, since if we do something in this area it should be widely supported.
Aside: Where's the pull request for your driver? ;-)
I have been working on tinydrm for 6 months straight now and it wasn't fun anymore. So I figured this was a good time to take a break from it and do something else for a while :-)
Noralf.
Cheers, Daniel
Noralf.
[1] https://lwn.net/Articles/589858/ [2] https://github.com/systemd/systemd/pull/747 [3] https://www.x.org/wiki/DRMJanitors/#makepanichandlingwork
Noralf Trønnes (3): drm: Add support for text framebuffer drm/text: Add panic and boot console support drm/text: Add VT console support
drivers/gpu/drm/Makefile | 1 + drivers/gpu/drm/drm-text/Makefile | 5 + drivers/gpu/drm/drm-text/drm-text-buffer.c | 340 ++++++++++++++++++++++++++++ drivers/gpu/drm/drm-text/drm-text-console.c | 205 +++++++++++++++++ drivers/gpu/drm/drm-text/drm-text-debugfs.c | 295 ++++++++++++++++++++++++ drivers/gpu/drm/drm-text/drm-text-vt.c | 197 ++++++++++++++++ drivers/gpu/drm/drm-text/drm-text.h | 99 ++++++++ 7 files changed, 1142 insertions(+) create mode 100644 drivers/gpu/drm/drm-text/Makefile create mode 100644 drivers/gpu/drm/drm-text/drm-text-buffer.c create mode 100644 drivers/gpu/drm/drm-text/drm-text-console.c create mode 100644 drivers/gpu/drm/drm-text/drm-text-debugfs.c create mode 100644 drivers/gpu/drm/drm-text/drm-text-vt.c create mode 100644 drivers/gpu/drm/drm-text/drm-text.h
-- 2.8.2
dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
-- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch
Den 30.07.2016 17:48, skrev Noralf Trønnes:
Den 29.07.2016 10:23, skrev Daniel Vetter:
Actually adding David. -Daniel
On Fri, Jul 29, 2016 at 10:20:51AM +0200, Daniel Vetter wrote:
On Thu, Jul 28, 2016 at 04:15:04PM +0200, Noralf Trønnes wrote:
This patchset explores the idea of adding a DRM text mode (like VGA text mode) to get an alternative to fbcon/fbdev.
David Hermann has done alot of work on a fbcon replacement:
- drm: add kernel-log renderer (Mar 2014)[1]
- kmscon: development started Nov 2011 added to systemd Oct 2014 removed from systemd Jul 2015[2]
Since this work seems to have stalled, I propose an alternative solution to this problem that will also give VT console support while we're waiting for a userspace console.
The idea is that the driver provides a modeset like with the fbdev emulation code, and from this a text buffer representation is made. The console code can now write to this text buffer and ask for the text buffer to be flushed/rendered to the pixel buffer.
In this hack/implementation of the idea, I have just hijacked a CMA backed fbdev framebuffer to keep it simple. I have reused the default buffer format that VT uses. Getting panic handling to actually work, seems to be a challenge as Daniel describes on the DRMJanitors page[3].
Is this idea of a DRM text mode worth developing further?
I guess some simpler drm console with vt support which would allow us to get rid of fbdev could make sense. And there's definitely going to be a lot of overlap with a full userspace solution using something like kmscon.
But we can't just add a new drm text console, there's a pile of prep work needed that David started for either approach:
- Nuking fbdev means no more fbdev drivers for firmware consoles
(uboot, uefi, vga, ...). The simpledrm driver would cover this, would be great to get that landed (especially now that we have the simple pipe helpers!).
I have rebased simpledrm on drm_simple_display_pipe and have it working on a Raspberry Pi. modetest gives me a wrong picture, but that is probably because of some wrong format conversion since fbdev using the native rgb565 format works fine.
I could finish this up and send a patch unless David is working on something?
I have used this version of simpledrm: [PATCH 09/11] drm: add SimpleDRM driver https://lists.freedesktop.org/archives/dri-devel/2014-January/052594.html
I have solved the format conversion problem.
Is there any reason why simpledrm can't use drm_gem_cma_helper? This is how it allocates memory:
int sdrm_gem_get_pages(struct sdrm_gem_object *obj) { [...] num = obj->base.size >> PAGE_SHIFT; obj->pages = drm_malloc_ab(num, sizeof(*obj->pages)); [...] for (i = 0; i < num; ++i) { obj->pages[i] = alloc_page(GFP_KERNEL | __GFP_ZERO); [...] obj->vmapping = vmap(obj->pages, num, 0, PAGE_KERNEL); [...] }
The simpledrm driver has this set_config:
static int sdrm_crtc_set_config(struct drm_mode_set *set) { struct drm_device *ddev; struct sdrm_device *sdrm; struct sdrm_framebuffer *fb; [...] ddev = set->crtc->dev; sdrm = ddev->dev_private; [...] fb = to_sdrm_fb(set->fb); [...] if (set->mode->hdisplay != sdrm->fb_width || set->mode->vdisplay != sdrm->fb_height) return -EINVAL; if (fb->base.width <= set->x || fb->base.height <= set->y || fb->base.width - set->x < sdrm->fb_width || fb->base.height - set->y < sdrm->fb_height) return -EINVAL; [...] }
Do I need to perform any of these checks in the new check function? And if so, how?
static int sdrm_display_pipe_check(struct drm_simple_display_pipe *pipe, struct drm_plane_state *plane_state, struct drm_crtc_state *crtc_state) { struct sdrm_device *sdrm = pipe_to_sdrm(pipe);
return 0; }
Noralf.
On Mon, Aug 1, 2016 at 12:50 PM, Noralf Trønnes noralf@tronnes.org wrote:
Den 30.07.2016 17:48, skrev Noralf Trønnes:
Den 29.07.2016 10:23, skrev Daniel Vetter:
Actually adding David. -Daniel
On Fri, Jul 29, 2016 at 10:20:51AM +0200, Daniel Vetter wrote:
On Thu, Jul 28, 2016 at 04:15:04PM +0200, Noralf Trønnes wrote:
This patchset explores the idea of adding a DRM text mode (like VGA text mode) to get an alternative to fbcon/fbdev.
David Hermann has done alot of work on a fbcon replacement:
- drm: add kernel-log renderer (Mar 2014)[1]
- kmscon: development started Nov 2011 added to systemd Oct 2014 removed from systemd Jul 2015[2]
Since this work seems to have stalled, I propose an alternative solution to this problem that will also give VT console support while we're waiting for a userspace console.
The idea is that the driver provides a modeset like with the fbdev emulation code, and from this a text buffer representation is made. The console code can now write to this text buffer and ask for the text buffer to be flushed/rendered to the pixel buffer.
In this hack/implementation of the idea, I have just hijacked a CMA backed fbdev framebuffer to keep it simple. I have reused the default buffer format that VT uses. Getting panic handling to actually work, seems to be a challenge as Daniel describes on the DRMJanitors page[3].
Is this idea of a DRM text mode worth developing further?
I guess some simpler drm console with vt support which would allow us to get rid of fbdev could make sense. And there's definitely going to be a lot of overlap with a full userspace solution using something like kmscon.
But we can't just add a new drm text console, there's a pile of prep work needed that David started for either approach:
- Nuking fbdev means no more fbdev drivers for firmware consoles (uboot, uefi, vga, ...). The simpledrm driver would cover this, would be
great to get that landed (especially now that we have the simple pipe helpers!).
I have rebased simpledrm on drm_simple_display_pipe and have it working on a Raspberry Pi. modetest gives me a wrong picture, but that is probably because of some wrong format conversion since fbdev using the native rgb565 format works fine.
I could finish this up and send a patch unless David is working on something?
I have used this version of simpledrm: [PATCH 09/11] drm: add SimpleDRM driver https://lists.freedesktop.org/archives/dri-devel/2014-January/052594.html
I have solved the format conversion problem.
Is there any reason why simpledrm can't use drm_gem_cma_helper? This is how it allocates memory:
I'm not sure on the details, but iirc simple_drm must reuse the framebuffer provided by the firmware. Hence it can't just use any random pile of memory allocated through other means. But David probably knows this better.
int sdrm_gem_get_pages(struct sdrm_gem_object *obj) { [...] num = obj->base.size >> PAGE_SHIFT; obj->pages = drm_malloc_ab(num, sizeof(*obj->pages)); [...] for (i = 0; i < num; ++i) { obj->pages[i] = alloc_page(GFP_KERNEL | __GFP_ZERO); [...] obj->vmapping = vmap(obj->pages, num, 0, PAGE_KERNEL); [...] }
The simpledrm driver has this set_config:
static int sdrm_crtc_set_config(struct drm_mode_set *set) { struct drm_device *ddev; struct sdrm_device *sdrm; struct sdrm_framebuffer *fb; [...] ddev = set->crtc->dev; sdrm = ddev->dev_private; [...] fb = to_sdrm_fb(set->fb); [...] if (set->mode->hdisplay != sdrm->fb_width || set->mode->vdisplay != sdrm->fb_height) return -EINVAL; if (fb->base.width <= set->x || fb->base.height <= set->y || fb->base.width - set->x < sdrm->fb_width || fb->base.height - set->y < sdrm->fb_height) return -EINVAL; [...] }
Do I need to perform any of these checks in the new check function? And if so, how?
Instead of set->(mode|x|y) look at crtc_state->(mode|x|y), and instead of fb look at plane_state->fb. Everything else should be checked with the default plane helper checks the simple pipe helpers already do. -Daniel
static int sdrm_display_pipe_check(struct drm_simple_display_pipe *pipe, struct drm_plane_state *plane_state, struct drm_crtc_state *crtc_state) { struct sdrm_device *sdrm = pipe_to_sdrm(pipe);
return 0;
}
Noralf.
On Sat, Jul 30, 2016 at 5:48 PM, Noralf Trønnes noralf@tronnes.org wrote:
Den 29.07.2016 10:23, skrev Daniel Vetter:
Actually adding David. -Daniel
On Fri, Jul 29, 2016 at 10:20:51AM +0200, Daniel Vetter wrote:
On Thu, Jul 28, 2016 at 04:15:04PM +0200, Noralf Trønnes wrote:
This patchset explores the idea of adding a DRM text mode (like VGA text mode) to get an alternative to fbcon/fbdev.
David Hermann has done alot of work on a fbcon replacement:
- drm: add kernel-log renderer (Mar 2014)[1]
- kmscon: development started Nov 2011 added to systemd Oct 2014 removed from systemd Jul 2015[2]
Since this work seems to have stalled, I propose an alternative solution to this problem that will also give VT console support while we're waiting for a userspace console.
The idea is that the driver provides a modeset like with the fbdev emulation code, and from this a text buffer representation is made. The console code can now write to this text buffer and ask for the text buffer to be flushed/rendered to the pixel buffer.
In this hack/implementation of the idea, I have just hijacked a CMA backed fbdev framebuffer to keep it simple. I have reused the default buffer format that VT uses. Getting panic handling to actually work, seems to be a challenge as Daniel describes on the DRMJanitors page[3].
Is this idea of a DRM text mode worth developing further?
I guess some simpler drm console with vt support which would allow us to get rid of fbdev could make sense. And there's definitely going to be a lot of overlap with a full userspace solution using something like kmscon.
But we can't just add a new drm text console, there's a pile of prep work needed that David started for either approach:
- Nuking fbdev means no more fbdev drivers for firmware consoles (uboot, uefi, vga, ...). The simpledrm driver would cover this, would be great to get that landed (especially now that we have the simple pipe helpers!).
I have rebased simpledrm on drm_simple_display_pipe and have it working on a Raspberry Pi. modetest gives me a wrong picture, but that is probably because of some wrong format conversion since fbdev using the native rgb565 format works fine.
I could finish this up and send a patch unless David is working on something?
I have used this version of simpledrm: [PATCH 09/11] drm: add SimpleDRM driver https://lists.freedesktop.org/archives/dri-devel/2014-January/052594.html
David seems busy with kdbus/bus1 still right now (I chatted with him on irc), so just go ahead. But please cc him so he can take a quick look and ack your version.
- One nice benefit of fbdev is that it automatically gets rid of these firmware-based display drivers when the real driver loads. Some
drivers do this properly even when fbdev isn't enabled (see i915_kick_out_vgacon and i915_kick_out_firmware_fb), but pretty much all others fail in some way or the other. David also had some code (iirc as part of simpledrm) to solve this issue.
I think we need more than rbg565 render support, iirc David also had some work in that area.
None of these approaches has a good answer yet to the configuration question. For a full VT I think we definitely should share the setup logic with the fbdev emulation code to make it useful, but as describe in the DRMJanitors page handlings panics is an entierly different problem.
Definitely coordinate with David Herrmann here too, since if we do something in this area it should be widely supported.
Aside: Where's the pull request for your driver? ;-)
I have been working on tinydrm for 6 months straight now and it wasn't fun anymore. So I figured this was a good time to take a break from it and do something else for a while :-)
:( Still looking forward to it, I think with all the nice prep work you've done it would be a shame if the reason for it all wouldn't make it in. -Daniel
Noralf.
Cheers, Daniel
Noralf.
[1] https://lwn.net/Articles/589858/ [2] https://github.com/systemd/systemd/pull/747 [3] https://www.x.org/wiki/DRMJanitors/#makepanichandlingwork
Noralf Trønnes (3): drm: Add support for text framebuffer drm/text: Add panic and boot console support drm/text: Add VT console support
drivers/gpu/drm/Makefile | 1 + drivers/gpu/drm/drm-text/Makefile | 5 + drivers/gpu/drm/drm-text/drm-text-buffer.c | 340 ++++++++++++++++++++++++++++ drivers/gpu/drm/drm-text/drm-text-console.c | 205 +++++++++++++++++ drivers/gpu/drm/drm-text/drm-text-debugfs.c | 295 ++++++++++++++++++++++++ drivers/gpu/drm/drm-text/drm-text-vt.c | 197 ++++++++++++++++ drivers/gpu/drm/drm-text/drm-text.h | 99 ++++++++ 7 files changed, 1142 insertions(+) create mode 100644 drivers/gpu/drm/drm-text/Makefile create mode 100644 drivers/gpu/drm/drm-text/drm-text-buffer.c create mode 100644 drivers/gpu/drm/drm-text/drm-text-console.c create mode 100644 drivers/gpu/drm/drm-text/drm-text-debugfs.c create mode 100644 drivers/gpu/drm/drm-text/drm-text-vt.c create mode 100644 drivers/gpu/drm/drm-text/drm-text.h
-- 2.8.2
dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
-- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch
Den 02.08.2016 15:05, skrev Daniel Vetter:
On Sat, Jul 30, 2016 at 5:48 PM, Noralf Trønnes noralf@tronnes.org wrote:
Den 29.07.2016 10:23, skrev Daniel Vetter:
Actually adding David. -Daniel
On Fri, Jul 29, 2016 at 10:20:51AM +0200, Daniel Vetter wrote:
On Thu, Jul 28, 2016 at 04:15:04PM +0200, Noralf Trønnes wrote:
<snip>
Aside: Where's the pull request for your driver? ;-)
I have been working on tinydrm for 6 months straight now and it wasn't fun anymore. So I figured this was a good time to take a break from it and do something else for a while :-)
:( Still looking forward to it, I think with all the nice prep work you've done it would be a shame if the reason for it all wouldn't make it in.
I've spent too much time on tinydrm to drop it now, I just need a break.
Noralf.
Hey
On Thu, Jul 28, 2016 at 4:15 PM, Noralf Trønnes noralf@tronnes.org wrote:
This patchset explores the idea of adding a DRM text mode (like VGA text mode) to get an alternative to fbcon/fbdev.
David Hermann has done alot of work on a fbcon replacement:
- drm: add kernel-log renderer (Mar 2014)[1]
- kmscon: development started Nov 2011 added to systemd Oct 2014 removed from systemd Jul 2015[2]
Since this work seems to have stalled, I propose an alternative solution to this problem that will also give VT console support while we're waiting for a userspace console.
The idea is that the driver provides a modeset like with the fbdev emulation code, and from this a text buffer representation is made. The console code can now write to this text buffer and ask for the text buffer to be flushed/rendered to the pixel buffer.
In this hack/implementation of the idea, I have just hijacked a CMA backed fbdev framebuffer to keep it simple. I have reused the default buffer format that VT uses. Getting panic handling to actually work, seems to be a challenge as Daniel describes on the DRMJanitors page[3].
Is this idea of a DRM text mode worth developing further?
Sorry, haven't done much on this stuff lately. I still appreciate being put on CC, thanks for that! I did change my mind several times when working on the VT-replacement layer and everything involved. In the end, my plan was this:
* Make VTs obsolete. Make sure a system can run with CONFIG_VT=n. systemd-logind provides an alternative access-control, but I would not mind dropping it as well and just go with a setup that only has a single gfx/input user per seat. No VTs, no multiplexing, etc. (which is what Ubuntu is going for with the system compositor).
* Make fbdev obsolete. Provide SimpleDRM as a slow-path for any graphics device that no real driver exists for. SimpleDRM always runs a _shadow_ FB, so no direct access to gfx-resources from user-space. If you need that, use something else.
* Support turnover from SimpleDRM to other drivers. This is as simple as destroying the related platform-device before loading a gfx-driver. Patches exist, but requires i915 to move aperture-management out of the ->load callback (i.e., out of drm_global_mutex). The best solution would be to drop ->load entirely. It is not needed, anyway.
* Write an in-kernel terminal layer that can be loaded as dynamic module and is a pure API _consumer_. Nothing can depend on it, hence, it is completely passive and can be loaded on-demand (unlike VTs, which lots of stuff is hooked into). This terminal/console serves as debugging console for developers and can be blended over any current screen content. It simply grabs all input and shadows DRM-Master. It can be toggled via SYSRQ. User-space is unaware of its existence.
Code for all these parts exists (I even wrote the console replacement using the DRM atomic APIs). However, I got distracted with kdbus+bus1, so haven't pushed on it lately.
I can see that the drmcon backend you propose is a nice-to-have, but I don't think it is the ultimate solution. It is a step forward, though, so maybe we should just take it and avoid thinking of the ultimate dream-solution... I don't know.
If there is interest in pushing SimpleDRM and/or related parts, ping me on IRC (@dvdhrm or via email in private). I'd gladly discuss this and try to find some time to revive the patches.
Thanks David
On Tue, Aug 2, 2016 at 3:41 PM, David Herrmann dh.herrmann@gmail.com wrote:
Hey
On Thu, Jul 28, 2016 at 4:15 PM, Noralf Trønnes noralf@tronnes.org wrote:
This patchset explores the idea of adding a DRM text mode (like VGA text mode) to get an alternative to fbcon/fbdev.
David Hermann has done alot of work on a fbcon replacement:
- drm: add kernel-log renderer (Mar 2014)[1]
- kmscon: development started Nov 2011 added to systemd Oct 2014 removed from systemd Jul 2015[2]
Since this work seems to have stalled, I propose an alternative solution to this problem that will also give VT console support while we're waiting for a userspace console.
The idea is that the driver provides a modeset like with the fbdev emulation code, and from this a text buffer representation is made. The console code can now write to this text buffer and ask for the text buffer to be flushed/rendered to the pixel buffer.
In this hack/implementation of the idea, I have just hijacked a CMA backed fbdev framebuffer to keep it simple. I have reused the default buffer format that VT uses. Getting panic handling to actually work, seems to be a challenge as Daniel describes on the DRMJanitors page[3].
Is this idea of a DRM text mode worth developing further?
Sorry, haven't done much on this stuff lately. I still appreciate being put on CC, thanks for that! I did change my mind several times when working on the VT-replacement layer and everything involved. In the end, my plan was this:
- Make VTs obsolete. Make sure a system can run with CONFIG_VT=n.
systemd-logind provides an alternative access-control, but I would not mind dropping it as well and just go with a setup that only has a single gfx/input user per seat. No VTs, no multiplexing, etc. (which is what Ubuntu is going for with the system compositor).
- Make fbdev obsolete. Provide SimpleDRM as a slow-path for any
graphics device that no real driver exists for. SimpleDRM always runs a _shadow_ FB, so no direct access to gfx-resources from user-space. If you need that, use something else.
- Support turnover from SimpleDRM to other drivers. This is as simple
as destroying the related platform-device before loading a gfx-driver. Patches exist, but requires i915 to move aperture-management out of the ->load callback (i.e., out of drm_global_mutex). The best solution would be to drop ->load entirely. It is not needed, anyway.
Good news: We've just fixed that. And many drivers lost their ->load callback too (But not yet amdgpu/radeon/nouveau unfortunately). -Daniel
- Write an in-kernel terminal layer that can be loaded as dynamic
module and is a pure API _consumer_. Nothing can depend on it, hence, it is completely passive and can be loaded on-demand (unlike VTs, which lots of stuff is hooked into). This terminal/console serves as debugging console for developers and can be blended over any current screen content. It simply grabs all input and shadows DRM-Master. It can be toggled via SYSRQ. User-space is unaware of its existence.
Code for all these parts exists (I even wrote the console replacement using the DRM atomic APIs). However, I got distracted with kdbus+bus1, so haven't pushed on it lately.
I can see that the drmcon backend you propose is a nice-to-have, but I don't think it is the ultimate solution. It is a step forward, though, so maybe we should just take it and avoid thinking of the ultimate dream-solution... I don't know.
If there is interest in pushing SimpleDRM and/or related parts, ping me on IRC (@dvdhrm or via email in private). I'd gladly discuss this and try to find some time to revive the patches.
Thanks David
dri-devel@lists.freedesktop.org