From patchwork Thu Jul 28 14:15:07 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Noralf_Tr=C3=B8nnes?= X-Patchwork-Id: 9251169 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 01F2E607D8 for ; Thu, 28 Jul 2016 14:21:18 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E6CE5212BE for ; Thu, 28 Jul 2016 14:21:17 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id DB7BA27813; Thu, 28 Jul 2016 14:21:17 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F2A82212BE for ; Thu, 28 Jul 2016 14:21:16 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id E4FD46E82F; Thu, 28 Jul 2016 14:21:12 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org X-Greylist: delayed 315 seconds by postgrey-1.35 at gabe; Thu, 28 Jul 2016 14:21:09 UTC Received: from smtp.domeneshop.no (smtp.domeneshop.no [IPv6:2a01:5b40:0:3005::1]) by gabe.freedesktop.org (Postfix) with ESMTPS id C90FA6E82E for ; Thu, 28 Jul 2016 14:21:09 +0000 (UTC) Received: from 211.81-166-168.customer.lyse.net ([81.166.168.211]:56115 helo=localhost.localdomain) by smtp.domeneshop.no with esmtpsa (TLS1.1:DHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.80) (envelope-from ) id 1bSm6K-0007dR-5f; Thu, 28 Jul 2016 16:15:52 +0200 From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= To: dri-devel@lists.freedesktop.org Subject: [RFC 3/3] drm/text: Add VT console support Date: Thu, 28 Jul 2016 16:15:07 +0200 Message-Id: <1469715307-32708-4-git-send-email-noralf@tronnes.org> X-Mailer: git-send-email 2.8.2 In-Reply-To: <1469715307-32708-1-git-send-email-noralf@tronnes.org> References: <1469715307-32708-1-git-send-email-noralf@tronnes.org> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP This adds VT console support. Signed-off-by: Noralf Trønnes --- 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 +#include +#include +#include + +#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__)