2005-04-16 22:20:36 +00:00
|
|
|
/*
|
|
|
|
* linux/drivers/video/fbcon.c -- Low level frame buffer based console driver
|
|
|
|
*
|
|
|
|
* Copyright (C) 1995 Geert Uytterhoeven
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* This file is based on the original Amiga console driver (amicon.c):
|
|
|
|
*
|
|
|
|
* Copyright (C) 1993 Hamish Macdonald
|
|
|
|
* Greg Harp
|
|
|
|
* Copyright (C) 1994 David Carter [carter@compsci.bristol.ac.uk]
|
|
|
|
*
|
|
|
|
* with work by William Rucklidge (wjr@cs.cornell.edu)
|
|
|
|
* Geert Uytterhoeven
|
|
|
|
* Jes Sorensen (jds@kom.auc.dk)
|
|
|
|
* Martin Apel
|
|
|
|
*
|
|
|
|
* and on the original Atari console driver (atacon.c):
|
|
|
|
*
|
|
|
|
* Copyright (C) 1993 Bjoern Brauel
|
|
|
|
* Roman Hodek
|
|
|
|
*
|
|
|
|
* with work by Guenther Kelleter
|
|
|
|
* Martin Schaller
|
|
|
|
* Andreas Schwab
|
|
|
|
*
|
|
|
|
* Hardware cursor support added by Emmanuel Marty (core@ggi-project.org)
|
|
|
|
* Smart redraw scrolling, arbitrary font width support, 512char font support
|
|
|
|
* and software scrollback added by
|
|
|
|
* Jakub Jelinek (jj@ultra.linux.cz)
|
|
|
|
*
|
|
|
|
* Random hacking by Martin Mares <mj@ucw.cz>
|
|
|
|
*
|
|
|
|
* 2001 - Documented with DocBook
|
|
|
|
* - Brad Douglas <brad@neruo.com>
|
|
|
|
*
|
|
|
|
* The low level operations for the various display memory organizations are
|
|
|
|
* now in separate source files.
|
|
|
|
*
|
|
|
|
* Currently the following organizations are supported:
|
|
|
|
*
|
|
|
|
* o afb Amiga bitplanes
|
|
|
|
* o cfb{2,4,8,16,24,32} Packed pixels
|
|
|
|
* o ilbm Amiga interleaved bitplanes
|
|
|
|
* o iplan2p[248] Atari interleaved bitplanes
|
|
|
|
* o mfb Monochrome
|
|
|
|
* o vga VGA characters/attributes
|
|
|
|
*
|
|
|
|
* To do:
|
|
|
|
*
|
|
|
|
* - Implement 16 plane mode (iplan2p16)
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* This file is subject to the terms and conditions of the GNU General Public
|
|
|
|
* License. See the file COPYING in the main directory of this archive for
|
|
|
|
* more details.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <linux/module.h>
|
|
|
|
#include <linux/types.h>
|
|
|
|
#include <linux/fs.h>
|
|
|
|
#include <linux/kernel.h>
|
|
|
|
#include <linux/delay.h> /* MSch: for IRQ probe */
|
|
|
|
#include <linux/console.h>
|
|
|
|
#include <linux/string.h>
|
|
|
|
#include <linux/kd.h>
|
|
|
|
#include <linux/slab.h>
|
|
|
|
#include <linux/fb.h>
|
fbcon: Make fbcon a built-time depency for fbdev
There's a bunch of folks who're trying to make printk less
contended and faster, but there's a problem: printk uses the
console_lock, and the console lock has become the BKL for all things
fbdev/fbcon, which in turn pulled in half the drm subsystem under that
lock. That's awkward.
There reasons for that is probably just a historical accident:
- fbcon is a runtime option of fbdev, i.e. at runtime you can pick
whether your fbdev driver instances are used as kernel consoles.
Unfortunately this wasn't implemented with some module option, but
through some module loading magic: As long as you don't load
fbcon.ko, there's no fbdev console support, but loading it (in any
order wrt fbdev drivers) will create console instances for all fbdev
drivers.
- This was implemented through a notifier chain. fbcon.ko enumerates
all fbdev instances at load time and also registers itself as
listener in the fbdev notifier. The fbdev core tries to register new
fbdev instances with fbcon using the notifier.
- On top of that the modifier chain is also used at runtime by the
fbdev subsystem to e.g. control backlights for panels.
- The problem is that the notifier puts a mutex locking context
between fbdev and fbcon, which mixes up the locking contexts for
both the runtime usage and the register time usage to notify fbcon.
And at runtime fbcon (through the fbdev core) might call into the
notifier from a printk critical section while console_lock is held.
- This means console_lock must be an outer lock for the entire fbdev
subsystem, which also means it must be acquired when registering a
new framebuffer driver as the outermost lock since we might call
into fbcon (through the notifier) which would result in a locking
inversion if fbcon would acquire the console_lock from its notifier
callback (which it needs to register the console).
- console_lock can be held anywhere, since printk can be called
anywhere, and through the above story, plus drm/kms being an fbdev
driver, we pull in a shocking amount of locking hiercharchy
underneath the console_lock. Which makes cleaning up printk really
hard (not even splitting console_lock into an rwsem is all that
useful due to this).
There's various ways to address this, but the cleanest would be to
make fbcon a compile-time option, where fbdev directly calls the fbcon
register functions from register_framebuffer, or dummy static inline
versions if fbcon is disabled. Maybe augmented with a runtime knob to
disable fbcon, if that's needed (for debugging perhaps).
But this could break some users who rely on the magic "loading
fbcon.ko enables/disables fbdev framebuffers at runtime" thing, even
if that's unlikely. Hence we must be careful:
1. Create a compile-time dependency between fbcon and fbdev in the
least minimal way. This is what this patch does.
2. Wait at least 1 year to give possible users time to scream about
how we broke their setup. Unlikely, since all distros make fbcon
compile-in, and embedded platforms only compile stuff they know they
need anyway. But still.
3. Convert the notifier to direct functions calls, with dummy static
inlines if fbcon is disabled. We'll still need the fb notifier for the
other uses (like backlights), but we can probably move it into the fb
core (atm it must be built-into vmlinux).
4. Push console_lock down the call-chain, until it is down in
console_register again.
5. Finally start to clean up and rework the printk/console locking.
For context of this saga see
commit 50e244cc793d511b86adea24972f3a7264cae114
Author: Alan Cox <alan@linux.intel.com>
Date: Fri Jan 25 10:28:15 2013 +1000
fb: rework locking to fix lock ordering on takeover
plus the pile of commits on top that tried to make this all work
without terminally upsetting lockdep. We've uncovered all this when
console_lock lockdep annotations where added in
commit daee779718a319ff9f83e1ba3339334ac650bb22
Author: Daniel Vetter <daniel.vetter@ffwll.ch>
Date: Sat Sep 22 19:52:11 2012 +0200
console: implement lockdep support for console_lock
On the patch itself:
- Switch CONFIG_FRAMEBUFFER_CONSOLE to be a boolean, using the overall
CONFIG_FB tristate to decided whether it should be a module or
built-in.
- At first I thought I could force the build depency with just a dummy
symbol that fbcon.ko exports and fb.ko uses. But that leads to a
module depency cycle (it works fine when built-in).
Since this tight binding is the entire goal the simplest solution is
to move all the fbcon modules (and there's a bunch of optinal
source-files which are each modules of their own, for no good
reason) into the overall fb.ko core module. That's a bit more than
what I would have liked to do in this patch, but oh well.
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Cc: Sergey Senozhatsky <sergey.senozhatsky.work@gmail.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Reviewed-by: Sean Paul <seanpaul@chromium.org>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
2017-08-01 15:32:07 +00:00
|
|
|
#include <linux/fbcon.h>
|
2005-04-16 22:20:36 +00:00
|
|
|
#include <linux/vt_kern.h>
|
|
|
|
#include <linux/selection.h>
|
|
|
|
#include <linux/font.h>
|
|
|
|
#include <linux/smp.h>
|
|
|
|
#include <linux/init.h>
|
|
|
|
#include <linux/interrupt.h>
|
|
|
|
#include <linux/crc32.h> /* For counting font checksums */
|
2019-05-28 09:03:01 +00:00
|
|
|
#include <linux/uaccess.h>
|
2007-07-17 11:05:28 +00:00
|
|
|
#include <asm/fb.h>
|
2005-04-16 22:20:36 +00:00
|
|
|
#include <asm/irq.h>
|
|
|
|
|
|
|
|
#include "fbcon.h"
|
|
|
|
|
2019-05-28 09:03:02 +00:00
|
|
|
/*
|
|
|
|
* FIXME: Locking
|
|
|
|
*
|
|
|
|
* - fbcon state itself is protected by the console_lock, and the code does a
|
|
|
|
* pretty good job at making sure that lock is held everywhere it's needed.
|
|
|
|
*
|
|
|
|
* - fbcon doesn't bother with fb_lock/unlock at all. This is buggy, since it
|
|
|
|
* means concurrent access to the same fbdev from both fbcon and userspace
|
|
|
|
* will blow up. To fix this all fbcon calls from fbmem.c need to be moved out
|
|
|
|
* of fb_lock/unlock protected sections, since otherwise we'll recurse and
|
|
|
|
* deadlock eventually. Aside: Due to these deadlock issues the fbdev code in
|
|
|
|
* fbmem.c cannot use locking asserts, and there's lots of callers which get
|
|
|
|
* the rules wrong, e.g. fbsysfs.c entirely missed fb_lock/unlock calls too.
|
|
|
|
*/
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
enum {
|
|
|
|
FBCON_LOGO_CANSHOW = -1, /* the logo can be shown */
|
|
|
|
FBCON_LOGO_DRAW = -2, /* draw the logo to a console */
|
|
|
|
FBCON_LOGO_DONTSHOW = -3 /* do not show the logo */
|
|
|
|
};
|
|
|
|
|
2019-05-28 09:02:39 +00:00
|
|
|
static struct fbcon_display fb_display[MAX_NR_CONSOLES];
|
[PATCH] fbcon: Console Rotation - Prepare fbcon for console rotation
This patch series implements generic code to rotate the console at 90, 180,
and 270 degrees. The implementation is completely done in the framebuffer
console level, thus no changes to the framebuffer layer or to the drivers
are needed.
Console rotation is required by some Sharp-based devices where the natural
orientation of the display is not at 0 degrees. Also, users that have
displays that can pivot will benefit by having a console in portrait mode
if they so desire.
The choice to implement the code in the console layer rather than in the
framebuffer layer is due to the following reasons:
- it's fast
- it does not require driver changes
- it can coexist with devices that can rotate the display at the hardware level
- it complements graphics applications that can do display rotation
The changes to core fbcon are minimal-- recognition of the console
rotation angle so it can swap directions, origins and axes (xres vs yres,
xpanstep vs ypanstep, xoffset vs yoffset, etc) and storage of the rotation
angle per display. The bulk of the code that does the actual drawing to the
screen are placed in separate files. Each angle of rotation has separate
methods (bmove, clear, putcs, cursor, update_start which is derived from
update_var, and clear_margins). To mimimize processing time, the fontdata
are pre-rotated at each console switch (only if the font or the angle has
changed).
The option can be compiled out (CONFIG_FRAMEBUFFER_CONSOLE_ROTATION = n) if
rotation is not needed.
Choosing the rotation angle can be done in several ways:
1. boot option fbcon=rotate:n, where
n = 0 - normal
n = 1 - 90 degrees (clockwise)
n = 2 - 180 degrees (upside down)
n = 3 - 270 degrees (counterclockwise)
2. echo n > /sys/class/graphics/fb[num]/con_rotate
where n is the same as described above. It sets the angle of rotation
of the current console
3 echo n > /sys/class/graphics/fb[num]/con_rotate_all
where n is the same as described above. Globally sets the angle of
rotation.
GOTCHAS:
The option, especially at angles of 90 and 270 degrees, will exercise
the least used code of drivers. Namely, at these angles, panning is done
in the x-axis, so it can reveal bugs in the driver if xpanstep is set
incorrectly. A workaround is to set xpanstep = 0.
Secondly, at these angles, the framebuffer memory access can be
unaligned if (fontheight * bpp) % 32 ~= 0 which can reveal bugs in the drivers
imageblit, fillrect and copyarea functions. (I think cfbfillrect may have
this buglet). A workaround is to use a standard 8x16 font.
Speed:
The scrolling speed difference between 0 and 180 degrees is minimal,
somewhere areound 1-2%. At 90 or 270 degress, speed drops down to a vicinity
of 30-40%. This is understandable because the blit direction is across the
framebuffer "direction." Scrolling will be helped at these angles if xpanstep
is not equal to zero, use of 8x16 fonts, and setting xres_virtual >= xres * 2.
Note: The code is tested on little-endian only, so I don't know if it will
work in big-endian. Please let me know, it will take only less than a minute
of your time.
This patch prepares fbcon for console rotation and contains the following
changes:
- add rotate field in struct fbcon_ops to keep fbcon's current rotation
angle
- add con_rotate field in struct display to store per-display rotation angle
- create a private copy of the current var to fbcon. This will prevent
fbcon from directly manipulating info->var, especially the fields xoffset,
yoffset and vmode.
- add ability to swap pertinent axes (xres, yres; xpanstep, ypanstep; etc)
depending on the rotation angle
- change global update_var() (function that sets the screen start address)
as an fbcon method update_start. This is required because the axes, start
offset, and/or direction can be reversed depending on the rotation angle.
- add fbcon method rotate_font() which will rotate each character bitmap to
the correct angle of rotation.
- add fbcon boot option 'rotate' to select the angle of rotation at bootime.
Currently does nothing until all patches are applied.
Signed-off-by: Antonino Daplas <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-11-09 05:39:09 +00:00
|
|
|
|
2022-04-05 21:03:35 +00:00
|
|
|
struct fb_info *fbcon_registered_fb[FB_MAX];
|
|
|
|
int fbcon_num_registered_fb;
|
|
|
|
|
|
|
|
#define fbcon_for_each_registered_fb(i) \
|
|
|
|
for (i = 0; WARN_CONSOLE_UNLOCKED(), i < FB_MAX; i++) \
|
|
|
|
if (!fbcon_registered_fb[i]) {} else
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
static signed char con2fb_map[MAX_NR_CONSOLES];
|
|
|
|
static signed char con2fb_map_boot[MAX_NR_CONSOLES];
|
2008-07-24 04:31:21 +00:00
|
|
|
|
2022-04-05 21:03:21 +00:00
|
|
|
static struct fb_info *fbcon_info_from_console(int console)
|
|
|
|
{
|
|
|
|
WARN_CONSOLE_UNLOCKED();
|
|
|
|
|
2022-04-05 21:03:35 +00:00
|
|
|
return fbcon_registered_fb[con2fb_map[console]];
|
2022-04-05 21:03:21 +00:00
|
|
|
}
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
static int logo_lines;
|
|
|
|
/* logo_shown is an index to vc_cons when >= 0; otherwise follows FBCON_LOGO
|
|
|
|
enums. */
|
|
|
|
static int logo_shown = FBCON_LOGO_CANSHOW;
|
|
|
|
/* console mappings */
|
|
|
|
static int first_fb_vc;
|
|
|
|
static int last_fb_vc = MAX_NR_CONSOLES - 1;
|
|
|
|
static int fbcon_is_default = 1;
|
2007-07-17 11:05:28 +00:00
|
|
|
static int primary_device = -1;
|
2009-09-22 23:47:52 +00:00
|
|
|
static int fbcon_has_console_bind;
|
2007-08-10 20:00:46 +00:00
|
|
|
|
|
|
|
#ifdef CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY
|
2007-07-17 11:05:28 +00:00
|
|
|
static int map_override;
|
2006-06-26 07:27:09 +00:00
|
|
|
|
2007-08-10 20:00:46 +00:00
|
|
|
static inline void fbcon_map_override(void)
|
|
|
|
{
|
|
|
|
map_override = 1;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
static inline void fbcon_map_override(void)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
#endif /* CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY */
|
|
|
|
|
2018-06-28 13:20:30 +00:00
|
|
|
#ifdef CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER
|
|
|
|
static bool deferred_takeover = true;
|
|
|
|
#else
|
|
|
|
#define deferred_takeover false
|
|
|
|
#endif
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
/* font data */
|
|
|
|
static char fontname[40];
|
|
|
|
|
|
|
|
/* current fb_info */
|
|
|
|
static int info_idx = -1;
|
|
|
|
|
[PATCH] fbcon: Console Rotation - Prepare fbcon for console rotation
This patch series implements generic code to rotate the console at 90, 180,
and 270 degrees. The implementation is completely done in the framebuffer
console level, thus no changes to the framebuffer layer or to the drivers
are needed.
Console rotation is required by some Sharp-based devices where the natural
orientation of the display is not at 0 degrees. Also, users that have
displays that can pivot will benefit by having a console in portrait mode
if they so desire.
The choice to implement the code in the console layer rather than in the
framebuffer layer is due to the following reasons:
- it's fast
- it does not require driver changes
- it can coexist with devices that can rotate the display at the hardware level
- it complements graphics applications that can do display rotation
The changes to core fbcon are minimal-- recognition of the console
rotation angle so it can swap directions, origins and axes (xres vs yres,
xpanstep vs ypanstep, xoffset vs yoffset, etc) and storage of the rotation
angle per display. The bulk of the code that does the actual drawing to the
screen are placed in separate files. Each angle of rotation has separate
methods (bmove, clear, putcs, cursor, update_start which is derived from
update_var, and clear_margins). To mimimize processing time, the fontdata
are pre-rotated at each console switch (only if the font or the angle has
changed).
The option can be compiled out (CONFIG_FRAMEBUFFER_CONSOLE_ROTATION = n) if
rotation is not needed.
Choosing the rotation angle can be done in several ways:
1. boot option fbcon=rotate:n, where
n = 0 - normal
n = 1 - 90 degrees (clockwise)
n = 2 - 180 degrees (upside down)
n = 3 - 270 degrees (counterclockwise)
2. echo n > /sys/class/graphics/fb[num]/con_rotate
where n is the same as described above. It sets the angle of rotation
of the current console
3 echo n > /sys/class/graphics/fb[num]/con_rotate_all
where n is the same as described above. Globally sets the angle of
rotation.
GOTCHAS:
The option, especially at angles of 90 and 270 degrees, will exercise
the least used code of drivers. Namely, at these angles, panning is done
in the x-axis, so it can reveal bugs in the driver if xpanstep is set
incorrectly. A workaround is to set xpanstep = 0.
Secondly, at these angles, the framebuffer memory access can be
unaligned if (fontheight * bpp) % 32 ~= 0 which can reveal bugs in the drivers
imageblit, fillrect and copyarea functions. (I think cfbfillrect may have
this buglet). A workaround is to use a standard 8x16 font.
Speed:
The scrolling speed difference between 0 and 180 degrees is minimal,
somewhere areound 1-2%. At 90 or 270 degress, speed drops down to a vicinity
of 30-40%. This is understandable because the blit direction is across the
framebuffer "direction." Scrolling will be helped at these angles if xpanstep
is not equal to zero, use of 8x16 fonts, and setting xres_virtual >= xres * 2.
Note: The code is tested on little-endian only, so I don't know if it will
work in big-endian. Please let me know, it will take only less than a minute
of your time.
This patch prepares fbcon for console rotation and contains the following
changes:
- add rotate field in struct fbcon_ops to keep fbcon's current rotation
angle
- add con_rotate field in struct display to store per-display rotation angle
- create a private copy of the current var to fbcon. This will prevent
fbcon from directly manipulating info->var, especially the fields xoffset,
yoffset and vmode.
- add ability to swap pertinent axes (xres, yres; xpanstep, ypanstep; etc)
depending on the rotation angle
- change global update_var() (function that sets the screen start address)
as an fbcon method update_start. This is required because the axes, start
offset, and/or direction can be reversed depending on the rotation angle.
- add fbcon method rotate_font() which will rotate each character bitmap to
the correct angle of rotation.
- add fbcon boot option 'rotate' to select the angle of rotation at bootime.
Currently does nothing until all patches are applied.
Signed-off-by: Antonino Daplas <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-11-09 05:39:09 +00:00
|
|
|
/* console rotation */
|
2017-08-18 17:56:39 +00:00
|
|
|
static int initial_rotation = -1;
|
2006-10-03 08:14:50 +00:00
|
|
|
static int fbcon_has_sysfs;
|
2017-08-18 17:56:40 +00:00
|
|
|
static int margin_color;
|
[PATCH] fbcon: Console Rotation - Prepare fbcon for console rotation
This patch series implements generic code to rotate the console at 90, 180,
and 270 degrees. The implementation is completely done in the framebuffer
console level, thus no changes to the framebuffer layer or to the drivers
are needed.
Console rotation is required by some Sharp-based devices where the natural
orientation of the display is not at 0 degrees. Also, users that have
displays that can pivot will benefit by having a console in portrait mode
if they so desire.
The choice to implement the code in the console layer rather than in the
framebuffer layer is due to the following reasons:
- it's fast
- it does not require driver changes
- it can coexist with devices that can rotate the display at the hardware level
- it complements graphics applications that can do display rotation
The changes to core fbcon are minimal-- recognition of the console
rotation angle so it can swap directions, origins and axes (xres vs yres,
xpanstep vs ypanstep, xoffset vs yoffset, etc) and storage of the rotation
angle per display. The bulk of the code that does the actual drawing to the
screen are placed in separate files. Each angle of rotation has separate
methods (bmove, clear, putcs, cursor, update_start which is derived from
update_var, and clear_margins). To mimimize processing time, the fontdata
are pre-rotated at each console switch (only if the font or the angle has
changed).
The option can be compiled out (CONFIG_FRAMEBUFFER_CONSOLE_ROTATION = n) if
rotation is not needed.
Choosing the rotation angle can be done in several ways:
1. boot option fbcon=rotate:n, where
n = 0 - normal
n = 1 - 90 degrees (clockwise)
n = 2 - 180 degrees (upside down)
n = 3 - 270 degrees (counterclockwise)
2. echo n > /sys/class/graphics/fb[num]/con_rotate
where n is the same as described above. It sets the angle of rotation
of the current console
3 echo n > /sys/class/graphics/fb[num]/con_rotate_all
where n is the same as described above. Globally sets the angle of
rotation.
GOTCHAS:
The option, especially at angles of 90 and 270 degrees, will exercise
the least used code of drivers. Namely, at these angles, panning is done
in the x-axis, so it can reveal bugs in the driver if xpanstep is set
incorrectly. A workaround is to set xpanstep = 0.
Secondly, at these angles, the framebuffer memory access can be
unaligned if (fontheight * bpp) % 32 ~= 0 which can reveal bugs in the drivers
imageblit, fillrect and copyarea functions. (I think cfbfillrect may have
this buglet). A workaround is to use a standard 8x16 font.
Speed:
The scrolling speed difference between 0 and 180 degrees is minimal,
somewhere areound 1-2%. At 90 or 270 degress, speed drops down to a vicinity
of 30-40%. This is understandable because the blit direction is across the
framebuffer "direction." Scrolling will be helped at these angles if xpanstep
is not equal to zero, use of 8x16 fonts, and setting xres_virtual >= xres * 2.
Note: The code is tested on little-endian only, so I don't know if it will
work in big-endian. Please let me know, it will take only less than a minute
of your time.
This patch prepares fbcon for console rotation and contains the following
changes:
- add rotate field in struct fbcon_ops to keep fbcon's current rotation
angle
- add con_rotate field in struct display to store per-display rotation angle
- create a private copy of the current var to fbcon. This will prevent
fbcon from directly manipulating info->var, especially the fields xoffset,
yoffset and vmode.
- add ability to swap pertinent axes (xres, yres; xpanstep, ypanstep; etc)
depending on the rotation angle
- change global update_var() (function that sets the screen start address)
as an fbcon method update_start. This is required because the axes, start
offset, and/or direction can be reversed depending on the rotation angle.
- add fbcon method rotate_font() which will rotate each character bitmap to
the correct angle of rotation.
- add fbcon boot option 'rotate' to select the angle of rotation at bootime.
Currently does nothing until all patches are applied.
Signed-off-by: Antonino Daplas <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-11-09 05:39:09 +00:00
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
static const struct consw fb_con;
|
|
|
|
|
|
|
|
#define advance_row(p, delta) (unsigned short *)((unsigned long)(p) + (delta) * vc->vc_size_row)
|
|
|
|
|
2007-07-17 11:05:26 +00:00
|
|
|
static int fbcon_cursor_noblink;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
#define divides(a, b) ((!(a) || (b)%(a)) ? 0 : 1)
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Interface used by the world
|
|
|
|
*/
|
|
|
|
|
|
|
|
static void fbcon_clear_margins(struct vc_data *vc, int bottom_only);
|
2016-06-23 11:34:27 +00:00
|
|
|
static void fbcon_set_palette(struct vc_data *vc, const unsigned char *table);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Internal routines
|
|
|
|
*/
|
|
|
|
static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var,
|
2007-07-17 11:05:32 +00:00
|
|
|
int unit);
|
Revert "fbdev: Garbage collect fbdev scrolling acceleration, part 1 (from TODO list)"
This reverts commit b3ec8cdf457e5e63d396fe1346cc788cf7c1b578.
Revert the second (of 2) commits which disabled scrolling acceleration
in fbcon/fbdev. It introduced a regression for fbdev-supported graphic
cards because of the performance penalty by doing screen scrolling by
software instead of using the existing graphic card 2D hardware
acceleration.
Console scrolling acceleration was disabled by dropping code which
checked at runtime the driver hardware capabilities for the
BINFO_HWACCEL_COPYAREA or FBINFO_HWACCEL_FILLRECT flags and if set, it
enabled scrollmode SCROLL_MOVE which uses hardware acceleration to move
screen contents. After dropping those checks scrollmode was hard-wired
to SCROLL_REDRAW instead, which forces all graphic cards to redraw every
character at the new screen position when scrolling.
This change effectively disabled all hardware-based scrolling acceleration for
ALL drivers, because now all kind of 2D hardware acceleration (bitblt,
fillrect) in the drivers isn't used any longer.
The original commit message mentions that only 3 DRM drivers (nouveau, omapdrm
and gma500) used hardware acceleration in the past and thus code for checking
and using scrolling acceleration is obsolete.
This statement is NOT TRUE, because beside the DRM drivers there are around 35
other fbdev drivers which depend on fbdev/fbcon and still provide hardware
acceleration for fbdev/fbcon.
The original commit message also states that syzbot found lots of bugs in fbcon
and thus it's "often the solution to just delete code and remove features".
This is true, and the bugs - which actually affected all users of fbcon,
including DRM - were fixed, or code was dropped like e.g. the support for
software scrollback in vgacon (commit 973c096f6a85).
So to further analyze which bugs were found by syzbot, I've looked through all
patches in drivers/video which were tagged with syzbot or syzkaller back to
year 2005. The vast majority fixed the reported issues on a higher level, e.g.
when screen is to be resized, or when font size is to be changed. The few ones
which touched driver code fixed a real driver bug, e.g. by adding a check.
But NONE of those patches touched code of either the SCROLL_MOVE or the
SCROLL_REDRAW case.
That means, there was no real reason why SCROLL_MOVE had to be ripped-out and
just SCROLL_REDRAW had to be used instead. The only reason I can imagine so far
was that SCROLL_MOVE wasn't used by DRM and as such it was assumed that it
could go away. That argument completely missed the fact that SCROLL_MOVE is
still heavily used by fbdev (non-DRM) drivers.
Some people mention that using memcpy() instead of the hardware acceleration is
pretty much the same speed. But that's not true, at least not for older graphic
cards and machines where we see speed decreases by factor 10 and more and thus
this change leads to console responsiveness way worse than before.
That's why the original commit is to be reverted. By reverting we
reintroduce hardware-based scrolling acceleration and fix the
performance regression for fbdev drivers.
There isn't any impact on DRM when reverting those patches.
Signed-off-by: Helge Deller <deller@gmx.de>
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
Acked-by: Sven Schnelle <svens@stackframe.org>
Cc: stable@vger.kernel.org # v5.16+
Signed-off-by: Helge Deller <deller@gmx.de>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/20220202135531.92183-2-deller@gmx.de
2022-02-02 13:55:29 +00:00
|
|
|
static void fbcon_redraw_move(struct vc_data *vc, struct fbcon_display *p,
|
|
|
|
int line, int count, int dy);
|
2005-11-09 05:39:15 +00:00
|
|
|
static void fbcon_modechanged(struct fb_info *info);
|
|
|
|
static void fbcon_set_all_vcs(struct fb_info *info);
|
2022-04-05 21:03:19 +00:00
|
|
|
|
2007-07-17 11:05:26 +00:00
|
|
|
static struct device *fbcon_device;
|
2006-06-26 07:27:05 +00:00
|
|
|
|
2005-11-09 05:39:12 +00:00
|
|
|
#ifdef CONFIG_FRAMEBUFFER_CONSOLE_ROTATION
|
2006-01-10 04:52:56 +00:00
|
|
|
static inline void fbcon_set_rotation(struct fb_info *info)
|
2005-11-09 05:39:12 +00:00
|
|
|
{
|
|
|
|
struct fbcon_ops *ops = info->fbcon_par;
|
|
|
|
|
|
|
|
if (!(info->flags & FBINFO_MISC_TILEBLITTING) &&
|
2006-01-10 04:52:56 +00:00
|
|
|
ops->p->con_rotate < 4)
|
|
|
|
ops->rotate = ops->p->con_rotate;
|
2005-11-09 05:39:12 +00:00
|
|
|
else
|
|
|
|
ops->rotate = 0;
|
|
|
|
}
|
2005-11-09 05:39:15 +00:00
|
|
|
|
|
|
|
static void fbcon_rotate(struct fb_info *info, u32 rotate)
|
|
|
|
{
|
|
|
|
struct fbcon_ops *ops= info->fbcon_par;
|
|
|
|
struct fb_info *fb_info;
|
|
|
|
|
|
|
|
if (!ops || ops->currcon == -1)
|
|
|
|
return;
|
|
|
|
|
2022-04-05 21:03:21 +00:00
|
|
|
fb_info = fbcon_info_from_console(ops->currcon);
|
2005-11-09 05:39:15 +00:00
|
|
|
|
|
|
|
if (info == fb_info) {
|
2019-05-28 09:02:39 +00:00
|
|
|
struct fbcon_display *p = &fb_display[ops->currcon];
|
2005-11-09 05:39:15 +00:00
|
|
|
|
|
|
|
if (rotate < 4)
|
|
|
|
p->con_rotate = rotate;
|
|
|
|
else
|
|
|
|
p->con_rotate = 0;
|
|
|
|
|
|
|
|
fbcon_modechanged(info);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void fbcon_rotate_all(struct fb_info *info, u32 rotate)
|
|
|
|
{
|
|
|
|
struct fbcon_ops *ops = info->fbcon_par;
|
|
|
|
struct vc_data *vc;
|
2019-05-28 09:02:39 +00:00
|
|
|
struct fbcon_display *p;
|
2005-11-09 05:39:15 +00:00
|
|
|
int i;
|
|
|
|
|
|
|
|
if (!ops || ops->currcon < 0 || rotate > 3)
|
|
|
|
return;
|
|
|
|
|
2006-06-26 07:27:09 +00:00
|
|
|
for (i = first_fb_vc; i <= last_fb_vc; i++) {
|
2005-11-09 05:39:15 +00:00
|
|
|
vc = vc_cons[i].d;
|
|
|
|
if (!vc || vc->vc_mode != KD_TEXT ||
|
2022-04-05 21:03:21 +00:00
|
|
|
fbcon_info_from_console(i) != info)
|
2005-11-09 05:39:15 +00:00
|
|
|
continue;
|
|
|
|
|
|
|
|
p = &fb_display[vc->vc_num];
|
|
|
|
p->con_rotate = rotate;
|
|
|
|
}
|
|
|
|
|
|
|
|
fbcon_set_all_vcs(info);
|
|
|
|
}
|
2005-11-09 05:39:12 +00:00
|
|
|
#else
|
2006-01-10 04:52:56 +00:00
|
|
|
static inline void fbcon_set_rotation(struct fb_info *info)
|
[PATCH] fbcon: Console Rotation - Prepare fbcon for console rotation
This patch series implements generic code to rotate the console at 90, 180,
and 270 degrees. The implementation is completely done in the framebuffer
console level, thus no changes to the framebuffer layer or to the drivers
are needed.
Console rotation is required by some Sharp-based devices where the natural
orientation of the display is not at 0 degrees. Also, users that have
displays that can pivot will benefit by having a console in portrait mode
if they so desire.
The choice to implement the code in the console layer rather than in the
framebuffer layer is due to the following reasons:
- it's fast
- it does not require driver changes
- it can coexist with devices that can rotate the display at the hardware level
- it complements graphics applications that can do display rotation
The changes to core fbcon are minimal-- recognition of the console
rotation angle so it can swap directions, origins and axes (xres vs yres,
xpanstep vs ypanstep, xoffset vs yoffset, etc) and storage of the rotation
angle per display. The bulk of the code that does the actual drawing to the
screen are placed in separate files. Each angle of rotation has separate
methods (bmove, clear, putcs, cursor, update_start which is derived from
update_var, and clear_margins). To mimimize processing time, the fontdata
are pre-rotated at each console switch (only if the font or the angle has
changed).
The option can be compiled out (CONFIG_FRAMEBUFFER_CONSOLE_ROTATION = n) if
rotation is not needed.
Choosing the rotation angle can be done in several ways:
1. boot option fbcon=rotate:n, where
n = 0 - normal
n = 1 - 90 degrees (clockwise)
n = 2 - 180 degrees (upside down)
n = 3 - 270 degrees (counterclockwise)
2. echo n > /sys/class/graphics/fb[num]/con_rotate
where n is the same as described above. It sets the angle of rotation
of the current console
3 echo n > /sys/class/graphics/fb[num]/con_rotate_all
where n is the same as described above. Globally sets the angle of
rotation.
GOTCHAS:
The option, especially at angles of 90 and 270 degrees, will exercise
the least used code of drivers. Namely, at these angles, panning is done
in the x-axis, so it can reveal bugs in the driver if xpanstep is set
incorrectly. A workaround is to set xpanstep = 0.
Secondly, at these angles, the framebuffer memory access can be
unaligned if (fontheight * bpp) % 32 ~= 0 which can reveal bugs in the drivers
imageblit, fillrect and copyarea functions. (I think cfbfillrect may have
this buglet). A workaround is to use a standard 8x16 font.
Speed:
The scrolling speed difference between 0 and 180 degrees is minimal,
somewhere areound 1-2%. At 90 or 270 degress, speed drops down to a vicinity
of 30-40%. This is understandable because the blit direction is across the
framebuffer "direction." Scrolling will be helped at these angles if xpanstep
is not equal to zero, use of 8x16 fonts, and setting xres_virtual >= xres * 2.
Note: The code is tested on little-endian only, so I don't know if it will
work in big-endian. Please let me know, it will take only less than a minute
of your time.
This patch prepares fbcon for console rotation and contains the following
changes:
- add rotate field in struct fbcon_ops to keep fbcon's current rotation
angle
- add con_rotate field in struct display to store per-display rotation angle
- create a private copy of the current var to fbcon. This will prevent
fbcon from directly manipulating info->var, especially the fields xoffset,
yoffset and vmode.
- add ability to swap pertinent axes (xres, yres; xpanstep, ypanstep; etc)
depending on the rotation angle
- change global update_var() (function that sets the screen start address)
as an fbcon method update_start. This is required because the axes, start
offset, and/or direction can be reversed depending on the rotation angle.
- add fbcon method rotate_font() which will rotate each character bitmap to
the correct angle of rotation.
- add fbcon boot option 'rotate' to select the angle of rotation at bootime.
Currently does nothing until all patches are applied.
Signed-off-by: Antonino Daplas <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-11-09 05:39:09 +00:00
|
|
|
{
|
|
|
|
struct fbcon_ops *ops = info->fbcon_par;
|
|
|
|
|
|
|
|
ops->rotate = FB_ROTATE_UR;
|
|
|
|
}
|
2005-11-09 05:39:15 +00:00
|
|
|
|
|
|
|
static void fbcon_rotate(struct fb_info *info, u32 rotate)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void fbcon_rotate_all(struct fb_info *info, u32 rotate)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2005-11-09 05:39:12 +00:00
|
|
|
#endif /* CONFIG_FRAMEBUFFER_CONSOLE_ROTATION */
|
[PATCH] fbcon: Console Rotation - Prepare fbcon for console rotation
This patch series implements generic code to rotate the console at 90, 180,
and 270 degrees. The implementation is completely done in the framebuffer
console level, thus no changes to the framebuffer layer or to the drivers
are needed.
Console rotation is required by some Sharp-based devices where the natural
orientation of the display is not at 0 degrees. Also, users that have
displays that can pivot will benefit by having a console in portrait mode
if they so desire.
The choice to implement the code in the console layer rather than in the
framebuffer layer is due to the following reasons:
- it's fast
- it does not require driver changes
- it can coexist with devices that can rotate the display at the hardware level
- it complements graphics applications that can do display rotation
The changes to core fbcon are minimal-- recognition of the console
rotation angle so it can swap directions, origins and axes (xres vs yres,
xpanstep vs ypanstep, xoffset vs yoffset, etc) and storage of the rotation
angle per display. The bulk of the code that does the actual drawing to the
screen are placed in separate files. Each angle of rotation has separate
methods (bmove, clear, putcs, cursor, update_start which is derived from
update_var, and clear_margins). To mimimize processing time, the fontdata
are pre-rotated at each console switch (only if the font or the angle has
changed).
The option can be compiled out (CONFIG_FRAMEBUFFER_CONSOLE_ROTATION = n) if
rotation is not needed.
Choosing the rotation angle can be done in several ways:
1. boot option fbcon=rotate:n, where
n = 0 - normal
n = 1 - 90 degrees (clockwise)
n = 2 - 180 degrees (upside down)
n = 3 - 270 degrees (counterclockwise)
2. echo n > /sys/class/graphics/fb[num]/con_rotate
where n is the same as described above. It sets the angle of rotation
of the current console
3 echo n > /sys/class/graphics/fb[num]/con_rotate_all
where n is the same as described above. Globally sets the angle of
rotation.
GOTCHAS:
The option, especially at angles of 90 and 270 degrees, will exercise
the least used code of drivers. Namely, at these angles, panning is done
in the x-axis, so it can reveal bugs in the driver if xpanstep is set
incorrectly. A workaround is to set xpanstep = 0.
Secondly, at these angles, the framebuffer memory access can be
unaligned if (fontheight * bpp) % 32 ~= 0 which can reveal bugs in the drivers
imageblit, fillrect and copyarea functions. (I think cfbfillrect may have
this buglet). A workaround is to use a standard 8x16 font.
Speed:
The scrolling speed difference between 0 and 180 degrees is minimal,
somewhere areound 1-2%. At 90 or 270 degress, speed drops down to a vicinity
of 30-40%. This is understandable because the blit direction is across the
framebuffer "direction." Scrolling will be helped at these angles if xpanstep
is not equal to zero, use of 8x16 fonts, and setting xres_virtual >= xres * 2.
Note: The code is tested on little-endian only, so I don't know if it will
work in big-endian. Please let me know, it will take only less than a minute
of your time.
This patch prepares fbcon for console rotation and contains the following
changes:
- add rotate field in struct fbcon_ops to keep fbcon's current rotation
angle
- add con_rotate field in struct display to store per-display rotation angle
- create a private copy of the current var to fbcon. This will prevent
fbcon from directly manipulating info->var, especially the fields xoffset,
yoffset and vmode.
- add ability to swap pertinent axes (xres, yres; xpanstep, ypanstep; etc)
depending on the rotation angle
- change global update_var() (function that sets the screen start address)
as an fbcon method update_start. This is required because the axes, start
offset, and/or direction can be reversed depending on the rotation angle.
- add fbcon method rotate_font() which will rotate each character bitmap to
the correct angle of rotation.
- add fbcon boot option 'rotate' to select the angle of rotation at bootime.
Currently does nothing until all patches are applied.
Signed-off-by: Antonino Daplas <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-11-09 05:39:09 +00:00
|
|
|
|
2005-11-09 05:39:15 +00:00
|
|
|
static int fbcon_get_rotate(struct fb_info *info)
|
|
|
|
{
|
|
|
|
struct fbcon_ops *ops = info->fbcon_par;
|
|
|
|
|
|
|
|
return (ops) ? ops->rotate : 0;
|
|
|
|
}
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
static inline int fbcon_is_inactive(struct vc_data *vc, struct fb_info *info)
|
|
|
|
{
|
|
|
|
struct fbcon_ops *ops = info->fbcon_par;
|
|
|
|
|
|
|
|
return (info->state != FBINFO_STATE_RUNNING ||
|
2018-08-22 08:54:03 +00:00
|
|
|
vc->vc_mode != KD_TEXT || ops->graphics);
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
|
2010-08-11 01:02:29 +00:00
|
|
|
static int get_color(struct vc_data *vc, struct fb_info *info,
|
2005-04-16 22:20:36 +00:00
|
|
|
u16 c, int is_fg)
|
|
|
|
{
|
2005-09-09 20:04:37 +00:00
|
|
|
int depth = fb_get_color_depth(&info->var, &info->fix);
|
2005-04-16 22:20:36 +00:00
|
|
|
int color = 0;
|
|
|
|
|
|
|
|
if (console_blanked) {
|
|
|
|
unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
|
|
|
|
|
|
|
|
c = vc->vc_video_erase_char & charmask;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (depth != 1)
|
|
|
|
color = (is_fg) ? attr_fgcol((vc->vc_hi_font_mask) ? 9 : 8, c)
|
|
|
|
: attr_bgcol((vc->vc_hi_font_mask) ? 13 : 12, c);
|
|
|
|
|
|
|
|
switch (depth) {
|
|
|
|
case 1:
|
|
|
|
{
|
2008-02-06 09:39:45 +00:00
|
|
|
int col = mono_col(info);
|
2005-04-16 22:20:36 +00:00
|
|
|
/* 0 or 1 */
|
2005-09-09 20:04:37 +00:00
|
|
|
int fg = (info->fix.visual != FB_VISUAL_MONO01) ? col : 0;
|
|
|
|
int bg = (info->fix.visual != FB_VISUAL_MONO01) ? 0 : col;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
if (console_blanked)
|
|
|
|
fg = bg;
|
|
|
|
|
|
|
|
color = (is_fg) ? fg : bg;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 2:
|
|
|
|
/*
|
|
|
|
* Scale down 16-colors to 4 colors. Default 4-color palette
|
[PATCH] fbcon: Saner 16-color to 4-color conversion
Currently, the default linux 16-colors are converted to 4-colors by simply
dividing the values by 4. However, this is not necessarily correct since the
first 4 colors are converted to black, rendering them invisible.
So, for black, no conversion; for light colors, convert to gray, for normal
text color, no conversion, and for bright colors, convert to intense white.
Signed-off-by: Antonino Daplas <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-09-09 20:04:38 +00:00
|
|
|
* is grayscale. However, simply dividing the values by 4
|
|
|
|
* will not work, as colors 1, 2 and 3 will be scaled-down
|
|
|
|
* to zero rendering them invisible. So empirically convert
|
|
|
|
* colors to a sane 4-level grayscale.
|
2005-04-16 22:20:36 +00:00
|
|
|
*/
|
[PATCH] fbcon: Saner 16-color to 4-color conversion
Currently, the default linux 16-colors are converted to 4-colors by simply
dividing the values by 4. However, this is not necessarily correct since the
first 4 colors are converted to black, rendering them invisible.
So, for black, no conversion; for light colors, convert to gray, for normal
text color, no conversion, and for bright colors, convert to intense white.
Signed-off-by: Antonino Daplas <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-09-09 20:04:38 +00:00
|
|
|
switch (color) {
|
|
|
|
case 0:
|
|
|
|
color = 0; /* black */
|
|
|
|
break;
|
|
|
|
case 1 ... 6:
|
|
|
|
color = 2; /* white */
|
|
|
|
break;
|
|
|
|
case 7 ... 8:
|
|
|
|
color = 1; /* gray */
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
color = 3; /* intense white */
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
2005-04-16 22:20:36 +00:00
|
|
|
case 3:
|
|
|
|
/*
|
|
|
|
* Last 8 entries of default 16-color palette is a more intense
|
|
|
|
* version of the first 8 (i.e., same chrominance, different
|
|
|
|
* luminance).
|
|
|
|
*/
|
|
|
|
color &= 7;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return color;
|
|
|
|
}
|
|
|
|
|
2006-11-22 14:57:56 +00:00
|
|
|
static void fb_flashcursor(struct work_struct *work)
|
2005-04-16 22:20:36 +00:00
|
|
|
{
|
2022-04-05 21:03:24 +00:00
|
|
|
struct fbcon_ops *ops = container_of(work, struct fbcon_ops, cursor_work.work);
|
|
|
|
struct fb_info *info;
|
2005-04-16 22:20:36 +00:00
|
|
|
struct vc_data *vc = NULL;
|
|
|
|
int c;
|
|
|
|
int mode;
|
2012-08-21 06:29:47 +00:00
|
|
|
int ret;
|
|
|
|
|
|
|
|
/* FIXME: we should sort out the unbind locking instead */
|
|
|
|
/* instead we just fail to flash the cursor if we can't get
|
|
|
|
* the lock instead of blocking fbcon deinit */
|
|
|
|
ret = console_trylock();
|
|
|
|
if (ret == 0)
|
|
|
|
return;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2022-04-05 21:03:24 +00:00
|
|
|
/* protected by console_lock */
|
|
|
|
info = ops->info;
|
|
|
|
|
|
|
|
if (ops->currcon != -1)
|
2005-04-16 22:20:36 +00:00
|
|
|
vc = vc_cons[ops->currcon].d;
|
|
|
|
|
2016-06-23 11:34:35 +00:00
|
|
|
if (!vc || !con_is_visible(vc) ||
|
2022-04-05 21:03:21 +00:00
|
|
|
fbcon_info_from_console(vc->vc_num) != info ||
|
2006-10-03 08:14:48 +00:00
|
|
|
vc->vc_deccm != 1) {
|
2011-01-25 23:07:35 +00:00
|
|
|
console_unlock();
|
2005-04-16 22:20:36 +00:00
|
|
|
return;
|
2006-06-26 07:27:06 +00:00
|
|
|
}
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
c = scr_readw((u16 *) vc->vc_pos);
|
|
|
|
mode = (!ops->cursor_flash || ops->cursor_state.enable) ?
|
|
|
|
CM_ERASE : CM_DRAW;
|
2020-09-08 17:56:27 +00:00
|
|
|
ops->cursor(vc, info, mode, get_color(vc, info, c, 1),
|
2005-04-16 22:20:36 +00:00
|
|
|
get_color(vc, info, c, 0));
|
2011-01-25 23:07:35 +00:00
|
|
|
console_unlock();
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2022-04-05 21:03:24 +00:00
|
|
|
queue_delayed_work(system_power_efficient_wq, &ops->cursor_work,
|
|
|
|
ops->cur_blink_jiffies);
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
|
2022-04-05 21:03:24 +00:00
|
|
|
static void fbcon_add_cursor_work(struct fb_info *info)
|
2005-09-09 20:10:00 +00:00
|
|
|
{
|
|
|
|
struct fbcon_ops *ops = info->fbcon_par;
|
|
|
|
|
2022-04-05 21:03:24 +00:00
|
|
|
if (!fbcon_cursor_noblink)
|
|
|
|
queue_delayed_work(system_power_efficient_wq, &ops->cursor_work,
|
|
|
|
ops->cur_blink_jiffies);
|
2005-09-09 20:10:00 +00:00
|
|
|
}
|
|
|
|
|
2022-04-05 21:03:24 +00:00
|
|
|
static void fbcon_del_cursor_work(struct fb_info *info)
|
2005-09-09 20:10:00 +00:00
|
|
|
{
|
|
|
|
struct fbcon_ops *ops = info->fbcon_par;
|
|
|
|
|
2022-04-05 21:03:24 +00:00
|
|
|
cancel_delayed_work_sync(&ops->cursor_work);
|
2005-09-09 20:10:00 +00:00
|
|
|
}
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
#ifndef MODULE
|
|
|
|
static int __init fb_console_setup(char *this_opt)
|
|
|
|
{
|
|
|
|
char *options;
|
|
|
|
int i, j;
|
|
|
|
|
|
|
|
if (!this_opt || !*this_opt)
|
2006-03-31 10:30:33 +00:00
|
|
|
return 1;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
while ((options = strsep(&this_opt, ",")) != NULL) {
|
2014-10-09 09:48:30 +00:00
|
|
|
if (!strncmp(options, "font:", 5)) {
|
2012-07-24 01:00:24 +00:00
|
|
|
strlcpy(fontname, options + 5, sizeof(fontname));
|
2014-10-09 09:48:30 +00:00
|
|
|
continue;
|
|
|
|
}
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
if (!strncmp(options, "scrollback:", 11)) {
|
2020-09-07 18:45:27 +00:00
|
|
|
pr_warn("Ignoring scrollback size option\n");
|
2014-10-09 09:48:30 +00:00
|
|
|
continue;
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!strncmp(options, "map:", 4)) {
|
|
|
|
options += 4;
|
2007-07-17 11:05:28 +00:00
|
|
|
if (*options) {
|
2005-04-16 22:20:36 +00:00
|
|
|
for (i = 0, j = 0; i < MAX_NR_CONSOLES; i++) {
|
|
|
|
if (!options[j])
|
|
|
|
j = 0;
|
|
|
|
con2fb_map_boot[i] =
|
|
|
|
(options[j++]-'0') % FB_MAX;
|
|
|
|
}
|
2007-07-17 11:05:28 +00:00
|
|
|
|
2007-08-10 20:00:46 +00:00
|
|
|
fbcon_map_override();
|
2007-07-17 11:05:28 +00:00
|
|
|
}
|
2014-10-09 09:48:30 +00:00
|
|
|
continue;
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!strncmp(options, "vc:", 3)) {
|
|
|
|
options += 3;
|
|
|
|
if (*options)
|
|
|
|
first_fb_vc = simple_strtoul(options, &options, 10) - 1;
|
|
|
|
if (first_fb_vc < 0)
|
|
|
|
first_fb_vc = 0;
|
|
|
|
if (*options++ == '-')
|
|
|
|
last_fb_vc = simple_strtoul(options, &options, 10) - 1;
|
|
|
|
fbcon_is_default = 0;
|
2014-10-09 09:48:30 +00:00
|
|
|
continue;
|
|
|
|
}
|
[PATCH] fbcon: Console Rotation - Prepare fbcon for console rotation
This patch series implements generic code to rotate the console at 90, 180,
and 270 degrees. The implementation is completely done in the framebuffer
console level, thus no changes to the framebuffer layer or to the drivers
are needed.
Console rotation is required by some Sharp-based devices where the natural
orientation of the display is not at 0 degrees. Also, users that have
displays that can pivot will benefit by having a console in portrait mode
if they so desire.
The choice to implement the code in the console layer rather than in the
framebuffer layer is due to the following reasons:
- it's fast
- it does not require driver changes
- it can coexist with devices that can rotate the display at the hardware level
- it complements graphics applications that can do display rotation
The changes to core fbcon are minimal-- recognition of the console
rotation angle so it can swap directions, origins and axes (xres vs yres,
xpanstep vs ypanstep, xoffset vs yoffset, etc) and storage of the rotation
angle per display. The bulk of the code that does the actual drawing to the
screen are placed in separate files. Each angle of rotation has separate
methods (bmove, clear, putcs, cursor, update_start which is derived from
update_var, and clear_margins). To mimimize processing time, the fontdata
are pre-rotated at each console switch (only if the font or the angle has
changed).
The option can be compiled out (CONFIG_FRAMEBUFFER_CONSOLE_ROTATION = n) if
rotation is not needed.
Choosing the rotation angle can be done in several ways:
1. boot option fbcon=rotate:n, where
n = 0 - normal
n = 1 - 90 degrees (clockwise)
n = 2 - 180 degrees (upside down)
n = 3 - 270 degrees (counterclockwise)
2. echo n > /sys/class/graphics/fb[num]/con_rotate
where n is the same as described above. It sets the angle of rotation
of the current console
3 echo n > /sys/class/graphics/fb[num]/con_rotate_all
where n is the same as described above. Globally sets the angle of
rotation.
GOTCHAS:
The option, especially at angles of 90 and 270 degrees, will exercise
the least used code of drivers. Namely, at these angles, panning is done
in the x-axis, so it can reveal bugs in the driver if xpanstep is set
incorrectly. A workaround is to set xpanstep = 0.
Secondly, at these angles, the framebuffer memory access can be
unaligned if (fontheight * bpp) % 32 ~= 0 which can reveal bugs in the drivers
imageblit, fillrect and copyarea functions. (I think cfbfillrect may have
this buglet). A workaround is to use a standard 8x16 font.
Speed:
The scrolling speed difference between 0 and 180 degrees is minimal,
somewhere areound 1-2%. At 90 or 270 degress, speed drops down to a vicinity
of 30-40%. This is understandable because the blit direction is across the
framebuffer "direction." Scrolling will be helped at these angles if xpanstep
is not equal to zero, use of 8x16 fonts, and setting xres_virtual >= xres * 2.
Note: The code is tested on little-endian only, so I don't know if it will
work in big-endian. Please let me know, it will take only less than a minute
of your time.
This patch prepares fbcon for console rotation and contains the following
changes:
- add rotate field in struct fbcon_ops to keep fbcon's current rotation
angle
- add con_rotate field in struct display to store per-display rotation angle
- create a private copy of the current var to fbcon. This will prevent
fbcon from directly manipulating info->var, especially the fields xoffset,
yoffset and vmode.
- add ability to swap pertinent axes (xres, yres; xpanstep, ypanstep; etc)
depending on the rotation angle
- change global update_var() (function that sets the screen start address)
as an fbcon method update_start. This is required because the axes, start
offset, and/or direction can be reversed depending on the rotation angle.
- add fbcon method rotate_font() which will rotate each character bitmap to
the correct angle of rotation.
- add fbcon boot option 'rotate' to select the angle of rotation at bootime.
Currently does nothing until all patches are applied.
Signed-off-by: Antonino Daplas <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-11-09 05:39:09 +00:00
|
|
|
|
|
|
|
if (!strncmp(options, "rotate:", 7)) {
|
|
|
|
options += 7;
|
|
|
|
if (*options)
|
2008-02-06 09:39:14 +00:00
|
|
|
initial_rotation = simple_strtoul(options, &options, 0);
|
|
|
|
if (initial_rotation > 3)
|
|
|
|
initial_rotation = 0;
|
2014-10-09 09:48:30 +00:00
|
|
|
continue;
|
[PATCH] fbcon: Console Rotation - Prepare fbcon for console rotation
This patch series implements generic code to rotate the console at 90, 180,
and 270 degrees. The implementation is completely done in the framebuffer
console level, thus no changes to the framebuffer layer or to the drivers
are needed.
Console rotation is required by some Sharp-based devices where the natural
orientation of the display is not at 0 degrees. Also, users that have
displays that can pivot will benefit by having a console in portrait mode
if they so desire.
The choice to implement the code in the console layer rather than in the
framebuffer layer is due to the following reasons:
- it's fast
- it does not require driver changes
- it can coexist with devices that can rotate the display at the hardware level
- it complements graphics applications that can do display rotation
The changes to core fbcon are minimal-- recognition of the console
rotation angle so it can swap directions, origins and axes (xres vs yres,
xpanstep vs ypanstep, xoffset vs yoffset, etc) and storage of the rotation
angle per display. The bulk of the code that does the actual drawing to the
screen are placed in separate files. Each angle of rotation has separate
methods (bmove, clear, putcs, cursor, update_start which is derived from
update_var, and clear_margins). To mimimize processing time, the fontdata
are pre-rotated at each console switch (only if the font or the angle has
changed).
The option can be compiled out (CONFIG_FRAMEBUFFER_CONSOLE_ROTATION = n) if
rotation is not needed.
Choosing the rotation angle can be done in several ways:
1. boot option fbcon=rotate:n, where
n = 0 - normal
n = 1 - 90 degrees (clockwise)
n = 2 - 180 degrees (upside down)
n = 3 - 270 degrees (counterclockwise)
2. echo n > /sys/class/graphics/fb[num]/con_rotate
where n is the same as described above. It sets the angle of rotation
of the current console
3 echo n > /sys/class/graphics/fb[num]/con_rotate_all
where n is the same as described above. Globally sets the angle of
rotation.
GOTCHAS:
The option, especially at angles of 90 and 270 degrees, will exercise
the least used code of drivers. Namely, at these angles, panning is done
in the x-axis, so it can reveal bugs in the driver if xpanstep is set
incorrectly. A workaround is to set xpanstep = 0.
Secondly, at these angles, the framebuffer memory access can be
unaligned if (fontheight * bpp) % 32 ~= 0 which can reveal bugs in the drivers
imageblit, fillrect and copyarea functions. (I think cfbfillrect may have
this buglet). A workaround is to use a standard 8x16 font.
Speed:
The scrolling speed difference between 0 and 180 degrees is minimal,
somewhere areound 1-2%. At 90 or 270 degress, speed drops down to a vicinity
of 30-40%. This is understandable because the blit direction is across the
framebuffer "direction." Scrolling will be helped at these angles if xpanstep
is not equal to zero, use of 8x16 fonts, and setting xres_virtual >= xres * 2.
Note: The code is tested on little-endian only, so I don't know if it will
work in big-endian. Please let me know, it will take only less than a minute
of your time.
This patch prepares fbcon for console rotation and contains the following
changes:
- add rotate field in struct fbcon_ops to keep fbcon's current rotation
angle
- add con_rotate field in struct display to store per-display rotation angle
- create a private copy of the current var to fbcon. This will prevent
fbcon from directly manipulating info->var, especially the fields xoffset,
yoffset and vmode.
- add ability to swap pertinent axes (xres, yres; xpanstep, ypanstep; etc)
depending on the rotation angle
- change global update_var() (function that sets the screen start address)
as an fbcon method update_start. This is required because the axes, start
offset, and/or direction can be reversed depending on the rotation angle.
- add fbcon method rotate_font() which will rotate each character bitmap to
the correct angle of rotation.
- add fbcon boot option 'rotate' to select the angle of rotation at bootime.
Currently does nothing until all patches are applied.
Signed-off-by: Antonino Daplas <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-11-09 05:39:09 +00:00
|
|
|
}
|
2017-08-18 17:56:40 +00:00
|
|
|
|
|
|
|
if (!strncmp(options, "margin:", 7)) {
|
|
|
|
options += 7;
|
|
|
|
if (*options)
|
|
|
|
margin_color = simple_strtoul(options, &options, 0);
|
|
|
|
continue;
|
|
|
|
}
|
2018-06-28 13:20:30 +00:00
|
|
|
#ifdef CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER
|
|
|
|
if (!strcmp(options, "nodefer")) {
|
|
|
|
deferred_takeover = false;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
#endif
|
2019-01-16 16:42:35 +00:00
|
|
|
|
|
|
|
if (!strncmp(options, "logo-pos:", 9)) {
|
|
|
|
options += 9;
|
|
|
|
if (!strcmp(options, "center"))
|
|
|
|
fb_center_logo = true;
|
|
|
|
continue;
|
|
|
|
}
|
2019-08-27 11:09:21 +00:00
|
|
|
|
|
|
|
if (!strncmp(options, "logo-count:", 11)) {
|
|
|
|
options += 11;
|
|
|
|
if (*options)
|
|
|
|
fb_logo_count = simple_strtol(options, &options, 0);
|
|
|
|
continue;
|
|
|
|
}
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
2006-03-31 10:30:33 +00:00
|
|
|
return 1;
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
__setup("fbcon=", fb_console_setup);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
static int search_fb_in_map(int idx)
|
|
|
|
{
|
|
|
|
int i, retval = 0;
|
|
|
|
|
2006-06-26 07:27:09 +00:00
|
|
|
for (i = first_fb_vc; i <= last_fb_vc; i++) {
|
2005-04-16 22:20:36 +00:00
|
|
|
if (con2fb_map[i] == idx)
|
|
|
|
retval = 1;
|
|
|
|
}
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int search_for_mapped_con(void)
|
|
|
|
{
|
|
|
|
int i, retval = 0;
|
|
|
|
|
2006-06-26 07:27:09 +00:00
|
|
|
for (i = first_fb_vc; i <= last_fb_vc; i++) {
|
2005-04-16 22:20:36 +00:00
|
|
|
if (con2fb_map[i] != -1)
|
|
|
|
retval = 1;
|
|
|
|
}
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
2013-01-25 00:28:15 +00:00
|
|
|
static int do_fbcon_takeover(int show_logo)
|
|
|
|
{
|
|
|
|
int err, i;
|
|
|
|
|
2022-04-05 21:03:35 +00:00
|
|
|
if (!fbcon_num_registered_fb)
|
2013-01-25 00:28:15 +00:00
|
|
|
return -ENODEV;
|
|
|
|
|
|
|
|
if (!show_logo)
|
|
|
|
logo_shown = FBCON_LOGO_DONTSHOW;
|
|
|
|
|
|
|
|
for (i = first_fb_vc; i <= last_fb_vc; i++)
|
|
|
|
con2fb_map[i] = info_idx;
|
|
|
|
|
|
|
|
err = do_take_over_console(&fb_con, first_fb_vc, last_fb_vc,
|
|
|
|
fbcon_is_default);
|
|
|
|
|
|
|
|
if (err) {
|
|
|
|
for (i = first_fb_vc; i <= last_fb_vc; i++)
|
|
|
|
con2fb_map[i] = -1;
|
|
|
|
info_idx = -1;
|
|
|
|
} else {
|
|
|
|
fbcon_has_console_bind = 1;
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
2007-05-08 07:38:14 +00:00
|
|
|
#ifdef MODULE
|
|
|
|
static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info,
|
|
|
|
int cols, int rows, int new_cols, int new_rows)
|
|
|
|
{
|
|
|
|
logo_shown = FBCON_LOGO_DONTSHOW;
|
|
|
|
}
|
|
|
|
#else
|
2005-04-16 22:20:36 +00:00
|
|
|
static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info,
|
|
|
|
int cols, int rows, int new_cols, int new_rows)
|
|
|
|
{
|
|
|
|
/* Need to make room for the logo */
|
2005-11-09 05:39:10 +00:00
|
|
|
struct fbcon_ops *ops = info->fbcon_par;
|
2005-04-16 22:20:36 +00:00
|
|
|
int cnt, erase = vc->vc_video_erase_char, step;
|
|
|
|
unsigned short *save = NULL, *r, *q;
|
2008-07-24 04:31:21 +00:00
|
|
|
int logo_height;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2017-08-01 15:33:02 +00:00
|
|
|
if (info->fbops->owner) {
|
2007-05-08 07:38:14 +00:00
|
|
|
logo_shown = FBCON_LOGO_DONTSHOW;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
/*
|
|
|
|
* remove underline attribute from erase character
|
|
|
|
* if black and white framebuffer.
|
|
|
|
*/
|
2005-09-09 20:04:37 +00:00
|
|
|
if (fb_get_color_depth(&info->var, &info->fix) == 1)
|
2005-04-16 22:20:36 +00:00
|
|
|
erase &= ~0x400;
|
2005-11-09 05:39:10 +00:00
|
|
|
logo_height = fb_prepare_logo(info, ops->rotate);
|
2008-04-28 09:14:51 +00:00
|
|
|
logo_lines = DIV_ROUND_UP(logo_height, vc->vc_font.height);
|
2005-04-16 22:20:36 +00:00
|
|
|
q = (unsigned short *) (vc->vc_origin +
|
|
|
|
vc->vc_size_row * rows);
|
|
|
|
step = logo_lines * cols;
|
|
|
|
for (r = q - logo_lines * cols; r < q; r++)
|
|
|
|
if (scr_readw(r) != vc->vc_video_erase_char)
|
|
|
|
break;
|
|
|
|
if (r != q && new_rows >= rows + logo_lines) {
|
treewide: kmalloc() -> kmalloc_array()
The kmalloc() function has a 2-factor argument form, kmalloc_array(). This
patch replaces cases of:
kmalloc(a * b, gfp)
with:
kmalloc_array(a * b, gfp)
as well as handling cases of:
kmalloc(a * b * c, gfp)
with:
kmalloc(array3_size(a, b, c), gfp)
as it's slightly less ugly than:
kmalloc_array(array_size(a, b), c, gfp)
This does, however, attempt to ignore constant size factors like:
kmalloc(4 * 1024, gfp)
though any constants defined via macros get caught up in the conversion.
Any factors with a sizeof() of "unsigned char", "char", and "u8" were
dropped, since they're redundant.
The tools/ directory was manually excluded, since it has its own
implementation of kmalloc().
The Coccinelle script used for this was:
// Fix redundant parens around sizeof().
@@
type TYPE;
expression THING, E;
@@
(
kmalloc(
- (sizeof(TYPE)) * E
+ sizeof(TYPE) * E
, ...)
|
kmalloc(
- (sizeof(THING)) * E
+ sizeof(THING) * E
, ...)
)
// Drop single-byte sizes and redundant parens.
@@
expression COUNT;
typedef u8;
typedef __u8;
@@
(
kmalloc(
- sizeof(u8) * (COUNT)
+ COUNT
, ...)
|
kmalloc(
- sizeof(__u8) * (COUNT)
+ COUNT
, ...)
|
kmalloc(
- sizeof(char) * (COUNT)
+ COUNT
, ...)
|
kmalloc(
- sizeof(unsigned char) * (COUNT)
+ COUNT
, ...)
|
kmalloc(
- sizeof(u8) * COUNT
+ COUNT
, ...)
|
kmalloc(
- sizeof(__u8) * COUNT
+ COUNT
, ...)
|
kmalloc(
- sizeof(char) * COUNT
+ COUNT
, ...)
|
kmalloc(
- sizeof(unsigned char) * COUNT
+ COUNT
, ...)
)
// 2-factor product with sizeof(type/expression) and identifier or constant.
@@
type TYPE;
expression THING;
identifier COUNT_ID;
constant COUNT_CONST;
@@
(
- kmalloc
+ kmalloc_array
(
- sizeof(TYPE) * (COUNT_ID)
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(TYPE) * COUNT_ID
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(TYPE) * (COUNT_CONST)
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(TYPE) * COUNT_CONST
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(THING) * (COUNT_ID)
+ COUNT_ID, sizeof(THING)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(THING) * COUNT_ID
+ COUNT_ID, sizeof(THING)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(THING) * (COUNT_CONST)
+ COUNT_CONST, sizeof(THING)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(THING) * COUNT_CONST
+ COUNT_CONST, sizeof(THING)
, ...)
)
// 2-factor product, only identifiers.
@@
identifier SIZE, COUNT;
@@
- kmalloc
+ kmalloc_array
(
- SIZE * COUNT
+ COUNT, SIZE
, ...)
// 3-factor product with 1 sizeof(type) or sizeof(expression), with
// redundant parens removed.
@@
expression THING;
identifier STRIDE, COUNT;
type TYPE;
@@
(
kmalloc(
- sizeof(TYPE) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kmalloc(
- sizeof(TYPE) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kmalloc(
- sizeof(TYPE) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kmalloc(
- sizeof(TYPE) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kmalloc(
- sizeof(THING) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kmalloc(
- sizeof(THING) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kmalloc(
- sizeof(THING) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kmalloc(
- sizeof(THING) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
)
// 3-factor product with 2 sizeof(variable), with redundant parens removed.
@@
expression THING1, THING2;
identifier COUNT;
type TYPE1, TYPE2;
@@
(
kmalloc(
- sizeof(TYPE1) * sizeof(TYPE2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
kmalloc(
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
kmalloc(
- sizeof(THING1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
kmalloc(
- sizeof(THING1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
kmalloc(
- sizeof(TYPE1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
|
kmalloc(
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
)
// 3-factor product, only identifiers, with redundant parens removed.
@@
identifier STRIDE, SIZE, COUNT;
@@
(
kmalloc(
- (COUNT) * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kmalloc(
- COUNT * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kmalloc(
- COUNT * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kmalloc(
- (COUNT) * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kmalloc(
- COUNT * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kmalloc(
- (COUNT) * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kmalloc(
- (COUNT) * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kmalloc(
- COUNT * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
)
// Any remaining multi-factor products, first at least 3-factor products,
// when they're not all constants...
@@
expression E1, E2, E3;
constant C1, C2, C3;
@@
(
kmalloc(C1 * C2 * C3, ...)
|
kmalloc(
- (E1) * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
|
kmalloc(
- (E1) * (E2) * E3
+ array3_size(E1, E2, E3)
, ...)
|
kmalloc(
- (E1) * (E2) * (E3)
+ array3_size(E1, E2, E3)
, ...)
|
kmalloc(
- E1 * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
)
// And then all remaining 2 factors products when they're not all constants,
// keeping sizeof() as the second factor argument.
@@
expression THING, E1, E2;
type TYPE;
constant C1, C2, C3;
@@
(
kmalloc(sizeof(THING) * C2, ...)
|
kmalloc(sizeof(TYPE) * C2, ...)
|
kmalloc(C1 * C2 * C3, ...)
|
kmalloc(C1 * C2, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(TYPE) * (E2)
+ E2, sizeof(TYPE)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(TYPE) * E2
+ E2, sizeof(TYPE)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(THING) * (E2)
+ E2, sizeof(THING)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(THING) * E2
+ E2, sizeof(THING)
, ...)
|
- kmalloc
+ kmalloc_array
(
- (E1) * E2
+ E1, E2
, ...)
|
- kmalloc
+ kmalloc_array
(
- (E1) * (E2)
+ E1, E2
, ...)
|
- kmalloc
+ kmalloc_array
(
- E1 * E2
+ E1, E2
, ...)
)
Signed-off-by: Kees Cook <keescook@chromium.org>
2018-06-12 20:55:00 +00:00
|
|
|
save = kmalloc(array3_size(logo_lines, new_cols, 2),
|
|
|
|
GFP_KERNEL);
|
2005-04-16 22:20:36 +00:00
|
|
|
if (save) {
|
2022-02-09 08:48:10 +00:00
|
|
|
int i = min(cols, new_cols);
|
2020-06-15 23:15:42 +00:00
|
|
|
scr_memsetw(save, erase, array3_size(logo_lines, new_cols, 2));
|
2005-04-16 22:20:36 +00:00
|
|
|
r = q - step;
|
|
|
|
for (cnt = 0; cnt < logo_lines; cnt++, r += i)
|
|
|
|
scr_memcpyw(save + cnt * new_cols, r, 2 * i);
|
|
|
|
r = q;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (r == q) {
|
|
|
|
/* We can scroll screen down */
|
|
|
|
r = q - step - cols;
|
|
|
|
for (cnt = rows - logo_lines; cnt > 0; cnt--) {
|
|
|
|
scr_memcpyw(r + step, r, vc->vc_size_row);
|
|
|
|
r -= cols;
|
|
|
|
}
|
|
|
|
if (!save) {
|
2007-05-08 07:37:53 +00:00
|
|
|
int lines;
|
2020-06-15 07:48:33 +00:00
|
|
|
if (vc->state.y + logo_lines >= rows)
|
|
|
|
lines = rows - vc->state.y - 1;
|
2007-05-08 07:37:53 +00:00
|
|
|
else
|
|
|
|
lines = logo_lines;
|
2020-06-15 07:48:33 +00:00
|
|
|
vc->state.y += lines;
|
2007-05-08 07:37:53 +00:00
|
|
|
vc->vc_pos += lines * vc->vc_size_row;
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
scr_memsetw((unsigned short *) vc->vc_origin,
|
|
|
|
erase,
|
|
|
|
vc->vc_size_row * logo_lines);
|
|
|
|
|
2016-06-23 11:34:35 +00:00
|
|
|
if (con_is_visible(vc) && vc->vc_mode == KD_TEXT) {
|
2005-04-16 22:20:36 +00:00
|
|
|
fbcon_clear_margins(vc, 0);
|
|
|
|
update_screen(vc);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (save) {
|
|
|
|
q = (unsigned short *) (vc->vc_origin +
|
|
|
|
vc->vc_size_row *
|
|
|
|
rows);
|
2020-06-15 23:15:42 +00:00
|
|
|
scr_memcpyw(q, save, array3_size(logo_lines, new_cols, 2));
|
2020-06-15 07:48:33 +00:00
|
|
|
vc->state.y += logo_lines;
|
2005-04-16 22:20:36 +00:00
|
|
|
vc->vc_pos += logo_lines * vc->vc_size_row;
|
|
|
|
kfree(save);
|
|
|
|
}
|
|
|
|
|
2019-02-08 18:24:49 +00:00
|
|
|
if (logo_shown == FBCON_LOGO_DONTSHOW)
|
|
|
|
return;
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
if (logo_lines > vc->vc_bottom) {
|
|
|
|
logo_shown = FBCON_LOGO_CANSHOW;
|
|
|
|
printk(KERN_INFO
|
|
|
|
"fbcon_init: disable boot-logo (boot-logo bigger than screen).\n");
|
2019-02-08 18:24:49 +00:00
|
|
|
} else {
|
2005-04-16 22:20:36 +00:00
|
|
|
logo_shown = FBCON_LOGO_DRAW;
|
|
|
|
vc->vc_top = logo_lines;
|
|
|
|
}
|
|
|
|
}
|
2007-05-08 07:38:14 +00:00
|
|
|
#endif /* MODULE */
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
#ifdef CONFIG_FB_TILEBLITTING
|
2006-01-10 04:52:56 +00:00
|
|
|
static void set_blitting_type(struct vc_data *vc, struct fb_info *info)
|
2005-04-16 22:20:36 +00:00
|
|
|
{
|
|
|
|
struct fbcon_ops *ops = info->fbcon_par;
|
|
|
|
|
2006-01-10 04:52:56 +00:00
|
|
|
ops->p = &fb_display[vc->vc_num];
|
2005-11-14 00:06:32 +00:00
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
if ((info->flags & FBINFO_MISC_TILEBLITTING))
|
2006-01-10 04:52:56 +00:00
|
|
|
fbcon_set_tileops(vc, info);
|
[PATCH] fbcon: Console Rotation - Prepare fbcon for console rotation
This patch series implements generic code to rotate the console at 90, 180,
and 270 degrees. The implementation is completely done in the framebuffer
console level, thus no changes to the framebuffer layer or to the drivers
are needed.
Console rotation is required by some Sharp-based devices where the natural
orientation of the display is not at 0 degrees. Also, users that have
displays that can pivot will benefit by having a console in portrait mode
if they so desire.
The choice to implement the code in the console layer rather than in the
framebuffer layer is due to the following reasons:
- it's fast
- it does not require driver changes
- it can coexist with devices that can rotate the display at the hardware level
- it complements graphics applications that can do display rotation
The changes to core fbcon are minimal-- recognition of the console
rotation angle so it can swap directions, origins and axes (xres vs yres,
xpanstep vs ypanstep, xoffset vs yoffset, etc) and storage of the rotation
angle per display. The bulk of the code that does the actual drawing to the
screen are placed in separate files. Each angle of rotation has separate
methods (bmove, clear, putcs, cursor, update_start which is derived from
update_var, and clear_margins). To mimimize processing time, the fontdata
are pre-rotated at each console switch (only if the font or the angle has
changed).
The option can be compiled out (CONFIG_FRAMEBUFFER_CONSOLE_ROTATION = n) if
rotation is not needed.
Choosing the rotation angle can be done in several ways:
1. boot option fbcon=rotate:n, where
n = 0 - normal
n = 1 - 90 degrees (clockwise)
n = 2 - 180 degrees (upside down)
n = 3 - 270 degrees (counterclockwise)
2. echo n > /sys/class/graphics/fb[num]/con_rotate
where n is the same as described above. It sets the angle of rotation
of the current console
3 echo n > /sys/class/graphics/fb[num]/con_rotate_all
where n is the same as described above. Globally sets the angle of
rotation.
GOTCHAS:
The option, especially at angles of 90 and 270 degrees, will exercise
the least used code of drivers. Namely, at these angles, panning is done
in the x-axis, so it can reveal bugs in the driver if xpanstep is set
incorrectly. A workaround is to set xpanstep = 0.
Secondly, at these angles, the framebuffer memory access can be
unaligned if (fontheight * bpp) % 32 ~= 0 which can reveal bugs in the drivers
imageblit, fillrect and copyarea functions. (I think cfbfillrect may have
this buglet). A workaround is to use a standard 8x16 font.
Speed:
The scrolling speed difference between 0 and 180 degrees is minimal,
somewhere areound 1-2%. At 90 or 270 degress, speed drops down to a vicinity
of 30-40%. This is understandable because the blit direction is across the
framebuffer "direction." Scrolling will be helped at these angles if xpanstep
is not equal to zero, use of 8x16 fonts, and setting xres_virtual >= xres * 2.
Note: The code is tested on little-endian only, so I don't know if it will
work in big-endian. Please let me know, it will take only less than a minute
of your time.
This patch prepares fbcon for console rotation and contains the following
changes:
- add rotate field in struct fbcon_ops to keep fbcon's current rotation
angle
- add con_rotate field in struct display to store per-display rotation angle
- create a private copy of the current var to fbcon. This will prevent
fbcon from directly manipulating info->var, especially the fields xoffset,
yoffset and vmode.
- add ability to swap pertinent axes (xres, yres; xpanstep, ypanstep; etc)
depending on the rotation angle
- change global update_var() (function that sets the screen start address)
as an fbcon method update_start. This is required because the axes, start
offset, and/or direction can be reversed depending on the rotation angle.
- add fbcon method rotate_font() which will rotate each character bitmap to
the correct angle of rotation.
- add fbcon boot option 'rotate' to select the angle of rotation at bootime.
Currently does nothing until all patches are applied.
Signed-off-by: Antonino Daplas <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-11-09 05:39:09 +00:00
|
|
|
else {
|
2006-01-10 04:52:56 +00:00
|
|
|
fbcon_set_rotation(info);
|
2005-04-16 22:20:36 +00:00
|
|
|
fbcon_set_bitops(ops);
|
[PATCH] fbcon: Console Rotation - Prepare fbcon for console rotation
This patch series implements generic code to rotate the console at 90, 180,
and 270 degrees. The implementation is completely done in the framebuffer
console level, thus no changes to the framebuffer layer or to the drivers
are needed.
Console rotation is required by some Sharp-based devices where the natural
orientation of the display is not at 0 degrees. Also, users that have
displays that can pivot will benefit by having a console in portrait mode
if they so desire.
The choice to implement the code in the console layer rather than in the
framebuffer layer is due to the following reasons:
- it's fast
- it does not require driver changes
- it can coexist with devices that can rotate the display at the hardware level
- it complements graphics applications that can do display rotation
The changes to core fbcon are minimal-- recognition of the console
rotation angle so it can swap directions, origins and axes (xres vs yres,
xpanstep vs ypanstep, xoffset vs yoffset, etc) and storage of the rotation
angle per display. The bulk of the code that does the actual drawing to the
screen are placed in separate files. Each angle of rotation has separate
methods (bmove, clear, putcs, cursor, update_start which is derived from
update_var, and clear_margins). To mimimize processing time, the fontdata
are pre-rotated at each console switch (only if the font or the angle has
changed).
The option can be compiled out (CONFIG_FRAMEBUFFER_CONSOLE_ROTATION = n) if
rotation is not needed.
Choosing the rotation angle can be done in several ways:
1. boot option fbcon=rotate:n, where
n = 0 - normal
n = 1 - 90 degrees (clockwise)
n = 2 - 180 degrees (upside down)
n = 3 - 270 degrees (counterclockwise)
2. echo n > /sys/class/graphics/fb[num]/con_rotate
where n is the same as described above. It sets the angle of rotation
of the current console
3 echo n > /sys/class/graphics/fb[num]/con_rotate_all
where n is the same as described above. Globally sets the angle of
rotation.
GOTCHAS:
The option, especially at angles of 90 and 270 degrees, will exercise
the least used code of drivers. Namely, at these angles, panning is done
in the x-axis, so it can reveal bugs in the driver if xpanstep is set
incorrectly. A workaround is to set xpanstep = 0.
Secondly, at these angles, the framebuffer memory access can be
unaligned if (fontheight * bpp) % 32 ~= 0 which can reveal bugs in the drivers
imageblit, fillrect and copyarea functions. (I think cfbfillrect may have
this buglet). A workaround is to use a standard 8x16 font.
Speed:
The scrolling speed difference between 0 and 180 degrees is minimal,
somewhere areound 1-2%. At 90 or 270 degress, speed drops down to a vicinity
of 30-40%. This is understandable because the blit direction is across the
framebuffer "direction." Scrolling will be helped at these angles if xpanstep
is not equal to zero, use of 8x16 fonts, and setting xres_virtual >= xres * 2.
Note: The code is tested on little-endian only, so I don't know if it will
work in big-endian. Please let me know, it will take only less than a minute
of your time.
This patch prepares fbcon for console rotation and contains the following
changes:
- add rotate field in struct fbcon_ops to keep fbcon's current rotation
angle
- add con_rotate field in struct display to store per-display rotation angle
- create a private copy of the current var to fbcon. This will prevent
fbcon from directly manipulating info->var, especially the fields xoffset,
yoffset and vmode.
- add ability to swap pertinent axes (xres, yres; xpanstep, ypanstep; etc)
depending on the rotation angle
- change global update_var() (function that sets the screen start address)
as an fbcon method update_start. This is required because the axes, start
offset, and/or direction can be reversed depending on the rotation angle.
- add fbcon method rotate_font() which will rotate each character bitmap to
the correct angle of rotation.
- add fbcon boot option 'rotate' to select the angle of rotation at bootime.
Currently does nothing until all patches are applied.
Signed-off-by: Antonino Daplas <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-11-09 05:39:09 +00:00
|
|
|
}
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
2007-05-08 07:39:19 +00:00
|
|
|
|
|
|
|
static int fbcon_invalid_charcount(struct fb_info *info, unsigned charcount)
|
|
|
|
{
|
|
|
|
int err = 0;
|
|
|
|
|
|
|
|
if (info->flags & FBINFO_MISC_TILEBLITTING &&
|
|
|
|
info->tileops->fb_get_tilemax(info) < charcount)
|
|
|
|
err = 1;
|
|
|
|
|
|
|
|
return err;
|
|
|
|
}
|
2005-04-16 22:20:36 +00:00
|
|
|
#else
|
2006-01-10 04:52:56 +00:00
|
|
|
static void set_blitting_type(struct vc_data *vc, struct fb_info *info)
|
2005-04-16 22:20:36 +00:00
|
|
|
{
|
|
|
|
struct fbcon_ops *ops = info->fbcon_par;
|
|
|
|
|
|
|
|
info->flags &= ~FBINFO_MISC_TILEBLITTING;
|
2006-01-10 04:52:56 +00:00
|
|
|
ops->p = &fb_display[vc->vc_num];
|
|
|
|
fbcon_set_rotation(info);
|
2005-04-16 22:20:36 +00:00
|
|
|
fbcon_set_bitops(ops);
|
|
|
|
}
|
2007-05-08 07:39:19 +00:00
|
|
|
|
|
|
|
static int fbcon_invalid_charcount(struct fb_info *info, unsigned charcount)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
#endif /* CONFIG_MISC_TILEBLITTING */
|
|
|
|
|
2022-04-05 21:03:29 +00:00
|
|
|
static void fbcon_release(struct fb_info *info)
|
|
|
|
{
|
2022-04-05 21:03:30 +00:00
|
|
|
lock_fb_info(info);
|
2022-04-05 21:03:29 +00:00
|
|
|
if (info->fbops->fb_release)
|
|
|
|
info->fbops->fb_release(info, 0);
|
2022-04-05 21:03:30 +00:00
|
|
|
unlock_fb_info(info);
|
2022-04-05 21:03:29 +00:00
|
|
|
|
|
|
|
module_put(info->fbops->owner);
|
2022-04-05 21:03:33 +00:00
|
|
|
|
|
|
|
if (info->fbcon_par) {
|
|
|
|
struct fbcon_ops *ops = info->fbcon_par;
|
|
|
|
|
|
|
|
fbcon_del_cursor_work(info);
|
|
|
|
kfree(ops->cursor_state.mask);
|
|
|
|
kfree(ops->cursor_data);
|
|
|
|
kfree(ops->cursor_src);
|
|
|
|
kfree(ops->fontbuffer);
|
|
|
|
kfree(info->fbcon_par);
|
|
|
|
info->fbcon_par = NULL;
|
|
|
|
}
|
2022-04-05 21:03:29 +00:00
|
|
|
}
|
|
|
|
|
2022-04-05 21:03:27 +00:00
|
|
|
static int fbcon_open(struct fb_info *info)
|
|
|
|
{
|
2022-04-05 21:03:29 +00:00
|
|
|
struct fbcon_ops *ops;
|
|
|
|
|
2022-04-05 21:03:27 +00:00
|
|
|
if (!try_module_get(info->fbops->owner))
|
|
|
|
return -ENODEV;
|
|
|
|
|
2022-04-05 21:03:30 +00:00
|
|
|
lock_fb_info(info);
|
2022-04-05 21:03:27 +00:00
|
|
|
if (info->fbops->fb_open &&
|
|
|
|
info->fbops->fb_open(info, 0)) {
|
2022-04-05 21:03:30 +00:00
|
|
|
unlock_fb_info(info);
|
2022-04-05 21:03:27 +00:00
|
|
|
module_put(info->fbops->owner);
|
|
|
|
return -ENODEV;
|
|
|
|
}
|
2022-04-05 21:03:30 +00:00
|
|
|
unlock_fb_info(info);
|
2022-04-05 21:03:27 +00:00
|
|
|
|
2022-04-05 21:03:29 +00:00
|
|
|
ops = kzalloc(sizeof(struct fbcon_ops), GFP_KERNEL);
|
|
|
|
if (!ops) {
|
|
|
|
fbcon_release(info);
|
|
|
|
return -ENOMEM;
|
|
|
|
}
|
2022-04-05 21:03:27 +00:00
|
|
|
|
2022-04-05 21:03:29 +00:00
|
|
|
INIT_DELAYED_WORK(&ops->cursor_work, fb_flashcursor);
|
|
|
|
ops->info = info;
|
|
|
|
info->fbcon_par = ops;
|
|
|
|
ops->cur_blink_jiffies = HZ / 5;
|
2022-04-05 21:03:27 +00:00
|
|
|
|
2022-04-05 21:03:29 +00:00
|
|
|
return 0;
|
2022-04-05 21:03:27 +00:00
|
|
|
}
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
static int con2fb_acquire_newinfo(struct vc_data *vc, struct fb_info *info,
|
2022-04-05 21:03:29 +00:00
|
|
|
int unit)
|
2005-04-16 22:20:36 +00:00
|
|
|
{
|
2022-04-05 21:03:27 +00:00
|
|
|
int err;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2022-04-05 21:03:27 +00:00
|
|
|
err = fbcon_open(info);
|
|
|
|
if (err)
|
|
|
|
return err;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2022-04-05 21:03:29 +00:00
|
|
|
if (vc)
|
|
|
|
set_blitting_type(vc, info);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
2022-04-05 21:03:28 +00:00
|
|
|
static void con2fb_release_oldinfo(struct vc_data *vc, struct fb_info *oldinfo,
|
|
|
|
struct fb_info *newinfo)
|
2005-04-16 22:20:36 +00:00
|
|
|
{
|
2022-04-05 21:03:27 +00:00
|
|
|
int ret;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2022-04-05 21:03:27 +00:00
|
|
|
fbcon_release(oldinfo);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2022-04-05 21:03:27 +00:00
|
|
|
/*
|
|
|
|
If oldinfo and newinfo are driving the same hardware,
|
|
|
|
the fb_release() method of oldinfo may attempt to
|
|
|
|
restore the hardware state. This will leave the
|
|
|
|
newinfo in an undefined state. Thus, a call to
|
|
|
|
fb_set_par() may be needed for the newinfo.
|
|
|
|
*/
|
|
|
|
if (newinfo && newinfo->fbops->fb_set_par) {
|
|
|
|
ret = newinfo->fbops->fb_set_par(newinfo);
|
2009-09-22 23:47:44 +00:00
|
|
|
|
2022-04-05 21:03:27 +00:00
|
|
|
if (ret)
|
|
|
|
printk(KERN_ERR "con2fb_release_oldinfo: "
|
|
|
|
"detected unhandled fb_set_par error, "
|
|
|
|
"error code %d\n", ret);
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void con2fb_init_display(struct vc_data *vc, struct fb_info *info,
|
|
|
|
int unit, int show_logo)
|
|
|
|
{
|
|
|
|
struct fbcon_ops *ops = info->fbcon_par;
|
2009-09-22 23:47:44 +00:00
|
|
|
int ret;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
ops->currcon = fg_console;
|
|
|
|
|
2022-04-05 21:03:25 +00:00
|
|
|
if (info->fbops->fb_set_par && !ops->initialized) {
|
2009-09-22 23:47:44 +00:00
|
|
|
ret = info->fbops->fb_set_par(info);
|
|
|
|
|
|
|
|
if (ret)
|
|
|
|
printk(KERN_ERR "con2fb_init_display: detected "
|
|
|
|
"unhandled fb_set_par error, "
|
|
|
|
"error code %d\n", ret);
|
|
|
|
}
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2022-04-05 21:03:25 +00:00
|
|
|
ops->initialized = true;
|
2005-04-16 22:20:36 +00:00
|
|
|
ops->graphics = 0;
|
2007-07-17 11:05:32 +00:00
|
|
|
fbcon_set_disp(info, &info->var, unit);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
if (show_logo) {
|
|
|
|
struct vc_data *fg_vc = vc_cons[fg_console].d;
|
|
|
|
struct fb_info *fg_info =
|
2022-04-05 21:03:21 +00:00
|
|
|
fbcon_info_from_console(fg_console);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
fbcon_prepare_logo(fg_vc, fg_info, fg_vc->vc_cols,
|
|
|
|
fg_vc->vc_rows, fg_vc->vc_cols,
|
|
|
|
fg_vc->vc_rows);
|
|
|
|
}
|
|
|
|
|
|
|
|
update_screen(vc_cons[fg_console].d);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* set_con2fb_map - map console to frame buffer device
|
|
|
|
* @unit: virtual console number to map
|
|
|
|
* @newidx: frame buffer index to map virtual console to
|
|
|
|
* @user: user request
|
|
|
|
*
|
|
|
|
* Maps a virtual console @unit to a frame buffer device
|
|
|
|
* @newidx.
|
2013-01-25 01:38:56 +00:00
|
|
|
*
|
|
|
|
* This should be called with the console lock held.
|
2005-04-16 22:20:36 +00:00
|
|
|
*/
|
|
|
|
static int set_con2fb_map(int unit, int newidx, int user)
|
|
|
|
{
|
|
|
|
struct vc_data *vc = vc_cons[unit].d;
|
|
|
|
int oldidx = con2fb_map[unit];
|
2022-04-05 21:03:35 +00:00
|
|
|
struct fb_info *info = fbcon_registered_fb[newidx];
|
2005-04-16 22:20:36 +00:00
|
|
|
struct fb_info *oldinfo = NULL;
|
2022-04-05 21:03:28 +00:00
|
|
|
int found, err = 0, show_logo;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2018-06-28 13:20:28 +00:00
|
|
|
WARN_CONSOLE_UNLOCKED();
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
if (oldidx == newidx)
|
|
|
|
return 0;
|
|
|
|
|
2010-12-21 01:41:17 +00:00
|
|
|
if (!info)
|
2006-06-26 07:27:09 +00:00
|
|
|
return -EINVAL;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2010-12-21 01:41:17 +00:00
|
|
|
if (!search_for_mapped_con() || !con_is_bound(&fb_con)) {
|
2005-04-16 22:20:36 +00:00
|
|
|
info_idx = newidx;
|
2013-01-25 01:38:56 +00:00
|
|
|
return do_fbcon_takeover(0);
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (oldidx != -1)
|
2022-04-05 21:03:35 +00:00
|
|
|
oldinfo = fbcon_registered_fb[oldidx];
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
found = search_fb_in_map(newidx);
|
|
|
|
|
2022-04-05 21:03:29 +00:00
|
|
|
if (!err && !found) {
|
|
|
|
err = con2fb_acquire_newinfo(vc, info, unit);
|
|
|
|
if (!err)
|
|
|
|
con2fb_map[unit] = newidx;
|
|
|
|
}
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* If old fb is not mapped to any of the consoles,
|
|
|
|
* fbcon should release it.
|
|
|
|
*/
|
2019-12-18 02:53:37 +00:00
|
|
|
if (!err && oldinfo && !search_fb_in_map(oldidx))
|
2022-04-05 21:03:28 +00:00
|
|
|
con2fb_release_oldinfo(vc, oldinfo, info);
|
2019-12-18 02:53:37 +00:00
|
|
|
|
2022-04-05 21:03:28 +00:00
|
|
|
show_logo = (fg_console == 0 && !user &&
|
|
|
|
logo_shown != FBCON_LOGO_DONTSHOW);
|
2019-12-18 02:53:37 +00:00
|
|
|
|
2022-04-05 21:03:28 +00:00
|
|
|
if (!found)
|
|
|
|
fbcon_add_cursor_work(info);
|
|
|
|
con2fb_map_boot[unit] = newidx;
|
|
|
|
con2fb_init_display(vc, info, unit, show_logo);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2006-06-26 07:27:09 +00:00
|
|
|
if (!search_fb_in_map(info_idx))
|
|
|
|
info_idx = newidx;
|
|
|
|
|
2019-12-18 02:53:37 +00:00
|
|
|
return err;
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Low Level Operations
|
|
|
|
*/
|
2013-05-21 05:15:12 +00:00
|
|
|
/* NOTE: fbcon cannot be __init: it may be called from do_take_over_console later */
|
2019-05-28 09:02:39 +00:00
|
|
|
static int var_to_display(struct fbcon_display *disp,
|
2005-04-16 22:20:36 +00:00
|
|
|
struct fb_var_screeninfo *var,
|
|
|
|
struct fb_info *info)
|
|
|
|
{
|
|
|
|
disp->xres_virtual = var->xres_virtual;
|
|
|
|
disp->yres_virtual = var->yres_virtual;
|
|
|
|
disp->bits_per_pixel = var->bits_per_pixel;
|
|
|
|
disp->grayscale = var->grayscale;
|
|
|
|
disp->nonstd = var->nonstd;
|
|
|
|
disp->accel_flags = var->accel_flags;
|
|
|
|
disp->height = var->height;
|
|
|
|
disp->width = var->width;
|
|
|
|
disp->red = var->red;
|
|
|
|
disp->green = var->green;
|
|
|
|
disp->blue = var->blue;
|
|
|
|
disp->transp = var->transp;
|
|
|
|
disp->rotate = var->rotate;
|
|
|
|
disp->mode = fb_match_mode(var, &info->modelist);
|
|
|
|
if (disp->mode == NULL)
|
|
|
|
/* This should not happen */
|
|
|
|
return -EINVAL;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void display_to_var(struct fb_var_screeninfo *var,
|
2019-05-28 09:02:39 +00:00
|
|
|
struct fbcon_display *disp)
|
2005-04-16 22:20:36 +00:00
|
|
|
{
|
|
|
|
fb_videomode_to_var(var, disp->mode);
|
|
|
|
var->xres_virtual = disp->xres_virtual;
|
|
|
|
var->yres_virtual = disp->yres_virtual;
|
|
|
|
var->bits_per_pixel = disp->bits_per_pixel;
|
|
|
|
var->grayscale = disp->grayscale;
|
|
|
|
var->nonstd = disp->nonstd;
|
|
|
|
var->accel_flags = disp->accel_flags;
|
|
|
|
var->height = disp->height;
|
|
|
|
var->width = disp->width;
|
|
|
|
var->red = disp->red;
|
|
|
|
var->green = disp->green;
|
|
|
|
var->blue = disp->blue;
|
|
|
|
var->transp = disp->transp;
|
|
|
|
var->rotate = disp->rotate;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const char *fbcon_startup(void)
|
|
|
|
{
|
|
|
|
const char *display_desc = "frame buffer device";
|
2019-05-28 09:02:39 +00:00
|
|
|
struct fbcon_display *p = &fb_display[fg_console];
|
2005-04-16 22:20:36 +00:00
|
|
|
struct vc_data *vc = vc_cons[fg_console].d;
|
2005-09-13 08:25:44 +00:00
|
|
|
const struct font_desc *font = NULL;
|
2005-04-16 22:20:36 +00:00
|
|
|
struct fb_info *info = NULL;
|
|
|
|
struct fbcon_ops *ops;
|
|
|
|
int rows, cols;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If num_registered_fb is zero, this is a call for the dummy part.
|
|
|
|
* The frame buffer devices weren't initialized yet.
|
|
|
|
*/
|
2022-04-05 21:03:35 +00:00
|
|
|
if (!fbcon_num_registered_fb || info_idx == -1)
|
2005-04-16 22:20:36 +00:00
|
|
|
return display_desc;
|
|
|
|
/*
|
|
|
|
* Instead of blindly using registered_fb[0], we use info_idx, set by
|
2022-04-05 21:03:22 +00:00
|
|
|
* fbcon_fb_registered();
|
2005-04-16 22:20:36 +00:00
|
|
|
*/
|
2022-04-05 21:03:35 +00:00
|
|
|
info = fbcon_registered_fb[info_idx];
|
2005-04-16 22:20:36 +00:00
|
|
|
if (!info)
|
|
|
|
return NULL;
|
|
|
|
|
2022-04-05 21:03:27 +00:00
|
|
|
if (fbcon_open(info))
|
2005-04-16 22:20:36 +00:00
|
|
|
return NULL;
|
|
|
|
|
2022-04-05 21:03:29 +00:00
|
|
|
ops = info->fbcon_par;
|
2005-04-16 22:20:36 +00:00
|
|
|
ops->currcon = -1;
|
|
|
|
ops->graphics = 1;
|
[PATCH] fbcon: Console Rotation - Prepare fbcon for console rotation
This patch series implements generic code to rotate the console at 90, 180,
and 270 degrees. The implementation is completely done in the framebuffer
console level, thus no changes to the framebuffer layer or to the drivers
are needed.
Console rotation is required by some Sharp-based devices where the natural
orientation of the display is not at 0 degrees. Also, users that have
displays that can pivot will benefit by having a console in portrait mode
if they so desire.
The choice to implement the code in the console layer rather than in the
framebuffer layer is due to the following reasons:
- it's fast
- it does not require driver changes
- it can coexist with devices that can rotate the display at the hardware level
- it complements graphics applications that can do display rotation
The changes to core fbcon are minimal-- recognition of the console
rotation angle so it can swap directions, origins and axes (xres vs yres,
xpanstep vs ypanstep, xoffset vs yoffset, etc) and storage of the rotation
angle per display. The bulk of the code that does the actual drawing to the
screen are placed in separate files. Each angle of rotation has separate
methods (bmove, clear, putcs, cursor, update_start which is derived from
update_var, and clear_margins). To mimimize processing time, the fontdata
are pre-rotated at each console switch (only if the font or the angle has
changed).
The option can be compiled out (CONFIG_FRAMEBUFFER_CONSOLE_ROTATION = n) if
rotation is not needed.
Choosing the rotation angle can be done in several ways:
1. boot option fbcon=rotate:n, where
n = 0 - normal
n = 1 - 90 degrees (clockwise)
n = 2 - 180 degrees (upside down)
n = 3 - 270 degrees (counterclockwise)
2. echo n > /sys/class/graphics/fb[num]/con_rotate
where n is the same as described above. It sets the angle of rotation
of the current console
3 echo n > /sys/class/graphics/fb[num]/con_rotate_all
where n is the same as described above. Globally sets the angle of
rotation.
GOTCHAS:
The option, especially at angles of 90 and 270 degrees, will exercise
the least used code of drivers. Namely, at these angles, panning is done
in the x-axis, so it can reveal bugs in the driver if xpanstep is set
incorrectly. A workaround is to set xpanstep = 0.
Secondly, at these angles, the framebuffer memory access can be
unaligned if (fontheight * bpp) % 32 ~= 0 which can reveal bugs in the drivers
imageblit, fillrect and copyarea functions. (I think cfbfillrect may have
this buglet). A workaround is to use a standard 8x16 font.
Speed:
The scrolling speed difference between 0 and 180 degrees is minimal,
somewhere areound 1-2%. At 90 or 270 degress, speed drops down to a vicinity
of 30-40%. This is understandable because the blit direction is across the
framebuffer "direction." Scrolling will be helped at these angles if xpanstep
is not equal to zero, use of 8x16 fonts, and setting xres_virtual >= xres * 2.
Note: The code is tested on little-endian only, so I don't know if it will
work in big-endian. Please let me know, it will take only less than a minute
of your time.
This patch prepares fbcon for console rotation and contains the following
changes:
- add rotate field in struct fbcon_ops to keep fbcon's current rotation
angle
- add con_rotate field in struct display to store per-display rotation angle
- create a private copy of the current var to fbcon. This will prevent
fbcon from directly manipulating info->var, especially the fields xoffset,
yoffset and vmode.
- add ability to swap pertinent axes (xres, yres; xpanstep, ypanstep; etc)
depending on the rotation angle
- change global update_var() (function that sets the screen start address)
as an fbcon method update_start. This is required because the axes, start
offset, and/or direction can be reversed depending on the rotation angle.
- add fbcon method rotate_font() which will rotate each character bitmap to
the correct angle of rotation.
- add fbcon boot option 'rotate' to select the angle of rotation at bootime.
Currently does nothing until all patches are applied.
Signed-off-by: Antonino Daplas <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-11-09 05:39:09 +00:00
|
|
|
ops->cur_rotate = -1;
|
2017-11-25 19:35:47 +00:00
|
|
|
|
|
|
|
p->con_rotate = initial_rotation;
|
|
|
|
if (p->con_rotate == -1)
|
|
|
|
p->con_rotate = info->fbcon_rotate_hint;
|
|
|
|
if (p->con_rotate == -1)
|
2017-11-25 19:35:53 +00:00
|
|
|
p->con_rotate = FB_ROTATE_UR;
|
2017-11-25 19:35:47 +00:00
|
|
|
|
2006-01-10 04:52:56 +00:00
|
|
|
set_blitting_type(vc, info);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
/* Setup default font */
|
2013-01-24 06:12:41 +00:00
|
|
|
if (!p->fontdata && !vc->vc_font.data) {
|
2005-04-16 22:20:36 +00:00
|
|
|
if (!fontname[0] || !(font = find_font(fontname)))
|
|
|
|
font = get_default_font(info->var.xres,
|
2007-05-08 07:39:11 +00:00
|
|
|
info->var.yres,
|
|
|
|
info->pixmap.blit_x,
|
|
|
|
info->pixmap.blit_y);
|
2005-04-16 22:20:36 +00:00
|
|
|
vc->vc_font.width = font->width;
|
|
|
|
vc->vc_font.height = font->height;
|
2005-09-13 08:25:44 +00:00
|
|
|
vc->vc_font.data = (void *)(p->fontdata = font->data);
|
fbcon: Avoid using FNTCHARCNT() and hard-coded built-in font charcount
For user-provided fonts, the framebuffer layer is using a magic
negative-indexing macro, FNTCHARCNT(), to keep track of their number of
characters:
#define FNTCHARCNT(fd) (((int *)(fd))[-3])
For built-in fonts, it is using hard-coded values (256). This results in
something like the following:
map.length = (ops->p->userfont) ?
FNTCHARCNT(ops->p->fontdata) : 256;
This is unsatisfactory. In fact, there is already a `charcount` field in
our virtual console descriptor (see `struct console_font` inside `struct
vc_data`), let us use it:
map.length = vc->vc_font.charcount;
Recently we added a `charcount` field to `struct font_desc`. Use it to set
`vc->vc_font.charcount` properly. The idea is:
- We only use FNTCHARCNT() on `vc->vc_font.data` and `p->fontdata`.
Assume FNTCHARCNT() is working as intended;
- Whenever `vc->vc_font.data` is set, also set `vc->vc_font.charcount`
properly;
- We can now replace `FNTCHARCNT(vc->vc_font.data)` with
`vc->vc_font.charcount`;
- Since `p->fontdata` always point to the same font data buffer with
`vc->vc_font.data`, we can also replace `FNTCHARCNT(p->fontdata)` with
`vc->vc_font.charcount`.
In conclusion, set `vc->vc_font.charcount` properly in fbcon_startup(),
fbcon_init(), fbcon_set_disp() and fbcon_do_set_font(), then replace
FNTCHARCNT() with `vc->vc_font.charcount`. No more if-else between
negative-indexing macros and hard-coded values.
Do not include <linux/font.h> in fbcon_rotate.c and tileblit.c, since they
no longer need it.
Depends on patch "Fonts: Add charcount field to font_desc".
Suggested-by: Daniel Vetter <daniel@ffwll.ch>
Signed-off-by: Peilin Ye <yepeilin.cs@gmail.com>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/e460a5780e54e3022661d5f09555144583b4cc59.1605169912.git.yepeilin.cs@gmail.com
2020-11-12 12:15:22 +00:00
|
|
|
vc->vc_font.charcount = font->charcount;
|
2013-01-24 06:12:41 +00:00
|
|
|
} else {
|
|
|
|
p->fontdata = vc->vc_font.data;
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
|
[PATCH] fbcon: Console Rotation - Prepare fbcon for console rotation
This patch series implements generic code to rotate the console at 90, 180,
and 270 degrees. The implementation is completely done in the framebuffer
console level, thus no changes to the framebuffer layer or to the drivers
are needed.
Console rotation is required by some Sharp-based devices where the natural
orientation of the display is not at 0 degrees. Also, users that have
displays that can pivot will benefit by having a console in portrait mode
if they so desire.
The choice to implement the code in the console layer rather than in the
framebuffer layer is due to the following reasons:
- it's fast
- it does not require driver changes
- it can coexist with devices that can rotate the display at the hardware level
- it complements graphics applications that can do display rotation
The changes to core fbcon are minimal-- recognition of the console
rotation angle so it can swap directions, origins and axes (xres vs yres,
xpanstep vs ypanstep, xoffset vs yoffset, etc) and storage of the rotation
angle per display. The bulk of the code that does the actual drawing to the
screen are placed in separate files. Each angle of rotation has separate
methods (bmove, clear, putcs, cursor, update_start which is derived from
update_var, and clear_margins). To mimimize processing time, the fontdata
are pre-rotated at each console switch (only if the font or the angle has
changed).
The option can be compiled out (CONFIG_FRAMEBUFFER_CONSOLE_ROTATION = n) if
rotation is not needed.
Choosing the rotation angle can be done in several ways:
1. boot option fbcon=rotate:n, where
n = 0 - normal
n = 1 - 90 degrees (clockwise)
n = 2 - 180 degrees (upside down)
n = 3 - 270 degrees (counterclockwise)
2. echo n > /sys/class/graphics/fb[num]/con_rotate
where n is the same as described above. It sets the angle of rotation
of the current console
3 echo n > /sys/class/graphics/fb[num]/con_rotate_all
where n is the same as described above. Globally sets the angle of
rotation.
GOTCHAS:
The option, especially at angles of 90 and 270 degrees, will exercise
the least used code of drivers. Namely, at these angles, panning is done
in the x-axis, so it can reveal bugs in the driver if xpanstep is set
incorrectly. A workaround is to set xpanstep = 0.
Secondly, at these angles, the framebuffer memory access can be
unaligned if (fontheight * bpp) % 32 ~= 0 which can reveal bugs in the drivers
imageblit, fillrect and copyarea functions. (I think cfbfillrect may have
this buglet). A workaround is to use a standard 8x16 font.
Speed:
The scrolling speed difference between 0 and 180 degrees is minimal,
somewhere areound 1-2%. At 90 or 270 degress, speed drops down to a vicinity
of 30-40%. This is understandable because the blit direction is across the
framebuffer "direction." Scrolling will be helped at these angles if xpanstep
is not equal to zero, use of 8x16 fonts, and setting xres_virtual >= xres * 2.
Note: The code is tested on little-endian only, so I don't know if it will
work in big-endian. Please let me know, it will take only less than a minute
of your time.
This patch prepares fbcon for console rotation and contains the following
changes:
- add rotate field in struct fbcon_ops to keep fbcon's current rotation
angle
- add con_rotate field in struct display to store per-display rotation angle
- create a private copy of the current var to fbcon. This will prevent
fbcon from directly manipulating info->var, especially the fields xoffset,
yoffset and vmode.
- add ability to swap pertinent axes (xres, yres; xpanstep, ypanstep; etc)
depending on the rotation angle
- change global update_var() (function that sets the screen start address)
as an fbcon method update_start. This is required because the axes, start
offset, and/or direction can be reversed depending on the rotation angle.
- add fbcon method rotate_font() which will rotate each character bitmap to
the correct angle of rotation.
- add fbcon boot option 'rotate' to select the angle of rotation at bootime.
Currently does nothing until all patches are applied.
Signed-off-by: Antonino Daplas <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-11-09 05:39:09 +00:00
|
|
|
cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
|
|
|
|
rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
|
|
|
|
cols /= vc->vc_font.width;
|
|
|
|
rows /= vc->vc_font.height;
|
2005-04-16 22:20:36 +00:00
|
|
|
vc_resize(vc, cols, rows);
|
|
|
|
|
2020-11-28 22:40:48 +00:00
|
|
|
pr_debug("mode: %s\n", info->fix.id);
|
|
|
|
pr_debug("visual: %d\n", info->fix.visual);
|
|
|
|
pr_debug("res: %dx%d-%d\n", info->var.xres,
|
|
|
|
info->var.yres,
|
|
|
|
info->var.bits_per_pixel);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2022-04-05 21:03:24 +00:00
|
|
|
fbcon_add_cursor_work(info);
|
2005-04-16 22:20:36 +00:00
|
|
|
return display_desc;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void fbcon_init(struct vc_data *vc, int init)
|
|
|
|
{
|
fbcon: Remove fbcon_has_exited
This is unused code since
commit 6104c37094e729f3d4ce65797002112735d49cd1
Author: Daniel Vetter <daniel.vetter@ffwll.ch>
Date: Tue Aug 1 17:32:07 2017 +0200
fbcon: Make fbcon a built-time depency for fbdev
when fbcon was made a compile-time static dependency of fbdev. We
can't exit fbcon anymore without exiting fbdev first, which only works
if all fbdev drivers have unloaded already. Hence this is all dead
code.
v2: I missed that fbcon_exit is also called from con_deinit stuff, and
there fbcon_has_exited prevents double-cleanup. But we can fix that
by properly resetting con2fb_map[] to all -1, which is used everywhere
else to indicate "no fb_info allocate to this console". With that
change the double-cleanup (which resulted in a module refcount underflow,
among other things) is prevented.
Aside: con2fb_map is a signed char, so don't register more than 128 fb_info
or hilarity will ensue.
v3: CI showed me that I still didn't fully understand what's going on
here. The leaked references in con2fb_map have been used upon
rebinding the fb console in fbcon_init. It worked because fbdev
unregistering still cleaned out con2fb_map, and reset it to info_idx.
If the last fbdev driver unregistered, then it also reset info_idx,
and unregistered the fbcon driver.
Imo that's all a bit fragile, so let's keep the con2fb_map reset to
-1, and in fbcon_init pick info_idx if we're starting fresh. That
means unbinding and rebinding will cleanse the mapping, but why are
you doing that if you want to retain the mapping, so should be fine.
Also, I think info_idx == -1 is impossible in fbcon_init - we
unregister the fbcon in that case. So catch&warn about that.
v4: Drop unecessary assignment - I forgot to delete the first
assignment of info in fbcon_init.
Cc: Sam Ravnborg <sam@ravnborg.org>
Reviewed-by: Sam Ravnborg <sam@ravnborg.org>
Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Hans de Goede <hdegoede@redhat.com>
Cc: "Noralf Trønnes" <noralf@tronnes.org>
Cc: Yisheng Xie <ysxie@foxmail.com>
Cc: Konstantin Khorenko <khorenko@virtuozzo.com>
Cc: Prarit Bhargava <prarit@redhat.com>
Cc: Kees Cook <keescook@chromium.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20190528090304.9388-10-daniel.vetter@ffwll.ch
2019-05-28 09:02:40 +00:00
|
|
|
struct fb_info *info;
|
2005-04-16 22:20:36 +00:00
|
|
|
struct fbcon_ops *ops;
|
|
|
|
struct vc_data **default_mode = vc->vc_display_fg;
|
|
|
|
struct vc_data *svc = *default_mode;
|
2019-05-28 09:02:39 +00:00
|
|
|
struct fbcon_display *t, *p = &fb_display[vc->vc_num];
|
fbcon: Avoid using FNTCHARCNT() and hard-coded built-in font charcount
For user-provided fonts, the framebuffer layer is using a magic
negative-indexing macro, FNTCHARCNT(), to keep track of their number of
characters:
#define FNTCHARCNT(fd) (((int *)(fd))[-3])
For built-in fonts, it is using hard-coded values (256). This results in
something like the following:
map.length = (ops->p->userfont) ?
FNTCHARCNT(ops->p->fontdata) : 256;
This is unsatisfactory. In fact, there is already a `charcount` field in
our virtual console descriptor (see `struct console_font` inside `struct
vc_data`), let us use it:
map.length = vc->vc_font.charcount;
Recently we added a `charcount` field to `struct font_desc`. Use it to set
`vc->vc_font.charcount` properly. The idea is:
- We only use FNTCHARCNT() on `vc->vc_font.data` and `p->fontdata`.
Assume FNTCHARCNT() is working as intended;
- Whenever `vc->vc_font.data` is set, also set `vc->vc_font.charcount`
properly;
- We can now replace `FNTCHARCNT(vc->vc_font.data)` with
`vc->vc_font.charcount`;
- Since `p->fontdata` always point to the same font data buffer with
`vc->vc_font.data`, we can also replace `FNTCHARCNT(p->fontdata)` with
`vc->vc_font.charcount`.
In conclusion, set `vc->vc_font.charcount` properly in fbcon_startup(),
fbcon_init(), fbcon_set_disp() and fbcon_do_set_font(), then replace
FNTCHARCNT() with `vc->vc_font.charcount`. No more if-else between
negative-indexing macros and hard-coded values.
Do not include <linux/font.h> in fbcon_rotate.c and tileblit.c, since they
no longer need it.
Depends on patch "Fonts: Add charcount field to font_desc".
Suggested-by: Daniel Vetter <daniel@ffwll.ch>
Signed-off-by: Peilin Ye <yepeilin.cs@gmail.com>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/e460a5780e54e3022661d5f09555144583b4cc59.1605169912.git.yepeilin.cs@gmail.com
2020-11-12 12:15:22 +00:00
|
|
|
int logo = 1, new_rows, new_cols, rows, cols;
|
2022-02-07 15:59:31 +00:00
|
|
|
int ret;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
fbcon: Remove fbcon_has_exited
This is unused code since
commit 6104c37094e729f3d4ce65797002112735d49cd1
Author: Daniel Vetter <daniel.vetter@ffwll.ch>
Date: Tue Aug 1 17:32:07 2017 +0200
fbcon: Make fbcon a built-time depency for fbdev
when fbcon was made a compile-time static dependency of fbdev. We
can't exit fbcon anymore without exiting fbdev first, which only works
if all fbdev drivers have unloaded already. Hence this is all dead
code.
v2: I missed that fbcon_exit is also called from con_deinit stuff, and
there fbcon_has_exited prevents double-cleanup. But we can fix that
by properly resetting con2fb_map[] to all -1, which is used everywhere
else to indicate "no fb_info allocate to this console". With that
change the double-cleanup (which resulted in a module refcount underflow,
among other things) is prevented.
Aside: con2fb_map is a signed char, so don't register more than 128 fb_info
or hilarity will ensue.
v3: CI showed me that I still didn't fully understand what's going on
here. The leaked references in con2fb_map have been used upon
rebinding the fb console in fbcon_init. It worked because fbdev
unregistering still cleaned out con2fb_map, and reset it to info_idx.
If the last fbdev driver unregistered, then it also reset info_idx,
and unregistered the fbcon driver.
Imo that's all a bit fragile, so let's keep the con2fb_map reset to
-1, and in fbcon_init pick info_idx if we're starting fresh. That
means unbinding and rebinding will cleanse the mapping, but why are
you doing that if you want to retain the mapping, so should be fine.
Also, I think info_idx == -1 is impossible in fbcon_init - we
unregister the fbcon in that case. So catch&warn about that.
v4: Drop unecessary assignment - I forgot to delete the first
assignment of info in fbcon_init.
Cc: Sam Ravnborg <sam@ravnborg.org>
Reviewed-by: Sam Ravnborg <sam@ravnborg.org>
Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Hans de Goede <hdegoede@redhat.com>
Cc: "Noralf Trønnes" <noralf@tronnes.org>
Cc: Yisheng Xie <ysxie@foxmail.com>
Cc: Konstantin Khorenko <khorenko@virtuozzo.com>
Cc: Prarit Bhargava <prarit@redhat.com>
Cc: Kees Cook <keescook@chromium.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20190528090304.9388-10-daniel.vetter@ffwll.ch
2019-05-28 09:02:40 +00:00
|
|
|
if (WARN_ON(info_idx == -1))
|
2005-04-16 22:20:36 +00:00
|
|
|
return;
|
2005-05-01 15:59:23 +00:00
|
|
|
|
fbcon: Remove fbcon_has_exited
This is unused code since
commit 6104c37094e729f3d4ce65797002112735d49cd1
Author: Daniel Vetter <daniel.vetter@ffwll.ch>
Date: Tue Aug 1 17:32:07 2017 +0200
fbcon: Make fbcon a built-time depency for fbdev
when fbcon was made a compile-time static dependency of fbdev. We
can't exit fbcon anymore without exiting fbdev first, which only works
if all fbdev drivers have unloaded already. Hence this is all dead
code.
v2: I missed that fbcon_exit is also called from con_deinit stuff, and
there fbcon_has_exited prevents double-cleanup. But we can fix that
by properly resetting con2fb_map[] to all -1, which is used everywhere
else to indicate "no fb_info allocate to this console". With that
change the double-cleanup (which resulted in a module refcount underflow,
among other things) is prevented.
Aside: con2fb_map is a signed char, so don't register more than 128 fb_info
or hilarity will ensue.
v3: CI showed me that I still didn't fully understand what's going on
here. The leaked references in con2fb_map have been used upon
rebinding the fb console in fbcon_init. It worked because fbdev
unregistering still cleaned out con2fb_map, and reset it to info_idx.
If the last fbdev driver unregistered, then it also reset info_idx,
and unregistered the fbcon driver.
Imo that's all a bit fragile, so let's keep the con2fb_map reset to
-1, and in fbcon_init pick info_idx if we're starting fresh. That
means unbinding and rebinding will cleanse the mapping, but why are
you doing that if you want to retain the mapping, so should be fine.
Also, I think info_idx == -1 is impossible in fbcon_init - we
unregister the fbcon in that case. So catch&warn about that.
v4: Drop unecessary assignment - I forgot to delete the first
assignment of info in fbcon_init.
Cc: Sam Ravnborg <sam@ravnborg.org>
Reviewed-by: Sam Ravnborg <sam@ravnborg.org>
Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Hans de Goede <hdegoede@redhat.com>
Cc: "Noralf Trønnes" <noralf@tronnes.org>
Cc: Yisheng Xie <ysxie@foxmail.com>
Cc: Konstantin Khorenko <khorenko@virtuozzo.com>
Cc: Prarit Bhargava <prarit@redhat.com>
Cc: Kees Cook <keescook@chromium.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20190528090304.9388-10-daniel.vetter@ffwll.ch
2019-05-28 09:02:40 +00:00
|
|
|
if (con2fb_map[vc->vc_num] == -1)
|
|
|
|
con2fb_map[vc->vc_num] = info_idx;
|
|
|
|
|
2022-04-05 21:03:21 +00:00
|
|
|
info = fbcon_info_from_console(vc->vc_num);
|
2005-05-01 15:59:23 +00:00
|
|
|
|
2019-05-06 13:57:47 +00:00
|
|
|
if (logo_shown < 0 && console_loglevel <= CONSOLE_LOGLEVEL_QUIET)
|
2019-02-08 18:24:49 +00:00
|
|
|
logo_shown = FBCON_LOGO_DONTSHOW;
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
if (vc != svc || logo_shown == FBCON_LOGO_DONTSHOW ||
|
|
|
|
(info->fix.type == FB_TYPE_TEXT))
|
|
|
|
logo = 0;
|
|
|
|
|
|
|
|
if (var_to_display(p, &info->var, info))
|
|
|
|
return;
|
|
|
|
|
2007-07-17 11:05:32 +00:00
|
|
|
if (!info->fbcon_par)
|
2022-04-05 21:03:29 +00:00
|
|
|
con2fb_acquire_newinfo(vc, info, vc->vc_num);
|
2007-07-17 11:05:32 +00:00
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
/* If we are not the first console on this
|
|
|
|
fb, copy the font from that console */
|
2006-06-26 07:27:09 +00:00
|
|
|
t = &fb_display[fg_console];
|
|
|
|
if (!p->fontdata) {
|
|
|
|
if (t->fontdata) {
|
|
|
|
struct vc_data *fvc = vc_cons[fg_console].d;
|
|
|
|
|
|
|
|
vc->vc_font.data = (void *)(p->fontdata =
|
|
|
|
fvc->vc_font.data);
|
|
|
|
vc->vc_font.width = fvc->vc_font.width;
|
|
|
|
vc->vc_font.height = fvc->vc_font.height;
|
fbcon: Avoid using FNTCHARCNT() and hard-coded built-in font charcount
For user-provided fonts, the framebuffer layer is using a magic
negative-indexing macro, FNTCHARCNT(), to keep track of their number of
characters:
#define FNTCHARCNT(fd) (((int *)(fd))[-3])
For built-in fonts, it is using hard-coded values (256). This results in
something like the following:
map.length = (ops->p->userfont) ?
FNTCHARCNT(ops->p->fontdata) : 256;
This is unsatisfactory. In fact, there is already a `charcount` field in
our virtual console descriptor (see `struct console_font` inside `struct
vc_data`), let us use it:
map.length = vc->vc_font.charcount;
Recently we added a `charcount` field to `struct font_desc`. Use it to set
`vc->vc_font.charcount` properly. The idea is:
- We only use FNTCHARCNT() on `vc->vc_font.data` and `p->fontdata`.
Assume FNTCHARCNT() is working as intended;
- Whenever `vc->vc_font.data` is set, also set `vc->vc_font.charcount`
properly;
- We can now replace `FNTCHARCNT(vc->vc_font.data)` with
`vc->vc_font.charcount`;
- Since `p->fontdata` always point to the same font data buffer with
`vc->vc_font.data`, we can also replace `FNTCHARCNT(p->fontdata)` with
`vc->vc_font.charcount`.
In conclusion, set `vc->vc_font.charcount` properly in fbcon_startup(),
fbcon_init(), fbcon_set_disp() and fbcon_do_set_font(), then replace
FNTCHARCNT() with `vc->vc_font.charcount`. No more if-else between
negative-indexing macros and hard-coded values.
Do not include <linux/font.h> in fbcon_rotate.c and tileblit.c, since they
no longer need it.
Depends on patch "Fonts: Add charcount field to font_desc".
Suggested-by: Daniel Vetter <daniel@ffwll.ch>
Signed-off-by: Peilin Ye <yepeilin.cs@gmail.com>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/e460a5780e54e3022661d5f09555144583b4cc59.1605169912.git.yepeilin.cs@gmail.com
2020-11-12 12:15:22 +00:00
|
|
|
vc->vc_font.charcount = fvc->vc_font.charcount;
|
2006-06-26 07:27:09 +00:00
|
|
|
p->userfont = t->userfont;
|
|
|
|
|
|
|
|
if (p->userfont)
|
|
|
|
REFCOUNT(p->fontdata)++;
|
|
|
|
} else {
|
|
|
|
const struct font_desc *font = NULL;
|
|
|
|
|
|
|
|
if (!fontname[0] || !(font = find_font(fontname)))
|
|
|
|
font = get_default_font(info->var.xres,
|
2007-05-08 07:39:11 +00:00
|
|
|
info->var.yres,
|
|
|
|
info->pixmap.blit_x,
|
|
|
|
info->pixmap.blit_y);
|
2006-06-26 07:27:09 +00:00
|
|
|
vc->vc_font.width = font->width;
|
|
|
|
vc->vc_font.height = font->height;
|
|
|
|
vc->vc_font.data = (void *)(p->fontdata = font->data);
|
fbcon: Avoid using FNTCHARCNT() and hard-coded built-in font charcount
For user-provided fonts, the framebuffer layer is using a magic
negative-indexing macro, FNTCHARCNT(), to keep track of their number of
characters:
#define FNTCHARCNT(fd) (((int *)(fd))[-3])
For built-in fonts, it is using hard-coded values (256). This results in
something like the following:
map.length = (ops->p->userfont) ?
FNTCHARCNT(ops->p->fontdata) : 256;
This is unsatisfactory. In fact, there is already a `charcount` field in
our virtual console descriptor (see `struct console_font` inside `struct
vc_data`), let us use it:
map.length = vc->vc_font.charcount;
Recently we added a `charcount` field to `struct font_desc`. Use it to set
`vc->vc_font.charcount` properly. The idea is:
- We only use FNTCHARCNT() on `vc->vc_font.data` and `p->fontdata`.
Assume FNTCHARCNT() is working as intended;
- Whenever `vc->vc_font.data` is set, also set `vc->vc_font.charcount`
properly;
- We can now replace `FNTCHARCNT(vc->vc_font.data)` with
`vc->vc_font.charcount`;
- Since `p->fontdata` always point to the same font data buffer with
`vc->vc_font.data`, we can also replace `FNTCHARCNT(p->fontdata)` with
`vc->vc_font.charcount`.
In conclusion, set `vc->vc_font.charcount` properly in fbcon_startup(),
fbcon_init(), fbcon_set_disp() and fbcon_do_set_font(), then replace
FNTCHARCNT() with `vc->vc_font.charcount`. No more if-else between
negative-indexing macros and hard-coded values.
Do not include <linux/font.h> in fbcon_rotate.c and tileblit.c, since they
no longer need it.
Depends on patch "Fonts: Add charcount field to font_desc".
Suggested-by: Daniel Vetter <daniel@ffwll.ch>
Signed-off-by: Peilin Ye <yepeilin.cs@gmail.com>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/e460a5780e54e3022661d5f09555144583b4cc59.1605169912.git.yepeilin.cs@gmail.com
2020-11-12 12:15:22 +00:00
|
|
|
vc->vc_font.charcount = font->charcount;
|
2006-06-26 07:27:09 +00:00
|
|
|
}
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
2006-06-26 07:27:09 +00:00
|
|
|
|
2005-09-09 20:04:37 +00:00
|
|
|
vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1);
|
2005-04-16 22:20:36 +00:00
|
|
|
vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800;
|
fbcon: Avoid using FNTCHARCNT() and hard-coded built-in font charcount
For user-provided fonts, the framebuffer layer is using a magic
negative-indexing macro, FNTCHARCNT(), to keep track of their number of
characters:
#define FNTCHARCNT(fd) (((int *)(fd))[-3])
For built-in fonts, it is using hard-coded values (256). This results in
something like the following:
map.length = (ops->p->userfont) ?
FNTCHARCNT(ops->p->fontdata) : 256;
This is unsatisfactory. In fact, there is already a `charcount` field in
our virtual console descriptor (see `struct console_font` inside `struct
vc_data`), let us use it:
map.length = vc->vc_font.charcount;
Recently we added a `charcount` field to `struct font_desc`. Use it to set
`vc->vc_font.charcount` properly. The idea is:
- We only use FNTCHARCNT() on `vc->vc_font.data` and `p->fontdata`.
Assume FNTCHARCNT() is working as intended;
- Whenever `vc->vc_font.data` is set, also set `vc->vc_font.charcount`
properly;
- We can now replace `FNTCHARCNT(vc->vc_font.data)` with
`vc->vc_font.charcount`;
- Since `p->fontdata` always point to the same font data buffer with
`vc->vc_font.data`, we can also replace `FNTCHARCNT(p->fontdata)` with
`vc->vc_font.charcount`.
In conclusion, set `vc->vc_font.charcount` properly in fbcon_startup(),
fbcon_init(), fbcon_set_disp() and fbcon_do_set_font(), then replace
FNTCHARCNT() with `vc->vc_font.charcount`. No more if-else between
negative-indexing macros and hard-coded values.
Do not include <linux/font.h> in fbcon_rotate.c and tileblit.c, since they
no longer need it.
Depends on patch "Fonts: Add charcount field to font_desc".
Suggested-by: Daniel Vetter <daniel@ffwll.ch>
Signed-off-by: Peilin Ye <yepeilin.cs@gmail.com>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/e460a5780e54e3022661d5f09555144583b4cc59.1605169912.git.yepeilin.cs@gmail.com
2020-11-12 12:15:22 +00:00
|
|
|
if (vc->vc_font.charcount == 256) {
|
2005-04-16 22:20:36 +00:00
|
|
|
vc->vc_hi_font_mask = 0;
|
|
|
|
} else {
|
|
|
|
vc->vc_hi_font_mask = 0x100;
|
|
|
|
if (vc->vc_can_do_color)
|
|
|
|
vc->vc_complement_mask <<= 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!*svc->vc_uni_pagedir_loc)
|
|
|
|
con_set_default_unimap(svc);
|
|
|
|
if (!*vc->vc_uni_pagedir_loc)
|
|
|
|
con_copy_unimap(vc, svc);
|
|
|
|
|
[PATCH] fbcon: Console Rotation - Prepare fbcon for console rotation
This patch series implements generic code to rotate the console at 90, 180,
and 270 degrees. The implementation is completely done in the framebuffer
console level, thus no changes to the framebuffer layer or to the drivers
are needed.
Console rotation is required by some Sharp-based devices where the natural
orientation of the display is not at 0 degrees. Also, users that have
displays that can pivot will benefit by having a console in portrait mode
if they so desire.
The choice to implement the code in the console layer rather than in the
framebuffer layer is due to the following reasons:
- it's fast
- it does not require driver changes
- it can coexist with devices that can rotate the display at the hardware level
- it complements graphics applications that can do display rotation
The changes to core fbcon are minimal-- recognition of the console
rotation angle so it can swap directions, origins and axes (xres vs yres,
xpanstep vs ypanstep, xoffset vs yoffset, etc) and storage of the rotation
angle per display. The bulk of the code that does the actual drawing to the
screen are placed in separate files. Each angle of rotation has separate
methods (bmove, clear, putcs, cursor, update_start which is derived from
update_var, and clear_margins). To mimimize processing time, the fontdata
are pre-rotated at each console switch (only if the font or the angle has
changed).
The option can be compiled out (CONFIG_FRAMEBUFFER_CONSOLE_ROTATION = n) if
rotation is not needed.
Choosing the rotation angle can be done in several ways:
1. boot option fbcon=rotate:n, where
n = 0 - normal
n = 1 - 90 degrees (clockwise)
n = 2 - 180 degrees (upside down)
n = 3 - 270 degrees (counterclockwise)
2. echo n > /sys/class/graphics/fb[num]/con_rotate
where n is the same as described above. It sets the angle of rotation
of the current console
3 echo n > /sys/class/graphics/fb[num]/con_rotate_all
where n is the same as described above. Globally sets the angle of
rotation.
GOTCHAS:
The option, especially at angles of 90 and 270 degrees, will exercise
the least used code of drivers. Namely, at these angles, panning is done
in the x-axis, so it can reveal bugs in the driver if xpanstep is set
incorrectly. A workaround is to set xpanstep = 0.
Secondly, at these angles, the framebuffer memory access can be
unaligned if (fontheight * bpp) % 32 ~= 0 which can reveal bugs in the drivers
imageblit, fillrect and copyarea functions. (I think cfbfillrect may have
this buglet). A workaround is to use a standard 8x16 font.
Speed:
The scrolling speed difference between 0 and 180 degrees is minimal,
somewhere areound 1-2%. At 90 or 270 degress, speed drops down to a vicinity
of 30-40%. This is understandable because the blit direction is across the
framebuffer "direction." Scrolling will be helped at these angles if xpanstep
is not equal to zero, use of 8x16 fonts, and setting xres_virtual >= xres * 2.
Note: The code is tested on little-endian only, so I don't know if it will
work in big-endian. Please let me know, it will take only less than a minute
of your time.
This patch prepares fbcon for console rotation and contains the following
changes:
- add rotate field in struct fbcon_ops to keep fbcon's current rotation
angle
- add con_rotate field in struct display to store per-display rotation angle
- create a private copy of the current var to fbcon. This will prevent
fbcon from directly manipulating info->var, especially the fields xoffset,
yoffset and vmode.
- add ability to swap pertinent axes (xres, yres; xpanstep, ypanstep; etc)
depending on the rotation angle
- change global update_var() (function that sets the screen start address)
as an fbcon method update_start. This is required because the axes, start
offset, and/or direction can be reversed depending on the rotation angle.
- add fbcon method rotate_font() which will rotate each character bitmap to
the correct angle of rotation.
- add fbcon boot option 'rotate' to select the angle of rotation at bootime.
Currently does nothing until all patches are applied.
Signed-off-by: Antonino Daplas <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-11-09 05:39:09 +00:00
|
|
|
ops = info->fbcon_par;
|
2015-10-09 15:08:10 +00:00
|
|
|
ops->cur_blink_jiffies = msecs_to_jiffies(vc->vc_cur_blink_ms);
|
2017-11-25 19:35:47 +00:00
|
|
|
|
|
|
|
p->con_rotate = initial_rotation;
|
|
|
|
if (p->con_rotate == -1)
|
|
|
|
p->con_rotate = info->fbcon_rotate_hint;
|
|
|
|
if (p->con_rotate == -1)
|
2017-11-25 19:35:53 +00:00
|
|
|
p->con_rotate = FB_ROTATE_UR;
|
2017-11-25 19:35:47 +00:00
|
|
|
|
2006-01-10 04:52:56 +00:00
|
|
|
set_blitting_type(vc, info);
|
[PATCH] fbcon: Console Rotation - Prepare fbcon for console rotation
This patch series implements generic code to rotate the console at 90, 180,
and 270 degrees. The implementation is completely done in the framebuffer
console level, thus no changes to the framebuffer layer or to the drivers
are needed.
Console rotation is required by some Sharp-based devices where the natural
orientation of the display is not at 0 degrees. Also, users that have
displays that can pivot will benefit by having a console in portrait mode
if they so desire.
The choice to implement the code in the console layer rather than in the
framebuffer layer is due to the following reasons:
- it's fast
- it does not require driver changes
- it can coexist with devices that can rotate the display at the hardware level
- it complements graphics applications that can do display rotation
The changes to core fbcon are minimal-- recognition of the console
rotation angle so it can swap directions, origins and axes (xres vs yres,
xpanstep vs ypanstep, xoffset vs yoffset, etc) and storage of the rotation
angle per display. The bulk of the code that does the actual drawing to the
screen are placed in separate files. Each angle of rotation has separate
methods (bmove, clear, putcs, cursor, update_start which is derived from
update_var, and clear_margins). To mimimize processing time, the fontdata
are pre-rotated at each console switch (only if the font or the angle has
changed).
The option can be compiled out (CONFIG_FRAMEBUFFER_CONSOLE_ROTATION = n) if
rotation is not needed.
Choosing the rotation angle can be done in several ways:
1. boot option fbcon=rotate:n, where
n = 0 - normal
n = 1 - 90 degrees (clockwise)
n = 2 - 180 degrees (upside down)
n = 3 - 270 degrees (counterclockwise)
2. echo n > /sys/class/graphics/fb[num]/con_rotate
where n is the same as described above. It sets the angle of rotation
of the current console
3 echo n > /sys/class/graphics/fb[num]/con_rotate_all
where n is the same as described above. Globally sets the angle of
rotation.
GOTCHAS:
The option, especially at angles of 90 and 270 degrees, will exercise
the least used code of drivers. Namely, at these angles, panning is done
in the x-axis, so it can reveal bugs in the driver if xpanstep is set
incorrectly. A workaround is to set xpanstep = 0.
Secondly, at these angles, the framebuffer memory access can be
unaligned if (fontheight * bpp) % 32 ~= 0 which can reveal bugs in the drivers
imageblit, fillrect and copyarea functions. (I think cfbfillrect may have
this buglet). A workaround is to use a standard 8x16 font.
Speed:
The scrolling speed difference between 0 and 180 degrees is minimal,
somewhere areound 1-2%. At 90 or 270 degress, speed drops down to a vicinity
of 30-40%. This is understandable because the blit direction is across the
framebuffer "direction." Scrolling will be helped at these angles if xpanstep
is not equal to zero, use of 8x16 fonts, and setting xres_virtual >= xres * 2.
Note: The code is tested on little-endian only, so I don't know if it will
work in big-endian. Please let me know, it will take only less than a minute
of your time.
This patch prepares fbcon for console rotation and contains the following
changes:
- add rotate field in struct fbcon_ops to keep fbcon's current rotation
angle
- add con_rotate field in struct display to store per-display rotation angle
- create a private copy of the current var to fbcon. This will prevent
fbcon from directly manipulating info->var, especially the fields xoffset,
yoffset and vmode.
- add ability to swap pertinent axes (xres, yres; xpanstep, ypanstep; etc)
depending on the rotation angle
- change global update_var() (function that sets the screen start address)
as an fbcon method update_start. This is required because the axes, start
offset, and/or direction can be reversed depending on the rotation angle.
- add fbcon method rotate_font() which will rotate each character bitmap to
the correct angle of rotation.
- add fbcon boot option 'rotate' to select the angle of rotation at bootime.
Currently does nothing until all patches are applied.
Signed-off-by: Antonino Daplas <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-11-09 05:39:09 +00:00
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
cols = vc->vc_cols;
|
|
|
|
rows = vc->vc_rows;
|
[PATCH] fbcon: Console Rotation - Prepare fbcon for console rotation
This patch series implements generic code to rotate the console at 90, 180,
and 270 degrees. The implementation is completely done in the framebuffer
console level, thus no changes to the framebuffer layer or to the drivers
are needed.
Console rotation is required by some Sharp-based devices where the natural
orientation of the display is not at 0 degrees. Also, users that have
displays that can pivot will benefit by having a console in portrait mode
if they so desire.
The choice to implement the code in the console layer rather than in the
framebuffer layer is due to the following reasons:
- it's fast
- it does not require driver changes
- it can coexist with devices that can rotate the display at the hardware level
- it complements graphics applications that can do display rotation
The changes to core fbcon are minimal-- recognition of the console
rotation angle so it can swap directions, origins and axes (xres vs yres,
xpanstep vs ypanstep, xoffset vs yoffset, etc) and storage of the rotation
angle per display. The bulk of the code that does the actual drawing to the
screen are placed in separate files. Each angle of rotation has separate
methods (bmove, clear, putcs, cursor, update_start which is derived from
update_var, and clear_margins). To mimimize processing time, the fontdata
are pre-rotated at each console switch (only if the font or the angle has
changed).
The option can be compiled out (CONFIG_FRAMEBUFFER_CONSOLE_ROTATION = n) if
rotation is not needed.
Choosing the rotation angle can be done in several ways:
1. boot option fbcon=rotate:n, where
n = 0 - normal
n = 1 - 90 degrees (clockwise)
n = 2 - 180 degrees (upside down)
n = 3 - 270 degrees (counterclockwise)
2. echo n > /sys/class/graphics/fb[num]/con_rotate
where n is the same as described above. It sets the angle of rotation
of the current console
3 echo n > /sys/class/graphics/fb[num]/con_rotate_all
where n is the same as described above. Globally sets the angle of
rotation.
GOTCHAS:
The option, especially at angles of 90 and 270 degrees, will exercise
the least used code of drivers. Namely, at these angles, panning is done
in the x-axis, so it can reveal bugs in the driver if xpanstep is set
incorrectly. A workaround is to set xpanstep = 0.
Secondly, at these angles, the framebuffer memory access can be
unaligned if (fontheight * bpp) % 32 ~= 0 which can reveal bugs in the drivers
imageblit, fillrect and copyarea functions. (I think cfbfillrect may have
this buglet). A workaround is to use a standard 8x16 font.
Speed:
The scrolling speed difference between 0 and 180 degrees is minimal,
somewhere areound 1-2%. At 90 or 270 degress, speed drops down to a vicinity
of 30-40%. This is understandable because the blit direction is across the
framebuffer "direction." Scrolling will be helped at these angles if xpanstep
is not equal to zero, use of 8x16 fonts, and setting xres_virtual >= xres * 2.
Note: The code is tested on little-endian only, so I don't know if it will
work in big-endian. Please let me know, it will take only less than a minute
of your time.
This patch prepares fbcon for console rotation and contains the following
changes:
- add rotate field in struct fbcon_ops to keep fbcon's current rotation
angle
- add con_rotate field in struct display to store per-display rotation angle
- create a private copy of the current var to fbcon. This will prevent
fbcon from directly manipulating info->var, especially the fields xoffset,
yoffset and vmode.
- add ability to swap pertinent axes (xres, yres; xpanstep, ypanstep; etc)
depending on the rotation angle
- change global update_var() (function that sets the screen start address)
as an fbcon method update_start. This is required because the axes, start
offset, and/or direction can be reversed depending on the rotation angle.
- add fbcon method rotate_font() which will rotate each character bitmap to
the correct angle of rotation.
- add fbcon boot option 'rotate' to select the angle of rotation at bootime.
Currently does nothing until all patches are applied.
Signed-off-by: Antonino Daplas <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-11-09 05:39:09 +00:00
|
|
|
new_cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
|
|
|
|
new_rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
|
|
|
|
new_cols /= vc->vc_font.width;
|
|
|
|
new_rows /= vc->vc_font.height;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* We must always set the mode. The mode of the previous console
|
|
|
|
* driver could be in the same resolution but we are using different
|
|
|
|
* hardware so we have to initialize the hardware.
|
|
|
|
*
|
|
|
|
* We need to do it in fbcon_init() to prevent screen corruption.
|
|
|
|
*/
|
2016-06-23 11:34:35 +00:00
|
|
|
if (con_is_visible(vc) && vc->vc_mode == KD_TEXT) {
|
2022-04-05 21:03:25 +00:00
|
|
|
if (info->fbops->fb_set_par && !ops->initialized) {
|
2009-09-22 23:47:44 +00:00
|
|
|
ret = info->fbops->fb_set_par(info);
|
|
|
|
|
|
|
|
if (ret)
|
|
|
|
printk(KERN_ERR "fbcon_init: detected "
|
|
|
|
"unhandled fb_set_par error, "
|
|
|
|
"error code %d\n", ret);
|
|
|
|
}
|
|
|
|
|
2022-04-05 21:03:25 +00:00
|
|
|
ops->initialized = true;
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ops->graphics = 0;
|
|
|
|
|
2022-02-02 13:55:31 +00:00
|
|
|
#ifdef CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION
|
2022-02-07 15:59:31 +00:00
|
|
|
if ((info->flags & FBINFO_HWACCEL_COPYAREA) &&
|
|
|
|
!(info->flags & FBINFO_HWACCEL_DISABLED))
|
Revert "fbcon: Disable accelerated scrolling"
This reverts commit 39aead8373b3c20bb5965c024dfb51a94e526151.
Revert the first (of 2) commits which disabled scrolling acceleration in
fbcon/fbdev. It introduced a regression for fbdev-supported graphic cards
because of the performance penalty by doing screen scrolling by software
instead of using the existing graphic card 2D hardware acceleration.
Console scrolling acceleration was disabled by dropping code which
checked at runtime the driver hardware capabilities for the
BINFO_HWACCEL_COPYAREA or FBINFO_HWACCEL_FILLRECT flags and if set, it
enabled scrollmode SCROLL_MOVE which uses hardware acceleration to move
screen contents. After dropping those checks scrollmode was hard-wired
to SCROLL_REDRAW instead, which forces all graphic cards to redraw every
character at the new screen position when scrolling.
This change effectively disabled all hardware-based scrolling acceleration for
ALL drivers, because now all kind of 2D hardware acceleration (bitblt,
fillrect) in the drivers isn't used any longer.
The original commit message mentions that only 3 DRM drivers (nouveau, omapdrm
and gma500) used hardware acceleration in the past and thus code for checking
and using scrolling acceleration is obsolete.
This statement is NOT TRUE, because beside the DRM drivers there are around 35
other fbdev drivers which depend on fbdev/fbcon and still provide hardware
acceleration for fbdev/fbcon.
The original commit message also states that syzbot found lots of bugs in fbcon
and thus it's "often the solution to just delete code and remove features".
This is true, and the bugs - which actually affected all users of fbcon,
including DRM - were fixed, or code was dropped like e.g. the support for
software scrollback in vgacon (commit 973c096f6a85).
So to further analyze which bugs were found by syzbot, I've looked through all
patches in drivers/video which were tagged with syzbot or syzkaller back to
year 2005. The vast majority fixed the reported issues on a higher level, e.g.
when screen is to be resized, or when font size is to be changed. The few ones
which touched driver code fixed a real driver bug, e.g. by adding a check.
But NONE of those patches touched code of either the SCROLL_MOVE or the
SCROLL_REDRAW case.
That means, there was no real reason why SCROLL_MOVE had to be ripped-out and
just SCROLL_REDRAW had to be used instead. The only reason I can imagine so far
was that SCROLL_MOVE wasn't used by DRM and as such it was assumed that it
could go away. That argument completely missed the fact that SCROLL_MOVE is
still heavily used by fbdev (non-DRM) drivers.
Some people mention that using memcpy() instead of the hardware acceleration is
pretty much the same speed. But that's not true, at least not for older graphic
cards and machines where we see speed decreases by factor 10 and more and thus
this change leads to console responsiveness way worse than before.
That's why the original commit is to be reverted. By reverting we
reintroduce hardware-based scrolling acceleration and fix the
performance regression for fbdev drivers.
There isn't any impact on DRM when reverting those patches.
Signed-off-by: Helge Deller <deller@gmx.de>
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
Acked-by: Sven Schnelle <svens@stackframe.org>
Cc: stable@vger.kernel.org # v5.10+
Signed-off-by: Helge Deller <deller@gmx.de>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/20220202135531.92183-3-deller@gmx.de
2022-02-02 13:55:30 +00:00
|
|
|
p->scrollmode = SCROLL_MOVE;
|
|
|
|
else /* default to something safe */
|
|
|
|
p->scrollmode = SCROLL_REDRAW;
|
2022-02-02 13:55:31 +00:00
|
|
|
#endif
|
Revert "fbdev: Garbage collect fbdev scrolling acceleration, part 1 (from TODO list)"
This reverts commit b3ec8cdf457e5e63d396fe1346cc788cf7c1b578.
Revert the second (of 2) commits which disabled scrolling acceleration
in fbcon/fbdev. It introduced a regression for fbdev-supported graphic
cards because of the performance penalty by doing screen scrolling by
software instead of using the existing graphic card 2D hardware
acceleration.
Console scrolling acceleration was disabled by dropping code which
checked at runtime the driver hardware capabilities for the
BINFO_HWACCEL_COPYAREA or FBINFO_HWACCEL_FILLRECT flags and if set, it
enabled scrollmode SCROLL_MOVE which uses hardware acceleration to move
screen contents. After dropping those checks scrollmode was hard-wired
to SCROLL_REDRAW instead, which forces all graphic cards to redraw every
character at the new screen position when scrolling.
This change effectively disabled all hardware-based scrolling acceleration for
ALL drivers, because now all kind of 2D hardware acceleration (bitblt,
fillrect) in the drivers isn't used any longer.
The original commit message mentions that only 3 DRM drivers (nouveau, omapdrm
and gma500) used hardware acceleration in the past and thus code for checking
and using scrolling acceleration is obsolete.
This statement is NOT TRUE, because beside the DRM drivers there are around 35
other fbdev drivers which depend on fbdev/fbcon and still provide hardware
acceleration for fbdev/fbcon.
The original commit message also states that syzbot found lots of bugs in fbcon
and thus it's "often the solution to just delete code and remove features".
This is true, and the bugs - which actually affected all users of fbcon,
including DRM - were fixed, or code was dropped like e.g. the support for
software scrollback in vgacon (commit 973c096f6a85).
So to further analyze which bugs were found by syzbot, I've looked through all
patches in drivers/video which were tagged with syzbot or syzkaller back to
year 2005. The vast majority fixed the reported issues on a higher level, e.g.
when screen is to be resized, or when font size is to be changed. The few ones
which touched driver code fixed a real driver bug, e.g. by adding a check.
But NONE of those patches touched code of either the SCROLL_MOVE or the
SCROLL_REDRAW case.
That means, there was no real reason why SCROLL_MOVE had to be ripped-out and
just SCROLL_REDRAW had to be used instead. The only reason I can imagine so far
was that SCROLL_MOVE wasn't used by DRM and as such it was assumed that it
could go away. That argument completely missed the fact that SCROLL_MOVE is
still heavily used by fbdev (non-DRM) drivers.
Some people mention that using memcpy() instead of the hardware acceleration is
pretty much the same speed. But that's not true, at least not for older graphic
cards and machines where we see speed decreases by factor 10 and more and thus
this change leads to console responsiveness way worse than before.
That's why the original commit is to be reverted. By reverting we
reintroduce hardware-based scrolling acceleration and fix the
performance regression for fbdev drivers.
There isn't any impact on DRM when reverting those patches.
Signed-off-by: Helge Deller <deller@gmx.de>
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
Acked-by: Sven Schnelle <svens@stackframe.org>
Cc: stable@vger.kernel.org # v5.16+
Signed-off-by: Helge Deller <deller@gmx.de>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/20220202135531.92183-2-deller@gmx.de
2022-02-02 13:55:29 +00:00
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
/*
|
|
|
|
* ++guenther: console.c:vc_allocate() relies on initializing
|
|
|
|
* vc_{cols,rows}, but we must not set those if we are only
|
|
|
|
* resizing the console.
|
|
|
|
*/
|
2009-08-06 22:07:36 +00:00
|
|
|
if (init) {
|
2005-04-16 22:20:36 +00:00
|
|
|
vc->vc_cols = new_cols;
|
|
|
|
vc->vc_rows = new_rows;
|
2009-08-06 22:07:36 +00:00
|
|
|
} else
|
|
|
|
vc_resize(vc, new_cols, new_rows);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
if (logo)
|
|
|
|
fbcon_prepare_logo(vc, info, cols, rows, new_cols, new_rows);
|
|
|
|
|
2006-01-10 04:52:56 +00:00
|
|
|
if (ops->rotate_font && ops->rotate_font(info, vc)) {
|
[PATCH] fbcon: Console Rotation - Prepare fbcon for console rotation
This patch series implements generic code to rotate the console at 90, 180,
and 270 degrees. The implementation is completely done in the framebuffer
console level, thus no changes to the framebuffer layer or to the drivers
are needed.
Console rotation is required by some Sharp-based devices where the natural
orientation of the display is not at 0 degrees. Also, users that have
displays that can pivot will benefit by having a console in portrait mode
if they so desire.
The choice to implement the code in the console layer rather than in the
framebuffer layer is due to the following reasons:
- it's fast
- it does not require driver changes
- it can coexist with devices that can rotate the display at the hardware level
- it complements graphics applications that can do display rotation
The changes to core fbcon are minimal-- recognition of the console
rotation angle so it can swap directions, origins and axes (xres vs yres,
xpanstep vs ypanstep, xoffset vs yoffset, etc) and storage of the rotation
angle per display. The bulk of the code that does the actual drawing to the
screen are placed in separate files. Each angle of rotation has separate
methods (bmove, clear, putcs, cursor, update_start which is derived from
update_var, and clear_margins). To mimimize processing time, the fontdata
are pre-rotated at each console switch (only if the font or the angle has
changed).
The option can be compiled out (CONFIG_FRAMEBUFFER_CONSOLE_ROTATION = n) if
rotation is not needed.
Choosing the rotation angle can be done in several ways:
1. boot option fbcon=rotate:n, where
n = 0 - normal
n = 1 - 90 degrees (clockwise)
n = 2 - 180 degrees (upside down)
n = 3 - 270 degrees (counterclockwise)
2. echo n > /sys/class/graphics/fb[num]/con_rotate
where n is the same as described above. It sets the angle of rotation
of the current console
3 echo n > /sys/class/graphics/fb[num]/con_rotate_all
where n is the same as described above. Globally sets the angle of
rotation.
GOTCHAS:
The option, especially at angles of 90 and 270 degrees, will exercise
the least used code of drivers. Namely, at these angles, panning is done
in the x-axis, so it can reveal bugs in the driver if xpanstep is set
incorrectly. A workaround is to set xpanstep = 0.
Secondly, at these angles, the framebuffer memory access can be
unaligned if (fontheight * bpp) % 32 ~= 0 which can reveal bugs in the drivers
imageblit, fillrect and copyarea functions. (I think cfbfillrect may have
this buglet). A workaround is to use a standard 8x16 font.
Speed:
The scrolling speed difference between 0 and 180 degrees is minimal,
somewhere areound 1-2%. At 90 or 270 degress, speed drops down to a vicinity
of 30-40%. This is understandable because the blit direction is across the
framebuffer "direction." Scrolling will be helped at these angles if xpanstep
is not equal to zero, use of 8x16 fonts, and setting xres_virtual >= xres * 2.
Note: The code is tested on little-endian only, so I don't know if it will
work in big-endian. Please let me know, it will take only less than a minute
of your time.
This patch prepares fbcon for console rotation and contains the following
changes:
- add rotate field in struct fbcon_ops to keep fbcon's current rotation
angle
- add con_rotate field in struct display to store per-display rotation angle
- create a private copy of the current var to fbcon. This will prevent
fbcon from directly manipulating info->var, especially the fields xoffset,
yoffset and vmode.
- add ability to swap pertinent axes (xres, yres; xpanstep, ypanstep; etc)
depending on the rotation angle
- change global update_var() (function that sets the screen start address)
as an fbcon method update_start. This is required because the axes, start
offset, and/or direction can be reversed depending on the rotation angle.
- add fbcon method rotate_font() which will rotate each character bitmap to
the correct angle of rotation.
- add fbcon boot option 'rotate' to select the angle of rotation at bootime.
Currently does nothing until all patches are applied.
Signed-off-by: Antonino Daplas <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-11-09 05:39:09 +00:00
|
|
|
ops->rotate = FB_ROTATE_UR;
|
2006-01-10 04:52:56 +00:00
|
|
|
set_blitting_type(vc, info);
|
[PATCH] fbcon: Console Rotation - Prepare fbcon for console rotation
This patch series implements generic code to rotate the console at 90, 180,
and 270 degrees. The implementation is completely done in the framebuffer
console level, thus no changes to the framebuffer layer or to the drivers
are needed.
Console rotation is required by some Sharp-based devices where the natural
orientation of the display is not at 0 degrees. Also, users that have
displays that can pivot will benefit by having a console in portrait mode
if they so desire.
The choice to implement the code in the console layer rather than in the
framebuffer layer is due to the following reasons:
- it's fast
- it does not require driver changes
- it can coexist with devices that can rotate the display at the hardware level
- it complements graphics applications that can do display rotation
The changes to core fbcon are minimal-- recognition of the console
rotation angle so it can swap directions, origins and axes (xres vs yres,
xpanstep vs ypanstep, xoffset vs yoffset, etc) and storage of the rotation
angle per display. The bulk of the code that does the actual drawing to the
screen are placed in separate files. Each angle of rotation has separate
methods (bmove, clear, putcs, cursor, update_start which is derived from
update_var, and clear_margins). To mimimize processing time, the fontdata
are pre-rotated at each console switch (only if the font or the angle has
changed).
The option can be compiled out (CONFIG_FRAMEBUFFER_CONSOLE_ROTATION = n) if
rotation is not needed.
Choosing the rotation angle can be done in several ways:
1. boot option fbcon=rotate:n, where
n = 0 - normal
n = 1 - 90 degrees (clockwise)
n = 2 - 180 degrees (upside down)
n = 3 - 270 degrees (counterclockwise)
2. echo n > /sys/class/graphics/fb[num]/con_rotate
where n is the same as described above. It sets the angle of rotation
of the current console
3 echo n > /sys/class/graphics/fb[num]/con_rotate_all
where n is the same as described above. Globally sets the angle of
rotation.
GOTCHAS:
The option, especially at angles of 90 and 270 degrees, will exercise
the least used code of drivers. Namely, at these angles, panning is done
in the x-axis, so it can reveal bugs in the driver if xpanstep is set
incorrectly. A workaround is to set xpanstep = 0.
Secondly, at these angles, the framebuffer memory access can be
unaligned if (fontheight * bpp) % 32 ~= 0 which can reveal bugs in the drivers
imageblit, fillrect and copyarea functions. (I think cfbfillrect may have
this buglet). A workaround is to use a standard 8x16 font.
Speed:
The scrolling speed difference between 0 and 180 degrees is minimal,
somewhere areound 1-2%. At 90 or 270 degress, speed drops down to a vicinity
of 30-40%. This is understandable because the blit direction is across the
framebuffer "direction." Scrolling will be helped at these angles if xpanstep
is not equal to zero, use of 8x16 fonts, and setting xres_virtual >= xres * 2.
Note: The code is tested on little-endian only, so I don't know if it will
work in big-endian. Please let me know, it will take only less than a minute
of your time.
This patch prepares fbcon for console rotation and contains the following
changes:
- add rotate field in struct fbcon_ops to keep fbcon's current rotation
angle
- add con_rotate field in struct display to store per-display rotation angle
- create a private copy of the current var to fbcon. This will prevent
fbcon from directly manipulating info->var, especially the fields xoffset,
yoffset and vmode.
- add ability to swap pertinent axes (xres, yres; xpanstep, ypanstep; etc)
depending on the rotation angle
- change global update_var() (function that sets the screen start address)
as an fbcon method update_start. This is required because the axes, start
offset, and/or direction can be reversed depending on the rotation angle.
- add fbcon method rotate_font() which will rotate each character bitmap to
the correct angle of rotation.
- add fbcon boot option 'rotate' to select the angle of rotation at bootime.
Currently does nothing until all patches are applied.
Signed-off-by: Antonino Daplas <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-11-09 05:39:09 +00:00
|
|
|
}
|
|
|
|
|
2006-03-31 10:31:45 +00:00
|
|
|
ops->p = &fb_display[fg_console];
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
|
2019-05-28 09:02:39 +00:00
|
|
|
static void fbcon_free_font(struct fbcon_display *p, bool freefont)
|
2006-06-26 07:27:09 +00:00
|
|
|
{
|
2013-01-24 06:12:41 +00:00
|
|
|
if (freefont && p->userfont && p->fontdata && (--REFCOUNT(p->fontdata) == 0))
|
2006-06-26 07:27:09 +00:00
|
|
|
kfree(p->fontdata - FONT_EXTRA_WORDS * sizeof(int));
|
|
|
|
p->fontdata = NULL;
|
|
|
|
p->userfont = 0;
|
|
|
|
}
|
|
|
|
|
fbcon: Fix vc attr at deinit
fbcon can deal with vc_hi_font_mask (the upper 256 chars) and adjust
the vc attrs dynamically when vc_hi_font_mask is changed at
fbcon_init(). When the vc_hi_font_mask is set, it remaps the attrs in
the existing console buffer with one bit shift up (for 9 bits), while
it remaps with one bit shift down (for 8 bits) when the value is
cleared. It works fine as long as the font gets updated after fbcon
was initialized.
However, we hit a bizarre problem when the console is switched to
another fb driver (typically from vesafb or efifb to drmfb). At
switching to the new fb driver, we temporarily rebind the console to
the dummy console, then rebind to the new driver. During the
switching, we leave the modified attrs as is. Thus, the new fbcon
takes over the old buffer as if it were to contain 8 bits chars
(although the attrs are still shifted for 9 bits), and effectively
this results in the yellow color texts instead of the original white
color, as found in the bugzilla entry below.
An easy fix for this is to re-adjust the attrs before leaving the
fbcon at con_deinit callback. Since the code to adjust the attrs is
already present in the current fbcon code, in this patch, we simply
factor out the relevant code, and call it from fbcon_deinit().
Bugzilla: https://bugzilla.suse.com/show_bug.cgi?id=1000619
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
2017-01-11 16:09:50 +00:00
|
|
|
static void set_vc_hi_font(struct vc_data *vc, bool set);
|
|
|
|
|
2022-04-05 21:03:34 +00:00
|
|
|
static void fbcon_release_all(void)
|
|
|
|
{
|
|
|
|
struct fb_info *info;
|
|
|
|
int i, j, mapped;
|
|
|
|
|
2022-04-05 21:03:35 +00:00
|
|
|
fbcon_for_each_registered_fb(i) {
|
2022-04-05 21:03:34 +00:00
|
|
|
mapped = 0;
|
2022-04-05 21:03:35 +00:00
|
|
|
info = fbcon_registered_fb[i];
|
2022-04-05 21:03:34 +00:00
|
|
|
|
|
|
|
for (j = first_fb_vc; j <= last_fb_vc; j++) {
|
|
|
|
if (con2fb_map[j] == i) {
|
|
|
|
mapped = 1;
|
|
|
|
con2fb_map[j] = -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mapped)
|
|
|
|
fbcon_release(info);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
static void fbcon_deinit(struct vc_data *vc)
|
|
|
|
{
|
2019-05-28 09:02:39 +00:00
|
|
|
struct fbcon_display *p = &fb_display[vc->vc_num];
|
2006-06-26 07:27:09 +00:00
|
|
|
struct fb_info *info;
|
|
|
|
struct fbcon_ops *ops;
|
|
|
|
int idx;
|
2013-01-24 06:12:41 +00:00
|
|
|
bool free_font = true;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2006-06-26 07:27:09 +00:00
|
|
|
idx = con2fb_map[vc->vc_num];
|
|
|
|
|
|
|
|
if (idx == -1)
|
|
|
|
goto finished;
|
|
|
|
|
2022-04-05 21:03:35 +00:00
|
|
|
info = fbcon_registered_fb[idx];
|
2006-06-26 07:27:09 +00:00
|
|
|
|
|
|
|
if (!info)
|
|
|
|
goto finished;
|
|
|
|
|
2013-01-24 06:12:41 +00:00
|
|
|
if (info->flags & FBINFO_MISC_FIRMWARE)
|
|
|
|
free_font = false;
|
2006-06-26 07:27:09 +00:00
|
|
|
ops = info->fbcon_par;
|
|
|
|
|
|
|
|
if (!ops)
|
|
|
|
goto finished;
|
|
|
|
|
2016-06-23 11:34:35 +00:00
|
|
|
if (con_is_visible(vc))
|
2022-04-05 21:03:24 +00:00
|
|
|
fbcon_del_cursor_work(info);
|
2006-06-26 07:27:09 +00:00
|
|
|
|
2022-04-05 21:03:25 +00:00
|
|
|
ops->initialized = false;
|
2006-06-26 07:27:09 +00:00
|
|
|
finished:
|
|
|
|
|
2013-01-24 06:12:41 +00:00
|
|
|
fbcon_free_font(p, free_font);
|
2013-04-22 11:19:26 +00:00
|
|
|
if (free_font)
|
|
|
|
vc->vc_font.data = NULL;
|
2013-01-24 06:12:41 +00:00
|
|
|
|
2019-04-26 14:59:46 +00:00
|
|
|
if (vc->vc_hi_font_mask && vc->vc_screenbuf)
|
fbcon: Fix vc attr at deinit
fbcon can deal with vc_hi_font_mask (the upper 256 chars) and adjust
the vc attrs dynamically when vc_hi_font_mask is changed at
fbcon_init(). When the vc_hi_font_mask is set, it remaps the attrs in
the existing console buffer with one bit shift up (for 9 bits), while
it remaps with one bit shift down (for 8 bits) when the value is
cleared. It works fine as long as the font gets updated after fbcon
was initialized.
However, we hit a bizarre problem when the console is switched to
another fb driver (typically from vesafb or efifb to drmfb). At
switching to the new fb driver, we temporarily rebind the console to
the dummy console, then rebind to the new driver. During the
switching, we leave the modified attrs as is. Thus, the new fbcon
takes over the old buffer as if it were to contain 8 bits chars
(although the attrs are still shifted for 9 bits), and effectively
this results in the yellow color texts instead of the original white
color, as found in the bugzilla entry below.
An easy fix for this is to re-adjust the attrs before leaving the
fbcon at con_deinit callback. Since the code to adjust the attrs is
already present in the current fbcon code, in this patch, we simply
factor out the relevant code, and call it from fbcon_deinit().
Bugzilla: https://bugzilla.suse.com/show_bug.cgi?id=1000619
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
2017-01-11 16:09:50 +00:00
|
|
|
set_vc_hi_font(vc, false);
|
|
|
|
|
2006-06-26 07:27:09 +00:00
|
|
|
if (!con_is_bound(&fb_con))
|
2022-04-05 21:03:34 +00:00
|
|
|
fbcon_release_all();
|
2006-06-26 07:27:09 +00:00
|
|
|
|
2020-03-29 08:56:47 +00:00
|
|
|
if (vc->vc_num == logo_shown)
|
|
|
|
logo_shown = FBCON_LOGO_CANSHOW;
|
|
|
|
|
2006-06-26 07:27:09 +00:00
|
|
|
return;
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ====================================================================== */
|
|
|
|
|
|
|
|
/* fbcon_XXX routines - interface used by the world
|
|
|
|
*
|
|
|
|
* This system is now divided into two levels because of complications
|
|
|
|
* caused by hardware scrolling. Top level functions:
|
|
|
|
*
|
Revert "fbdev: Garbage collect fbdev scrolling acceleration, part 1 (from TODO list)"
This reverts commit b3ec8cdf457e5e63d396fe1346cc788cf7c1b578.
Revert the second (of 2) commits which disabled scrolling acceleration
in fbcon/fbdev. It introduced a regression for fbdev-supported graphic
cards because of the performance penalty by doing screen scrolling by
software instead of using the existing graphic card 2D hardware
acceleration.
Console scrolling acceleration was disabled by dropping code which
checked at runtime the driver hardware capabilities for the
BINFO_HWACCEL_COPYAREA or FBINFO_HWACCEL_FILLRECT flags and if set, it
enabled scrollmode SCROLL_MOVE which uses hardware acceleration to move
screen contents. After dropping those checks scrollmode was hard-wired
to SCROLL_REDRAW instead, which forces all graphic cards to redraw every
character at the new screen position when scrolling.
This change effectively disabled all hardware-based scrolling acceleration for
ALL drivers, because now all kind of 2D hardware acceleration (bitblt,
fillrect) in the drivers isn't used any longer.
The original commit message mentions that only 3 DRM drivers (nouveau, omapdrm
and gma500) used hardware acceleration in the past and thus code for checking
and using scrolling acceleration is obsolete.
This statement is NOT TRUE, because beside the DRM drivers there are around 35
other fbdev drivers which depend on fbdev/fbcon and still provide hardware
acceleration for fbdev/fbcon.
The original commit message also states that syzbot found lots of bugs in fbcon
and thus it's "often the solution to just delete code and remove features".
This is true, and the bugs - which actually affected all users of fbcon,
including DRM - were fixed, or code was dropped like e.g. the support for
software scrollback in vgacon (commit 973c096f6a85).
So to further analyze which bugs were found by syzbot, I've looked through all
patches in drivers/video which were tagged with syzbot or syzkaller back to
year 2005. The vast majority fixed the reported issues on a higher level, e.g.
when screen is to be resized, or when font size is to be changed. The few ones
which touched driver code fixed a real driver bug, e.g. by adding a check.
But NONE of those patches touched code of either the SCROLL_MOVE or the
SCROLL_REDRAW case.
That means, there was no real reason why SCROLL_MOVE had to be ripped-out and
just SCROLL_REDRAW had to be used instead. The only reason I can imagine so far
was that SCROLL_MOVE wasn't used by DRM and as such it was assumed that it
could go away. That argument completely missed the fact that SCROLL_MOVE is
still heavily used by fbdev (non-DRM) drivers.
Some people mention that using memcpy() instead of the hardware acceleration is
pretty much the same speed. But that's not true, at least not for older graphic
cards and machines where we see speed decreases by factor 10 and more and thus
this change leads to console responsiveness way worse than before.
That's why the original commit is to be reverted. By reverting we
reintroduce hardware-based scrolling acceleration and fix the
performance regression for fbdev drivers.
There isn't any impact on DRM when reverting those patches.
Signed-off-by: Helge Deller <deller@gmx.de>
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
Acked-by: Sven Schnelle <svens@stackframe.org>
Cc: stable@vger.kernel.org # v5.16+
Signed-off-by: Helge Deller <deller@gmx.de>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/20220202135531.92183-2-deller@gmx.de
2022-02-02 13:55:29 +00:00
|
|
|
* fbcon_bmove(), fbcon_clear(), fbcon_putc(), fbcon_clear_margins()
|
2005-04-16 22:20:36 +00:00
|
|
|
*
|
|
|
|
* handles y values in range [0, scr_height-1] that correspond to real
|
|
|
|
* screen positions. y_wrap shift means that first line of bitmap may be
|
|
|
|
* anywhere on this display. These functions convert lineoffsets to
|
|
|
|
* bitmap offsets and deal with the wrap-around case by splitting blits.
|
|
|
|
*
|
Revert "fbdev: Garbage collect fbdev scrolling acceleration, part 1 (from TODO list)"
This reverts commit b3ec8cdf457e5e63d396fe1346cc788cf7c1b578.
Revert the second (of 2) commits which disabled scrolling acceleration
in fbcon/fbdev. It introduced a regression for fbdev-supported graphic
cards because of the performance penalty by doing screen scrolling by
software instead of using the existing graphic card 2D hardware
acceleration.
Console scrolling acceleration was disabled by dropping code which
checked at runtime the driver hardware capabilities for the
BINFO_HWACCEL_COPYAREA or FBINFO_HWACCEL_FILLRECT flags and if set, it
enabled scrollmode SCROLL_MOVE which uses hardware acceleration to move
screen contents. After dropping those checks scrollmode was hard-wired
to SCROLL_REDRAW instead, which forces all graphic cards to redraw every
character at the new screen position when scrolling.
This change effectively disabled all hardware-based scrolling acceleration for
ALL drivers, because now all kind of 2D hardware acceleration (bitblt,
fillrect) in the drivers isn't used any longer.
The original commit message mentions that only 3 DRM drivers (nouveau, omapdrm
and gma500) used hardware acceleration in the past and thus code for checking
and using scrolling acceleration is obsolete.
This statement is NOT TRUE, because beside the DRM drivers there are around 35
other fbdev drivers which depend on fbdev/fbcon and still provide hardware
acceleration for fbdev/fbcon.
The original commit message also states that syzbot found lots of bugs in fbcon
and thus it's "often the solution to just delete code and remove features".
This is true, and the bugs - which actually affected all users of fbcon,
including DRM - were fixed, or code was dropped like e.g. the support for
software scrollback in vgacon (commit 973c096f6a85).
So to further analyze which bugs were found by syzbot, I've looked through all
patches in drivers/video which were tagged with syzbot or syzkaller back to
year 2005. The vast majority fixed the reported issues on a higher level, e.g.
when screen is to be resized, or when font size is to be changed. The few ones
which touched driver code fixed a real driver bug, e.g. by adding a check.
But NONE of those patches touched code of either the SCROLL_MOVE or the
SCROLL_REDRAW case.
That means, there was no real reason why SCROLL_MOVE had to be ripped-out and
just SCROLL_REDRAW had to be used instead. The only reason I can imagine so far
was that SCROLL_MOVE wasn't used by DRM and as such it was assumed that it
could go away. That argument completely missed the fact that SCROLL_MOVE is
still heavily used by fbdev (non-DRM) drivers.
Some people mention that using memcpy() instead of the hardware acceleration is
pretty much the same speed. But that's not true, at least not for older graphic
cards and machines where we see speed decreases by factor 10 and more and thus
this change leads to console responsiveness way worse than before.
That's why the original commit is to be reverted. By reverting we
reintroduce hardware-based scrolling acceleration and fix the
performance regression for fbdev drivers.
There isn't any impact on DRM when reverting those patches.
Signed-off-by: Helge Deller <deller@gmx.de>
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
Acked-by: Sven Schnelle <svens@stackframe.org>
Cc: stable@vger.kernel.org # v5.16+
Signed-off-by: Helge Deller <deller@gmx.de>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/20220202135531.92183-2-deller@gmx.de
2022-02-02 13:55:29 +00:00
|
|
|
* fbcon_bmove_physical_8() -- These functions fast implementations
|
2005-04-16 22:20:36 +00:00
|
|
|
* fbcon_clear_physical_8() -- of original fbcon_XXX fns.
|
|
|
|
* fbcon_putc_physical_8() -- (font width != 8) may be added later
|
|
|
|
*
|
|
|
|
* WARNING:
|
|
|
|
*
|
|
|
|
* At the moment fbcon_putc() cannot blit across vertical wrap boundary
|
|
|
|
* Implies should only really hardware scroll in rows. Only reason for
|
|
|
|
* restriction is simplicity & efficiency at the moment.
|
|
|
|
*/
|
|
|
|
|
|
|
|
static void fbcon_clear(struct vc_data *vc, int sy, int sx, int height,
|
|
|
|
int width)
|
|
|
|
{
|
2022-04-05 21:03:21 +00:00
|
|
|
struct fb_info *info = fbcon_info_from_console(vc->vc_num);
|
2005-04-16 22:20:36 +00:00
|
|
|
struct fbcon_ops *ops = info->fbcon_par;
|
|
|
|
|
2019-05-28 09:02:39 +00:00
|
|
|
struct fbcon_display *p = &fb_display[vc->vc_num];
|
2005-04-16 22:20:36 +00:00
|
|
|
u_int y_break;
|
|
|
|
|
|
|
|
if (fbcon_is_inactive(vc, info))
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (!height || !width)
|
|
|
|
return;
|
|
|
|
|
2013-02-22 00:42:07 +00:00
|
|
|
if (sy < vc->vc_top && vc->vc_top == logo_lines) {
|
2008-08-05 20:01:26 +00:00
|
|
|
vc->vc_top = 0;
|
2013-02-22 00:42:07 +00:00
|
|
|
/*
|
|
|
|
* If the font dimensions are not an integral of the display
|
|
|
|
* dimensions then the ops->clear below won't end up clearing
|
|
|
|
* the margins. Call clear_margins here in case the logo
|
|
|
|
* bitmap stretched into the margin area.
|
|
|
|
*/
|
|
|
|
fbcon_clear_margins(vc, 0);
|
|
|
|
}
|
2008-08-05 20:01:26 +00:00
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
/* Split blits that cross physical y_wrap boundary */
|
|
|
|
|
|
|
|
y_break = p->vrows - p->yscroll;
|
|
|
|
if (sy < y_break && sy + height - 1 >= y_break) {
|
|
|
|
u_int b = y_break - sy;
|
|
|
|
ops->clear(vc, info, real_y(p, sy), sx, b, width);
|
|
|
|
ops->clear(vc, info, real_y(p, sy + b), sx, height - b,
|
|
|
|
width);
|
|
|
|
} else
|
|
|
|
ops->clear(vc, info, real_y(p, sy), sx, height, width);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void fbcon_putcs(struct vc_data *vc, const unsigned short *s,
|
|
|
|
int count, int ypos, int xpos)
|
|
|
|
{
|
2022-04-05 21:03:21 +00:00
|
|
|
struct fb_info *info = fbcon_info_from_console(vc->vc_num);
|
2019-05-28 09:02:39 +00:00
|
|
|
struct fbcon_display *p = &fb_display[vc->vc_num];
|
2005-04-16 22:20:36 +00:00
|
|
|
struct fbcon_ops *ops = info->fbcon_par;
|
|
|
|
|
|
|
|
if (!fbcon_is_inactive(vc, info))
|
|
|
|
ops->putcs(vc, info, s, count, real_y(p, ypos), xpos,
|
|
|
|
get_color(vc, info, scr_readw(s), 1),
|
|
|
|
get_color(vc, info, scr_readw(s), 0));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void fbcon_putc(struct vc_data *vc, int c, int ypos, int xpos)
|
|
|
|
{
|
|
|
|
unsigned short chr;
|
|
|
|
|
|
|
|
scr_writew(c, &chr);
|
|
|
|
fbcon_putcs(vc, &chr, 1, ypos, xpos);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void fbcon_clear_margins(struct vc_data *vc, int bottom_only)
|
|
|
|
{
|
2022-04-05 21:03:21 +00:00
|
|
|
struct fb_info *info = fbcon_info_from_console(vc->vc_num);
|
2005-04-16 22:20:36 +00:00
|
|
|
struct fbcon_ops *ops = info->fbcon_par;
|
|
|
|
|
|
|
|
if (!fbcon_is_inactive(vc, info))
|
2017-08-18 17:56:40 +00:00
|
|
|
ops->clear_margins(vc, info, margin_color, bottom_only);
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void fbcon_cursor(struct vc_data *vc, int mode)
|
|
|
|
{
|
2022-04-05 21:03:21 +00:00
|
|
|
struct fb_info *info = fbcon_info_from_console(vc->vc_num);
|
2005-04-16 22:20:36 +00:00
|
|
|
struct fbcon_ops *ops = info->fbcon_par;
|
|
|
|
int c = scr_readw((u16 *) vc->vc_pos);
|
|
|
|
|
2015-08-04 12:33:32 +00:00
|
|
|
ops->cur_blink_jiffies = msecs_to_jiffies(vc->vc_cur_blink_ms);
|
|
|
|
|
2007-05-08 07:38:07 +00:00
|
|
|
if (fbcon_is_inactive(vc, info) || vc->vc_deccm != 1)
|
2005-04-16 22:20:36 +00:00
|
|
|
return;
|
|
|
|
|
2020-06-15 07:48:58 +00:00
|
|
|
if (vc->vc_cursor_type & CUR_SW)
|
2022-04-05 21:03:24 +00:00
|
|
|
fbcon_del_cursor_work(info);
|
2015-05-21 07:58:03 +00:00
|
|
|
else
|
2022-04-05 21:03:24 +00:00
|
|
|
fbcon_add_cursor_work(info);
|
2007-07-17 11:05:26 +00:00
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
ops->cursor_flash = (mode == CM_ERASE) ? 0 : 1;
|
|
|
|
|
2021-03-12 08:14:21 +00:00
|
|
|
if (!ops->cursor)
|
|
|
|
return;
|
|
|
|
|
2020-09-08 17:56:27 +00:00
|
|
|
ops->cursor(vc, info, mode, get_color(vc, info, c, 1),
|
2005-04-16 22:20:36 +00:00
|
|
|
get_color(vc, info, c, 0));
|
|
|
|
}
|
|
|
|
|
|
|
|
static int scrollback_phys_max = 0;
|
|
|
|
static int scrollback_max = 0;
|
|
|
|
static int scrollback_current = 0;
|
|
|
|
|
|
|
|
static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var,
|
2007-07-17 11:05:32 +00:00
|
|
|
int unit)
|
2005-04-16 22:20:36 +00:00
|
|
|
{
|
2019-05-28 09:02:39 +00:00
|
|
|
struct fbcon_display *p, *t;
|
2007-07-17 11:05:32 +00:00
|
|
|
struct vc_data **default_mode, *vc;
|
|
|
|
struct vc_data *svc;
|
[PATCH] fbcon: Console Rotation - Prepare fbcon for console rotation
This patch series implements generic code to rotate the console at 90, 180,
and 270 degrees. The implementation is completely done in the framebuffer
console level, thus no changes to the framebuffer layer or to the drivers
are needed.
Console rotation is required by some Sharp-based devices where the natural
orientation of the display is not at 0 degrees. Also, users that have
displays that can pivot will benefit by having a console in portrait mode
if they so desire.
The choice to implement the code in the console layer rather than in the
framebuffer layer is due to the following reasons:
- it's fast
- it does not require driver changes
- it can coexist with devices that can rotate the display at the hardware level
- it complements graphics applications that can do display rotation
The changes to core fbcon are minimal-- recognition of the console
rotation angle so it can swap directions, origins and axes (xres vs yres,
xpanstep vs ypanstep, xoffset vs yoffset, etc) and storage of the rotation
angle per display. The bulk of the code that does the actual drawing to the
screen are placed in separate files. Each angle of rotation has separate
methods (bmove, clear, putcs, cursor, update_start which is derived from
update_var, and clear_margins). To mimimize processing time, the fontdata
are pre-rotated at each console switch (only if the font or the angle has
changed).
The option can be compiled out (CONFIG_FRAMEBUFFER_CONSOLE_ROTATION = n) if
rotation is not needed.
Choosing the rotation angle can be done in several ways:
1. boot option fbcon=rotate:n, where
n = 0 - normal
n = 1 - 90 degrees (clockwise)
n = 2 - 180 degrees (upside down)
n = 3 - 270 degrees (counterclockwise)
2. echo n > /sys/class/graphics/fb[num]/con_rotate
where n is the same as described above. It sets the angle of rotation
of the current console
3 echo n > /sys/class/graphics/fb[num]/con_rotate_all
where n is the same as described above. Globally sets the angle of
rotation.
GOTCHAS:
The option, especially at angles of 90 and 270 degrees, will exercise
the least used code of drivers. Namely, at these angles, panning is done
in the x-axis, so it can reveal bugs in the driver if xpanstep is set
incorrectly. A workaround is to set xpanstep = 0.
Secondly, at these angles, the framebuffer memory access can be
unaligned if (fontheight * bpp) % 32 ~= 0 which can reveal bugs in the drivers
imageblit, fillrect and copyarea functions. (I think cfbfillrect may have
this buglet). A workaround is to use a standard 8x16 font.
Speed:
The scrolling speed difference between 0 and 180 degrees is minimal,
somewhere areound 1-2%. At 90 or 270 degress, speed drops down to a vicinity
of 30-40%. This is understandable because the blit direction is across the
framebuffer "direction." Scrolling will be helped at these angles if xpanstep
is not equal to zero, use of 8x16 fonts, and setting xres_virtual >= xres * 2.
Note: The code is tested on little-endian only, so I don't know if it will
work in big-endian. Please let me know, it will take only less than a minute
of your time.
This patch prepares fbcon for console rotation and contains the following
changes:
- add rotate field in struct fbcon_ops to keep fbcon's current rotation
angle
- add con_rotate field in struct display to store per-display rotation angle
- create a private copy of the current var to fbcon. This will prevent
fbcon from directly manipulating info->var, especially the fields xoffset,
yoffset and vmode.
- add ability to swap pertinent axes (xres, yres; xpanstep, ypanstep; etc)
depending on the rotation angle
- change global update_var() (function that sets the screen start address)
as an fbcon method update_start. This is required because the axes, start
offset, and/or direction can be reversed depending on the rotation angle.
- add fbcon method rotate_font() which will rotate each character bitmap to
the correct angle of rotation.
- add fbcon boot option 'rotate' to select the angle of rotation at bootime.
Currently does nothing until all patches are applied.
Signed-off-by: Antonino Daplas <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-11-09 05:39:09 +00:00
|
|
|
struct fbcon_ops *ops = info->fbcon_par;
|
fbcon: Avoid using FNTCHARCNT() and hard-coded built-in font charcount
For user-provided fonts, the framebuffer layer is using a magic
negative-indexing macro, FNTCHARCNT(), to keep track of their number of
characters:
#define FNTCHARCNT(fd) (((int *)(fd))[-3])
For built-in fonts, it is using hard-coded values (256). This results in
something like the following:
map.length = (ops->p->userfont) ?
FNTCHARCNT(ops->p->fontdata) : 256;
This is unsatisfactory. In fact, there is already a `charcount` field in
our virtual console descriptor (see `struct console_font` inside `struct
vc_data`), let us use it:
map.length = vc->vc_font.charcount;
Recently we added a `charcount` field to `struct font_desc`. Use it to set
`vc->vc_font.charcount` properly. The idea is:
- We only use FNTCHARCNT() on `vc->vc_font.data` and `p->fontdata`.
Assume FNTCHARCNT() is working as intended;
- Whenever `vc->vc_font.data` is set, also set `vc->vc_font.charcount`
properly;
- We can now replace `FNTCHARCNT(vc->vc_font.data)` with
`vc->vc_font.charcount`;
- Since `p->fontdata` always point to the same font data buffer with
`vc->vc_font.data`, we can also replace `FNTCHARCNT(p->fontdata)` with
`vc->vc_font.charcount`.
In conclusion, set `vc->vc_font.charcount` properly in fbcon_startup(),
fbcon_init(), fbcon_set_disp() and fbcon_do_set_font(), then replace
FNTCHARCNT() with `vc->vc_font.charcount`. No more if-else between
negative-indexing macros and hard-coded values.
Do not include <linux/font.h> in fbcon_rotate.c and tileblit.c, since they
no longer need it.
Depends on patch "Fonts: Add charcount field to font_desc".
Suggested-by: Daniel Vetter <daniel@ffwll.ch>
Signed-off-by: Peilin Ye <yepeilin.cs@gmail.com>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/e460a5780e54e3022661d5f09555144583b4cc59.1605169912.git.yepeilin.cs@gmail.com
2020-11-12 12:15:22 +00:00
|
|
|
int rows, cols;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2007-07-17 11:05:32 +00:00
|
|
|
p = &fb_display[unit];
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
if (var_to_display(p, var, info))
|
|
|
|
return;
|
2007-07-17 11:05:32 +00:00
|
|
|
|
|
|
|
vc = vc_cons[unit].d;
|
|
|
|
|
|
|
|
if (!vc)
|
|
|
|
return;
|
|
|
|
|
|
|
|
default_mode = vc->vc_display_fg;
|
|
|
|
svc = *default_mode;
|
2005-04-16 22:20:36 +00:00
|
|
|
t = &fb_display[svc->vc_num];
|
2007-07-17 11:05:32 +00:00
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
if (!vc->vc_font.data) {
|
2005-09-13 08:25:44 +00:00
|
|
|
vc->vc_font.data = (void *)(p->fontdata = t->fontdata);
|
2005-04-16 22:20:36 +00:00
|
|
|
vc->vc_font.width = (*default_mode)->vc_font.width;
|
|
|
|
vc->vc_font.height = (*default_mode)->vc_font.height;
|
fbcon: Avoid using FNTCHARCNT() and hard-coded built-in font charcount
For user-provided fonts, the framebuffer layer is using a magic
negative-indexing macro, FNTCHARCNT(), to keep track of their number of
characters:
#define FNTCHARCNT(fd) (((int *)(fd))[-3])
For built-in fonts, it is using hard-coded values (256). This results in
something like the following:
map.length = (ops->p->userfont) ?
FNTCHARCNT(ops->p->fontdata) : 256;
This is unsatisfactory. In fact, there is already a `charcount` field in
our virtual console descriptor (see `struct console_font` inside `struct
vc_data`), let us use it:
map.length = vc->vc_font.charcount;
Recently we added a `charcount` field to `struct font_desc`. Use it to set
`vc->vc_font.charcount` properly. The idea is:
- We only use FNTCHARCNT() on `vc->vc_font.data` and `p->fontdata`.
Assume FNTCHARCNT() is working as intended;
- Whenever `vc->vc_font.data` is set, also set `vc->vc_font.charcount`
properly;
- We can now replace `FNTCHARCNT(vc->vc_font.data)` with
`vc->vc_font.charcount`;
- Since `p->fontdata` always point to the same font data buffer with
`vc->vc_font.data`, we can also replace `FNTCHARCNT(p->fontdata)` with
`vc->vc_font.charcount`.
In conclusion, set `vc->vc_font.charcount` properly in fbcon_startup(),
fbcon_init(), fbcon_set_disp() and fbcon_do_set_font(), then replace
FNTCHARCNT() with `vc->vc_font.charcount`. No more if-else between
negative-indexing macros and hard-coded values.
Do not include <linux/font.h> in fbcon_rotate.c and tileblit.c, since they
no longer need it.
Depends on patch "Fonts: Add charcount field to font_desc".
Suggested-by: Daniel Vetter <daniel@ffwll.ch>
Signed-off-by: Peilin Ye <yepeilin.cs@gmail.com>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/e460a5780e54e3022661d5f09555144583b4cc59.1605169912.git.yepeilin.cs@gmail.com
2020-11-12 12:15:22 +00:00
|
|
|
vc->vc_font.charcount = (*default_mode)->vc_font.charcount;
|
2005-04-16 22:20:36 +00:00
|
|
|
p->userfont = t->userfont;
|
|
|
|
if (p->userfont)
|
|
|
|
REFCOUNT(p->fontdata)++;
|
|
|
|
}
|
|
|
|
|
2005-09-09 20:04:37 +00:00
|
|
|
var->activate = FB_ACTIVATE_NOW;
|
|
|
|
info->var.activate = var->activate;
|
[PATCH] fbcon: Console Rotation - Prepare fbcon for console rotation
This patch series implements generic code to rotate the console at 90, 180,
and 270 degrees. The implementation is completely done in the framebuffer
console level, thus no changes to the framebuffer layer or to the drivers
are needed.
Console rotation is required by some Sharp-based devices where the natural
orientation of the display is not at 0 degrees. Also, users that have
displays that can pivot will benefit by having a console in portrait mode
if they so desire.
The choice to implement the code in the console layer rather than in the
framebuffer layer is due to the following reasons:
- it's fast
- it does not require driver changes
- it can coexist with devices that can rotate the display at the hardware level
- it complements graphics applications that can do display rotation
The changes to core fbcon are minimal-- recognition of the console
rotation angle so it can swap directions, origins and axes (xres vs yres,
xpanstep vs ypanstep, xoffset vs yoffset, etc) and storage of the rotation
angle per display. The bulk of the code that does the actual drawing to the
screen are placed in separate files. Each angle of rotation has separate
methods (bmove, clear, putcs, cursor, update_start which is derived from
update_var, and clear_margins). To mimimize processing time, the fontdata
are pre-rotated at each console switch (only if the font or the angle has
changed).
The option can be compiled out (CONFIG_FRAMEBUFFER_CONSOLE_ROTATION = n) if
rotation is not needed.
Choosing the rotation angle can be done in several ways:
1. boot option fbcon=rotate:n, where
n = 0 - normal
n = 1 - 90 degrees (clockwise)
n = 2 - 180 degrees (upside down)
n = 3 - 270 degrees (counterclockwise)
2. echo n > /sys/class/graphics/fb[num]/con_rotate
where n is the same as described above. It sets the angle of rotation
of the current console
3 echo n > /sys/class/graphics/fb[num]/con_rotate_all
where n is the same as described above. Globally sets the angle of
rotation.
GOTCHAS:
The option, especially at angles of 90 and 270 degrees, will exercise
the least used code of drivers. Namely, at these angles, panning is done
in the x-axis, so it can reveal bugs in the driver if xpanstep is set
incorrectly. A workaround is to set xpanstep = 0.
Secondly, at these angles, the framebuffer memory access can be
unaligned if (fontheight * bpp) % 32 ~= 0 which can reveal bugs in the drivers
imageblit, fillrect and copyarea functions. (I think cfbfillrect may have
this buglet). A workaround is to use a standard 8x16 font.
Speed:
The scrolling speed difference between 0 and 180 degrees is minimal,
somewhere areound 1-2%. At 90 or 270 degress, speed drops down to a vicinity
of 30-40%. This is understandable because the blit direction is across the
framebuffer "direction." Scrolling will be helped at these angles if xpanstep
is not equal to zero, use of 8x16 fonts, and setting xres_virtual >= xres * 2.
Note: The code is tested on little-endian only, so I don't know if it will
work in big-endian. Please let me know, it will take only less than a minute
of your time.
This patch prepares fbcon for console rotation and contains the following
changes:
- add rotate field in struct fbcon_ops to keep fbcon's current rotation
angle
- add con_rotate field in struct display to store per-display rotation angle
- create a private copy of the current var to fbcon. This will prevent
fbcon from directly manipulating info->var, especially the fields xoffset,
yoffset and vmode.
- add ability to swap pertinent axes (xres, yres; xpanstep, ypanstep; etc)
depending on the rotation angle
- change global update_var() (function that sets the screen start address)
as an fbcon method update_start. This is required because the axes, start
offset, and/or direction can be reversed depending on the rotation angle.
- add fbcon method rotate_font() which will rotate each character bitmap to
the correct angle of rotation.
- add fbcon boot option 'rotate' to select the angle of rotation at bootime.
Currently does nothing until all patches are applied.
Signed-off-by: Antonino Daplas <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-11-09 05:39:09 +00:00
|
|
|
var->yoffset = info->var.yoffset;
|
|
|
|
var->xoffset = info->var.xoffset;
|
2005-09-09 20:04:37 +00:00
|
|
|
fb_set_var(info, var);
|
[PATCH] fbcon: Console Rotation - Prepare fbcon for console rotation
This patch series implements generic code to rotate the console at 90, 180,
and 270 degrees. The implementation is completely done in the framebuffer
console level, thus no changes to the framebuffer layer or to the drivers
are needed.
Console rotation is required by some Sharp-based devices where the natural
orientation of the display is not at 0 degrees. Also, users that have
displays that can pivot will benefit by having a console in portrait mode
if they so desire.
The choice to implement the code in the console layer rather than in the
framebuffer layer is due to the following reasons:
- it's fast
- it does not require driver changes
- it can coexist with devices that can rotate the display at the hardware level
- it complements graphics applications that can do display rotation
The changes to core fbcon are minimal-- recognition of the console
rotation angle so it can swap directions, origins and axes (xres vs yres,
xpanstep vs ypanstep, xoffset vs yoffset, etc) and storage of the rotation
angle per display. The bulk of the code that does the actual drawing to the
screen are placed in separate files. Each angle of rotation has separate
methods (bmove, clear, putcs, cursor, update_start which is derived from
update_var, and clear_margins). To mimimize processing time, the fontdata
are pre-rotated at each console switch (only if the font or the angle has
changed).
The option can be compiled out (CONFIG_FRAMEBUFFER_CONSOLE_ROTATION = n) if
rotation is not needed.
Choosing the rotation angle can be done in several ways:
1. boot option fbcon=rotate:n, where
n = 0 - normal
n = 1 - 90 degrees (clockwise)
n = 2 - 180 degrees (upside down)
n = 3 - 270 degrees (counterclockwise)
2. echo n > /sys/class/graphics/fb[num]/con_rotate
where n is the same as described above. It sets the angle of rotation
of the current console
3 echo n > /sys/class/graphics/fb[num]/con_rotate_all
where n is the same as described above. Globally sets the angle of
rotation.
GOTCHAS:
The option, especially at angles of 90 and 270 degrees, will exercise
the least used code of drivers. Namely, at these angles, panning is done
in the x-axis, so it can reveal bugs in the driver if xpanstep is set
incorrectly. A workaround is to set xpanstep = 0.
Secondly, at these angles, the framebuffer memory access can be
unaligned if (fontheight * bpp) % 32 ~= 0 which can reveal bugs in the drivers
imageblit, fillrect and copyarea functions. (I think cfbfillrect may have
this buglet). A workaround is to use a standard 8x16 font.
Speed:
The scrolling speed difference between 0 and 180 degrees is minimal,
somewhere areound 1-2%. At 90 or 270 degress, speed drops down to a vicinity
of 30-40%. This is understandable because the blit direction is across the
framebuffer "direction." Scrolling will be helped at these angles if xpanstep
is not equal to zero, use of 8x16 fonts, and setting xres_virtual >= xres * 2.
Note: The code is tested on little-endian only, so I don't know if it will
work in big-endian. Please let me know, it will take only less than a minute
of your time.
This patch prepares fbcon for console rotation and contains the following
changes:
- add rotate field in struct fbcon_ops to keep fbcon's current rotation
angle
- add con_rotate field in struct display to store per-display rotation angle
- create a private copy of the current var to fbcon. This will prevent
fbcon from directly manipulating info->var, especially the fields xoffset,
yoffset and vmode.
- add ability to swap pertinent axes (xres, yres; xpanstep, ypanstep; etc)
depending on the rotation angle
- change global update_var() (function that sets the screen start address)
as an fbcon method update_start. This is required because the axes, start
offset, and/or direction can be reversed depending on the rotation angle.
- add fbcon method rotate_font() which will rotate each character bitmap to
the correct angle of rotation.
- add fbcon boot option 'rotate' to select the angle of rotation at bootime.
Currently does nothing until all patches are applied.
Signed-off-by: Antonino Daplas <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-11-09 05:39:09 +00:00
|
|
|
ops->var = info->var;
|
2005-09-09 20:04:37 +00:00
|
|
|
vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1);
|
2005-04-16 22:20:36 +00:00
|
|
|
vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800;
|
fbcon: Avoid using FNTCHARCNT() and hard-coded built-in font charcount
For user-provided fonts, the framebuffer layer is using a magic
negative-indexing macro, FNTCHARCNT(), to keep track of their number of
characters:
#define FNTCHARCNT(fd) (((int *)(fd))[-3])
For built-in fonts, it is using hard-coded values (256). This results in
something like the following:
map.length = (ops->p->userfont) ?
FNTCHARCNT(ops->p->fontdata) : 256;
This is unsatisfactory. In fact, there is already a `charcount` field in
our virtual console descriptor (see `struct console_font` inside `struct
vc_data`), let us use it:
map.length = vc->vc_font.charcount;
Recently we added a `charcount` field to `struct font_desc`. Use it to set
`vc->vc_font.charcount` properly. The idea is:
- We only use FNTCHARCNT() on `vc->vc_font.data` and `p->fontdata`.
Assume FNTCHARCNT() is working as intended;
- Whenever `vc->vc_font.data` is set, also set `vc->vc_font.charcount`
properly;
- We can now replace `FNTCHARCNT(vc->vc_font.data)` with
`vc->vc_font.charcount`;
- Since `p->fontdata` always point to the same font data buffer with
`vc->vc_font.data`, we can also replace `FNTCHARCNT(p->fontdata)` with
`vc->vc_font.charcount`.
In conclusion, set `vc->vc_font.charcount` properly in fbcon_startup(),
fbcon_init(), fbcon_set_disp() and fbcon_do_set_font(), then replace
FNTCHARCNT() with `vc->vc_font.charcount`. No more if-else between
negative-indexing macros and hard-coded values.
Do not include <linux/font.h> in fbcon_rotate.c and tileblit.c, since they
no longer need it.
Depends on patch "Fonts: Add charcount field to font_desc".
Suggested-by: Daniel Vetter <daniel@ffwll.ch>
Signed-off-by: Peilin Ye <yepeilin.cs@gmail.com>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/e460a5780e54e3022661d5f09555144583b4cc59.1605169912.git.yepeilin.cs@gmail.com
2020-11-12 12:15:22 +00:00
|
|
|
if (vc->vc_font.charcount == 256) {
|
2005-04-16 22:20:36 +00:00
|
|
|
vc->vc_hi_font_mask = 0;
|
|
|
|
} else {
|
|
|
|
vc->vc_hi_font_mask = 0x100;
|
|
|
|
if (vc->vc_can_do_color)
|
|
|
|
vc->vc_complement_mask <<= 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!*svc->vc_uni_pagedir_loc)
|
|
|
|
con_set_default_unimap(svc);
|
|
|
|
if (!*vc->vc_uni_pagedir_loc)
|
|
|
|
con_copy_unimap(vc, svc);
|
|
|
|
|
[PATCH] fbcon: Console Rotation - Prepare fbcon for console rotation
This patch series implements generic code to rotate the console at 90, 180,
and 270 degrees. The implementation is completely done in the framebuffer
console level, thus no changes to the framebuffer layer or to the drivers
are needed.
Console rotation is required by some Sharp-based devices where the natural
orientation of the display is not at 0 degrees. Also, users that have
displays that can pivot will benefit by having a console in portrait mode
if they so desire.
The choice to implement the code in the console layer rather than in the
framebuffer layer is due to the following reasons:
- it's fast
- it does not require driver changes
- it can coexist with devices that can rotate the display at the hardware level
- it complements graphics applications that can do display rotation
The changes to core fbcon are minimal-- recognition of the console
rotation angle so it can swap directions, origins and axes (xres vs yres,
xpanstep vs ypanstep, xoffset vs yoffset, etc) and storage of the rotation
angle per display. The bulk of the code that does the actual drawing to the
screen are placed in separate files. Each angle of rotation has separate
methods (bmove, clear, putcs, cursor, update_start which is derived from
update_var, and clear_margins). To mimimize processing time, the fontdata
are pre-rotated at each console switch (only if the font or the angle has
changed).
The option can be compiled out (CONFIG_FRAMEBUFFER_CONSOLE_ROTATION = n) if
rotation is not needed.
Choosing the rotation angle can be done in several ways:
1. boot option fbcon=rotate:n, where
n = 0 - normal
n = 1 - 90 degrees (clockwise)
n = 2 - 180 degrees (upside down)
n = 3 - 270 degrees (counterclockwise)
2. echo n > /sys/class/graphics/fb[num]/con_rotate
where n is the same as described above. It sets the angle of rotation
of the current console
3 echo n > /sys/class/graphics/fb[num]/con_rotate_all
where n is the same as described above. Globally sets the angle of
rotation.
GOTCHAS:
The option, especially at angles of 90 and 270 degrees, will exercise
the least used code of drivers. Namely, at these angles, panning is done
in the x-axis, so it can reveal bugs in the driver if xpanstep is set
incorrectly. A workaround is to set xpanstep = 0.
Secondly, at these angles, the framebuffer memory access can be
unaligned if (fontheight * bpp) % 32 ~= 0 which can reveal bugs in the drivers
imageblit, fillrect and copyarea functions. (I think cfbfillrect may have
this buglet). A workaround is to use a standard 8x16 font.
Speed:
The scrolling speed difference between 0 and 180 degrees is minimal,
somewhere areound 1-2%. At 90 or 270 degress, speed drops down to a vicinity
of 30-40%. This is understandable because the blit direction is across the
framebuffer "direction." Scrolling will be helped at these angles if xpanstep
is not equal to zero, use of 8x16 fonts, and setting xres_virtual >= xres * 2.
Note: The code is tested on little-endian only, so I don't know if it will
work in big-endian. Please let me know, it will take only less than a minute
of your time.
This patch prepares fbcon for console rotation and contains the following
changes:
- add rotate field in struct fbcon_ops to keep fbcon's current rotation
angle
- add con_rotate field in struct display to store per-display rotation angle
- create a private copy of the current var to fbcon. This will prevent
fbcon from directly manipulating info->var, especially the fields xoffset,
yoffset and vmode.
- add ability to swap pertinent axes (xres, yres; xpanstep, ypanstep; etc)
depending on the rotation angle
- change global update_var() (function that sets the screen start address)
as an fbcon method update_start. This is required because the axes, start
offset, and/or direction can be reversed depending on the rotation angle.
- add fbcon method rotate_font() which will rotate each character bitmap to
the correct angle of rotation.
- add fbcon boot option 'rotate' to select the angle of rotation at bootime.
Currently does nothing until all patches are applied.
Signed-off-by: Antonino Daplas <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-11-09 05:39:09 +00:00
|
|
|
cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
|
|
|
|
rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
|
|
|
|
cols /= vc->vc_font.width;
|
|
|
|
rows /= vc->vc_font.height;
|
2005-04-16 22:20:36 +00:00
|
|
|
vc_resize(vc, cols, rows);
|
[PATCH] fbcon: Console Rotation - Prepare fbcon for console rotation
This patch series implements generic code to rotate the console at 90, 180,
and 270 degrees. The implementation is completely done in the framebuffer
console level, thus no changes to the framebuffer layer or to the drivers
are needed.
Console rotation is required by some Sharp-based devices where the natural
orientation of the display is not at 0 degrees. Also, users that have
displays that can pivot will benefit by having a console in portrait mode
if they so desire.
The choice to implement the code in the console layer rather than in the
framebuffer layer is due to the following reasons:
- it's fast
- it does not require driver changes
- it can coexist with devices that can rotate the display at the hardware level
- it complements graphics applications that can do display rotation
The changes to core fbcon are minimal-- recognition of the console
rotation angle so it can swap directions, origins and axes (xres vs yres,
xpanstep vs ypanstep, xoffset vs yoffset, etc) and storage of the rotation
angle per display. The bulk of the code that does the actual drawing to the
screen are placed in separate files. Each angle of rotation has separate
methods (bmove, clear, putcs, cursor, update_start which is derived from
update_var, and clear_margins). To mimimize processing time, the fontdata
are pre-rotated at each console switch (only if the font or the angle has
changed).
The option can be compiled out (CONFIG_FRAMEBUFFER_CONSOLE_ROTATION = n) if
rotation is not needed.
Choosing the rotation angle can be done in several ways:
1. boot option fbcon=rotate:n, where
n = 0 - normal
n = 1 - 90 degrees (clockwise)
n = 2 - 180 degrees (upside down)
n = 3 - 270 degrees (counterclockwise)
2. echo n > /sys/class/graphics/fb[num]/con_rotate
where n is the same as described above. It sets the angle of rotation
of the current console
3 echo n > /sys/class/graphics/fb[num]/con_rotate_all
where n is the same as described above. Globally sets the angle of
rotation.
GOTCHAS:
The option, especially at angles of 90 and 270 degrees, will exercise
the least used code of drivers. Namely, at these angles, panning is done
in the x-axis, so it can reveal bugs in the driver if xpanstep is set
incorrectly. A workaround is to set xpanstep = 0.
Secondly, at these angles, the framebuffer memory access can be
unaligned if (fontheight * bpp) % 32 ~= 0 which can reveal bugs in the drivers
imageblit, fillrect and copyarea functions. (I think cfbfillrect may have
this buglet). A workaround is to use a standard 8x16 font.
Speed:
The scrolling speed difference between 0 and 180 degrees is minimal,
somewhere areound 1-2%. At 90 or 270 degress, speed drops down to a vicinity
of 30-40%. This is understandable because the blit direction is across the
framebuffer "direction." Scrolling will be helped at these angles if xpanstep
is not equal to zero, use of 8x16 fonts, and setting xres_virtual >= xres * 2.
Note: The code is tested on little-endian only, so I don't know if it will
work in big-endian. Please let me know, it will take only less than a minute
of your time.
This patch prepares fbcon for console rotation and contains the following
changes:
- add rotate field in struct fbcon_ops to keep fbcon's current rotation
angle
- add con_rotate field in struct display to store per-display rotation angle
- create a private copy of the current var to fbcon. This will prevent
fbcon from directly manipulating info->var, especially the fields xoffset,
yoffset and vmode.
- add ability to swap pertinent axes (xres, yres; xpanstep, ypanstep; etc)
depending on the rotation angle
- change global update_var() (function that sets the screen start address)
as an fbcon method update_start. This is required because the axes, start
offset, and/or direction can be reversed depending on the rotation angle.
- add fbcon method rotate_font() which will rotate each character bitmap to
the correct angle of rotation.
- add fbcon boot option 'rotate' to select the angle of rotation at bootime.
Currently does nothing until all patches are applied.
Signed-off-by: Antonino Daplas <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-11-09 05:39:09 +00:00
|
|
|
|
2016-06-23 11:34:35 +00:00
|
|
|
if (con_is_visible(vc)) {
|
2005-04-16 22:20:36 +00:00
|
|
|
update_screen(vc);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Revert "fbdev: Garbage collect fbdev scrolling acceleration, part 1 (from TODO list)"
This reverts commit b3ec8cdf457e5e63d396fe1346cc788cf7c1b578.
Revert the second (of 2) commits which disabled scrolling acceleration
in fbcon/fbdev. It introduced a regression for fbdev-supported graphic
cards because of the performance penalty by doing screen scrolling by
software instead of using the existing graphic card 2D hardware
acceleration.
Console scrolling acceleration was disabled by dropping code which
checked at runtime the driver hardware capabilities for the
BINFO_HWACCEL_COPYAREA or FBINFO_HWACCEL_FILLRECT flags and if set, it
enabled scrollmode SCROLL_MOVE which uses hardware acceleration to move
screen contents. After dropping those checks scrollmode was hard-wired
to SCROLL_REDRAW instead, which forces all graphic cards to redraw every
character at the new screen position when scrolling.
This change effectively disabled all hardware-based scrolling acceleration for
ALL drivers, because now all kind of 2D hardware acceleration (bitblt,
fillrect) in the drivers isn't used any longer.
The original commit message mentions that only 3 DRM drivers (nouveau, omapdrm
and gma500) used hardware acceleration in the past and thus code for checking
and using scrolling acceleration is obsolete.
This statement is NOT TRUE, because beside the DRM drivers there are around 35
other fbdev drivers which depend on fbdev/fbcon and still provide hardware
acceleration for fbdev/fbcon.
The original commit message also states that syzbot found lots of bugs in fbcon
and thus it's "often the solution to just delete code and remove features".
This is true, and the bugs - which actually affected all users of fbcon,
including DRM - were fixed, or code was dropped like e.g. the support for
software scrollback in vgacon (commit 973c096f6a85).
So to further analyze which bugs were found by syzbot, I've looked through all
patches in drivers/video which were tagged with syzbot or syzkaller back to
year 2005. The vast majority fixed the reported issues on a higher level, e.g.
when screen is to be resized, or when font size is to be changed. The few ones
which touched driver code fixed a real driver bug, e.g. by adding a check.
But NONE of those patches touched code of either the SCROLL_MOVE or the
SCROLL_REDRAW case.
That means, there was no real reason why SCROLL_MOVE had to be ripped-out and
just SCROLL_REDRAW had to be used instead. The only reason I can imagine so far
was that SCROLL_MOVE wasn't used by DRM and as such it was assumed that it
could go away. That argument completely missed the fact that SCROLL_MOVE is
still heavily used by fbdev (non-DRM) drivers.
Some people mention that using memcpy() instead of the hardware acceleration is
pretty much the same speed. But that's not true, at least not for older graphic
cards and machines where we see speed decreases by factor 10 and more and thus
this change leads to console responsiveness way worse than before.
That's why the original commit is to be reverted. By reverting we
reintroduce hardware-based scrolling acceleration and fix the
performance regression for fbdev drivers.
There isn't any impact on DRM when reverting those patches.
Signed-off-by: Helge Deller <deller@gmx.de>
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
Acked-by: Sven Schnelle <svens@stackframe.org>
Cc: stable@vger.kernel.org # v5.16+
Signed-off-by: Helge Deller <deller@gmx.de>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/20220202135531.92183-2-deller@gmx.de
2022-02-02 13:55:29 +00:00
|
|
|
static __inline__ void ywrap_up(struct vc_data *vc, int count)
|
|
|
|
{
|
2022-04-05 21:03:21 +00:00
|
|
|
struct fb_info *info = fbcon_info_from_console(vc->vc_num);
|
Revert "fbdev: Garbage collect fbdev scrolling acceleration, part 1 (from TODO list)"
This reverts commit b3ec8cdf457e5e63d396fe1346cc788cf7c1b578.
Revert the second (of 2) commits which disabled scrolling acceleration
in fbcon/fbdev. It introduced a regression for fbdev-supported graphic
cards because of the performance penalty by doing screen scrolling by
software instead of using the existing graphic card 2D hardware
acceleration.
Console scrolling acceleration was disabled by dropping code which
checked at runtime the driver hardware capabilities for the
BINFO_HWACCEL_COPYAREA or FBINFO_HWACCEL_FILLRECT flags and if set, it
enabled scrollmode SCROLL_MOVE which uses hardware acceleration to move
screen contents. After dropping those checks scrollmode was hard-wired
to SCROLL_REDRAW instead, which forces all graphic cards to redraw every
character at the new screen position when scrolling.
This change effectively disabled all hardware-based scrolling acceleration for
ALL drivers, because now all kind of 2D hardware acceleration (bitblt,
fillrect) in the drivers isn't used any longer.
The original commit message mentions that only 3 DRM drivers (nouveau, omapdrm
and gma500) used hardware acceleration in the past and thus code for checking
and using scrolling acceleration is obsolete.
This statement is NOT TRUE, because beside the DRM drivers there are around 35
other fbdev drivers which depend on fbdev/fbcon and still provide hardware
acceleration for fbdev/fbcon.
The original commit message also states that syzbot found lots of bugs in fbcon
and thus it's "often the solution to just delete code and remove features".
This is true, and the bugs - which actually affected all users of fbcon,
including DRM - were fixed, or code was dropped like e.g. the support for
software scrollback in vgacon (commit 973c096f6a85).
So to further analyze which bugs were found by syzbot, I've looked through all
patches in drivers/video which were tagged with syzbot or syzkaller back to
year 2005. The vast majority fixed the reported issues on a higher level, e.g.
when screen is to be resized, or when font size is to be changed. The few ones
which touched driver code fixed a real driver bug, e.g. by adding a check.
But NONE of those patches touched code of either the SCROLL_MOVE or the
SCROLL_REDRAW case.
That means, there was no real reason why SCROLL_MOVE had to be ripped-out and
just SCROLL_REDRAW had to be used instead. The only reason I can imagine so far
was that SCROLL_MOVE wasn't used by DRM and as such it was assumed that it
could go away. That argument completely missed the fact that SCROLL_MOVE is
still heavily used by fbdev (non-DRM) drivers.
Some people mention that using memcpy() instead of the hardware acceleration is
pretty much the same speed. But that's not true, at least not for older graphic
cards and machines where we see speed decreases by factor 10 and more and thus
this change leads to console responsiveness way worse than before.
That's why the original commit is to be reverted. By reverting we
reintroduce hardware-based scrolling acceleration and fix the
performance regression for fbdev drivers.
There isn't any impact on DRM when reverting those patches.
Signed-off-by: Helge Deller <deller@gmx.de>
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
Acked-by: Sven Schnelle <svens@stackframe.org>
Cc: stable@vger.kernel.org # v5.16+
Signed-off-by: Helge Deller <deller@gmx.de>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/20220202135531.92183-2-deller@gmx.de
2022-02-02 13:55:29 +00:00
|
|
|
struct fbcon_ops *ops = info->fbcon_par;
|
|
|
|
struct fbcon_display *p = &fb_display[vc->vc_num];
|
|
|
|
|
|
|
|
p->yscroll += count;
|
|
|
|
if (p->yscroll >= p->vrows) /* Deal with wrap */
|
|
|
|
p->yscroll -= p->vrows;
|
|
|
|
ops->var.xoffset = 0;
|
|
|
|
ops->var.yoffset = p->yscroll * vc->vc_font.height;
|
|
|
|
ops->var.vmode |= FB_VMODE_YWRAP;
|
|
|
|
ops->update_start(info);
|
|
|
|
scrollback_max += count;
|
|
|
|
if (scrollback_max > scrollback_phys_max)
|
|
|
|
scrollback_max = scrollback_phys_max;
|
|
|
|
scrollback_current = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static __inline__ void ywrap_down(struct vc_data *vc, int count)
|
|
|
|
{
|
2022-04-05 21:03:21 +00:00
|
|
|
struct fb_info *info = fbcon_info_from_console(vc->vc_num);
|
Revert "fbdev: Garbage collect fbdev scrolling acceleration, part 1 (from TODO list)"
This reverts commit b3ec8cdf457e5e63d396fe1346cc788cf7c1b578.
Revert the second (of 2) commits which disabled scrolling acceleration
in fbcon/fbdev. It introduced a regression for fbdev-supported graphic
cards because of the performance penalty by doing screen scrolling by
software instead of using the existing graphic card 2D hardware
acceleration.
Console scrolling acceleration was disabled by dropping code which
checked at runtime the driver hardware capabilities for the
BINFO_HWACCEL_COPYAREA or FBINFO_HWACCEL_FILLRECT flags and if set, it
enabled scrollmode SCROLL_MOVE which uses hardware acceleration to move
screen contents. After dropping those checks scrollmode was hard-wired
to SCROLL_REDRAW instead, which forces all graphic cards to redraw every
character at the new screen position when scrolling.
This change effectively disabled all hardware-based scrolling acceleration for
ALL drivers, because now all kind of 2D hardware acceleration (bitblt,
fillrect) in the drivers isn't used any longer.
The original commit message mentions that only 3 DRM drivers (nouveau, omapdrm
and gma500) used hardware acceleration in the past and thus code for checking
and using scrolling acceleration is obsolete.
This statement is NOT TRUE, because beside the DRM drivers there are around 35
other fbdev drivers which depend on fbdev/fbcon and still provide hardware
acceleration for fbdev/fbcon.
The original commit message also states that syzbot found lots of bugs in fbcon
and thus it's "often the solution to just delete code and remove features".
This is true, and the bugs - which actually affected all users of fbcon,
including DRM - were fixed, or code was dropped like e.g. the support for
software scrollback in vgacon (commit 973c096f6a85).
So to further analyze which bugs were found by syzbot, I've looked through all
patches in drivers/video which were tagged with syzbot or syzkaller back to
year 2005. The vast majority fixed the reported issues on a higher level, e.g.
when screen is to be resized, or when font size is to be changed. The few ones
which touched driver code fixed a real driver bug, e.g. by adding a check.
But NONE of those patches touched code of either the SCROLL_MOVE or the
SCROLL_REDRAW case.
That means, there was no real reason why SCROLL_MOVE had to be ripped-out and
just SCROLL_REDRAW had to be used instead. The only reason I can imagine so far
was that SCROLL_MOVE wasn't used by DRM and as such it was assumed that it
could go away. That argument completely missed the fact that SCROLL_MOVE is
still heavily used by fbdev (non-DRM) drivers.
Some people mention that using memcpy() instead of the hardware acceleration is
pretty much the same speed. But that's not true, at least not for older graphic
cards and machines where we see speed decreases by factor 10 and more and thus
this change leads to console responsiveness way worse than before.
That's why the original commit is to be reverted. By reverting we
reintroduce hardware-based scrolling acceleration and fix the
performance regression for fbdev drivers.
There isn't any impact on DRM when reverting those patches.
Signed-off-by: Helge Deller <deller@gmx.de>
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
Acked-by: Sven Schnelle <svens@stackframe.org>
Cc: stable@vger.kernel.org # v5.16+
Signed-off-by: Helge Deller <deller@gmx.de>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/20220202135531.92183-2-deller@gmx.de
2022-02-02 13:55:29 +00:00
|
|
|
struct fbcon_ops *ops = info->fbcon_par;
|
|
|
|
struct fbcon_display *p = &fb_display[vc->vc_num];
|
|
|
|
|
|
|
|
p->yscroll -= count;
|
|
|
|
if (p->yscroll < 0) /* Deal with wrap */
|
|
|
|
p->yscroll += p->vrows;
|
|
|
|
ops->var.xoffset = 0;
|
|
|
|
ops->var.yoffset = p->yscroll * vc->vc_font.height;
|
|
|
|
ops->var.vmode |= FB_VMODE_YWRAP;
|
|
|
|
ops->update_start(info);
|
|
|
|
scrollback_max -= count;
|
|
|
|
if (scrollback_max < 0)
|
|
|
|
scrollback_max = 0;
|
|
|
|
scrollback_current = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static __inline__ void ypan_up(struct vc_data *vc, int count)
|
|
|
|
{
|
2022-04-05 21:03:21 +00:00
|
|
|
struct fb_info *info = fbcon_info_from_console(vc->vc_num);
|
Revert "fbdev: Garbage collect fbdev scrolling acceleration, part 1 (from TODO list)"
This reverts commit b3ec8cdf457e5e63d396fe1346cc788cf7c1b578.
Revert the second (of 2) commits which disabled scrolling acceleration
in fbcon/fbdev. It introduced a regression for fbdev-supported graphic
cards because of the performance penalty by doing screen scrolling by
software instead of using the existing graphic card 2D hardware
acceleration.
Console scrolling acceleration was disabled by dropping code which
checked at runtime the driver hardware capabilities for the
BINFO_HWACCEL_COPYAREA or FBINFO_HWACCEL_FILLRECT flags and if set, it
enabled scrollmode SCROLL_MOVE which uses hardware acceleration to move
screen contents. After dropping those checks scrollmode was hard-wired
to SCROLL_REDRAW instead, which forces all graphic cards to redraw every
character at the new screen position when scrolling.
This change effectively disabled all hardware-based scrolling acceleration for
ALL drivers, because now all kind of 2D hardware acceleration (bitblt,
fillrect) in the drivers isn't used any longer.
The original commit message mentions that only 3 DRM drivers (nouveau, omapdrm
and gma500) used hardware acceleration in the past and thus code for checking
and using scrolling acceleration is obsolete.
This statement is NOT TRUE, because beside the DRM drivers there are around 35
other fbdev drivers which depend on fbdev/fbcon and still provide hardware
acceleration for fbdev/fbcon.
The original commit message also states that syzbot found lots of bugs in fbcon
and thus it's "often the solution to just delete code and remove features".
This is true, and the bugs - which actually affected all users of fbcon,
including DRM - were fixed, or code was dropped like e.g. the support for
software scrollback in vgacon (commit 973c096f6a85).
So to further analyze which bugs were found by syzbot, I've looked through all
patches in drivers/video which were tagged with syzbot or syzkaller back to
year 2005. The vast majority fixed the reported issues on a higher level, e.g.
when screen is to be resized, or when font size is to be changed. The few ones
which touched driver code fixed a real driver bug, e.g. by adding a check.
But NONE of those patches touched code of either the SCROLL_MOVE or the
SCROLL_REDRAW case.
That means, there was no real reason why SCROLL_MOVE had to be ripped-out and
just SCROLL_REDRAW had to be used instead. The only reason I can imagine so far
was that SCROLL_MOVE wasn't used by DRM and as such it was assumed that it
could go away. That argument completely missed the fact that SCROLL_MOVE is
still heavily used by fbdev (non-DRM) drivers.
Some people mention that using memcpy() instead of the hardware acceleration is
pretty much the same speed. But that's not true, at least not for older graphic
cards and machines where we see speed decreases by factor 10 and more and thus
this change leads to console responsiveness way worse than before.
That's why the original commit is to be reverted. By reverting we
reintroduce hardware-based scrolling acceleration and fix the
performance regression for fbdev drivers.
There isn't any impact on DRM when reverting those patches.
Signed-off-by: Helge Deller <deller@gmx.de>
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
Acked-by: Sven Schnelle <svens@stackframe.org>
Cc: stable@vger.kernel.org # v5.16+
Signed-off-by: Helge Deller <deller@gmx.de>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/20220202135531.92183-2-deller@gmx.de
2022-02-02 13:55:29 +00:00
|
|
|
struct fbcon_display *p = &fb_display[vc->vc_num];
|
|
|
|
struct fbcon_ops *ops = info->fbcon_par;
|
|
|
|
|
|
|
|
p->yscroll += count;
|
|
|
|
if (p->yscroll > p->vrows - vc->vc_rows) {
|
|
|
|
ops->bmove(vc, info, p->vrows - vc->vc_rows,
|
|
|
|
0, 0, 0, vc->vc_rows, vc->vc_cols);
|
|
|
|
p->yscroll -= p->vrows - vc->vc_rows;
|
|
|
|
}
|
|
|
|
|
|
|
|
ops->var.xoffset = 0;
|
|
|
|
ops->var.yoffset = p->yscroll * vc->vc_font.height;
|
|
|
|
ops->var.vmode &= ~FB_VMODE_YWRAP;
|
|
|
|
ops->update_start(info);
|
|
|
|
fbcon_clear_margins(vc, 1);
|
|
|
|
scrollback_max += count;
|
|
|
|
if (scrollback_max > scrollback_phys_max)
|
|
|
|
scrollback_max = scrollback_phys_max;
|
|
|
|
scrollback_current = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static __inline__ void ypan_up_redraw(struct vc_data *vc, int t, int count)
|
|
|
|
{
|
2022-04-05 21:03:21 +00:00
|
|
|
struct fb_info *info = fbcon_info_from_console(vc->vc_num);
|
Revert "fbdev: Garbage collect fbdev scrolling acceleration, part 1 (from TODO list)"
This reverts commit b3ec8cdf457e5e63d396fe1346cc788cf7c1b578.
Revert the second (of 2) commits which disabled scrolling acceleration
in fbcon/fbdev. It introduced a regression for fbdev-supported graphic
cards because of the performance penalty by doing screen scrolling by
software instead of using the existing graphic card 2D hardware
acceleration.
Console scrolling acceleration was disabled by dropping code which
checked at runtime the driver hardware capabilities for the
BINFO_HWACCEL_COPYAREA or FBINFO_HWACCEL_FILLRECT flags and if set, it
enabled scrollmode SCROLL_MOVE which uses hardware acceleration to move
screen contents. After dropping those checks scrollmode was hard-wired
to SCROLL_REDRAW instead, which forces all graphic cards to redraw every
character at the new screen position when scrolling.
This change effectively disabled all hardware-based scrolling acceleration for
ALL drivers, because now all kind of 2D hardware acceleration (bitblt,
fillrect) in the drivers isn't used any longer.
The original commit message mentions that only 3 DRM drivers (nouveau, omapdrm
and gma500) used hardware acceleration in the past and thus code for checking
and using scrolling acceleration is obsolete.
This statement is NOT TRUE, because beside the DRM drivers there are around 35
other fbdev drivers which depend on fbdev/fbcon and still provide hardware
acceleration for fbdev/fbcon.
The original commit message also states that syzbot found lots of bugs in fbcon
and thus it's "often the solution to just delete code and remove features".
This is true, and the bugs - which actually affected all users of fbcon,
including DRM - were fixed, or code was dropped like e.g. the support for
software scrollback in vgacon (commit 973c096f6a85).
So to further analyze which bugs were found by syzbot, I've looked through all
patches in drivers/video which were tagged with syzbot or syzkaller back to
year 2005. The vast majority fixed the reported issues on a higher level, e.g.
when screen is to be resized, or when font size is to be changed. The few ones
which touched driver code fixed a real driver bug, e.g. by adding a check.
But NONE of those patches touched code of either the SCROLL_MOVE or the
SCROLL_REDRAW case.
That means, there was no real reason why SCROLL_MOVE had to be ripped-out and
just SCROLL_REDRAW had to be used instead. The only reason I can imagine so far
was that SCROLL_MOVE wasn't used by DRM and as such it was assumed that it
could go away. That argument completely missed the fact that SCROLL_MOVE is
still heavily used by fbdev (non-DRM) drivers.
Some people mention that using memcpy() instead of the hardware acceleration is
pretty much the same speed. But that's not true, at least not for older graphic
cards and machines where we see speed decreases by factor 10 and more and thus
this change leads to console responsiveness way worse than before.
That's why the original commit is to be reverted. By reverting we
reintroduce hardware-based scrolling acceleration and fix the
performance regression for fbdev drivers.
There isn't any impact on DRM when reverting those patches.
Signed-off-by: Helge Deller <deller@gmx.de>
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
Acked-by: Sven Schnelle <svens@stackframe.org>
Cc: stable@vger.kernel.org # v5.16+
Signed-off-by: Helge Deller <deller@gmx.de>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/20220202135531.92183-2-deller@gmx.de
2022-02-02 13:55:29 +00:00
|
|
|
struct fbcon_ops *ops = info->fbcon_par;
|
|
|
|
struct fbcon_display *p = &fb_display[vc->vc_num];
|
|
|
|
|
|
|
|
p->yscroll += count;
|
|
|
|
|
|
|
|
if (p->yscroll > p->vrows - vc->vc_rows) {
|
|
|
|
p->yscroll -= p->vrows - vc->vc_rows;
|
|
|
|
fbcon_redraw_move(vc, p, t + count, vc->vc_rows - count, t);
|
|
|
|
}
|
|
|
|
|
|
|
|
ops->var.xoffset = 0;
|
|
|
|
ops->var.yoffset = p->yscroll * vc->vc_font.height;
|
|
|
|
ops->var.vmode &= ~FB_VMODE_YWRAP;
|
|
|
|
ops->update_start(info);
|
|
|
|
fbcon_clear_margins(vc, 1);
|
|
|
|
scrollback_max += count;
|
|
|
|
if (scrollback_max > scrollback_phys_max)
|
|
|
|
scrollback_max = scrollback_phys_max;
|
|
|
|
scrollback_current = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static __inline__ void ypan_down(struct vc_data *vc, int count)
|
|
|
|
{
|
2022-04-05 21:03:21 +00:00
|
|
|
struct fb_info *info = fbcon_info_from_console(vc->vc_num);
|
Revert "fbdev: Garbage collect fbdev scrolling acceleration, part 1 (from TODO list)"
This reverts commit b3ec8cdf457e5e63d396fe1346cc788cf7c1b578.
Revert the second (of 2) commits which disabled scrolling acceleration
in fbcon/fbdev. It introduced a regression for fbdev-supported graphic
cards because of the performance penalty by doing screen scrolling by
software instead of using the existing graphic card 2D hardware
acceleration.
Console scrolling acceleration was disabled by dropping code which
checked at runtime the driver hardware capabilities for the
BINFO_HWACCEL_COPYAREA or FBINFO_HWACCEL_FILLRECT flags and if set, it
enabled scrollmode SCROLL_MOVE which uses hardware acceleration to move
screen contents. After dropping those checks scrollmode was hard-wired
to SCROLL_REDRAW instead, which forces all graphic cards to redraw every
character at the new screen position when scrolling.
This change effectively disabled all hardware-based scrolling acceleration for
ALL drivers, because now all kind of 2D hardware acceleration (bitblt,
fillrect) in the drivers isn't used any longer.
The original commit message mentions that only 3 DRM drivers (nouveau, omapdrm
and gma500) used hardware acceleration in the past and thus code for checking
and using scrolling acceleration is obsolete.
This statement is NOT TRUE, because beside the DRM drivers there are around 35
other fbdev drivers which depend on fbdev/fbcon and still provide hardware
acceleration for fbdev/fbcon.
The original commit message also states that syzbot found lots of bugs in fbcon
and thus it's "often the solution to just delete code and remove features".
This is true, and the bugs - which actually affected all users of fbcon,
including DRM - were fixed, or code was dropped like e.g. the support for
software scrollback in vgacon (commit 973c096f6a85).
So to further analyze which bugs were found by syzbot, I've looked through all
patches in drivers/video which were tagged with syzbot or syzkaller back to
year 2005. The vast majority fixed the reported issues on a higher level, e.g.
when screen is to be resized, or when font size is to be changed. The few ones
which touched driver code fixed a real driver bug, e.g. by adding a check.
But NONE of those patches touched code of either the SCROLL_MOVE or the
SCROLL_REDRAW case.
That means, there was no real reason why SCROLL_MOVE had to be ripped-out and
just SCROLL_REDRAW had to be used instead. The only reason I can imagine so far
was that SCROLL_MOVE wasn't used by DRM and as such it was assumed that it
could go away. That argument completely missed the fact that SCROLL_MOVE is
still heavily used by fbdev (non-DRM) drivers.
Some people mention that using memcpy() instead of the hardware acceleration is
pretty much the same speed. But that's not true, at least not for older graphic
cards and machines where we see speed decreases by factor 10 and more and thus
this change leads to console responsiveness way worse than before.
That's why the original commit is to be reverted. By reverting we
reintroduce hardware-based scrolling acceleration and fix the
performance regression for fbdev drivers.
There isn't any impact on DRM when reverting those patches.
Signed-off-by: Helge Deller <deller@gmx.de>
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
Acked-by: Sven Schnelle <svens@stackframe.org>
Cc: stable@vger.kernel.org # v5.16+
Signed-off-by: Helge Deller <deller@gmx.de>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/20220202135531.92183-2-deller@gmx.de
2022-02-02 13:55:29 +00:00
|
|
|
struct fbcon_display *p = &fb_display[vc->vc_num];
|
|
|
|
struct fbcon_ops *ops = info->fbcon_par;
|
|
|
|
|
|
|
|
p->yscroll -= count;
|
|
|
|
if (p->yscroll < 0) {
|
|
|
|
ops->bmove(vc, info, 0, 0, p->vrows - vc->vc_rows,
|
|
|
|
0, vc->vc_rows, vc->vc_cols);
|
|
|
|
p->yscroll += p->vrows - vc->vc_rows;
|
|
|
|
}
|
|
|
|
|
|
|
|
ops->var.xoffset = 0;
|
|
|
|
ops->var.yoffset = p->yscroll * vc->vc_font.height;
|
|
|
|
ops->var.vmode &= ~FB_VMODE_YWRAP;
|
|
|
|
ops->update_start(info);
|
|
|
|
fbcon_clear_margins(vc, 1);
|
|
|
|
scrollback_max -= count;
|
|
|
|
if (scrollback_max < 0)
|
|
|
|
scrollback_max = 0;
|
|
|
|
scrollback_current = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static __inline__ void ypan_down_redraw(struct vc_data *vc, int t, int count)
|
|
|
|
{
|
2022-04-05 21:03:21 +00:00
|
|
|
struct fb_info *info = fbcon_info_from_console(vc->vc_num);
|
Revert "fbdev: Garbage collect fbdev scrolling acceleration, part 1 (from TODO list)"
This reverts commit b3ec8cdf457e5e63d396fe1346cc788cf7c1b578.
Revert the second (of 2) commits which disabled scrolling acceleration
in fbcon/fbdev. It introduced a regression for fbdev-supported graphic
cards because of the performance penalty by doing screen scrolling by
software instead of using the existing graphic card 2D hardware
acceleration.
Console scrolling acceleration was disabled by dropping code which
checked at runtime the driver hardware capabilities for the
BINFO_HWACCEL_COPYAREA or FBINFO_HWACCEL_FILLRECT flags and if set, it
enabled scrollmode SCROLL_MOVE which uses hardware acceleration to move
screen contents. After dropping those checks scrollmode was hard-wired
to SCROLL_REDRAW instead, which forces all graphic cards to redraw every
character at the new screen position when scrolling.
This change effectively disabled all hardware-based scrolling acceleration for
ALL drivers, because now all kind of 2D hardware acceleration (bitblt,
fillrect) in the drivers isn't used any longer.
The original commit message mentions that only 3 DRM drivers (nouveau, omapdrm
and gma500) used hardware acceleration in the past and thus code for checking
and using scrolling acceleration is obsolete.
This statement is NOT TRUE, because beside the DRM drivers there are around 35
other fbdev drivers which depend on fbdev/fbcon and still provide hardware
acceleration for fbdev/fbcon.
The original commit message also states that syzbot found lots of bugs in fbcon
and thus it's "often the solution to just delete code and remove features".
This is true, and the bugs - which actually affected all users of fbcon,
including DRM - were fixed, or code was dropped like e.g. the support for
software scrollback in vgacon (commit 973c096f6a85).
So to further analyze which bugs were found by syzbot, I've looked through all
patches in drivers/video which were tagged with syzbot or syzkaller back to
year 2005. The vast majority fixed the reported issues on a higher level, e.g.
when screen is to be resized, or when font size is to be changed. The few ones
which touched driver code fixed a real driver bug, e.g. by adding a check.
But NONE of those patches touched code of either the SCROLL_MOVE or the
SCROLL_REDRAW case.
That means, there was no real reason why SCROLL_MOVE had to be ripped-out and
just SCROLL_REDRAW had to be used instead. The only reason I can imagine so far
was that SCROLL_MOVE wasn't used by DRM and as such it was assumed that it
could go away. That argument completely missed the fact that SCROLL_MOVE is
still heavily used by fbdev (non-DRM) drivers.
Some people mention that using memcpy() instead of the hardware acceleration is
pretty much the same speed. But that's not true, at least not for older graphic
cards and machines where we see speed decreases by factor 10 and more and thus
this change leads to console responsiveness way worse than before.
That's why the original commit is to be reverted. By reverting we
reintroduce hardware-based scrolling acceleration and fix the
performance regression for fbdev drivers.
There isn't any impact on DRM when reverting those patches.
Signed-off-by: Helge Deller <deller@gmx.de>
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
Acked-by: Sven Schnelle <svens@stackframe.org>
Cc: stable@vger.kernel.org # v5.16+
Signed-off-by: Helge Deller <deller@gmx.de>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/20220202135531.92183-2-deller@gmx.de
2022-02-02 13:55:29 +00:00
|
|
|
struct fbcon_ops *ops = info->fbcon_par;
|
|
|
|
struct fbcon_display *p = &fb_display[vc->vc_num];
|
|
|
|
|
|
|
|
p->yscroll -= count;
|
|
|
|
|
|
|
|
if (p->yscroll < 0) {
|
|
|
|
p->yscroll += p->vrows - vc->vc_rows;
|
|
|
|
fbcon_redraw_move(vc, p, t, vc->vc_rows - count, t + count);
|
|
|
|
}
|
|
|
|
|
|
|
|
ops->var.xoffset = 0;
|
|
|
|
ops->var.yoffset = p->yscroll * vc->vc_font.height;
|
|
|
|
ops->var.vmode &= ~FB_VMODE_YWRAP;
|
|
|
|
ops->update_start(info);
|
|
|
|
fbcon_clear_margins(vc, 1);
|
|
|
|
scrollback_max -= count;
|
|
|
|
if (scrollback_max < 0)
|
|
|
|
scrollback_max = 0;
|
|
|
|
scrollback_current = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void fbcon_redraw_move(struct vc_data *vc, struct fbcon_display *p,
|
|
|
|
int line, int count, int dy)
|
|
|
|
{
|
|
|
|
unsigned short *s = (unsigned short *)
|
|
|
|
(vc->vc_origin + vc->vc_size_row * line);
|
|
|
|
|
|
|
|
while (count--) {
|
|
|
|
unsigned short *start = s;
|
|
|
|
unsigned short *le = advance_row(s, 1);
|
|
|
|
unsigned short c;
|
|
|
|
int x = 0;
|
|
|
|
unsigned short attr = 1;
|
|
|
|
|
|
|
|
do {
|
|
|
|
c = scr_readw(s);
|
|
|
|
if (attr != (c & 0xff00)) {
|
|
|
|
attr = c & 0xff00;
|
|
|
|
if (s > start) {
|
|
|
|
fbcon_putcs(vc, start, s - start,
|
|
|
|
dy, x);
|
|
|
|
x += s - start;
|
|
|
|
start = s;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
console_conditional_schedule();
|
|
|
|
s++;
|
|
|
|
} while (s < le);
|
|
|
|
if (s > start)
|
|
|
|
fbcon_putcs(vc, start, s - start, dy, x);
|
|
|
|
console_conditional_schedule();
|
|
|
|
dy++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void fbcon_redraw_blit(struct vc_data *vc, struct fb_info *info,
|
|
|
|
struct fbcon_display *p, int line, int count, int ycount)
|
|
|
|
{
|
|
|
|
int offset = ycount * vc->vc_cols;
|
|
|
|
unsigned short *d = (unsigned short *)
|
|
|
|
(vc->vc_origin + vc->vc_size_row * line);
|
|
|
|
unsigned short *s = d + offset;
|
|
|
|
struct fbcon_ops *ops = info->fbcon_par;
|
|
|
|
|
|
|
|
while (count--) {
|
|
|
|
unsigned short *start = s;
|
|
|
|
unsigned short *le = advance_row(s, 1);
|
|
|
|
unsigned short c;
|
|
|
|
int x = 0;
|
|
|
|
|
|
|
|
do {
|
|
|
|
c = scr_readw(s);
|
|
|
|
|
|
|
|
if (c == scr_readw(d)) {
|
|
|
|
if (s > start) {
|
|
|
|
ops->bmove(vc, info, line + ycount, x,
|
|
|
|
line, x, 1, s-start);
|
|
|
|
x += s - start + 1;
|
|
|
|
start = s + 1;
|
|
|
|
} else {
|
|
|
|
x++;
|
|
|
|
start++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
scr_writew(c, d);
|
|
|
|
console_conditional_schedule();
|
|
|
|
s++;
|
|
|
|
d++;
|
|
|
|
} while (s < le);
|
|
|
|
if (s > start)
|
|
|
|
ops->bmove(vc, info, line + ycount, x, line, x, 1,
|
|
|
|
s-start);
|
|
|
|
console_conditional_schedule();
|
|
|
|
if (ycount > 0)
|
|
|
|
line++;
|
|
|
|
else {
|
|
|
|
line--;
|
|
|
|
/* NOTE: We subtract two lines from these pointers */
|
|
|
|
s -= vc->vc_size_row;
|
|
|
|
d -= vc->vc_size_row;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-28 09:02:39 +00:00
|
|
|
static void fbcon_redraw(struct vc_data *vc, struct fbcon_display *p,
|
2005-04-16 22:20:36 +00:00
|
|
|
int line, int count, int offset)
|
|
|
|
{
|
|
|
|
unsigned short *d = (unsigned short *)
|
|
|
|
(vc->vc_origin + vc->vc_size_row * line);
|
|
|
|
unsigned short *s = d + offset;
|
|
|
|
|
|
|
|
while (count--) {
|
|
|
|
unsigned short *start = s;
|
|
|
|
unsigned short *le = advance_row(s, 1);
|
|
|
|
unsigned short c;
|
|
|
|
int x = 0;
|
|
|
|
unsigned short attr = 1;
|
|
|
|
|
|
|
|
do {
|
|
|
|
c = scr_readw(s);
|
|
|
|
if (attr != (c & 0xff00)) {
|
|
|
|
attr = c & 0xff00;
|
|
|
|
if (s > start) {
|
|
|
|
fbcon_putcs(vc, start, s - start,
|
|
|
|
line, x);
|
|
|
|
x += s - start;
|
|
|
|
start = s;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (c == scr_readw(d)) {
|
|
|
|
if (s > start) {
|
|
|
|
fbcon_putcs(vc, start, s - start,
|
|
|
|
line, x);
|
|
|
|
x += s - start + 1;
|
|
|
|
start = s + 1;
|
|
|
|
} else {
|
|
|
|
x++;
|
|
|
|
start++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
scr_writew(c, d);
|
|
|
|
console_conditional_schedule();
|
|
|
|
s++;
|
|
|
|
d++;
|
|
|
|
} while (s < le);
|
|
|
|
if (s > start)
|
|
|
|
fbcon_putcs(vc, start, s - start, line, x);
|
|
|
|
console_conditional_schedule();
|
|
|
|
if (offset > 0)
|
|
|
|
line++;
|
|
|
|
else {
|
|
|
|
line--;
|
|
|
|
/* NOTE: We subtract two lines from these pointers */
|
|
|
|
s -= vc->vc_size_row;
|
|
|
|
d -= vc->vc_size_row;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-05 21:03:20 +00:00
|
|
|
static void fbcon_bmove_rec(struct vc_data *vc, struct fbcon_display *p, int sy, int sx,
|
|
|
|
int dy, int dx, int height, int width, u_int y_break)
|
|
|
|
{
|
2022-04-05 21:03:21 +00:00
|
|
|
struct fb_info *info = fbcon_info_from_console(vc->vc_num);
|
2022-04-05 21:03:20 +00:00
|
|
|
struct fbcon_ops *ops = info->fbcon_par;
|
|
|
|
u_int b;
|
|
|
|
|
|
|
|
if (sy < y_break && sy + height > y_break) {
|
|
|
|
b = y_break - sy;
|
|
|
|
if (dy < sy) { /* Avoid trashing self */
|
|
|
|
fbcon_bmove_rec(vc, p, sy, sx, dy, dx, b, width,
|
|
|
|
y_break);
|
|
|
|
fbcon_bmove_rec(vc, p, sy + b, sx, dy + b, dx,
|
|
|
|
height - b, width, y_break);
|
|
|
|
} else {
|
|
|
|
fbcon_bmove_rec(vc, p, sy + b, sx, dy + b, dx,
|
|
|
|
height - b, width, y_break);
|
|
|
|
fbcon_bmove_rec(vc, p, sy, sx, dy, dx, b, width,
|
|
|
|
y_break);
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (dy < y_break && dy + height > y_break) {
|
|
|
|
b = y_break - dy;
|
|
|
|
if (dy < sy) { /* Avoid trashing self */
|
|
|
|
fbcon_bmove_rec(vc, p, sy, sx, dy, dx, b, width,
|
|
|
|
y_break);
|
|
|
|
fbcon_bmove_rec(vc, p, sy + b, sx, dy + b, dx,
|
|
|
|
height - b, width, y_break);
|
|
|
|
} else {
|
|
|
|
fbcon_bmove_rec(vc, p, sy + b, sx, dy + b, dx,
|
|
|
|
height - b, width, y_break);
|
|
|
|
fbcon_bmove_rec(vc, p, sy, sx, dy, dx, b, width,
|
|
|
|
y_break);
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
ops->bmove(vc, info, real_y(p, sy), sx, real_y(p, dy), dx,
|
|
|
|
height, width);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void fbcon_bmove(struct vc_data *vc, int sy, int sx, int dy, int dx,
|
|
|
|
int height, int width)
|
|
|
|
{
|
2022-04-05 21:03:21 +00:00
|
|
|
struct fb_info *info = fbcon_info_from_console(vc->vc_num);
|
2022-04-05 21:03:20 +00:00
|
|
|
struct fbcon_display *p = &fb_display[vc->vc_num];
|
|
|
|
|
|
|
|
if (fbcon_is_inactive(vc, info))
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (!width || !height)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* Split blits that cross physical y_wrap case.
|
|
|
|
* Pathological case involves 4 blits, better to use recursive
|
|
|
|
* code rather than unrolled case
|
|
|
|
*
|
|
|
|
* Recursive invocations don't need to erase the cursor over and
|
|
|
|
* over again, so we use fbcon_bmove_rec()
|
|
|
|
*/
|
|
|
|
fbcon_bmove_rec(vc, p, sy, sx, dy, dx, height, width,
|
|
|
|
p->vrows - p->yscroll);
|
|
|
|
}
|
|
|
|
|
2016-10-03 09:18:33 +00:00
|
|
|
static bool fbcon_scroll(struct vc_data *vc, unsigned int t, unsigned int b,
|
|
|
|
enum con_scroll dir, unsigned int count)
|
2005-04-16 22:20:36 +00:00
|
|
|
{
|
2022-04-05 21:03:21 +00:00
|
|
|
struct fb_info *info = fbcon_info_from_console(vc->vc_num);
|
2019-05-28 09:02:39 +00:00
|
|
|
struct fbcon_display *p = &fb_display[vc->vc_num];
|
Revert "fbdev: Garbage collect fbdev scrolling acceleration, part 1 (from TODO list)"
This reverts commit b3ec8cdf457e5e63d396fe1346cc788cf7c1b578.
Revert the second (of 2) commits which disabled scrolling acceleration
in fbcon/fbdev. It introduced a regression for fbdev-supported graphic
cards because of the performance penalty by doing screen scrolling by
software instead of using the existing graphic card 2D hardware
acceleration.
Console scrolling acceleration was disabled by dropping code which
checked at runtime the driver hardware capabilities for the
BINFO_HWACCEL_COPYAREA or FBINFO_HWACCEL_FILLRECT flags and if set, it
enabled scrollmode SCROLL_MOVE which uses hardware acceleration to move
screen contents. After dropping those checks scrollmode was hard-wired
to SCROLL_REDRAW instead, which forces all graphic cards to redraw every
character at the new screen position when scrolling.
This change effectively disabled all hardware-based scrolling acceleration for
ALL drivers, because now all kind of 2D hardware acceleration (bitblt,
fillrect) in the drivers isn't used any longer.
The original commit message mentions that only 3 DRM drivers (nouveau, omapdrm
and gma500) used hardware acceleration in the past and thus code for checking
and using scrolling acceleration is obsolete.
This statement is NOT TRUE, because beside the DRM drivers there are around 35
other fbdev drivers which depend on fbdev/fbcon and still provide hardware
acceleration for fbdev/fbcon.
The original commit message also states that syzbot found lots of bugs in fbcon
and thus it's "often the solution to just delete code and remove features".
This is true, and the bugs - which actually affected all users of fbcon,
including DRM - were fixed, or code was dropped like e.g. the support for
software scrollback in vgacon (commit 973c096f6a85).
So to further analyze which bugs were found by syzbot, I've looked through all
patches in drivers/video which were tagged with syzbot or syzkaller back to
year 2005. The vast majority fixed the reported issues on a higher level, e.g.
when screen is to be resized, or when font size is to be changed. The few ones
which touched driver code fixed a real driver bug, e.g. by adding a check.
But NONE of those patches touched code of either the SCROLL_MOVE or the
SCROLL_REDRAW case.
That means, there was no real reason why SCROLL_MOVE had to be ripped-out and
just SCROLL_REDRAW had to be used instead. The only reason I can imagine so far
was that SCROLL_MOVE wasn't used by DRM and as such it was assumed that it
could go away. That argument completely missed the fact that SCROLL_MOVE is
still heavily used by fbdev (non-DRM) drivers.
Some people mention that using memcpy() instead of the hardware acceleration is
pretty much the same speed. But that's not true, at least not for older graphic
cards and machines where we see speed decreases by factor 10 and more and thus
this change leads to console responsiveness way worse than before.
That's why the original commit is to be reverted. By reverting we
reintroduce hardware-based scrolling acceleration and fix the
performance regression for fbdev drivers.
There isn't any impact on DRM when reverting those patches.
Signed-off-by: Helge Deller <deller@gmx.de>
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
Acked-by: Sven Schnelle <svens@stackframe.org>
Cc: stable@vger.kernel.org # v5.16+
Signed-off-by: Helge Deller <deller@gmx.de>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/20220202135531.92183-2-deller@gmx.de
2022-02-02 13:55:29 +00:00
|
|
|
int scroll_partial = info->flags & FBINFO_PARTIAL_PAN_OK;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
if (fbcon_is_inactive(vc, info))
|
2016-10-03 09:18:33 +00:00
|
|
|
return true;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
fbcon_cursor(vc, CM_ERASE);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* ++Geert: Only use ywrap/ypan if the console is in text mode
|
|
|
|
* ++Andrew: Only use ypan on hardware text mode when scrolling the
|
|
|
|
* whole screen (prevents flicker).
|
|
|
|
*/
|
|
|
|
|
|
|
|
switch (dir) {
|
|
|
|
case SM_UP:
|
|
|
|
if (count > vc->vc_rows) /* Maximum realistic size */
|
|
|
|
count = vc->vc_rows;
|
Revert "fbdev: Garbage collect fbdev scrolling acceleration, part 1 (from TODO list)"
This reverts commit b3ec8cdf457e5e63d396fe1346cc788cf7c1b578.
Revert the second (of 2) commits which disabled scrolling acceleration
in fbcon/fbdev. It introduced a regression for fbdev-supported graphic
cards because of the performance penalty by doing screen scrolling by
software instead of using the existing graphic card 2D hardware
acceleration.
Console scrolling acceleration was disabled by dropping code which
checked at runtime the driver hardware capabilities for the
BINFO_HWACCEL_COPYAREA or FBINFO_HWACCEL_FILLRECT flags and if set, it
enabled scrollmode SCROLL_MOVE which uses hardware acceleration to move
screen contents. After dropping those checks scrollmode was hard-wired
to SCROLL_REDRAW instead, which forces all graphic cards to redraw every
character at the new screen position when scrolling.
This change effectively disabled all hardware-based scrolling acceleration for
ALL drivers, because now all kind of 2D hardware acceleration (bitblt,
fillrect) in the drivers isn't used any longer.
The original commit message mentions that only 3 DRM drivers (nouveau, omapdrm
and gma500) used hardware acceleration in the past and thus code for checking
and using scrolling acceleration is obsolete.
This statement is NOT TRUE, because beside the DRM drivers there are around 35
other fbdev drivers which depend on fbdev/fbcon and still provide hardware
acceleration for fbdev/fbcon.
The original commit message also states that syzbot found lots of bugs in fbcon
and thus it's "often the solution to just delete code and remove features".
This is true, and the bugs - which actually affected all users of fbcon,
including DRM - were fixed, or code was dropped like e.g. the support for
software scrollback in vgacon (commit 973c096f6a85).
So to further analyze which bugs were found by syzbot, I've looked through all
patches in drivers/video which were tagged with syzbot or syzkaller back to
year 2005. The vast majority fixed the reported issues on a higher level, e.g.
when screen is to be resized, or when font size is to be changed. The few ones
which touched driver code fixed a real driver bug, e.g. by adding a check.
But NONE of those patches touched code of either the SCROLL_MOVE or the
SCROLL_REDRAW case.
That means, there was no real reason why SCROLL_MOVE had to be ripped-out and
just SCROLL_REDRAW had to be used instead. The only reason I can imagine so far
was that SCROLL_MOVE wasn't used by DRM and as such it was assumed that it
could go away. That argument completely missed the fact that SCROLL_MOVE is
still heavily used by fbdev (non-DRM) drivers.
Some people mention that using memcpy() instead of the hardware acceleration is
pretty much the same speed. But that's not true, at least not for older graphic
cards and machines where we see speed decreases by factor 10 and more and thus
this change leads to console responsiveness way worse than before.
That's why the original commit is to be reverted. By reverting we
reintroduce hardware-based scrolling acceleration and fix the
performance regression for fbdev drivers.
There isn't any impact on DRM when reverting those patches.
Signed-off-by: Helge Deller <deller@gmx.de>
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
Acked-by: Sven Schnelle <svens@stackframe.org>
Cc: stable@vger.kernel.org # v5.16+
Signed-off-by: Helge Deller <deller@gmx.de>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/20220202135531.92183-2-deller@gmx.de
2022-02-02 13:55:29 +00:00
|
|
|
if (logo_shown >= 0)
|
|
|
|
goto redraw_up;
|
2022-02-02 13:55:31 +00:00
|
|
|
switch (fb_scrollmode(p)) {
|
Revert "fbdev: Garbage collect fbdev scrolling acceleration, part 1 (from TODO list)"
This reverts commit b3ec8cdf457e5e63d396fe1346cc788cf7c1b578.
Revert the second (of 2) commits which disabled scrolling acceleration
in fbcon/fbdev. It introduced a regression for fbdev-supported graphic
cards because of the performance penalty by doing screen scrolling by
software instead of using the existing graphic card 2D hardware
acceleration.
Console scrolling acceleration was disabled by dropping code which
checked at runtime the driver hardware capabilities for the
BINFO_HWACCEL_COPYAREA or FBINFO_HWACCEL_FILLRECT flags and if set, it
enabled scrollmode SCROLL_MOVE which uses hardware acceleration to move
screen contents. After dropping those checks scrollmode was hard-wired
to SCROLL_REDRAW instead, which forces all graphic cards to redraw every
character at the new screen position when scrolling.
This change effectively disabled all hardware-based scrolling acceleration for
ALL drivers, because now all kind of 2D hardware acceleration (bitblt,
fillrect) in the drivers isn't used any longer.
The original commit message mentions that only 3 DRM drivers (nouveau, omapdrm
and gma500) used hardware acceleration in the past and thus code for checking
and using scrolling acceleration is obsolete.
This statement is NOT TRUE, because beside the DRM drivers there are around 35
other fbdev drivers which depend on fbdev/fbcon and still provide hardware
acceleration for fbdev/fbcon.
The original commit message also states that syzbot found lots of bugs in fbcon
and thus it's "often the solution to just delete code and remove features".
This is true, and the bugs - which actually affected all users of fbcon,
including DRM - were fixed, or code was dropped like e.g. the support for
software scrollback in vgacon (commit 973c096f6a85).
So to further analyze which bugs were found by syzbot, I've looked through all
patches in drivers/video which were tagged with syzbot or syzkaller back to
year 2005. The vast majority fixed the reported issues on a higher level, e.g.
when screen is to be resized, or when font size is to be changed. The few ones
which touched driver code fixed a real driver bug, e.g. by adding a check.
But NONE of those patches touched code of either the SCROLL_MOVE or the
SCROLL_REDRAW case.
That means, there was no real reason why SCROLL_MOVE had to be ripped-out and
just SCROLL_REDRAW had to be used instead. The only reason I can imagine so far
was that SCROLL_MOVE wasn't used by DRM and as such it was assumed that it
could go away. That argument completely missed the fact that SCROLL_MOVE is
still heavily used by fbdev (non-DRM) drivers.
Some people mention that using memcpy() instead of the hardware acceleration is
pretty much the same speed. But that's not true, at least not for older graphic
cards and machines where we see speed decreases by factor 10 and more and thus
this change leads to console responsiveness way worse than before.
That's why the original commit is to be reverted. By reverting we
reintroduce hardware-based scrolling acceleration and fix the
performance regression for fbdev drivers.
There isn't any impact on DRM when reverting those patches.
Signed-off-by: Helge Deller <deller@gmx.de>
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
Acked-by: Sven Schnelle <svens@stackframe.org>
Cc: stable@vger.kernel.org # v5.16+
Signed-off-by: Helge Deller <deller@gmx.de>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/20220202135531.92183-2-deller@gmx.de
2022-02-02 13:55:29 +00:00
|
|
|
case SCROLL_MOVE:
|
|
|
|
fbcon_redraw_blit(vc, info, p, t, b - t - count,
|
|
|
|
count);
|
|
|
|
fbcon_clear(vc, b - count, 0, count, vc->vc_cols);
|
|
|
|
scr_memsetw((unsigned short *) (vc->vc_origin +
|
|
|
|
vc->vc_size_row *
|
|
|
|
(b - count)),
|
|
|
|
vc->vc_video_erase_char,
|
|
|
|
vc->vc_size_row * count);
|
|
|
|
return true;
|
|
|
|
|
|
|
|
case SCROLL_WRAP_MOVE:
|
|
|
|
if (b - t - count > 3 * vc->vc_rows >> 2) {
|
|
|
|
if (t > 0)
|
|
|
|
fbcon_bmove(vc, 0, 0, count, 0, t,
|
|
|
|
vc->vc_cols);
|
|
|
|
ywrap_up(vc, count);
|
|
|
|
if (vc->vc_rows - b > 0)
|
|
|
|
fbcon_bmove(vc, b - count, 0, b, 0,
|
|
|
|
vc->vc_rows - b,
|
|
|
|
vc->vc_cols);
|
|
|
|
} else if (info->flags & FBINFO_READS_FAST)
|
|
|
|
fbcon_bmove(vc, t + count, 0, t, 0,
|
|
|
|
b - t - count, vc->vc_cols);
|
|
|
|
else
|
|
|
|
goto redraw_up;
|
|
|
|
fbcon_clear(vc, b - count, 0, count, vc->vc_cols);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SCROLL_PAN_REDRAW:
|
|
|
|
if ((p->yscroll + count <=
|
|
|
|
2 * (p->vrows - vc->vc_rows))
|
|
|
|
&& ((!scroll_partial && (b - t == vc->vc_rows))
|
|
|
|
|| (scroll_partial
|
|
|
|
&& (b - t - count >
|
|
|
|
3 * vc->vc_rows >> 2)))) {
|
|
|
|
if (t > 0)
|
|
|
|
fbcon_redraw_move(vc, p, 0, t, count);
|
|
|
|
ypan_up_redraw(vc, t, count);
|
|
|
|
if (vc->vc_rows - b > 0)
|
|
|
|
fbcon_redraw_move(vc, p, b,
|
|
|
|
vc->vc_rows - b, b);
|
|
|
|
} else
|
|
|
|
fbcon_redraw_move(vc, p, t + count, b - t - count, t);
|
|
|
|
fbcon_clear(vc, b - count, 0, count, vc->vc_cols);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SCROLL_PAN_MOVE:
|
|
|
|
if ((p->yscroll + count <=
|
|
|
|
2 * (p->vrows - vc->vc_rows))
|
|
|
|
&& ((!scroll_partial && (b - t == vc->vc_rows))
|
|
|
|
|| (scroll_partial
|
|
|
|
&& (b - t - count >
|
|
|
|
3 * vc->vc_rows >> 2)))) {
|
|
|
|
if (t > 0)
|
|
|
|
fbcon_bmove(vc, 0, 0, count, 0, t,
|
|
|
|
vc->vc_cols);
|
|
|
|
ypan_up(vc, count);
|
|
|
|
if (vc->vc_rows - b > 0)
|
|
|
|
fbcon_bmove(vc, b - count, 0, b, 0,
|
|
|
|
vc->vc_rows - b,
|
|
|
|
vc->vc_cols);
|
|
|
|
} else if (info->flags & FBINFO_READS_FAST)
|
|
|
|
fbcon_bmove(vc, t + count, 0, t, 0,
|
|
|
|
b - t - count, vc->vc_cols);
|
|
|
|
else
|
|
|
|
goto redraw_up;
|
|
|
|
fbcon_clear(vc, b - count, 0, count, vc->vc_cols);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SCROLL_REDRAW:
|
|
|
|
redraw_up:
|
|
|
|
fbcon_redraw(vc, p, t, b - t - count,
|
|
|
|
count * vc->vc_cols);
|
|
|
|
fbcon_clear(vc, b - count, 0, count, vc->vc_cols);
|
|
|
|
scr_memsetw((unsigned short *) (vc->vc_origin +
|
|
|
|
vc->vc_size_row *
|
|
|
|
(b - count)),
|
|
|
|
vc->vc_video_erase_char,
|
|
|
|
vc->vc_size_row * count);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
break;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
case SM_DOWN:
|
|
|
|
if (count > vc->vc_rows) /* Maximum realistic size */
|
|
|
|
count = vc->vc_rows;
|
Revert "fbdev: Garbage collect fbdev scrolling acceleration, part 1 (from TODO list)"
This reverts commit b3ec8cdf457e5e63d396fe1346cc788cf7c1b578.
Revert the second (of 2) commits which disabled scrolling acceleration
in fbcon/fbdev. It introduced a regression for fbdev-supported graphic
cards because of the performance penalty by doing screen scrolling by
software instead of using the existing graphic card 2D hardware
acceleration.
Console scrolling acceleration was disabled by dropping code which
checked at runtime the driver hardware capabilities for the
BINFO_HWACCEL_COPYAREA or FBINFO_HWACCEL_FILLRECT flags and if set, it
enabled scrollmode SCROLL_MOVE which uses hardware acceleration to move
screen contents. After dropping those checks scrollmode was hard-wired
to SCROLL_REDRAW instead, which forces all graphic cards to redraw every
character at the new screen position when scrolling.
This change effectively disabled all hardware-based scrolling acceleration for
ALL drivers, because now all kind of 2D hardware acceleration (bitblt,
fillrect) in the drivers isn't used any longer.
The original commit message mentions that only 3 DRM drivers (nouveau, omapdrm
and gma500) used hardware acceleration in the past and thus code for checking
and using scrolling acceleration is obsolete.
This statement is NOT TRUE, because beside the DRM drivers there are around 35
other fbdev drivers which depend on fbdev/fbcon and still provide hardware
acceleration for fbdev/fbcon.
The original commit message also states that syzbot found lots of bugs in fbcon
and thus it's "often the solution to just delete code and remove features".
This is true, and the bugs - which actually affected all users of fbcon,
including DRM - were fixed, or code was dropped like e.g. the support for
software scrollback in vgacon (commit 973c096f6a85).
So to further analyze which bugs were found by syzbot, I've looked through all
patches in drivers/video which were tagged with syzbot or syzkaller back to
year 2005. The vast majority fixed the reported issues on a higher level, e.g.
when screen is to be resized, or when font size is to be changed. The few ones
which touched driver code fixed a real driver bug, e.g. by adding a check.
But NONE of those patches touched code of either the SCROLL_MOVE or the
SCROLL_REDRAW case.
That means, there was no real reason why SCROLL_MOVE had to be ripped-out and
just SCROLL_REDRAW had to be used instead. The only reason I can imagine so far
was that SCROLL_MOVE wasn't used by DRM and as such it was assumed that it
could go away. That argument completely missed the fact that SCROLL_MOVE is
still heavily used by fbdev (non-DRM) drivers.
Some people mention that using memcpy() instead of the hardware acceleration is
pretty much the same speed. But that's not true, at least not for older graphic
cards and machines where we see speed decreases by factor 10 and more and thus
this change leads to console responsiveness way worse than before.
That's why the original commit is to be reverted. By reverting we
reintroduce hardware-based scrolling acceleration and fix the
performance regression for fbdev drivers.
There isn't any impact on DRM when reverting those patches.
Signed-off-by: Helge Deller <deller@gmx.de>
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
Acked-by: Sven Schnelle <svens@stackframe.org>
Cc: stable@vger.kernel.org # v5.16+
Signed-off-by: Helge Deller <deller@gmx.de>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/20220202135531.92183-2-deller@gmx.de
2022-02-02 13:55:29 +00:00
|
|
|
if (logo_shown >= 0)
|
|
|
|
goto redraw_down;
|
2022-02-02 13:55:31 +00:00
|
|
|
switch (fb_scrollmode(p)) {
|
Revert "fbdev: Garbage collect fbdev scrolling acceleration, part 1 (from TODO list)"
This reverts commit b3ec8cdf457e5e63d396fe1346cc788cf7c1b578.
Revert the second (of 2) commits which disabled scrolling acceleration
in fbcon/fbdev. It introduced a regression for fbdev-supported graphic
cards because of the performance penalty by doing screen scrolling by
software instead of using the existing graphic card 2D hardware
acceleration.
Console scrolling acceleration was disabled by dropping code which
checked at runtime the driver hardware capabilities for the
BINFO_HWACCEL_COPYAREA or FBINFO_HWACCEL_FILLRECT flags and if set, it
enabled scrollmode SCROLL_MOVE which uses hardware acceleration to move
screen contents. After dropping those checks scrollmode was hard-wired
to SCROLL_REDRAW instead, which forces all graphic cards to redraw every
character at the new screen position when scrolling.
This change effectively disabled all hardware-based scrolling acceleration for
ALL drivers, because now all kind of 2D hardware acceleration (bitblt,
fillrect) in the drivers isn't used any longer.
The original commit message mentions that only 3 DRM drivers (nouveau, omapdrm
and gma500) used hardware acceleration in the past and thus code for checking
and using scrolling acceleration is obsolete.
This statement is NOT TRUE, because beside the DRM drivers there are around 35
other fbdev drivers which depend on fbdev/fbcon and still provide hardware
acceleration for fbdev/fbcon.
The original commit message also states that syzbot found lots of bugs in fbcon
and thus it's "often the solution to just delete code and remove features".
This is true, and the bugs - which actually affected all users of fbcon,
including DRM - were fixed, or code was dropped like e.g. the support for
software scrollback in vgacon (commit 973c096f6a85).
So to further analyze which bugs were found by syzbot, I've looked through all
patches in drivers/video which were tagged with syzbot or syzkaller back to
year 2005. The vast majority fixed the reported issues on a higher level, e.g.
when screen is to be resized, or when font size is to be changed. The few ones
which touched driver code fixed a real driver bug, e.g. by adding a check.
But NONE of those patches touched code of either the SCROLL_MOVE or the
SCROLL_REDRAW case.
That means, there was no real reason why SCROLL_MOVE had to be ripped-out and
just SCROLL_REDRAW had to be used instead. The only reason I can imagine so far
was that SCROLL_MOVE wasn't used by DRM and as such it was assumed that it
could go away. That argument completely missed the fact that SCROLL_MOVE is
still heavily used by fbdev (non-DRM) drivers.
Some people mention that using memcpy() instead of the hardware acceleration is
pretty much the same speed. But that's not true, at least not for older graphic
cards and machines where we see speed decreases by factor 10 and more and thus
this change leads to console responsiveness way worse than before.
That's why the original commit is to be reverted. By reverting we
reintroduce hardware-based scrolling acceleration and fix the
performance regression for fbdev drivers.
There isn't any impact on DRM when reverting those patches.
Signed-off-by: Helge Deller <deller@gmx.de>
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
Acked-by: Sven Schnelle <svens@stackframe.org>
Cc: stable@vger.kernel.org # v5.16+
Signed-off-by: Helge Deller <deller@gmx.de>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/20220202135531.92183-2-deller@gmx.de
2022-02-02 13:55:29 +00:00
|
|
|
case SCROLL_MOVE:
|
|
|
|
fbcon_redraw_blit(vc, info, p, b - 1, b - t - count,
|
|
|
|
-count);
|
|
|
|
fbcon_clear(vc, t, 0, count, vc->vc_cols);
|
|
|
|
scr_memsetw((unsigned short *) (vc->vc_origin +
|
|
|
|
vc->vc_size_row *
|
|
|
|
t),
|
|
|
|
vc->vc_video_erase_char,
|
|
|
|
vc->vc_size_row * count);
|
|
|
|
return true;
|
|
|
|
|
|
|
|
case SCROLL_WRAP_MOVE:
|
|
|
|
if (b - t - count > 3 * vc->vc_rows >> 2) {
|
|
|
|
if (vc->vc_rows - b > 0)
|
|
|
|
fbcon_bmove(vc, b, 0, b - count, 0,
|
|
|
|
vc->vc_rows - b,
|
|
|
|
vc->vc_cols);
|
|
|
|
ywrap_down(vc, count);
|
|
|
|
if (t > 0)
|
|
|
|
fbcon_bmove(vc, count, 0, 0, 0, t,
|
|
|
|
vc->vc_cols);
|
|
|
|
} else if (info->flags & FBINFO_READS_FAST)
|
|
|
|
fbcon_bmove(vc, t, 0, t + count, 0,
|
|
|
|
b - t - count, vc->vc_cols);
|
|
|
|
else
|
|
|
|
goto redraw_down;
|
|
|
|
fbcon_clear(vc, t, 0, count, vc->vc_cols);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SCROLL_PAN_MOVE:
|
|
|
|
if ((count - p->yscroll <= p->vrows - vc->vc_rows)
|
|
|
|
&& ((!scroll_partial && (b - t == vc->vc_rows))
|
|
|
|
|| (scroll_partial
|
|
|
|
&& (b - t - count >
|
|
|
|
3 * vc->vc_rows >> 2)))) {
|
|
|
|
if (vc->vc_rows - b > 0)
|
|
|
|
fbcon_bmove(vc, b, 0, b - count, 0,
|
|
|
|
vc->vc_rows - b,
|
|
|
|
vc->vc_cols);
|
|
|
|
ypan_down(vc, count);
|
|
|
|
if (t > 0)
|
|
|
|
fbcon_bmove(vc, count, 0, 0, 0, t,
|
|
|
|
vc->vc_cols);
|
|
|
|
} else if (info->flags & FBINFO_READS_FAST)
|
|
|
|
fbcon_bmove(vc, t, 0, t + count, 0,
|
|
|
|
b - t - count, vc->vc_cols);
|
|
|
|
else
|
|
|
|
goto redraw_down;
|
|
|
|
fbcon_clear(vc, t, 0, count, vc->vc_cols);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SCROLL_PAN_REDRAW:
|
|
|
|
if ((count - p->yscroll <= p->vrows - vc->vc_rows)
|
|
|
|
&& ((!scroll_partial && (b - t == vc->vc_rows))
|
|
|
|
|| (scroll_partial
|
|
|
|
&& (b - t - count >
|
|
|
|
3 * vc->vc_rows >> 2)))) {
|
|
|
|
if (vc->vc_rows - b > 0)
|
|
|
|
fbcon_redraw_move(vc, p, b, vc->vc_rows - b,
|
|
|
|
b - count);
|
|
|
|
ypan_down_redraw(vc, t, count);
|
|
|
|
if (t > 0)
|
|
|
|
fbcon_redraw_move(vc, p, count, t, 0);
|
|
|
|
} else
|
|
|
|
fbcon_redraw_move(vc, p, t, b - t - count, t + count);
|
|
|
|
fbcon_clear(vc, t, 0, count, vc->vc_cols);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SCROLL_REDRAW:
|
|
|
|
redraw_down:
|
|
|
|
fbcon_redraw(vc, p, b - 1, b - t - count,
|
|
|
|
-count * vc->vc_cols);
|
|
|
|
fbcon_clear(vc, t, 0, count, vc->vc_cols);
|
|
|
|
scr_memsetw((unsigned short *) (vc->vc_origin +
|
|
|
|
vc->vc_size_row *
|
|
|
|
t),
|
|
|
|
vc->vc_video_erase_char,
|
|
|
|
vc->vc_size_row * count);
|
|
|
|
return true;
|
|
|
|
}
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
2016-10-03 09:18:33 +00:00
|
|
|
return false;
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
|
Revert "fbdev: Garbage collect fbdev scrolling acceleration, part 1 (from TODO list)"
This reverts commit b3ec8cdf457e5e63d396fe1346cc788cf7c1b578.
Revert the second (of 2) commits which disabled scrolling acceleration
in fbcon/fbdev. It introduced a regression for fbdev-supported graphic
cards because of the performance penalty by doing screen scrolling by
software instead of using the existing graphic card 2D hardware
acceleration.
Console scrolling acceleration was disabled by dropping code which
checked at runtime the driver hardware capabilities for the
BINFO_HWACCEL_COPYAREA or FBINFO_HWACCEL_FILLRECT flags and if set, it
enabled scrollmode SCROLL_MOVE which uses hardware acceleration to move
screen contents. After dropping those checks scrollmode was hard-wired
to SCROLL_REDRAW instead, which forces all graphic cards to redraw every
character at the new screen position when scrolling.
This change effectively disabled all hardware-based scrolling acceleration for
ALL drivers, because now all kind of 2D hardware acceleration (bitblt,
fillrect) in the drivers isn't used any longer.
The original commit message mentions that only 3 DRM drivers (nouveau, omapdrm
and gma500) used hardware acceleration in the past and thus code for checking
and using scrolling acceleration is obsolete.
This statement is NOT TRUE, because beside the DRM drivers there are around 35
other fbdev drivers which depend on fbdev/fbcon and still provide hardware
acceleration for fbdev/fbcon.
The original commit message also states that syzbot found lots of bugs in fbcon
and thus it's "often the solution to just delete code and remove features".
This is true, and the bugs - which actually affected all users of fbcon,
including DRM - were fixed, or code was dropped like e.g. the support for
software scrollback in vgacon (commit 973c096f6a85).
So to further analyze which bugs were found by syzbot, I've looked through all
patches in drivers/video which were tagged with syzbot or syzkaller back to
year 2005. The vast majority fixed the reported issues on a higher level, e.g.
when screen is to be resized, or when font size is to be changed. The few ones
which touched driver code fixed a real driver bug, e.g. by adding a check.
But NONE of those patches touched code of either the SCROLL_MOVE or the
SCROLL_REDRAW case.
That means, there was no real reason why SCROLL_MOVE had to be ripped-out and
just SCROLL_REDRAW had to be used instead. The only reason I can imagine so far
was that SCROLL_MOVE wasn't used by DRM and as such it was assumed that it
could go away. That argument completely missed the fact that SCROLL_MOVE is
still heavily used by fbdev (non-DRM) drivers.
Some people mention that using memcpy() instead of the hardware acceleration is
pretty much the same speed. But that's not true, at least not for older graphic
cards and machines where we see speed decreases by factor 10 and more and thus
this change leads to console responsiveness way worse than before.
That's why the original commit is to be reverted. By reverting we
reintroduce hardware-based scrolling acceleration and fix the
performance regression for fbdev drivers.
There isn't any impact on DRM when reverting those patches.
Signed-off-by: Helge Deller <deller@gmx.de>
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
Acked-by: Sven Schnelle <svens@stackframe.org>
Cc: stable@vger.kernel.org # v5.16+
Signed-off-by: Helge Deller <deller@gmx.de>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/20220202135531.92183-2-deller@gmx.de
2022-02-02 13:55:29 +00:00
|
|
|
|
2022-02-02 13:55:31 +00:00
|
|
|
static void updatescrollmode_accel(struct fbcon_display *p,
|
[PATCH] fbcon: Console Rotation - Prepare fbcon for console rotation
This patch series implements generic code to rotate the console at 90, 180,
and 270 degrees. The implementation is completely done in the framebuffer
console level, thus no changes to the framebuffer layer or to the drivers
are needed.
Console rotation is required by some Sharp-based devices where the natural
orientation of the display is not at 0 degrees. Also, users that have
displays that can pivot will benefit by having a console in portrait mode
if they so desire.
The choice to implement the code in the console layer rather than in the
framebuffer layer is due to the following reasons:
- it's fast
- it does not require driver changes
- it can coexist with devices that can rotate the display at the hardware level
- it complements graphics applications that can do display rotation
The changes to core fbcon are minimal-- recognition of the console
rotation angle so it can swap directions, origins and axes (xres vs yres,
xpanstep vs ypanstep, xoffset vs yoffset, etc) and storage of the rotation
angle per display. The bulk of the code that does the actual drawing to the
screen are placed in separate files. Each angle of rotation has separate
methods (bmove, clear, putcs, cursor, update_start which is derived from
update_var, and clear_margins). To mimimize processing time, the fontdata
are pre-rotated at each console switch (only if the font or the angle has
changed).
The option can be compiled out (CONFIG_FRAMEBUFFER_CONSOLE_ROTATION = n) if
rotation is not needed.
Choosing the rotation angle can be done in several ways:
1. boot option fbcon=rotate:n, where
n = 0 - normal
n = 1 - 90 degrees (clockwise)
n = 2 - 180 degrees (upside down)
n = 3 - 270 degrees (counterclockwise)
2. echo n > /sys/class/graphics/fb[num]/con_rotate
where n is the same as described above. It sets the angle of rotation
of the current console
3 echo n > /sys/class/graphics/fb[num]/con_rotate_all
where n is the same as described above. Globally sets the angle of
rotation.
GOTCHAS:
The option, especially at angles of 90 and 270 degrees, will exercise
the least used code of drivers. Namely, at these angles, panning is done
in the x-axis, so it can reveal bugs in the driver if xpanstep is set
incorrectly. A workaround is to set xpanstep = 0.
Secondly, at these angles, the framebuffer memory access can be
unaligned if (fontheight * bpp) % 32 ~= 0 which can reveal bugs in the drivers
imageblit, fillrect and copyarea functions. (I think cfbfillrect may have
this buglet). A workaround is to use a standard 8x16 font.
Speed:
The scrolling speed difference between 0 and 180 degrees is minimal,
somewhere areound 1-2%. At 90 or 270 degress, speed drops down to a vicinity
of 30-40%. This is understandable because the blit direction is across the
framebuffer "direction." Scrolling will be helped at these angles if xpanstep
is not equal to zero, use of 8x16 fonts, and setting xres_virtual >= xres * 2.
Note: The code is tested on little-endian only, so I don't know if it will
work in big-endian. Please let me know, it will take only less than a minute
of your time.
This patch prepares fbcon for console rotation and contains the following
changes:
- add rotate field in struct fbcon_ops to keep fbcon's current rotation
angle
- add con_rotate field in struct display to store per-display rotation angle
- create a private copy of the current var to fbcon. This will prevent
fbcon from directly manipulating info->var, especially the fields xoffset,
yoffset and vmode.
- add ability to swap pertinent axes (xres, yres; xpanstep, ypanstep; etc)
depending on the rotation angle
- change global update_var() (function that sets the screen start address)
as an fbcon method update_start. This is required because the axes, start
offset, and/or direction can be reversed depending on the rotation angle.
- add fbcon method rotate_font() which will rotate each character bitmap to
the correct angle of rotation.
- add fbcon boot option 'rotate' to select the angle of rotation at bootime.
Currently does nothing until all patches are applied.
Signed-off-by: Antonino Daplas <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-11-09 05:39:09 +00:00
|
|
|
struct fb_info *info,
|
2005-04-16 22:20:36 +00:00
|
|
|
struct vc_data *vc)
|
|
|
|
{
|
2022-02-02 13:55:31 +00:00
|
|
|
#ifdef CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION
|
[PATCH] fbcon: Console Rotation - Prepare fbcon for console rotation
This patch series implements generic code to rotate the console at 90, 180,
and 270 degrees. The implementation is completely done in the framebuffer
console level, thus no changes to the framebuffer layer or to the drivers
are needed.
Console rotation is required by some Sharp-based devices where the natural
orientation of the display is not at 0 degrees. Also, users that have
displays that can pivot will benefit by having a console in portrait mode
if they so desire.
The choice to implement the code in the console layer rather than in the
framebuffer layer is due to the following reasons:
- it's fast
- it does not require driver changes
- it can coexist with devices that can rotate the display at the hardware level
- it complements graphics applications that can do display rotation
The changes to core fbcon are minimal-- recognition of the console
rotation angle so it can swap directions, origins and axes (xres vs yres,
xpanstep vs ypanstep, xoffset vs yoffset, etc) and storage of the rotation
angle per display. The bulk of the code that does the actual drawing to the
screen are placed in separate files. Each angle of rotation has separate
methods (bmove, clear, putcs, cursor, update_start which is derived from
update_var, and clear_margins). To mimimize processing time, the fontdata
are pre-rotated at each console switch (only if the font or the angle has
changed).
The option can be compiled out (CONFIG_FRAMEBUFFER_CONSOLE_ROTATION = n) if
rotation is not needed.
Choosing the rotation angle can be done in several ways:
1. boot option fbcon=rotate:n, where
n = 0 - normal
n = 1 - 90 degrees (clockwise)
n = 2 - 180 degrees (upside down)
n = 3 - 270 degrees (counterclockwise)
2. echo n > /sys/class/graphics/fb[num]/con_rotate
where n is the same as described above. It sets the angle of rotation
of the current console
3 echo n > /sys/class/graphics/fb[num]/con_rotate_all
where n is the same as described above. Globally sets the angle of
rotation.
GOTCHAS:
The option, especially at angles of 90 and 270 degrees, will exercise
the least used code of drivers. Namely, at these angles, panning is done
in the x-axis, so it can reveal bugs in the driver if xpanstep is set
incorrectly. A workaround is to set xpanstep = 0.
Secondly, at these angles, the framebuffer memory access can be
unaligned if (fontheight * bpp) % 32 ~= 0 which can reveal bugs in the drivers
imageblit, fillrect and copyarea functions. (I think cfbfillrect may have
this buglet). A workaround is to use a standard 8x16 font.
Speed:
The scrolling speed difference between 0 and 180 degrees is minimal,
somewhere areound 1-2%. At 90 or 270 degress, speed drops down to a vicinity
of 30-40%. This is understandable because the blit direction is across the
framebuffer "direction." Scrolling will be helped at these angles if xpanstep
is not equal to zero, use of 8x16 fonts, and setting xres_virtual >= xres * 2.
Note: The code is tested on little-endian only, so I don't know if it will
work in big-endian. Please let me know, it will take only less than a minute
of your time.
This patch prepares fbcon for console rotation and contains the following
changes:
- add rotate field in struct fbcon_ops to keep fbcon's current rotation
angle
- add con_rotate field in struct display to store per-display rotation angle
- create a private copy of the current var to fbcon. This will prevent
fbcon from directly manipulating info->var, especially the fields xoffset,
yoffset and vmode.
- add ability to swap pertinent axes (xres, yres; xpanstep, ypanstep; etc)
depending on the rotation angle
- change global update_var() (function that sets the screen start address)
as an fbcon method update_start. This is required because the axes, start
offset, and/or direction can be reversed depending on the rotation angle.
- add fbcon method rotate_font() which will rotate each character bitmap to
the correct angle of rotation.
- add fbcon boot option 'rotate' to select the angle of rotation at bootime.
Currently does nothing until all patches are applied.
Signed-off-by: Antonino Daplas <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-11-09 05:39:09 +00:00
|
|
|
struct fbcon_ops *ops = info->fbcon_par;
|
Revert "fbcon: Disable accelerated scrolling"
This reverts commit 39aead8373b3c20bb5965c024dfb51a94e526151.
Revert the first (of 2) commits which disabled scrolling acceleration in
fbcon/fbdev. It introduced a regression for fbdev-supported graphic cards
because of the performance penalty by doing screen scrolling by software
instead of using the existing graphic card 2D hardware acceleration.
Console scrolling acceleration was disabled by dropping code which
checked at runtime the driver hardware capabilities for the
BINFO_HWACCEL_COPYAREA or FBINFO_HWACCEL_FILLRECT flags and if set, it
enabled scrollmode SCROLL_MOVE which uses hardware acceleration to move
screen contents. After dropping those checks scrollmode was hard-wired
to SCROLL_REDRAW instead, which forces all graphic cards to redraw every
character at the new screen position when scrolling.
This change effectively disabled all hardware-based scrolling acceleration for
ALL drivers, because now all kind of 2D hardware acceleration (bitblt,
fillrect) in the drivers isn't used any longer.
The original commit message mentions that only 3 DRM drivers (nouveau, omapdrm
and gma500) used hardware acceleration in the past and thus code for checking
and using scrolling acceleration is obsolete.
This statement is NOT TRUE, because beside the DRM drivers there are around 35
other fbdev drivers which depend on fbdev/fbcon and still provide hardware
acceleration for fbdev/fbcon.
The original commit message also states that syzbot found lots of bugs in fbcon
and thus it's "often the solution to just delete code and remove features".
This is true, and the bugs - which actually affected all users of fbcon,
including DRM - were fixed, or code was dropped like e.g. the support for
software scrollback in vgacon (commit 973c096f6a85).
So to further analyze which bugs were found by syzbot, I've looked through all
patches in drivers/video which were tagged with syzbot or syzkaller back to
year 2005. The vast majority fixed the reported issues on a higher level, e.g.
when screen is to be resized, or when font size is to be changed. The few ones
which touched driver code fixed a real driver bug, e.g. by adding a check.
But NONE of those patches touched code of either the SCROLL_MOVE or the
SCROLL_REDRAW case.
That means, there was no real reason why SCROLL_MOVE had to be ripped-out and
just SCROLL_REDRAW had to be used instead. The only reason I can imagine so far
was that SCROLL_MOVE wasn't used by DRM and as such it was assumed that it
could go away. That argument completely missed the fact that SCROLL_MOVE is
still heavily used by fbdev (non-DRM) drivers.
Some people mention that using memcpy() instead of the hardware acceleration is
pretty much the same speed. But that's not true, at least not for older graphic
cards and machines where we see speed decreases by factor 10 and more and thus
this change leads to console responsiveness way worse than before.
That's why the original commit is to be reverted. By reverting we
reintroduce hardware-based scrolling acceleration and fix the
performance regression for fbdev drivers.
There isn't any impact on DRM when reverting those patches.
Signed-off-by: Helge Deller <deller@gmx.de>
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
Acked-by: Sven Schnelle <svens@stackframe.org>
Cc: stable@vger.kernel.org # v5.10+
Signed-off-by: Helge Deller <deller@gmx.de>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/20220202135531.92183-3-deller@gmx.de
2022-02-02 13:55:30 +00:00
|
|
|
int cap = info->flags;
|
|
|
|
u16 t = 0;
|
|
|
|
int ypan = FBCON_SWAP(ops->rotate, info->fix.ypanstep,
|
|
|
|
info->fix.xpanstep);
|
|
|
|
int ywrap = FBCON_SWAP(ops->rotate, info->fix.ywrapstep, t);
|
[PATCH] fbcon: Console Rotation - Prepare fbcon for console rotation
This patch series implements generic code to rotate the console at 90, 180,
and 270 degrees. The implementation is completely done in the framebuffer
console level, thus no changes to the framebuffer layer or to the drivers
are needed.
Console rotation is required by some Sharp-based devices where the natural
orientation of the display is not at 0 degrees. Also, users that have
displays that can pivot will benefit by having a console in portrait mode
if they so desire.
The choice to implement the code in the console layer rather than in the
framebuffer layer is due to the following reasons:
- it's fast
- it does not require driver changes
- it can coexist with devices that can rotate the display at the hardware level
- it complements graphics applications that can do display rotation
The changes to core fbcon are minimal-- recognition of the console
rotation angle so it can swap directions, origins and axes (xres vs yres,
xpanstep vs ypanstep, xoffset vs yoffset, etc) and storage of the rotation
angle per display. The bulk of the code that does the actual drawing to the
screen are placed in separate files. Each angle of rotation has separate
methods (bmove, clear, putcs, cursor, update_start which is derived from
update_var, and clear_margins). To mimimize processing time, the fontdata
are pre-rotated at each console switch (only if the font or the angle has
changed).
The option can be compiled out (CONFIG_FRAMEBUFFER_CONSOLE_ROTATION = n) if
rotation is not needed.
Choosing the rotation angle can be done in several ways:
1. boot option fbcon=rotate:n, where
n = 0 - normal
n = 1 - 90 degrees (clockwise)
n = 2 - 180 degrees (upside down)
n = 3 - 270 degrees (counterclockwise)
2. echo n > /sys/class/graphics/fb[num]/con_rotate
where n is the same as described above. It sets the angle of rotation
of the current console
3 echo n > /sys/class/graphics/fb[num]/con_rotate_all
where n is the same as described above. Globally sets the angle of
rotation.
GOTCHAS:
The option, especially at angles of 90 and 270 degrees, will exercise
the least used code of drivers. Namely, at these angles, panning is done
in the x-axis, so it can reveal bugs in the driver if xpanstep is set
incorrectly. A workaround is to set xpanstep = 0.
Secondly, at these angles, the framebuffer memory access can be
unaligned if (fontheight * bpp) % 32 ~= 0 which can reveal bugs in the drivers
imageblit, fillrect and copyarea functions. (I think cfbfillrect may have
this buglet). A workaround is to use a standard 8x16 font.
Speed:
The scrolling speed difference between 0 and 180 degrees is minimal,
somewhere areound 1-2%. At 90 or 270 degress, speed drops down to a vicinity
of 30-40%. This is understandable because the blit direction is across the
framebuffer "direction." Scrolling will be helped at these angles if xpanstep
is not equal to zero, use of 8x16 fonts, and setting xres_virtual >= xres * 2.
Note: The code is tested on little-endian only, so I don't know if it will
work in big-endian. Please let me know, it will take only less than a minute
of your time.
This patch prepares fbcon for console rotation and contains the following
changes:
- add rotate field in struct fbcon_ops to keep fbcon's current rotation
angle
- add con_rotate field in struct display to store per-display rotation angle
- create a private copy of the current var to fbcon. This will prevent
fbcon from directly manipulating info->var, especially the fields xoffset,
yoffset and vmode.
- add ability to swap pertinent axes (xres, yres; xpanstep, ypanstep; etc)
depending on the rotation angle
- change global update_var() (function that sets the screen start address)
as an fbcon method update_start. This is required because the axes, start
offset, and/or direction can be reversed depending on the rotation angle.
- add fbcon method rotate_font() which will rotate each character bitmap to
the correct angle of rotation.
- add fbcon boot option 'rotate' to select the angle of rotation at bootime.
Currently does nothing until all patches are applied.
Signed-off-by: Antonino Daplas <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-11-09 05:39:09 +00:00
|
|
|
int yres = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
|
|
|
|
int vyres = FBCON_SWAP(ops->rotate, info->var.yres_virtual,
|
|
|
|
info->var.xres_virtual);
|
Revert "fbcon: Disable accelerated scrolling"
This reverts commit 39aead8373b3c20bb5965c024dfb51a94e526151.
Revert the first (of 2) commits which disabled scrolling acceleration in
fbcon/fbdev. It introduced a regression for fbdev-supported graphic cards
because of the performance penalty by doing screen scrolling by software
instead of using the existing graphic card 2D hardware acceleration.
Console scrolling acceleration was disabled by dropping code which
checked at runtime the driver hardware capabilities for the
BINFO_HWACCEL_COPYAREA or FBINFO_HWACCEL_FILLRECT flags and if set, it
enabled scrollmode SCROLL_MOVE which uses hardware acceleration to move
screen contents. After dropping those checks scrollmode was hard-wired
to SCROLL_REDRAW instead, which forces all graphic cards to redraw every
character at the new screen position when scrolling.
This change effectively disabled all hardware-based scrolling acceleration for
ALL drivers, because now all kind of 2D hardware acceleration (bitblt,
fillrect) in the drivers isn't used any longer.
The original commit message mentions that only 3 DRM drivers (nouveau, omapdrm
and gma500) used hardware acceleration in the past and thus code for checking
and using scrolling acceleration is obsolete.
This statement is NOT TRUE, because beside the DRM drivers there are around 35
other fbdev drivers which depend on fbdev/fbcon and still provide hardware
acceleration for fbdev/fbcon.
The original commit message also states that syzbot found lots of bugs in fbcon
and thus it's "often the solution to just delete code and remove features".
This is true, and the bugs - which actually affected all users of fbcon,
including DRM - were fixed, or code was dropped like e.g. the support for
software scrollback in vgacon (commit 973c096f6a85).
So to further analyze which bugs were found by syzbot, I've looked through all
patches in drivers/video which were tagged with syzbot or syzkaller back to
year 2005. The vast majority fixed the reported issues on a higher level, e.g.
when screen is to be resized, or when font size is to be changed. The few ones
which touched driver code fixed a real driver bug, e.g. by adding a check.
But NONE of those patches touched code of either the SCROLL_MOVE or the
SCROLL_REDRAW case.
That means, there was no real reason why SCROLL_MOVE had to be ripped-out and
just SCROLL_REDRAW had to be used instead. The only reason I can imagine so far
was that SCROLL_MOVE wasn't used by DRM and as such it was assumed that it
could go away. That argument completely missed the fact that SCROLL_MOVE is
still heavily used by fbdev (non-DRM) drivers.
Some people mention that using memcpy() instead of the hardware acceleration is
pretty much the same speed. But that's not true, at least not for older graphic
cards and machines where we see speed decreases by factor 10 and more and thus
this change leads to console responsiveness way worse than before.
That's why the original commit is to be reverted. By reverting we
reintroduce hardware-based scrolling acceleration and fix the
performance regression for fbdev drivers.
There isn't any impact on DRM when reverting those patches.
Signed-off-by: Helge Deller <deller@gmx.de>
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
Acked-by: Sven Schnelle <svens@stackframe.org>
Cc: stable@vger.kernel.org # v5.10+
Signed-off-by: Helge Deller <deller@gmx.de>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/20220202135531.92183-3-deller@gmx.de
2022-02-02 13:55:30 +00:00
|
|
|
int good_pan = (cap & FBINFO_HWACCEL_YPAN) &&
|
|
|
|
divides(ypan, vc->vc_font.height) && vyres > yres;
|
|
|
|
int good_wrap = (cap & FBINFO_HWACCEL_YWRAP) &&
|
|
|
|
divides(ywrap, vc->vc_font.height) &&
|
|
|
|
divides(vc->vc_font.height, vyres) &&
|
|
|
|
divides(vc->vc_font.height, yres);
|
|
|
|
int reading_fast = cap & FBINFO_READS_FAST;
|
|
|
|
int fast_copyarea = (cap & FBINFO_HWACCEL_COPYAREA) &&
|
|
|
|
!(cap & FBINFO_HWACCEL_DISABLED);
|
|
|
|
int fast_imageblit = (cap & FBINFO_HWACCEL_IMAGEBLIT) &&
|
|
|
|
!(cap & FBINFO_HWACCEL_DISABLED);
|
[PATCH] fbcon: Console Rotation - Prepare fbcon for console rotation
This patch series implements generic code to rotate the console at 90, 180,
and 270 degrees. The implementation is completely done in the framebuffer
console level, thus no changes to the framebuffer layer or to the drivers
are needed.
Console rotation is required by some Sharp-based devices where the natural
orientation of the display is not at 0 degrees. Also, users that have
displays that can pivot will benefit by having a console in portrait mode
if they so desire.
The choice to implement the code in the console layer rather than in the
framebuffer layer is due to the following reasons:
- it's fast
- it does not require driver changes
- it can coexist with devices that can rotate the display at the hardware level
- it complements graphics applications that can do display rotation
The changes to core fbcon are minimal-- recognition of the console
rotation angle so it can swap directions, origins and axes (xres vs yres,
xpanstep vs ypanstep, xoffset vs yoffset, etc) and storage of the rotation
angle per display. The bulk of the code that does the actual drawing to the
screen are placed in separate files. Each angle of rotation has separate
methods (bmove, clear, putcs, cursor, update_start which is derived from
update_var, and clear_margins). To mimimize processing time, the fontdata
are pre-rotated at each console switch (only if the font or the angle has
changed).
The option can be compiled out (CONFIG_FRAMEBUFFER_CONSOLE_ROTATION = n) if
rotation is not needed.
Choosing the rotation angle can be done in several ways:
1. boot option fbcon=rotate:n, where
n = 0 - normal
n = 1 - 90 degrees (clockwise)
n = 2 - 180 degrees (upside down)
n = 3 - 270 degrees (counterclockwise)
2. echo n > /sys/class/graphics/fb[num]/con_rotate
where n is the same as described above. It sets the angle of rotation
of the current console
3 echo n > /sys/class/graphics/fb[num]/con_rotate_all
where n is the same as described above. Globally sets the angle of
rotation.
GOTCHAS:
The option, especially at angles of 90 and 270 degrees, will exercise
the least used code of drivers. Namely, at these angles, panning is done
in the x-axis, so it can reveal bugs in the driver if xpanstep is set
incorrectly. A workaround is to set xpanstep = 0.
Secondly, at these angles, the framebuffer memory access can be
unaligned if (fontheight * bpp) % 32 ~= 0 which can reveal bugs in the drivers
imageblit, fillrect and copyarea functions. (I think cfbfillrect may have
this buglet). A workaround is to use a standard 8x16 font.
Speed:
The scrolling speed difference between 0 and 180 degrees is minimal,
somewhere areound 1-2%. At 90 or 270 degress, speed drops down to a vicinity
of 30-40%. This is understandable because the blit direction is across the
framebuffer "direction." Scrolling will be helped at these angles if xpanstep
is not equal to zero, use of 8x16 fonts, and setting xres_virtual >= xres * 2.
Note: The code is tested on little-endian only, so I don't know if it will
work in big-endian. Please let me know, it will take only less than a minute
of your time.
This patch prepares fbcon for console rotation and contains the following
changes:
- add rotate field in struct fbcon_ops to keep fbcon's current rotation
angle
- add con_rotate field in struct display to store per-display rotation angle
- create a private copy of the current var to fbcon. This will prevent
fbcon from directly manipulating info->var, especially the fields xoffset,
yoffset and vmode.
- add ability to swap pertinent axes (xres, yres; xpanstep, ypanstep; etc)
depending on the rotation angle
- change global update_var() (function that sets the screen start address)
as an fbcon method update_start. This is required because the axes, start
offset, and/or direction can be reversed depending on the rotation angle.
- add fbcon method rotate_font() which will rotate each character bitmap to
the correct angle of rotation.
- add fbcon boot option 'rotate' to select the angle of rotation at bootime.
Currently does nothing until all patches are applied.
Signed-off-by: Antonino Daplas <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-11-09 05:39:09 +00:00
|
|
|
|
Revert "fbcon: Disable accelerated scrolling"
This reverts commit 39aead8373b3c20bb5965c024dfb51a94e526151.
Revert the first (of 2) commits which disabled scrolling acceleration in
fbcon/fbdev. It introduced a regression for fbdev-supported graphic cards
because of the performance penalty by doing screen scrolling by software
instead of using the existing graphic card 2D hardware acceleration.
Console scrolling acceleration was disabled by dropping code which
checked at runtime the driver hardware capabilities for the
BINFO_HWACCEL_COPYAREA or FBINFO_HWACCEL_FILLRECT flags and if set, it
enabled scrollmode SCROLL_MOVE which uses hardware acceleration to move
screen contents. After dropping those checks scrollmode was hard-wired
to SCROLL_REDRAW instead, which forces all graphic cards to redraw every
character at the new screen position when scrolling.
This change effectively disabled all hardware-based scrolling acceleration for
ALL drivers, because now all kind of 2D hardware acceleration (bitblt,
fillrect) in the drivers isn't used any longer.
The original commit message mentions that only 3 DRM drivers (nouveau, omapdrm
and gma500) used hardware acceleration in the past and thus code for checking
and using scrolling acceleration is obsolete.
This statement is NOT TRUE, because beside the DRM drivers there are around 35
other fbdev drivers which depend on fbdev/fbcon and still provide hardware
acceleration for fbdev/fbcon.
The original commit message also states that syzbot found lots of bugs in fbcon
and thus it's "often the solution to just delete code and remove features".
This is true, and the bugs - which actually affected all users of fbcon,
including DRM - were fixed, or code was dropped like e.g. the support for
software scrollback in vgacon (commit 973c096f6a85).
So to further analyze which bugs were found by syzbot, I've looked through all
patches in drivers/video which were tagged with syzbot or syzkaller back to
year 2005. The vast majority fixed the reported issues on a higher level, e.g.
when screen is to be resized, or when font size is to be changed. The few ones
which touched driver code fixed a real driver bug, e.g. by adding a check.
But NONE of those patches touched code of either the SCROLL_MOVE or the
SCROLL_REDRAW case.
That means, there was no real reason why SCROLL_MOVE had to be ripped-out and
just SCROLL_REDRAW had to be used instead. The only reason I can imagine so far
was that SCROLL_MOVE wasn't used by DRM and as such it was assumed that it
could go away. That argument completely missed the fact that SCROLL_MOVE is
still heavily used by fbdev (non-DRM) drivers.
Some people mention that using memcpy() instead of the hardware acceleration is
pretty much the same speed. But that's not true, at least not for older graphic
cards and machines where we see speed decreases by factor 10 and more and thus
this change leads to console responsiveness way worse than before.
That's why the original commit is to be reverted. By reverting we
reintroduce hardware-based scrolling acceleration and fix the
performance regression for fbdev drivers.
There isn't any impact on DRM when reverting those patches.
Signed-off-by: Helge Deller <deller@gmx.de>
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
Acked-by: Sven Schnelle <svens@stackframe.org>
Cc: stable@vger.kernel.org # v5.10+
Signed-off-by: Helge Deller <deller@gmx.de>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/20220202135531.92183-3-deller@gmx.de
2022-02-02 13:55:30 +00:00
|
|
|
if (good_wrap || good_pan) {
|
|
|
|
if (reading_fast || fast_copyarea)
|
|
|
|
p->scrollmode = good_wrap ?
|
|
|
|
SCROLL_WRAP_MOVE : SCROLL_PAN_MOVE;
|
|
|
|
else
|
|
|
|
p->scrollmode = good_wrap ? SCROLL_REDRAW :
|
|
|
|
SCROLL_PAN_REDRAW;
|
|
|
|
} else {
|
|
|
|
if (reading_fast || (fast_copyarea && !fast_imageblit))
|
|
|
|
p->scrollmode = SCROLL_MOVE;
|
|
|
|
else
|
|
|
|
p->scrollmode = SCROLL_REDRAW;
|
|
|
|
}
|
2022-02-02 13:55:31 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
static void updatescrollmode(struct fbcon_display *p,
|
|
|
|
struct fb_info *info,
|
|
|
|
struct vc_data *vc)
|
|
|
|
{
|
|
|
|
struct fbcon_ops *ops = info->fbcon_par;
|
|
|
|
int fh = vc->vc_font.height;
|
|
|
|
int yres = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
|
|
|
|
int vyres = FBCON_SWAP(ops->rotate, info->var.yres_virtual,
|
|
|
|
info->var.xres_virtual);
|
|
|
|
|
|
|
|
p->vrows = vyres/fh;
|
|
|
|
if (yres > (fh * (vc->vc_rows + 1)))
|
|
|
|
p->vrows -= (yres - (fh * vc->vc_rows)) / fh;
|
|
|
|
if ((yres % fh) && (vyres % fh < yres % fh))
|
|
|
|
p->vrows--;
|
|
|
|
|
|
|
|
/* update scrollmode in case hardware acceleration is used */
|
|
|
|
updatescrollmode_accel(p, info, vc);
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
|
2020-07-31 16:33:11 +00:00
|
|
|
#define PITCH(w) (((w) + 7) >> 3)
|
|
|
|
#define CALC_FONTSZ(h, p, c) ((h) * (p) * (c)) /* size = height * pitch * charcount */
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
static int fbcon_resize(struct vc_data *vc, unsigned int width,
|
vt/vgacon: Check if screen resize request comes from userspace
Various console drivers are able to resize the screen via the con_resize()
hook. This hook is also visible in userspace via the TIOCWINSZ, VT_RESIZE and
VT_RESIZEX ioctl's. One particular utility, SVGATextMode, expects that
con_resize() of the VGA console will always return success even if the
resulting screen is not compatible with the hardware. However, this
particular behavior of the VGA console, as reported in Kernel Bugzilla Bug
7513, can cause undefined behavior if the user starts with a console size
larger than 80x25.
To work around this problem, add an extra parameter to con_resize(). This
parameter is ignored by drivers except for vgacon. If this parameter is
non-zero, then the resize request came from a VT_RESIZE or VT_RESIZEX ioctl
and vgacon will always return success. If this parameter is zero, vgacon will
return -EINVAL if the requested size is not compatible with the hardware. The
latter is the more correct behavior.
With this change, SVGATextMode should still work correctly while in-kernel and
stty resize calls can expect correct behavior from vgacon.
Signed-off-by: Antonino Daplas <adaplas@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2007-10-16 08:29:35 +00:00
|
|
|
unsigned int height, unsigned int user)
|
2005-04-16 22:20:36 +00:00
|
|
|
{
|
2022-04-05 21:03:21 +00:00
|
|
|
struct fb_info *info = fbcon_info_from_console(vc->vc_num);
|
[PATCH] fbcon: Console Rotation - Prepare fbcon for console rotation
This patch series implements generic code to rotate the console at 90, 180,
and 270 degrees. The implementation is completely done in the framebuffer
console level, thus no changes to the framebuffer layer or to the drivers
are needed.
Console rotation is required by some Sharp-based devices where the natural
orientation of the display is not at 0 degrees. Also, users that have
displays that can pivot will benefit by having a console in portrait mode
if they so desire.
The choice to implement the code in the console layer rather than in the
framebuffer layer is due to the following reasons:
- it's fast
- it does not require driver changes
- it can coexist with devices that can rotate the display at the hardware level
- it complements graphics applications that can do display rotation
The changes to core fbcon are minimal-- recognition of the console
rotation angle so it can swap directions, origins and axes (xres vs yres,
xpanstep vs ypanstep, xoffset vs yoffset, etc) and storage of the rotation
angle per display. The bulk of the code that does the actual drawing to the
screen are placed in separate files. Each angle of rotation has separate
methods (bmove, clear, putcs, cursor, update_start which is derived from
update_var, and clear_margins). To mimimize processing time, the fontdata
are pre-rotated at each console switch (only if the font or the angle has
changed).
The option can be compiled out (CONFIG_FRAMEBUFFER_CONSOLE_ROTATION = n) if
rotation is not needed.
Choosing the rotation angle can be done in several ways:
1. boot option fbcon=rotate:n, where
n = 0 - normal
n = 1 - 90 degrees (clockwise)
n = 2 - 180 degrees (upside down)
n = 3 - 270 degrees (counterclockwise)
2. echo n > /sys/class/graphics/fb[num]/con_rotate
where n is the same as described above. It sets the angle of rotation
of the current console
3 echo n > /sys/class/graphics/fb[num]/con_rotate_all
where n is the same as described above. Globally sets the angle of
rotation.
GOTCHAS:
The option, especially at angles of 90 and 270 degrees, will exercise
the least used code of drivers. Namely, at these angles, panning is done
in the x-axis, so it can reveal bugs in the driver if xpanstep is set
incorrectly. A workaround is to set xpanstep = 0.
Secondly, at these angles, the framebuffer memory access can be
unaligned if (fontheight * bpp) % 32 ~= 0 which can reveal bugs in the drivers
imageblit, fillrect and copyarea functions. (I think cfbfillrect may have
this buglet). A workaround is to use a standard 8x16 font.
Speed:
The scrolling speed difference between 0 and 180 degrees is minimal,
somewhere areound 1-2%. At 90 or 270 degress, speed drops down to a vicinity
of 30-40%. This is understandable because the blit direction is across the
framebuffer "direction." Scrolling will be helped at these angles if xpanstep
is not equal to zero, use of 8x16 fonts, and setting xres_virtual >= xres * 2.
Note: The code is tested on little-endian only, so I don't know if it will
work in big-endian. Please let me know, it will take only less than a minute
of your time.
This patch prepares fbcon for console rotation and contains the following
changes:
- add rotate field in struct fbcon_ops to keep fbcon's current rotation
angle
- add con_rotate field in struct display to store per-display rotation angle
- create a private copy of the current var to fbcon. This will prevent
fbcon from directly manipulating info->var, especially the fields xoffset,
yoffset and vmode.
- add ability to swap pertinent axes (xres, yres; xpanstep, ypanstep; etc)
depending on the rotation angle
- change global update_var() (function that sets the screen start address)
as an fbcon method update_start. This is required because the axes, start
offset, and/or direction can be reversed depending on the rotation angle.
- add fbcon method rotate_font() which will rotate each character bitmap to
the correct angle of rotation.
- add fbcon boot option 'rotate' to select the angle of rotation at bootime.
Currently does nothing until all patches are applied.
Signed-off-by: Antonino Daplas <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-11-09 05:39:09 +00:00
|
|
|
struct fbcon_ops *ops = info->fbcon_par;
|
2019-05-28 09:02:39 +00:00
|
|
|
struct fbcon_display *p = &fb_display[vc->vc_num];
|
2005-04-16 22:20:36 +00:00
|
|
|
struct fb_var_screeninfo var = info->var;
|
[PATCH] fbcon: Console Rotation - Prepare fbcon for console rotation
This patch series implements generic code to rotate the console at 90, 180,
and 270 degrees. The implementation is completely done in the framebuffer
console level, thus no changes to the framebuffer layer or to the drivers
are needed.
Console rotation is required by some Sharp-based devices where the natural
orientation of the display is not at 0 degrees. Also, users that have
displays that can pivot will benefit by having a console in portrait mode
if they so desire.
The choice to implement the code in the console layer rather than in the
framebuffer layer is due to the following reasons:
- it's fast
- it does not require driver changes
- it can coexist with devices that can rotate the display at the hardware level
- it complements graphics applications that can do display rotation
The changes to core fbcon are minimal-- recognition of the console
rotation angle so it can swap directions, origins and axes (xres vs yres,
xpanstep vs ypanstep, xoffset vs yoffset, etc) and storage of the rotation
angle per display. The bulk of the code that does the actual drawing to the
screen are placed in separate files. Each angle of rotation has separate
methods (bmove, clear, putcs, cursor, update_start which is derived from
update_var, and clear_margins). To mimimize processing time, the fontdata
are pre-rotated at each console switch (only if the font or the angle has
changed).
The option can be compiled out (CONFIG_FRAMEBUFFER_CONSOLE_ROTATION = n) if
rotation is not needed.
Choosing the rotation angle can be done in several ways:
1. boot option fbcon=rotate:n, where
n = 0 - normal
n = 1 - 90 degrees (clockwise)
n = 2 - 180 degrees (upside down)
n = 3 - 270 degrees (counterclockwise)
2. echo n > /sys/class/graphics/fb[num]/con_rotate
where n is the same as described above. It sets the angle of rotation
of the current console
3 echo n > /sys/class/graphics/fb[num]/con_rotate_all
where n is the same as described above. Globally sets the angle of
rotation.
GOTCHAS:
The option, especially at angles of 90 and 270 degrees, will exercise
the least used code of drivers. Namely, at these angles, panning is done
in the x-axis, so it can reveal bugs in the driver if xpanstep is set
incorrectly. A workaround is to set xpanstep = 0.
Secondly, at these angles, the framebuffer memory access can be
unaligned if (fontheight * bpp) % 32 ~= 0 which can reveal bugs in the drivers
imageblit, fillrect and copyarea functions. (I think cfbfillrect may have
this buglet). A workaround is to use a standard 8x16 font.
Speed:
The scrolling speed difference between 0 and 180 degrees is minimal,
somewhere areound 1-2%. At 90 or 270 degress, speed drops down to a vicinity
of 30-40%. This is understandable because the blit direction is across the
framebuffer "direction." Scrolling will be helped at these angles if xpanstep
is not equal to zero, use of 8x16 fonts, and setting xres_virtual >= xres * 2.
Note: The code is tested on little-endian only, so I don't know if it will
work in big-endian. Please let me know, it will take only less than a minute
of your time.
This patch prepares fbcon for console rotation and contains the following
changes:
- add rotate field in struct fbcon_ops to keep fbcon's current rotation
angle
- add con_rotate field in struct display to store per-display rotation angle
- create a private copy of the current var to fbcon. This will prevent
fbcon from directly manipulating info->var, especially the fields xoffset,
yoffset and vmode.
- add ability to swap pertinent axes (xres, yres; xpanstep, ypanstep; etc)
depending on the rotation angle
- change global update_var() (function that sets the screen start address)
as an fbcon method update_start. This is required because the axes, start
offset, and/or direction can be reversed depending on the rotation angle.
- add fbcon method rotate_font() which will rotate each character bitmap to
the correct angle of rotation.
- add fbcon boot option 'rotate' to select the angle of rotation at bootime.
Currently does nothing until all patches are applied.
Signed-off-by: Antonino Daplas <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-11-09 05:39:09 +00:00
|
|
|
int x_diff, y_diff, virt_w, virt_h, virt_fw, virt_fh;
|
|
|
|
|
2020-09-10 22:57:06 +00:00
|
|
|
if (p->userfont && FNTSIZE(vc->vc_font.data)) {
|
2020-07-31 16:33:11 +00:00
|
|
|
int size;
|
|
|
|
int pitch = PITCH(vc->vc_font.width);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If user font, ensure that a possible change to user font
|
|
|
|
* height or width will not allow a font data out-of-bounds access.
|
|
|
|
* NOTE: must use original charcount in calculation as font
|
|
|
|
* charcount can change and cannot be used to determine the
|
|
|
|
* font data allocated size.
|
|
|
|
*/
|
|
|
|
if (pitch <= 0)
|
|
|
|
return -EINVAL;
|
fbcon: Avoid using FNTCHARCNT() and hard-coded built-in font charcount
For user-provided fonts, the framebuffer layer is using a magic
negative-indexing macro, FNTCHARCNT(), to keep track of their number of
characters:
#define FNTCHARCNT(fd) (((int *)(fd))[-3])
For built-in fonts, it is using hard-coded values (256). This results in
something like the following:
map.length = (ops->p->userfont) ?
FNTCHARCNT(ops->p->fontdata) : 256;
This is unsatisfactory. In fact, there is already a `charcount` field in
our virtual console descriptor (see `struct console_font` inside `struct
vc_data`), let us use it:
map.length = vc->vc_font.charcount;
Recently we added a `charcount` field to `struct font_desc`. Use it to set
`vc->vc_font.charcount` properly. The idea is:
- We only use FNTCHARCNT() on `vc->vc_font.data` and `p->fontdata`.
Assume FNTCHARCNT() is working as intended;
- Whenever `vc->vc_font.data` is set, also set `vc->vc_font.charcount`
properly;
- We can now replace `FNTCHARCNT(vc->vc_font.data)` with
`vc->vc_font.charcount`;
- Since `p->fontdata` always point to the same font data buffer with
`vc->vc_font.data`, we can also replace `FNTCHARCNT(p->fontdata)` with
`vc->vc_font.charcount`.
In conclusion, set `vc->vc_font.charcount` properly in fbcon_startup(),
fbcon_init(), fbcon_set_disp() and fbcon_do_set_font(), then replace
FNTCHARCNT() with `vc->vc_font.charcount`. No more if-else between
negative-indexing macros and hard-coded values.
Do not include <linux/font.h> in fbcon_rotate.c and tileblit.c, since they
no longer need it.
Depends on patch "Fonts: Add charcount field to font_desc".
Suggested-by: Daniel Vetter <daniel@ffwll.ch>
Signed-off-by: Peilin Ye <yepeilin.cs@gmail.com>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/e460a5780e54e3022661d5f09555144583b4cc59.1605169912.git.yepeilin.cs@gmail.com
2020-11-12 12:15:22 +00:00
|
|
|
size = CALC_FONTSZ(vc->vc_font.height, pitch, vc->vc_font.charcount);
|
2020-07-31 16:33:11 +00:00
|
|
|
if (size > FNTSIZE(vc->vc_font.data))
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
[PATCH] fbcon: Console Rotation - Prepare fbcon for console rotation
This patch series implements generic code to rotate the console at 90, 180,
and 270 degrees. The implementation is completely done in the framebuffer
console level, thus no changes to the framebuffer layer or to the drivers
are needed.
Console rotation is required by some Sharp-based devices where the natural
orientation of the display is not at 0 degrees. Also, users that have
displays that can pivot will benefit by having a console in portrait mode
if they so desire.
The choice to implement the code in the console layer rather than in the
framebuffer layer is due to the following reasons:
- it's fast
- it does not require driver changes
- it can coexist with devices that can rotate the display at the hardware level
- it complements graphics applications that can do display rotation
The changes to core fbcon are minimal-- recognition of the console
rotation angle so it can swap directions, origins and axes (xres vs yres,
xpanstep vs ypanstep, xoffset vs yoffset, etc) and storage of the rotation
angle per display. The bulk of the code that does the actual drawing to the
screen are placed in separate files. Each angle of rotation has separate
methods (bmove, clear, putcs, cursor, update_start which is derived from
update_var, and clear_margins). To mimimize processing time, the fontdata
are pre-rotated at each console switch (only if the font or the angle has
changed).
The option can be compiled out (CONFIG_FRAMEBUFFER_CONSOLE_ROTATION = n) if
rotation is not needed.
Choosing the rotation angle can be done in several ways:
1. boot option fbcon=rotate:n, where
n = 0 - normal
n = 1 - 90 degrees (clockwise)
n = 2 - 180 degrees (upside down)
n = 3 - 270 degrees (counterclockwise)
2. echo n > /sys/class/graphics/fb[num]/con_rotate
where n is the same as described above. It sets the angle of rotation
of the current console
3 echo n > /sys/class/graphics/fb[num]/con_rotate_all
where n is the same as described above. Globally sets the angle of
rotation.
GOTCHAS:
The option, especially at angles of 90 and 270 degrees, will exercise
the least used code of drivers. Namely, at these angles, panning is done
in the x-axis, so it can reveal bugs in the driver if xpanstep is set
incorrectly. A workaround is to set xpanstep = 0.
Secondly, at these angles, the framebuffer memory access can be
unaligned if (fontheight * bpp) % 32 ~= 0 which can reveal bugs in the drivers
imageblit, fillrect and copyarea functions. (I think cfbfillrect may have
this buglet). A workaround is to use a standard 8x16 font.
Speed:
The scrolling speed difference between 0 and 180 degrees is minimal,
somewhere areound 1-2%. At 90 or 270 degress, speed drops down to a vicinity
of 30-40%. This is understandable because the blit direction is across the
framebuffer "direction." Scrolling will be helped at these angles if xpanstep
is not equal to zero, use of 8x16 fonts, and setting xres_virtual >= xres * 2.
Note: The code is tested on little-endian only, so I don't know if it will
work in big-endian. Please let me know, it will take only less than a minute
of your time.
This patch prepares fbcon for console rotation and contains the following
changes:
- add rotate field in struct fbcon_ops to keep fbcon's current rotation
angle
- add con_rotate field in struct display to store per-display rotation angle
- create a private copy of the current var to fbcon. This will prevent
fbcon from directly manipulating info->var, especially the fields xoffset,
yoffset and vmode.
- add ability to swap pertinent axes (xres, yres; xpanstep, ypanstep; etc)
depending on the rotation angle
- change global update_var() (function that sets the screen start address)
as an fbcon method update_start. This is required because the axes, start
offset, and/or direction can be reversed depending on the rotation angle.
- add fbcon method rotate_font() which will rotate each character bitmap to
the correct angle of rotation.
- add fbcon boot option 'rotate' to select the angle of rotation at bootime.
Currently does nothing until all patches are applied.
Signed-off-by: Antonino Daplas <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-11-09 05:39:09 +00:00
|
|
|
virt_w = FBCON_SWAP(ops->rotate, width, height);
|
|
|
|
virt_h = FBCON_SWAP(ops->rotate, height, width);
|
|
|
|
virt_fw = FBCON_SWAP(ops->rotate, vc->vc_font.width,
|
|
|
|
vc->vc_font.height);
|
|
|
|
virt_fh = FBCON_SWAP(ops->rotate, vc->vc_font.height,
|
|
|
|
vc->vc_font.width);
|
|
|
|
var.xres = virt_w * virt_fw;
|
|
|
|
var.yres = virt_h * virt_fh;
|
2005-04-16 22:20:36 +00:00
|
|
|
x_diff = info->var.xres - var.xres;
|
|
|
|
y_diff = info->var.yres - var.yres;
|
[PATCH] fbcon: Console Rotation - Prepare fbcon for console rotation
This patch series implements generic code to rotate the console at 90, 180,
and 270 degrees. The implementation is completely done in the framebuffer
console level, thus no changes to the framebuffer layer or to the drivers
are needed.
Console rotation is required by some Sharp-based devices where the natural
orientation of the display is not at 0 degrees. Also, users that have
displays that can pivot will benefit by having a console in portrait mode
if they so desire.
The choice to implement the code in the console layer rather than in the
framebuffer layer is due to the following reasons:
- it's fast
- it does not require driver changes
- it can coexist with devices that can rotate the display at the hardware level
- it complements graphics applications that can do display rotation
The changes to core fbcon are minimal-- recognition of the console
rotation angle so it can swap directions, origins and axes (xres vs yres,
xpanstep vs ypanstep, xoffset vs yoffset, etc) and storage of the rotation
angle per display. The bulk of the code that does the actual drawing to the
screen are placed in separate files. Each angle of rotation has separate
methods (bmove, clear, putcs, cursor, update_start which is derived from
update_var, and clear_margins). To mimimize processing time, the fontdata
are pre-rotated at each console switch (only if the font or the angle has
changed).
The option can be compiled out (CONFIG_FRAMEBUFFER_CONSOLE_ROTATION = n) if
rotation is not needed.
Choosing the rotation angle can be done in several ways:
1. boot option fbcon=rotate:n, where
n = 0 - normal
n = 1 - 90 degrees (clockwise)
n = 2 - 180 degrees (upside down)
n = 3 - 270 degrees (counterclockwise)
2. echo n > /sys/class/graphics/fb[num]/con_rotate
where n is the same as described above. It sets the angle of rotation
of the current console
3 echo n > /sys/class/graphics/fb[num]/con_rotate_all
where n is the same as described above. Globally sets the angle of
rotation.
GOTCHAS:
The option, especially at angles of 90 and 270 degrees, will exercise
the least used code of drivers. Namely, at these angles, panning is done
in the x-axis, so it can reveal bugs in the driver if xpanstep is set
incorrectly. A workaround is to set xpanstep = 0.
Secondly, at these angles, the framebuffer memory access can be
unaligned if (fontheight * bpp) % 32 ~= 0 which can reveal bugs in the drivers
imageblit, fillrect and copyarea functions. (I think cfbfillrect may have
this buglet). A workaround is to use a standard 8x16 font.
Speed:
The scrolling speed difference between 0 and 180 degrees is minimal,
somewhere areound 1-2%. At 90 or 270 degress, speed drops down to a vicinity
of 30-40%. This is understandable because the blit direction is across the
framebuffer "direction." Scrolling will be helped at these angles if xpanstep
is not equal to zero, use of 8x16 fonts, and setting xres_virtual >= xres * 2.
Note: The code is tested on little-endian only, so I don't know if it will
work in big-endian. Please let me know, it will take only less than a minute
of your time.
This patch prepares fbcon for console rotation and contains the following
changes:
- add rotate field in struct fbcon_ops to keep fbcon's current rotation
angle
- add con_rotate field in struct display to store per-display rotation angle
- create a private copy of the current var to fbcon. This will prevent
fbcon from directly manipulating info->var, especially the fields xoffset,
yoffset and vmode.
- add ability to swap pertinent axes (xres, yres; xpanstep, ypanstep; etc)
depending on the rotation angle
- change global update_var() (function that sets the screen start address)
as an fbcon method update_start. This is required because the axes, start
offset, and/or direction can be reversed depending on the rotation angle.
- add fbcon method rotate_font() which will rotate each character bitmap to
the correct angle of rotation.
- add fbcon boot option 'rotate' to select the angle of rotation at bootime.
Currently does nothing until all patches are applied.
Signed-off-by: Antonino Daplas <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-11-09 05:39:09 +00:00
|
|
|
if (x_diff < 0 || x_diff > virt_fw ||
|
|
|
|
y_diff < 0 || y_diff > virt_fh) {
|
2007-02-12 08:55:19 +00:00
|
|
|
const struct fb_videomode *mode;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2020-11-28 22:40:48 +00:00
|
|
|
pr_debug("attempting resize %ix%i\n", var.xres, var.yres);
|
2005-04-16 22:20:36 +00:00
|
|
|
mode = fb_find_best_mode(&var, &info->modelist);
|
|
|
|
if (mode == NULL)
|
|
|
|
return -EINVAL;
|
2005-11-07 09:00:37 +00:00
|
|
|
display_to_var(&var, p);
|
2005-04-16 22:20:36 +00:00
|
|
|
fb_videomode_to_var(&var, mode);
|
2005-11-07 09:00:37 +00:00
|
|
|
|
[PATCH] fbcon: Console Rotation - Prepare fbcon for console rotation
This patch series implements generic code to rotate the console at 90, 180,
and 270 degrees. The implementation is completely done in the framebuffer
console level, thus no changes to the framebuffer layer or to the drivers
are needed.
Console rotation is required by some Sharp-based devices where the natural
orientation of the display is not at 0 degrees. Also, users that have
displays that can pivot will benefit by having a console in portrait mode
if they so desire.
The choice to implement the code in the console layer rather than in the
framebuffer layer is due to the following reasons:
- it's fast
- it does not require driver changes
- it can coexist with devices that can rotate the display at the hardware level
- it complements graphics applications that can do display rotation
The changes to core fbcon are minimal-- recognition of the console
rotation angle so it can swap directions, origins and axes (xres vs yres,
xpanstep vs ypanstep, xoffset vs yoffset, etc) and storage of the rotation
angle per display. The bulk of the code that does the actual drawing to the
screen are placed in separate files. Each angle of rotation has separate
methods (bmove, clear, putcs, cursor, update_start which is derived from
update_var, and clear_margins). To mimimize processing time, the fontdata
are pre-rotated at each console switch (only if the font or the angle has
changed).
The option can be compiled out (CONFIG_FRAMEBUFFER_CONSOLE_ROTATION = n) if
rotation is not needed.
Choosing the rotation angle can be done in several ways:
1. boot option fbcon=rotate:n, where
n = 0 - normal
n = 1 - 90 degrees (clockwise)
n = 2 - 180 degrees (upside down)
n = 3 - 270 degrees (counterclockwise)
2. echo n > /sys/class/graphics/fb[num]/con_rotate
where n is the same as described above. It sets the angle of rotation
of the current console
3 echo n > /sys/class/graphics/fb[num]/con_rotate_all
where n is the same as described above. Globally sets the angle of
rotation.
GOTCHAS:
The option, especially at angles of 90 and 270 degrees, will exercise
the least used code of drivers. Namely, at these angles, panning is done
in the x-axis, so it can reveal bugs in the driver if xpanstep is set
incorrectly. A workaround is to set xpanstep = 0.
Secondly, at these angles, the framebuffer memory access can be
unaligned if (fontheight * bpp) % 32 ~= 0 which can reveal bugs in the drivers
imageblit, fillrect and copyarea functions. (I think cfbfillrect may have
this buglet). A workaround is to use a standard 8x16 font.
Speed:
The scrolling speed difference between 0 and 180 degrees is minimal,
somewhere areound 1-2%. At 90 or 270 degress, speed drops down to a vicinity
of 30-40%. This is understandable because the blit direction is across the
framebuffer "direction." Scrolling will be helped at these angles if xpanstep
is not equal to zero, use of 8x16 fonts, and setting xres_virtual >= xres * 2.
Note: The code is tested on little-endian only, so I don't know if it will
work in big-endian. Please let me know, it will take only less than a minute
of your time.
This patch prepares fbcon for console rotation and contains the following
changes:
- add rotate field in struct fbcon_ops to keep fbcon's current rotation
angle
- add con_rotate field in struct display to store per-display rotation angle
- create a private copy of the current var to fbcon. This will prevent
fbcon from directly manipulating info->var, especially the fields xoffset,
yoffset and vmode.
- add ability to swap pertinent axes (xres, yres; xpanstep, ypanstep; etc)
depending on the rotation angle
- change global update_var() (function that sets the screen start address)
as an fbcon method update_start. This is required because the axes, start
offset, and/or direction can be reversed depending on the rotation angle.
- add fbcon method rotate_font() which will rotate each character bitmap to
the correct angle of rotation.
- add fbcon boot option 'rotate' to select the angle of rotation at bootime.
Currently does nothing until all patches are applied.
Signed-off-by: Antonino Daplas <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-11-09 05:39:09 +00:00
|
|
|
if (virt_w > var.xres/virt_fw || virt_h > var.yres/virt_fh)
|
2005-04-16 22:20:36 +00:00
|
|
|
return -EINVAL;
|
|
|
|
|
2020-11-28 22:40:48 +00:00
|
|
|
pr_debug("resize now %ix%i\n", var.xres, var.yres);
|
tty: vt: always invoke vc->vc_sw->con_resize callback
syzbot is reporting OOB write at vga16fb_imageblit() [1], for
resize_screen() from ioctl(VT_RESIZE) returns 0 without checking whether
requested rows/columns fit the amount of memory reserved for the graphical
screen if current mode is KD_GRAPHICS.
----------
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/kd.h>
#include <linux/vt.h>
int main(int argc, char *argv[])
{
const int fd = open("/dev/char/4:1", O_RDWR);
struct vt_sizes vt = { 0x4100, 2 };
ioctl(fd, KDSETMODE, KD_GRAPHICS);
ioctl(fd, VT_RESIZE, &vt);
ioctl(fd, KDSETMODE, KD_TEXT);
return 0;
}
----------
Allow framebuffer drivers to return -EINVAL, by moving vc->vc_mode !=
KD_GRAPHICS check from resize_screen() to fbcon_resize().
Link: https://syzkaller.appspot.com/bug?extid=1f29e126cf461c4de3b3 [1]
Reported-by: syzbot <syzbot+1f29e126cf461c4de3b3@syzkaller.appspotmail.com>
Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Tested-by: syzbot <syzbot+1f29e126cf461c4de3b3@syzkaller.appspotmail.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2021-05-15 03:00:37 +00:00
|
|
|
if (con_is_visible(vc) && vc->vc_mode == KD_TEXT) {
|
2005-04-16 22:20:36 +00:00
|
|
|
var.activate = FB_ACTIVATE_NOW |
|
|
|
|
FB_ACTIVATE_FORCE;
|
|
|
|
fb_set_var(info, &var);
|
|
|
|
}
|
|
|
|
var_to_display(p, &info->var, info);
|
[PATCH] fbcon: Console Rotation - Prepare fbcon for console rotation
This patch series implements generic code to rotate the console at 90, 180,
and 270 degrees. The implementation is completely done in the framebuffer
console level, thus no changes to the framebuffer layer or to the drivers
are needed.
Console rotation is required by some Sharp-based devices where the natural
orientation of the display is not at 0 degrees. Also, users that have
displays that can pivot will benefit by having a console in portrait mode
if they so desire.
The choice to implement the code in the console layer rather than in the
framebuffer layer is due to the following reasons:
- it's fast
- it does not require driver changes
- it can coexist with devices that can rotate the display at the hardware level
- it complements graphics applications that can do display rotation
The changes to core fbcon are minimal-- recognition of the console
rotation angle so it can swap directions, origins and axes (xres vs yres,
xpanstep vs ypanstep, xoffset vs yoffset, etc) and storage of the rotation
angle per display. The bulk of the code that does the actual drawing to the
screen are placed in separate files. Each angle of rotation has separate
methods (bmove, clear, putcs, cursor, update_start which is derived from
update_var, and clear_margins). To mimimize processing time, the fontdata
are pre-rotated at each console switch (only if the font or the angle has
changed).
The option can be compiled out (CONFIG_FRAMEBUFFER_CONSOLE_ROTATION = n) if
rotation is not needed.
Choosing the rotation angle can be done in several ways:
1. boot option fbcon=rotate:n, where
n = 0 - normal
n = 1 - 90 degrees (clockwise)
n = 2 - 180 degrees (upside down)
n = 3 - 270 degrees (counterclockwise)
2. echo n > /sys/class/graphics/fb[num]/con_rotate
where n is the same as described above. It sets the angle of rotation
of the current console
3 echo n > /sys/class/graphics/fb[num]/con_rotate_all
where n is the same as described above. Globally sets the angle of
rotation.
GOTCHAS:
The option, especially at angles of 90 and 270 degrees, will exercise
the least used code of drivers. Namely, at these angles, panning is done
in the x-axis, so it can reveal bugs in the driver if xpanstep is set
incorrectly. A workaround is to set xpanstep = 0.
Secondly, at these angles, the framebuffer memory access can be
unaligned if (fontheight * bpp) % 32 ~= 0 which can reveal bugs in the drivers
imageblit, fillrect and copyarea functions. (I think cfbfillrect may have
this buglet). A workaround is to use a standard 8x16 font.
Speed:
The scrolling speed difference between 0 and 180 degrees is minimal,
somewhere areound 1-2%. At 90 or 270 degress, speed drops down to a vicinity
of 30-40%. This is understandable because the blit direction is across the
framebuffer "direction." Scrolling will be helped at these angles if xpanstep
is not equal to zero, use of 8x16 fonts, and setting xres_virtual >= xres * 2.
Note: The code is tested on little-endian only, so I don't know if it will
work in big-endian. Please let me know, it will take only less than a minute
of your time.
This patch prepares fbcon for console rotation and contains the following
changes:
- add rotate field in struct fbcon_ops to keep fbcon's current rotation
angle
- add con_rotate field in struct display to store per-display rotation angle
- create a private copy of the current var to fbcon. This will prevent
fbcon from directly manipulating info->var, especially the fields xoffset,
yoffset and vmode.
- add ability to swap pertinent axes (xres, yres; xpanstep, ypanstep; etc)
depending on the rotation angle
- change global update_var() (function that sets the screen start address)
as an fbcon method update_start. This is required because the axes, start
offset, and/or direction can be reversed depending on the rotation angle.
- add fbcon method rotate_font() which will rotate each character bitmap to
the correct angle of rotation.
- add fbcon boot option 'rotate' to select the angle of rotation at bootime.
Currently does nothing until all patches are applied.
Signed-off-by: Antonino Daplas <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-11-09 05:39:09 +00:00
|
|
|
ops->var = info->var;
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
updatescrollmode(p, info, vc);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int fbcon_switch(struct vc_data *vc)
|
|
|
|
{
|
2005-09-09 20:10:00 +00:00
|
|
|
struct fb_info *info, *old_info = NULL;
|
[PATCH] fbcon: Console Rotation - Prepare fbcon for console rotation
This patch series implements generic code to rotate the console at 90, 180,
and 270 degrees. The implementation is completely done in the framebuffer
console level, thus no changes to the framebuffer layer or to the drivers
are needed.
Console rotation is required by some Sharp-based devices where the natural
orientation of the display is not at 0 degrees. Also, users that have
displays that can pivot will benefit by having a console in portrait mode
if they so desire.
The choice to implement the code in the console layer rather than in the
framebuffer layer is due to the following reasons:
- it's fast
- it does not require driver changes
- it can coexist with devices that can rotate the display at the hardware level
- it complements graphics applications that can do display rotation
The changes to core fbcon are minimal-- recognition of the console
rotation angle so it can swap directions, origins and axes (xres vs yres,
xpanstep vs ypanstep, xoffset vs yoffset, etc) and storage of the rotation
angle per display. The bulk of the code that does the actual drawing to the
screen are placed in separate files. Each angle of rotation has separate
methods (bmove, clear, putcs, cursor, update_start which is derived from
update_var, and clear_margins). To mimimize processing time, the fontdata
are pre-rotated at each console switch (only if the font or the angle has
changed).
The option can be compiled out (CONFIG_FRAMEBUFFER_CONSOLE_ROTATION = n) if
rotation is not needed.
Choosing the rotation angle can be done in several ways:
1. boot option fbcon=rotate:n, where
n = 0 - normal
n = 1 - 90 degrees (clockwise)
n = 2 - 180 degrees (upside down)
n = 3 - 270 degrees (counterclockwise)
2. echo n > /sys/class/graphics/fb[num]/con_rotate
where n is the same as described above. It sets the angle of rotation
of the current console
3 echo n > /sys/class/graphics/fb[num]/con_rotate_all
where n is the same as described above. Globally sets the angle of
rotation.
GOTCHAS:
The option, especially at angles of 90 and 270 degrees, will exercise
the least used code of drivers. Namely, at these angles, panning is done
in the x-axis, so it can reveal bugs in the driver if xpanstep is set
incorrectly. A workaround is to set xpanstep = 0.
Secondly, at these angles, the framebuffer memory access can be
unaligned if (fontheight * bpp) % 32 ~= 0 which can reveal bugs in the drivers
imageblit, fillrect and copyarea functions. (I think cfbfillrect may have
this buglet). A workaround is to use a standard 8x16 font.
Speed:
The scrolling speed difference between 0 and 180 degrees is minimal,
somewhere areound 1-2%. At 90 or 270 degress, speed drops down to a vicinity
of 30-40%. This is understandable because the blit direction is across the
framebuffer "direction." Scrolling will be helped at these angles if xpanstep
is not equal to zero, use of 8x16 fonts, and setting xres_virtual >= xres * 2.
Note: The code is tested on little-endian only, so I don't know if it will
work in big-endian. Please let me know, it will take only less than a minute
of your time.
This patch prepares fbcon for console rotation and contains the following
changes:
- add rotate field in struct fbcon_ops to keep fbcon's current rotation
angle
- add con_rotate field in struct display to store per-display rotation angle
- create a private copy of the current var to fbcon. This will prevent
fbcon from directly manipulating info->var, especially the fields xoffset,
yoffset and vmode.
- add ability to swap pertinent axes (xres, yres; xpanstep, ypanstep; etc)
depending on the rotation angle
- change global update_var() (function that sets the screen start address)
as an fbcon method update_start. This is required because the axes, start
offset, and/or direction can be reversed depending on the rotation angle.
- add fbcon method rotate_font() which will rotate each character bitmap to
the correct angle of rotation.
- add fbcon boot option 'rotate' to select the angle of rotation at bootime.
Currently does nothing until all patches are applied.
Signed-off-by: Antonino Daplas <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-11-09 05:39:09 +00:00
|
|
|
struct fbcon_ops *ops;
|
2019-05-28 09:02:39 +00:00
|
|
|
struct fbcon_display *p = &fb_display[vc->vc_num];
|
2005-04-16 22:20:36 +00:00
|
|
|
struct fb_var_screeninfo var;
|
fbcon: Avoid using FNTCHARCNT() and hard-coded built-in font charcount
For user-provided fonts, the framebuffer layer is using a magic
negative-indexing macro, FNTCHARCNT(), to keep track of their number of
characters:
#define FNTCHARCNT(fd) (((int *)(fd))[-3])
For built-in fonts, it is using hard-coded values (256). This results in
something like the following:
map.length = (ops->p->userfont) ?
FNTCHARCNT(ops->p->fontdata) : 256;
This is unsatisfactory. In fact, there is already a `charcount` field in
our virtual console descriptor (see `struct console_font` inside `struct
vc_data`), let us use it:
map.length = vc->vc_font.charcount;
Recently we added a `charcount` field to `struct font_desc`. Use it to set
`vc->vc_font.charcount` properly. The idea is:
- We only use FNTCHARCNT() on `vc->vc_font.data` and `p->fontdata`.
Assume FNTCHARCNT() is working as intended;
- Whenever `vc->vc_font.data` is set, also set `vc->vc_font.charcount`
properly;
- We can now replace `FNTCHARCNT(vc->vc_font.data)` with
`vc->vc_font.charcount`;
- Since `p->fontdata` always point to the same font data buffer with
`vc->vc_font.data`, we can also replace `FNTCHARCNT(p->fontdata)` with
`vc->vc_font.charcount`.
In conclusion, set `vc->vc_font.charcount` properly in fbcon_startup(),
fbcon_init(), fbcon_set_disp() and fbcon_do_set_font(), then replace
FNTCHARCNT() with `vc->vc_font.charcount`. No more if-else between
negative-indexing macros and hard-coded values.
Do not include <linux/font.h> in fbcon_rotate.c and tileblit.c, since they
no longer need it.
Depends on patch "Fonts: Add charcount field to font_desc".
Suggested-by: Daniel Vetter <daniel@ffwll.ch>
Signed-off-by: Peilin Ye <yepeilin.cs@gmail.com>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/e460a5780e54e3022661d5f09555144583b4cc59.1605169912.git.yepeilin.cs@gmail.com
2020-11-12 12:15:22 +00:00
|
|
|
int i, ret, prev_console;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2022-04-05 21:03:21 +00:00
|
|
|
info = fbcon_info_from_console(vc->vc_num);
|
[PATCH] fbcon: Console Rotation - Prepare fbcon for console rotation
This patch series implements generic code to rotate the console at 90, 180,
and 270 degrees. The implementation is completely done in the framebuffer
console level, thus no changes to the framebuffer layer or to the drivers
are needed.
Console rotation is required by some Sharp-based devices where the natural
orientation of the display is not at 0 degrees. Also, users that have
displays that can pivot will benefit by having a console in portrait mode
if they so desire.
The choice to implement the code in the console layer rather than in the
framebuffer layer is due to the following reasons:
- it's fast
- it does not require driver changes
- it can coexist with devices that can rotate the display at the hardware level
- it complements graphics applications that can do display rotation
The changes to core fbcon are minimal-- recognition of the console
rotation angle so it can swap directions, origins and axes (xres vs yres,
xpanstep vs ypanstep, xoffset vs yoffset, etc) and storage of the rotation
angle per display. The bulk of the code that does the actual drawing to the
screen are placed in separate files. Each angle of rotation has separate
methods (bmove, clear, putcs, cursor, update_start which is derived from
update_var, and clear_margins). To mimimize processing time, the fontdata
are pre-rotated at each console switch (only if the font or the angle has
changed).
The option can be compiled out (CONFIG_FRAMEBUFFER_CONSOLE_ROTATION = n) if
rotation is not needed.
Choosing the rotation angle can be done in several ways:
1. boot option fbcon=rotate:n, where
n = 0 - normal
n = 1 - 90 degrees (clockwise)
n = 2 - 180 degrees (upside down)
n = 3 - 270 degrees (counterclockwise)
2. echo n > /sys/class/graphics/fb[num]/con_rotate
where n is the same as described above. It sets the angle of rotation
of the current console
3 echo n > /sys/class/graphics/fb[num]/con_rotate_all
where n is the same as described above. Globally sets the angle of
rotation.
GOTCHAS:
The option, especially at angles of 90 and 270 degrees, will exercise
the least used code of drivers. Namely, at these angles, panning is done
in the x-axis, so it can reveal bugs in the driver if xpanstep is set
incorrectly. A workaround is to set xpanstep = 0.
Secondly, at these angles, the framebuffer memory access can be
unaligned if (fontheight * bpp) % 32 ~= 0 which can reveal bugs in the drivers
imageblit, fillrect and copyarea functions. (I think cfbfillrect may have
this buglet). A workaround is to use a standard 8x16 font.
Speed:
The scrolling speed difference between 0 and 180 degrees is minimal,
somewhere areound 1-2%. At 90 or 270 degress, speed drops down to a vicinity
of 30-40%. This is understandable because the blit direction is across the
framebuffer "direction." Scrolling will be helped at these angles if xpanstep
is not equal to zero, use of 8x16 fonts, and setting xres_virtual >= xres * 2.
Note: The code is tested on little-endian only, so I don't know if it will
work in big-endian. Please let me know, it will take only less than a minute
of your time.
This patch prepares fbcon for console rotation and contains the following
changes:
- add rotate field in struct fbcon_ops to keep fbcon's current rotation
angle
- add con_rotate field in struct display to store per-display rotation angle
- create a private copy of the current var to fbcon. This will prevent
fbcon from directly manipulating info->var, especially the fields xoffset,
yoffset and vmode.
- add ability to swap pertinent axes (xres, yres; xpanstep, ypanstep; etc)
depending on the rotation angle
- change global update_var() (function that sets the screen start address)
as an fbcon method update_start. This is required because the axes, start
offset, and/or direction can be reversed depending on the rotation angle.
- add fbcon method rotate_font() which will rotate each character bitmap to
the correct angle of rotation.
- add fbcon boot option 'rotate' to select the angle of rotation at bootime.
Currently does nothing until all patches are applied.
Signed-off-by: Antonino Daplas <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-11-09 05:39:09 +00:00
|
|
|
ops = info->fbcon_par;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
if (logo_shown >= 0) {
|
|
|
|
struct vc_data *conp2 = vc_cons[logo_shown].d;
|
|
|
|
|
|
|
|
if (conp2->vc_top == logo_lines
|
|
|
|
&& conp2->vc_bottom == conp2->vc_rows)
|
|
|
|
conp2->vc_top = 0;
|
|
|
|
logo_shown = FBCON_LOGO_CANSHOW;
|
|
|
|
}
|
|
|
|
|
[PATCH] fbcon: Console Rotation - Prepare fbcon for console rotation
This patch series implements generic code to rotate the console at 90, 180,
and 270 degrees. The implementation is completely done in the framebuffer
console level, thus no changes to the framebuffer layer or to the drivers
are needed.
Console rotation is required by some Sharp-based devices where the natural
orientation of the display is not at 0 degrees. Also, users that have
displays that can pivot will benefit by having a console in portrait mode
if they so desire.
The choice to implement the code in the console layer rather than in the
framebuffer layer is due to the following reasons:
- it's fast
- it does not require driver changes
- it can coexist with devices that can rotate the display at the hardware level
- it complements graphics applications that can do display rotation
The changes to core fbcon are minimal-- recognition of the console
rotation angle so it can swap directions, origins and axes (xres vs yres,
xpanstep vs ypanstep, xoffset vs yoffset, etc) and storage of the rotation
angle per display. The bulk of the code that does the actual drawing to the
screen are placed in separate files. Each angle of rotation has separate
methods (bmove, clear, putcs, cursor, update_start which is derived from
update_var, and clear_margins). To mimimize processing time, the fontdata
are pre-rotated at each console switch (only if the font or the angle has
changed).
The option can be compiled out (CONFIG_FRAMEBUFFER_CONSOLE_ROTATION = n) if
rotation is not needed.
Choosing the rotation angle can be done in several ways:
1. boot option fbcon=rotate:n, where
n = 0 - normal
n = 1 - 90 degrees (clockwise)
n = 2 - 180 degrees (upside down)
n = 3 - 270 degrees (counterclockwise)
2. echo n > /sys/class/graphics/fb[num]/con_rotate
where n is the same as described above. It sets the angle of rotation
of the current console
3 echo n > /sys/class/graphics/fb[num]/con_rotate_all
where n is the same as described above. Globally sets the angle of
rotation.
GOTCHAS:
The option, especially at angles of 90 and 270 degrees, will exercise
the least used code of drivers. Namely, at these angles, panning is done
in the x-axis, so it can reveal bugs in the driver if xpanstep is set
incorrectly. A workaround is to set xpanstep = 0.
Secondly, at these angles, the framebuffer memory access can be
unaligned if (fontheight * bpp) % 32 ~= 0 which can reveal bugs in the drivers
imageblit, fillrect and copyarea functions. (I think cfbfillrect may have
this buglet). A workaround is to use a standard 8x16 font.
Speed:
The scrolling speed difference between 0 and 180 degrees is minimal,
somewhere areound 1-2%. At 90 or 270 degress, speed drops down to a vicinity
of 30-40%. This is understandable because the blit direction is across the
framebuffer "direction." Scrolling will be helped at these angles if xpanstep
is not equal to zero, use of 8x16 fonts, and setting xres_virtual >= xres * 2.
Note: The code is tested on little-endian only, so I don't know if it will
work in big-endian. Please let me know, it will take only less than a minute
of your time.
This patch prepares fbcon for console rotation and contains the following
changes:
- add rotate field in struct fbcon_ops to keep fbcon's current rotation
angle
- add con_rotate field in struct display to store per-display rotation angle
- create a private copy of the current var to fbcon. This will prevent
fbcon from directly manipulating info->var, especially the fields xoffset,
yoffset and vmode.
- add ability to swap pertinent axes (xres, yres; xpanstep, ypanstep; etc)
depending on the rotation angle
- change global update_var() (function that sets the screen start address)
as an fbcon method update_start. This is required because the axes, start
offset, and/or direction can be reversed depending on the rotation angle.
- add fbcon method rotate_font() which will rotate each character bitmap to
the correct angle of rotation.
- add fbcon boot option 'rotate' to select the angle of rotation at bootime.
Currently does nothing until all patches are applied.
Signed-off-by: Antonino Daplas <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-11-09 05:39:09 +00:00
|
|
|
prev_console = ops->currcon;
|
2005-09-09 20:10:00 +00:00
|
|
|
if (prev_console != -1)
|
2022-04-05 21:03:21 +00:00
|
|
|
old_info = fbcon_info_from_console(prev_console);
|
2005-04-16 22:20:36 +00:00
|
|
|
/*
|
|
|
|
* FIXME: If we have multiple fbdev's loaded, we need to
|
|
|
|
* update all info->currcon. Perhaps, we can place this
|
|
|
|
* in a centralized structure, but this might break some
|
|
|
|
* drivers.
|
|
|
|
*
|
|
|
|
* info->currcon = vc->vc_num;
|
|
|
|
*/
|
2022-04-05 21:03:35 +00:00
|
|
|
fbcon_for_each_registered_fb(i) {
|
|
|
|
if (fbcon_registered_fb[i]->fbcon_par) {
|
|
|
|
struct fbcon_ops *o = fbcon_registered_fb[i]->fbcon_par;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
[PATCH] fbcon: Console Rotation - Prepare fbcon for console rotation
This patch series implements generic code to rotate the console at 90, 180,
and 270 degrees. The implementation is completely done in the framebuffer
console level, thus no changes to the framebuffer layer or to the drivers
are needed.
Console rotation is required by some Sharp-based devices where the natural
orientation of the display is not at 0 degrees. Also, users that have
displays that can pivot will benefit by having a console in portrait mode
if they so desire.
The choice to implement the code in the console layer rather than in the
framebuffer layer is due to the following reasons:
- it's fast
- it does not require driver changes
- it can coexist with devices that can rotate the display at the hardware level
- it complements graphics applications that can do display rotation
The changes to core fbcon are minimal-- recognition of the console
rotation angle so it can swap directions, origins and axes (xres vs yres,
xpanstep vs ypanstep, xoffset vs yoffset, etc) and storage of the rotation
angle per display. The bulk of the code that does the actual drawing to the
screen are placed in separate files. Each angle of rotation has separate
methods (bmove, clear, putcs, cursor, update_start which is derived from
update_var, and clear_margins). To mimimize processing time, the fontdata
are pre-rotated at each console switch (only if the font or the angle has
changed).
The option can be compiled out (CONFIG_FRAMEBUFFER_CONSOLE_ROTATION = n) if
rotation is not needed.
Choosing the rotation angle can be done in several ways:
1. boot option fbcon=rotate:n, where
n = 0 - normal
n = 1 - 90 degrees (clockwise)
n = 2 - 180 degrees (upside down)
n = 3 - 270 degrees (counterclockwise)
2. echo n > /sys/class/graphics/fb[num]/con_rotate
where n is the same as described above. It sets the angle of rotation
of the current console
3 echo n > /sys/class/graphics/fb[num]/con_rotate_all
where n is the same as described above. Globally sets the angle of
rotation.
GOTCHAS:
The option, especially at angles of 90 and 270 degrees, will exercise
the least used code of drivers. Namely, at these angles, panning is done
in the x-axis, so it can reveal bugs in the driver if xpanstep is set
incorrectly. A workaround is to set xpanstep = 0.
Secondly, at these angles, the framebuffer memory access can be
unaligned if (fontheight * bpp) % 32 ~= 0 which can reveal bugs in the drivers
imageblit, fillrect and copyarea functions. (I think cfbfillrect may have
this buglet). A workaround is to use a standard 8x16 font.
Speed:
The scrolling speed difference between 0 and 180 degrees is minimal,
somewhere areound 1-2%. At 90 or 270 degress, speed drops down to a vicinity
of 30-40%. This is understandable because the blit direction is across the
framebuffer "direction." Scrolling will be helped at these angles if xpanstep
is not equal to zero, use of 8x16 fonts, and setting xres_virtual >= xres * 2.
Note: The code is tested on little-endian only, so I don't know if it will
work in big-endian. Please let me know, it will take only less than a minute
of your time.
This patch prepares fbcon for console rotation and contains the following
changes:
- add rotate field in struct fbcon_ops to keep fbcon's current rotation
angle
- add con_rotate field in struct display to store per-display rotation angle
- create a private copy of the current var to fbcon. This will prevent
fbcon from directly manipulating info->var, especially the fields xoffset,
yoffset and vmode.
- add ability to swap pertinent axes (xres, yres; xpanstep, ypanstep; etc)
depending on the rotation angle
- change global update_var() (function that sets the screen start address)
as an fbcon method update_start. This is required because the axes, start
offset, and/or direction can be reversed depending on the rotation angle.
- add fbcon method rotate_font() which will rotate each character bitmap to
the correct angle of rotation.
- add fbcon boot option 'rotate' to select the angle of rotation at bootime.
Currently does nothing until all patches are applied.
Signed-off-by: Antonino Daplas <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-11-09 05:39:09 +00:00
|
|
|
o->currcon = vc->vc_num;
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
memset(&var, 0, sizeof(struct fb_var_screeninfo));
|
|
|
|
display_to_var(&var, p);
|
|
|
|
var.activate = FB_ACTIVATE_NOW;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* make sure we don't unnecessarily trip the memcmp()
|
|
|
|
* in fb_set_var()
|
|
|
|
*/
|
|
|
|
info->var.activate = var.activate;
|
2008-06-06 05:46:33 +00:00
|
|
|
var.vmode |= info->var.vmode & ~FB_VMODE_MASK;
|
2005-04-16 22:20:36 +00:00
|
|
|
fb_set_var(info, &var);
|
[PATCH] fbcon: Console Rotation - Prepare fbcon for console rotation
This patch series implements generic code to rotate the console at 90, 180,
and 270 degrees. The implementation is completely done in the framebuffer
console level, thus no changes to the framebuffer layer or to the drivers
are needed.
Console rotation is required by some Sharp-based devices where the natural
orientation of the display is not at 0 degrees. Also, users that have
displays that can pivot will benefit by having a console in portrait mode
if they so desire.
The choice to implement the code in the console layer rather than in the
framebuffer layer is due to the following reasons:
- it's fast
- it does not require driver changes
- it can coexist with devices that can rotate the display at the hardware level
- it complements graphics applications that can do display rotation
The changes to core fbcon are minimal-- recognition of the console
rotation angle so it can swap directions, origins and axes (xres vs yres,
xpanstep vs ypanstep, xoffset vs yoffset, etc) and storage of the rotation
angle per display. The bulk of the code that does the actual drawing to the
screen are placed in separate files. Each angle of rotation has separate
methods (bmove, clear, putcs, cursor, update_start which is derived from
update_var, and clear_margins). To mimimize processing time, the fontdata
are pre-rotated at each console switch (only if the font or the angle has
changed).
The option can be compiled out (CONFIG_FRAMEBUFFER_CONSOLE_ROTATION = n) if
rotation is not needed.
Choosing the rotation angle can be done in several ways:
1. boot option fbcon=rotate:n, where
n = 0 - normal
n = 1 - 90 degrees (clockwise)
n = 2 - 180 degrees (upside down)
n = 3 - 270 degrees (counterclockwise)
2. echo n > /sys/class/graphics/fb[num]/con_rotate
where n is the same as described above. It sets the angle of rotation
of the current console
3 echo n > /sys/class/graphics/fb[num]/con_rotate_all
where n is the same as described above. Globally sets the angle of
rotation.
GOTCHAS:
The option, especially at angles of 90 and 270 degrees, will exercise
the least used code of drivers. Namely, at these angles, panning is done
in the x-axis, so it can reveal bugs in the driver if xpanstep is set
incorrectly. A workaround is to set xpanstep = 0.
Secondly, at these angles, the framebuffer memory access can be
unaligned if (fontheight * bpp) % 32 ~= 0 which can reveal bugs in the drivers
imageblit, fillrect and copyarea functions. (I think cfbfillrect may have
this buglet). A workaround is to use a standard 8x16 font.
Speed:
The scrolling speed difference between 0 and 180 degrees is minimal,
somewhere areound 1-2%. At 90 or 270 degress, speed drops down to a vicinity
of 30-40%. This is understandable because the blit direction is across the
framebuffer "direction." Scrolling will be helped at these angles if xpanstep
is not equal to zero, use of 8x16 fonts, and setting xres_virtual >= xres * 2.
Note: The code is tested on little-endian only, so I don't know if it will
work in big-endian. Please let me know, it will take only less than a minute
of your time.
This patch prepares fbcon for console rotation and contains the following
changes:
- add rotate field in struct fbcon_ops to keep fbcon's current rotation
angle
- add con_rotate field in struct display to store per-display rotation angle
- create a private copy of the current var to fbcon. This will prevent
fbcon from directly manipulating info->var, especially the fields xoffset,
yoffset and vmode.
- add ability to swap pertinent axes (xres, yres; xpanstep, ypanstep; etc)
depending on the rotation angle
- change global update_var() (function that sets the screen start address)
as an fbcon method update_start. This is required because the axes, start
offset, and/or direction can be reversed depending on the rotation angle.
- add fbcon method rotate_font() which will rotate each character bitmap to
the correct angle of rotation.
- add fbcon boot option 'rotate' to select the angle of rotation at bootime.
Currently does nothing until all patches are applied.
Signed-off-by: Antonino Daplas <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-11-09 05:39:09 +00:00
|
|
|
ops->var = info->var;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2005-12-13 06:17:19 +00:00
|
|
|
if (old_info != NULL && (old_info != info ||
|
|
|
|
info->flags & FBINFO_MISC_ALWAYS_SETPAR)) {
|
2009-09-22 23:47:44 +00:00
|
|
|
if (info->fbops->fb_set_par) {
|
|
|
|
ret = info->fbops->fb_set_par(info);
|
|
|
|
|
|
|
|
if (ret)
|
|
|
|
printk(KERN_ERR "fbcon_switch: detected "
|
|
|
|
"unhandled fb_set_par error, "
|
|
|
|
"error code %d\n", ret);
|
|
|
|
}
|
2006-01-10 04:53:44 +00:00
|
|
|
|
2006-06-26 07:27:06 +00:00
|
|
|
if (old_info != info)
|
2022-04-05 21:03:24 +00:00
|
|
|
fbcon_del_cursor_work(old_info);
|
2005-09-09 20:10:00 +00:00
|
|
|
}
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2006-10-03 08:14:48 +00:00
|
|
|
if (fbcon_is_inactive(vc, info) ||
|
|
|
|
ops->blank_state != FB_BLANK_UNBLANK)
|
2022-04-05 21:03:24 +00:00
|
|
|
fbcon_del_cursor_work(info);
|
2006-10-03 08:14:48 +00:00
|
|
|
else
|
2022-04-05 21:03:24 +00:00
|
|
|
fbcon_add_cursor_work(info);
|
2006-10-03 08:14:48 +00:00
|
|
|
|
2006-01-10 04:52:56 +00:00
|
|
|
set_blitting_type(vc, info);
|
[PATCH] fbcon: Console Rotation - Prepare fbcon for console rotation
This patch series implements generic code to rotate the console at 90, 180,
and 270 degrees. The implementation is completely done in the framebuffer
console level, thus no changes to the framebuffer layer or to the drivers
are needed.
Console rotation is required by some Sharp-based devices where the natural
orientation of the display is not at 0 degrees. Also, users that have
displays that can pivot will benefit by having a console in portrait mode
if they so desire.
The choice to implement the code in the console layer rather than in the
framebuffer layer is due to the following reasons:
- it's fast
- it does not require driver changes
- it can coexist with devices that can rotate the display at the hardware level
- it complements graphics applications that can do display rotation
The changes to core fbcon are minimal-- recognition of the console
rotation angle so it can swap directions, origins and axes (xres vs yres,
xpanstep vs ypanstep, xoffset vs yoffset, etc) and storage of the rotation
angle per display. The bulk of the code that does the actual drawing to the
screen are placed in separate files. Each angle of rotation has separate
methods (bmove, clear, putcs, cursor, update_start which is derived from
update_var, and clear_margins). To mimimize processing time, the fontdata
are pre-rotated at each console switch (only if the font or the angle has
changed).
The option can be compiled out (CONFIG_FRAMEBUFFER_CONSOLE_ROTATION = n) if
rotation is not needed.
Choosing the rotation angle can be done in several ways:
1. boot option fbcon=rotate:n, where
n = 0 - normal
n = 1 - 90 degrees (clockwise)
n = 2 - 180 degrees (upside down)
n = 3 - 270 degrees (counterclockwise)
2. echo n > /sys/class/graphics/fb[num]/con_rotate
where n is the same as described above. It sets the angle of rotation
of the current console
3 echo n > /sys/class/graphics/fb[num]/con_rotate_all
where n is the same as described above. Globally sets the angle of
rotation.
GOTCHAS:
The option, especially at angles of 90 and 270 degrees, will exercise
the least used code of drivers. Namely, at these angles, panning is done
in the x-axis, so it can reveal bugs in the driver if xpanstep is set
incorrectly. A workaround is to set xpanstep = 0.
Secondly, at these angles, the framebuffer memory access can be
unaligned if (fontheight * bpp) % 32 ~= 0 which can reveal bugs in the drivers
imageblit, fillrect and copyarea functions. (I think cfbfillrect may have
this buglet). A workaround is to use a standard 8x16 font.
Speed:
The scrolling speed difference between 0 and 180 degrees is minimal,
somewhere areound 1-2%. At 90 or 270 degress, speed drops down to a vicinity
of 30-40%. This is understandable because the blit direction is across the
framebuffer "direction." Scrolling will be helped at these angles if xpanstep
is not equal to zero, use of 8x16 fonts, and setting xres_virtual >= xres * 2.
Note: The code is tested on little-endian only, so I don't know if it will
work in big-endian. Please let me know, it will take only less than a minute
of your time.
This patch prepares fbcon for console rotation and contains the following
changes:
- add rotate field in struct fbcon_ops to keep fbcon's current rotation
angle
- add con_rotate field in struct display to store per-display rotation angle
- create a private copy of the current var to fbcon. This will prevent
fbcon from directly manipulating info->var, especially the fields xoffset,
yoffset and vmode.
- add ability to swap pertinent axes (xres, yres; xpanstep, ypanstep; etc)
depending on the rotation angle
- change global update_var() (function that sets the screen start address)
as an fbcon method update_start. This is required because the axes, start
offset, and/or direction can be reversed depending on the rotation angle.
- add fbcon method rotate_font() which will rotate each character bitmap to
the correct angle of rotation.
- add fbcon boot option 'rotate' to select the angle of rotation at bootime.
Currently does nothing until all patches are applied.
Signed-off-by: Antonino Daplas <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-11-09 05:39:09 +00:00
|
|
|
ops->cursor_reset = 1;
|
|
|
|
|
2006-01-10 04:52:56 +00:00
|
|
|
if (ops->rotate_font && ops->rotate_font(info, vc)) {
|
[PATCH] fbcon: Console Rotation - Prepare fbcon for console rotation
This patch series implements generic code to rotate the console at 90, 180,
and 270 degrees. The implementation is completely done in the framebuffer
console level, thus no changes to the framebuffer layer or to the drivers
are needed.
Console rotation is required by some Sharp-based devices where the natural
orientation of the display is not at 0 degrees. Also, users that have
displays that can pivot will benefit by having a console in portrait mode
if they so desire.
The choice to implement the code in the console layer rather than in the
framebuffer layer is due to the following reasons:
- it's fast
- it does not require driver changes
- it can coexist with devices that can rotate the display at the hardware level
- it complements graphics applications that can do display rotation
The changes to core fbcon are minimal-- recognition of the console
rotation angle so it can swap directions, origins and axes (xres vs yres,
xpanstep vs ypanstep, xoffset vs yoffset, etc) and storage of the rotation
angle per display. The bulk of the code that does the actual drawing to the
screen are placed in separate files. Each angle of rotation has separate
methods (bmove, clear, putcs, cursor, update_start which is derived from
update_var, and clear_margins). To mimimize processing time, the fontdata
are pre-rotated at each console switch (only if the font or the angle has
changed).
The option can be compiled out (CONFIG_FRAMEBUFFER_CONSOLE_ROTATION = n) if
rotation is not needed.
Choosing the rotation angle can be done in several ways:
1. boot option fbcon=rotate:n, where
n = 0 - normal
n = 1 - 90 degrees (clockwise)
n = 2 - 180 degrees (upside down)
n = 3 - 270 degrees (counterclockwise)
2. echo n > /sys/class/graphics/fb[num]/con_rotate
where n is the same as described above. It sets the angle of rotation
of the current console
3 echo n > /sys/class/graphics/fb[num]/con_rotate_all
where n is the same as described above. Globally sets the angle of
rotation.
GOTCHAS:
The option, especially at angles of 90 and 270 degrees, will exercise
the least used code of drivers. Namely, at these angles, panning is done
in the x-axis, so it can reveal bugs in the driver if xpanstep is set
incorrectly. A workaround is to set xpanstep = 0.
Secondly, at these angles, the framebuffer memory access can be
unaligned if (fontheight * bpp) % 32 ~= 0 which can reveal bugs in the drivers
imageblit, fillrect and copyarea functions. (I think cfbfillrect may have
this buglet). A workaround is to use a standard 8x16 font.
Speed:
The scrolling speed difference between 0 and 180 degrees is minimal,
somewhere areound 1-2%. At 90 or 270 degress, speed drops down to a vicinity
of 30-40%. This is understandable because the blit direction is across the
framebuffer "direction." Scrolling will be helped at these angles if xpanstep
is not equal to zero, use of 8x16 fonts, and setting xres_virtual >= xres * 2.
Note: The code is tested on little-endian only, so I don't know if it will
work in big-endian. Please let me know, it will take only less than a minute
of your time.
This patch prepares fbcon for console rotation and contains the following
changes:
- add rotate field in struct fbcon_ops to keep fbcon's current rotation
angle
- add con_rotate field in struct display to store per-display rotation angle
- create a private copy of the current var to fbcon. This will prevent
fbcon from directly manipulating info->var, especially the fields xoffset,
yoffset and vmode.
- add ability to swap pertinent axes (xres, yres; xpanstep, ypanstep; etc)
depending on the rotation angle
- change global update_var() (function that sets the screen start address)
as an fbcon method update_start. This is required because the axes, start
offset, and/or direction can be reversed depending on the rotation angle.
- add fbcon method rotate_font() which will rotate each character bitmap to
the correct angle of rotation.
- add fbcon boot option 'rotate' to select the angle of rotation at bootime.
Currently does nothing until all patches are applied.
Signed-off-by: Antonino Daplas <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-11-09 05:39:09 +00:00
|
|
|
ops->rotate = FB_ROTATE_UR;
|
2006-01-10 04:52:56 +00:00
|
|
|
set_blitting_type(vc, info);
|
[PATCH] fbcon: Console Rotation - Prepare fbcon for console rotation
This patch series implements generic code to rotate the console at 90, 180,
and 270 degrees. The implementation is completely done in the framebuffer
console level, thus no changes to the framebuffer layer or to the drivers
are needed.
Console rotation is required by some Sharp-based devices where the natural
orientation of the display is not at 0 degrees. Also, users that have
displays that can pivot will benefit by having a console in portrait mode
if they so desire.
The choice to implement the code in the console layer rather than in the
framebuffer layer is due to the following reasons:
- it's fast
- it does not require driver changes
- it can coexist with devices that can rotate the display at the hardware level
- it complements graphics applications that can do display rotation
The changes to core fbcon are minimal-- recognition of the console
rotation angle so it can swap directions, origins and axes (xres vs yres,
xpanstep vs ypanstep, xoffset vs yoffset, etc) and storage of the rotation
angle per display. The bulk of the code that does the actual drawing to the
screen are placed in separate files. Each angle of rotation has separate
methods (bmove, clear, putcs, cursor, update_start which is derived from
update_var, and clear_margins). To mimimize processing time, the fontdata
are pre-rotated at each console switch (only if the font or the angle has
changed).
The option can be compiled out (CONFIG_FRAMEBUFFER_CONSOLE_ROTATION = n) if
rotation is not needed.
Choosing the rotation angle can be done in several ways:
1. boot option fbcon=rotate:n, where
n = 0 - normal
n = 1 - 90 degrees (clockwise)
n = 2 - 180 degrees (upside down)
n = 3 - 270 degrees (counterclockwise)
2. echo n > /sys/class/graphics/fb[num]/con_rotate
where n is the same as described above. It sets the angle of rotation
of the current console
3 echo n > /sys/class/graphics/fb[num]/con_rotate_all
where n is the same as described above. Globally sets the angle of
rotation.
GOTCHAS:
The option, especially at angles of 90 and 270 degrees, will exercise
the least used code of drivers. Namely, at these angles, panning is done
in the x-axis, so it can reveal bugs in the driver if xpanstep is set
incorrectly. A workaround is to set xpanstep = 0.
Secondly, at these angles, the framebuffer memory access can be
unaligned if (fontheight * bpp) % 32 ~= 0 which can reveal bugs in the drivers
imageblit, fillrect and copyarea functions. (I think cfbfillrect may have
this buglet). A workaround is to use a standard 8x16 font.
Speed:
The scrolling speed difference between 0 and 180 degrees is minimal,
somewhere areound 1-2%. At 90 or 270 degress, speed drops down to a vicinity
of 30-40%. This is understandable because the blit direction is across the
framebuffer "direction." Scrolling will be helped at these angles if xpanstep
is not equal to zero, use of 8x16 fonts, and setting xres_virtual >= xres * 2.
Note: The code is tested on little-endian only, so I don't know if it will
work in big-endian. Please let me know, it will take only less than a minute
of your time.
This patch prepares fbcon for console rotation and contains the following
changes:
- add rotate field in struct fbcon_ops to keep fbcon's current rotation
angle
- add con_rotate field in struct display to store per-display rotation angle
- create a private copy of the current var to fbcon. This will prevent
fbcon from directly manipulating info->var, especially the fields xoffset,
yoffset and vmode.
- add ability to swap pertinent axes (xres, yres; xpanstep, ypanstep; etc)
depending on the rotation angle
- change global update_var() (function that sets the screen start address)
as an fbcon method update_start. This is required because the axes, start
offset, and/or direction can be reversed depending on the rotation angle.
- add fbcon method rotate_font() which will rotate each character bitmap to
the correct angle of rotation.
- add fbcon boot option 'rotate' to select the angle of rotation at bootime.
Currently does nothing until all patches are applied.
Signed-off-by: Antonino Daplas <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-11-09 05:39:09 +00:00
|
|
|
}
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2005-09-09 20:04:37 +00:00
|
|
|
vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1);
|
2005-04-16 22:20:36 +00:00
|
|
|
vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800;
|
2005-12-13 06:17:15 +00:00
|
|
|
|
fbcon: Avoid using FNTCHARCNT() and hard-coded built-in font charcount
For user-provided fonts, the framebuffer layer is using a magic
negative-indexing macro, FNTCHARCNT(), to keep track of their number of
characters:
#define FNTCHARCNT(fd) (((int *)(fd))[-3])
For built-in fonts, it is using hard-coded values (256). This results in
something like the following:
map.length = (ops->p->userfont) ?
FNTCHARCNT(ops->p->fontdata) : 256;
This is unsatisfactory. In fact, there is already a `charcount` field in
our virtual console descriptor (see `struct console_font` inside `struct
vc_data`), let us use it:
map.length = vc->vc_font.charcount;
Recently we added a `charcount` field to `struct font_desc`. Use it to set
`vc->vc_font.charcount` properly. The idea is:
- We only use FNTCHARCNT() on `vc->vc_font.data` and `p->fontdata`.
Assume FNTCHARCNT() is working as intended;
- Whenever `vc->vc_font.data` is set, also set `vc->vc_font.charcount`
properly;
- We can now replace `FNTCHARCNT(vc->vc_font.data)` with
`vc->vc_font.charcount`;
- Since `p->fontdata` always point to the same font data buffer with
`vc->vc_font.data`, we can also replace `FNTCHARCNT(p->fontdata)` with
`vc->vc_font.charcount`.
In conclusion, set `vc->vc_font.charcount` properly in fbcon_startup(),
fbcon_init(), fbcon_set_disp() and fbcon_do_set_font(), then replace
FNTCHARCNT() with `vc->vc_font.charcount`. No more if-else between
negative-indexing macros and hard-coded values.
Do not include <linux/font.h> in fbcon_rotate.c and tileblit.c, since they
no longer need it.
Depends on patch "Fonts: Add charcount field to font_desc".
Suggested-by: Daniel Vetter <daniel@ffwll.ch>
Signed-off-by: Peilin Ye <yepeilin.cs@gmail.com>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/e460a5780e54e3022661d5f09555144583b4cc59.1605169912.git.yepeilin.cs@gmail.com
2020-11-12 12:15:22 +00:00
|
|
|
if (vc->vc_font.charcount > 256)
|
2005-12-13 06:17:15 +00:00
|
|
|
vc->vc_complement_mask <<= 1;
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
updatescrollmode(p, info, vc);
|
|
|
|
|
2022-02-02 13:55:31 +00:00
|
|
|
switch (fb_scrollmode(p)) {
|
Revert "fbdev: Garbage collect fbdev scrolling acceleration, part 1 (from TODO list)"
This reverts commit b3ec8cdf457e5e63d396fe1346cc788cf7c1b578.
Revert the second (of 2) commits which disabled scrolling acceleration
in fbcon/fbdev. It introduced a regression for fbdev-supported graphic
cards because of the performance penalty by doing screen scrolling by
software instead of using the existing graphic card 2D hardware
acceleration.
Console scrolling acceleration was disabled by dropping code which
checked at runtime the driver hardware capabilities for the
BINFO_HWACCEL_COPYAREA or FBINFO_HWACCEL_FILLRECT flags and if set, it
enabled scrollmode SCROLL_MOVE which uses hardware acceleration to move
screen contents. After dropping those checks scrollmode was hard-wired
to SCROLL_REDRAW instead, which forces all graphic cards to redraw every
character at the new screen position when scrolling.
This change effectively disabled all hardware-based scrolling acceleration for
ALL drivers, because now all kind of 2D hardware acceleration (bitblt,
fillrect) in the drivers isn't used any longer.
The original commit message mentions that only 3 DRM drivers (nouveau, omapdrm
and gma500) used hardware acceleration in the past and thus code for checking
and using scrolling acceleration is obsolete.
This statement is NOT TRUE, because beside the DRM drivers there are around 35
other fbdev drivers which depend on fbdev/fbcon and still provide hardware
acceleration for fbdev/fbcon.
The original commit message also states that syzbot found lots of bugs in fbcon
and thus it's "often the solution to just delete code and remove features".
This is true, and the bugs - which actually affected all users of fbcon,
including DRM - were fixed, or code was dropped like e.g. the support for
software scrollback in vgacon (commit 973c096f6a85).
So to further analyze which bugs were found by syzbot, I've looked through all
patches in drivers/video which were tagged with syzbot or syzkaller back to
year 2005. The vast majority fixed the reported issues on a higher level, e.g.
when screen is to be resized, or when font size is to be changed. The few ones
which touched driver code fixed a real driver bug, e.g. by adding a check.
But NONE of those patches touched code of either the SCROLL_MOVE or the
SCROLL_REDRAW case.
That means, there was no real reason why SCROLL_MOVE had to be ripped-out and
just SCROLL_REDRAW had to be used instead. The only reason I can imagine so far
was that SCROLL_MOVE wasn't used by DRM and as such it was assumed that it
could go away. That argument completely missed the fact that SCROLL_MOVE is
still heavily used by fbdev (non-DRM) drivers.
Some people mention that using memcpy() instead of the hardware acceleration is
pretty much the same speed. But that's not true, at least not for older graphic
cards and machines where we see speed decreases by factor 10 and more and thus
this change leads to console responsiveness way worse than before.
That's why the original commit is to be reverted. By reverting we
reintroduce hardware-based scrolling acceleration and fix the
performance regression for fbdev drivers.
There isn't any impact on DRM when reverting those patches.
Signed-off-by: Helge Deller <deller@gmx.de>
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
Acked-by: Sven Schnelle <svens@stackframe.org>
Cc: stable@vger.kernel.org # v5.16+
Signed-off-by: Helge Deller <deller@gmx.de>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/20220202135531.92183-2-deller@gmx.de
2022-02-02 13:55:29 +00:00
|
|
|
case SCROLL_WRAP_MOVE:
|
|
|
|
scrollback_phys_max = p->vrows - vc->vc_rows;
|
|
|
|
break;
|
|
|
|
case SCROLL_PAN_MOVE:
|
|
|
|
case SCROLL_PAN_REDRAW:
|
|
|
|
scrollback_phys_max = p->vrows - 2 * vc->vc_rows;
|
|
|
|
if (scrollback_phys_max < 0)
|
|
|
|
scrollback_phys_max = 0;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
scrollback_phys_max = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
scrollback_max = 0;
|
|
|
|
scrollback_current = 0;
|
2005-12-13 06:17:18 +00:00
|
|
|
|
|
|
|
if (!fbcon_is_inactive(vc, info)) {
|
|
|
|
ops->var.xoffset = ops->var.yoffset = p->yscroll = 0;
|
|
|
|
ops->update_start(info);
|
|
|
|
}
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
fbcon_set_palette(vc, color_table);
|
|
|
|
fbcon_clear_margins(vc, 0);
|
|
|
|
|
|
|
|
if (logo_shown == FBCON_LOGO_DRAW) {
|
|
|
|
|
|
|
|
logo_shown = fg_console;
|
|
|
|
/* This is protected above by initmem_freed */
|
2005-11-09 05:39:10 +00:00
|
|
|
fb_show_logo(info, ops->rotate);
|
2005-04-16 22:20:36 +00:00
|
|
|
update_region(vc,
|
|
|
|
vc->vc_origin + vc->vc_size_row * vc->vc_top,
|
|
|
|
vc->vc_size_row * (vc->vc_bottom -
|
|
|
|
vc->vc_top) / 2);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void fbcon_generic_blank(struct vc_data *vc, struct fb_info *info,
|
|
|
|
int blank)
|
|
|
|
{
|
|
|
|
if (blank) {
|
|
|
|
unsigned short charmask = vc->vc_hi_font_mask ?
|
|
|
|
0x1ff : 0xff;
|
|
|
|
unsigned short oldc;
|
|
|
|
|
|
|
|
oldc = vc->vc_video_erase_char;
|
|
|
|
vc->vc_video_erase_char &= charmask;
|
|
|
|
fbcon_clear(vc, 0, 0, vc->vc_rows, vc->vc_cols);
|
|
|
|
vc->vc_video_erase_char = oldc;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch)
|
|
|
|
{
|
2022-04-05 21:03:21 +00:00
|
|
|
struct fb_info *info = fbcon_info_from_console(vc->vc_num);
|
2005-04-16 22:20:36 +00:00
|
|
|
struct fbcon_ops *ops = info->fbcon_par;
|
|
|
|
|
|
|
|
if (mode_switch) {
|
|
|
|
struct fb_var_screeninfo var = info->var;
|
|
|
|
|
|
|
|
ops->graphics = 1;
|
|
|
|
|
|
|
|
if (!blank) {
|
drm/fb-helper: Fix vt restore
In the past we had a pile of hacks to orchestrate access between fbdev
emulation and native kms clients. We've tried to streamline this, by
always preferring the kms side above fbdev calls when a drm master
exists, because drm master controls access to the display resources.
Unfortunately this breaks existing userspace, specifically Xorg. When
exiting Xorg first restores the console to text mode using the KDSET
ioctl on the vt. This does nothing, because a drm master is still
around. Then it drops the drm master status, which again does nothing,
because logind is keeping additional drm fd open to be able to
orchestrate vt switches. In the past this is the point where fbdev was
restored, as part of the ->lastclose hook on the drm side.
Now to fix this regression we don't want to go back to letting fbdev
restore things whenever it feels like, or to the pile of hacks we've
had before. Instead try and go with a minimal exception to make the
KDSET case work again, and nothing else.
This means that if userspace does a KDSET call when switching between
graphical compositors, there will be some flickering with fbcon
showing up for a bit. But a) that's not a regression and b) userspace
can fix it by improving the vt switching dance - logind should have
all the information it needs.
While pondering all this I'm also wondering wheter we should have a
SWITCH_MASTER ioctl to allow race-free master status handover. But
that's for another day.
v2: Somehow forgot to cc all the fbdev people.
v3: Fix typo Alex spotted.
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=208179
Cc: shlomo@fastmail.com
Reported-and-Tested-by: shlomo@fastmail.com
Cc: Michel Dänzer <michel@daenzer.net>
Fixes: 64914da24ea9 ("drm/fbdev-helper: don't force restores")
Cc: Noralf Trønnes <noralf@tronnes.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: Daniel Vetter <daniel.vetter@intel.com>
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Maxime Ripard <mripard@kernel.org>
Cc: David Airlie <airlied@linux.ie>
Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: dri-devel@lists.freedesktop.org
Cc: <stable@vger.kernel.org> # v5.7+
Cc: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Nathan Chancellor <natechancellor@gmail.com>
Cc: Qiujun Huang <hqjagain@gmail.com>
Cc: Peter Rosin <peda@axentia.se>
Cc: linux-fbdev@vger.kernel.org
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200624092910.3280448-1-daniel.vetter@ffwll.ch
2020-06-24 09:29:10 +00:00
|
|
|
var.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE |
|
|
|
|
FB_ACTIVATE_KD_TEXT;
|
2005-04-16 22:20:36 +00:00
|
|
|
fb_set_var(info, &var);
|
|
|
|
ops->graphics = 0;
|
[PATCH] fbcon: Console Rotation - Prepare fbcon for console rotation
This patch series implements generic code to rotate the console at 90, 180,
and 270 degrees. The implementation is completely done in the framebuffer
console level, thus no changes to the framebuffer layer or to the drivers
are needed.
Console rotation is required by some Sharp-based devices where the natural
orientation of the display is not at 0 degrees. Also, users that have
displays that can pivot will benefit by having a console in portrait mode
if they so desire.
The choice to implement the code in the console layer rather than in the
framebuffer layer is due to the following reasons:
- it's fast
- it does not require driver changes
- it can coexist with devices that can rotate the display at the hardware level
- it complements graphics applications that can do display rotation
The changes to core fbcon are minimal-- recognition of the console
rotation angle so it can swap directions, origins and axes (xres vs yres,
xpanstep vs ypanstep, xoffset vs yoffset, etc) and storage of the rotation
angle per display. The bulk of the code that does the actual drawing to the
screen are placed in separate files. Each angle of rotation has separate
methods (bmove, clear, putcs, cursor, update_start which is derived from
update_var, and clear_margins). To mimimize processing time, the fontdata
are pre-rotated at each console switch (only if the font or the angle has
changed).
The option can be compiled out (CONFIG_FRAMEBUFFER_CONSOLE_ROTATION = n) if
rotation is not needed.
Choosing the rotation angle can be done in several ways:
1. boot option fbcon=rotate:n, where
n = 0 - normal
n = 1 - 90 degrees (clockwise)
n = 2 - 180 degrees (upside down)
n = 3 - 270 degrees (counterclockwise)
2. echo n > /sys/class/graphics/fb[num]/con_rotate
where n is the same as described above. It sets the angle of rotation
of the current console
3 echo n > /sys/class/graphics/fb[num]/con_rotate_all
where n is the same as described above. Globally sets the angle of
rotation.
GOTCHAS:
The option, especially at angles of 90 and 270 degrees, will exercise
the least used code of drivers. Namely, at these angles, panning is done
in the x-axis, so it can reveal bugs in the driver if xpanstep is set
incorrectly. A workaround is to set xpanstep = 0.
Secondly, at these angles, the framebuffer memory access can be
unaligned if (fontheight * bpp) % 32 ~= 0 which can reveal bugs in the drivers
imageblit, fillrect and copyarea functions. (I think cfbfillrect may have
this buglet). A workaround is to use a standard 8x16 font.
Speed:
The scrolling speed difference between 0 and 180 degrees is minimal,
somewhere areound 1-2%. At 90 or 270 degress, speed drops down to a vicinity
of 30-40%. This is understandable because the blit direction is across the
framebuffer "direction." Scrolling will be helped at these angles if xpanstep
is not equal to zero, use of 8x16 fonts, and setting xres_virtual >= xres * 2.
Note: The code is tested on little-endian only, so I don't know if it will
work in big-endian. Please let me know, it will take only less than a minute
of your time.
This patch prepares fbcon for console rotation and contains the following
changes:
- add rotate field in struct fbcon_ops to keep fbcon's current rotation
angle
- add con_rotate field in struct display to store per-display rotation angle
- create a private copy of the current var to fbcon. This will prevent
fbcon from directly manipulating info->var, especially the fields xoffset,
yoffset and vmode.
- add ability to swap pertinent axes (xres, yres; xpanstep, ypanstep; etc)
depending on the rotation angle
- change global update_var() (function that sets the screen start address)
as an fbcon method update_start. This is required because the axes, start
offset, and/or direction can be reversed depending on the rotation angle.
- add fbcon method rotate_font() which will rotate each character bitmap to
the correct angle of rotation.
- add fbcon boot option 'rotate' to select the angle of rotation at bootime.
Currently does nothing until all patches are applied.
Signed-off-by: Antonino Daplas <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-11-09 05:39:09 +00:00
|
|
|
ops->var = info->var;
|
2009-11-11 22:26:22 +00:00
|
|
|
}
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!fbcon_is_inactive(vc, info)) {
|
|
|
|
if (ops->blank_state != blank) {
|
|
|
|
ops->blank_state = blank;
|
|
|
|
fbcon_cursor(vc, blank ? CM_ERASE : CM_DRAW);
|
|
|
|
ops->cursor_flash = (!blank);
|
|
|
|
|
2019-05-28 09:02:57 +00:00
|
|
|
if (fb_blank(info, blank))
|
|
|
|
fbcon_generic_blank(vc, info, blank);
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
|
2005-09-09 20:10:00 +00:00
|
|
|
if (!blank)
|
|
|
|
update_screen(vc);
|
|
|
|
}
|
|
|
|
|
2007-10-16 08:29:55 +00:00
|
|
|
if (mode_switch || fbcon_is_inactive(vc, info) ||
|
2006-10-03 08:14:48 +00:00
|
|
|
ops->blank_state != FB_BLANK_UNBLANK)
|
2022-04-05 21:03:24 +00:00
|
|
|
fbcon_del_cursor_work(info);
|
2006-10-03 08:14:48 +00:00
|
|
|
else
|
2022-04-05 21:03:24 +00:00
|
|
|
fbcon_add_cursor_work(info);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2005-09-09 20:10:00 +00:00
|
|
|
return 0;
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
|
2010-08-02 19:05:41 +00:00
|
|
|
static int fbcon_debug_enter(struct vc_data *vc)
|
|
|
|
{
|
2022-04-05 21:03:21 +00:00
|
|
|
struct fb_info *info = fbcon_info_from_console(vc->vc_num);
|
2010-08-02 19:05:41 +00:00
|
|
|
struct fbcon_ops *ops = info->fbcon_par;
|
|
|
|
|
|
|
|
ops->save_graphics = ops->graphics;
|
|
|
|
ops->graphics = 0;
|
|
|
|
if (info->fbops->fb_debug_enter)
|
|
|
|
info->fbops->fb_debug_enter(info);
|
|
|
|
fbcon_set_palette(vc, color_table);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int fbcon_debug_leave(struct vc_data *vc)
|
|
|
|
{
|
2022-04-05 21:03:21 +00:00
|
|
|
struct fb_info *info = fbcon_info_from_console(vc->vc_num);
|
2010-08-02 19:05:41 +00:00
|
|
|
struct fbcon_ops *ops = info->fbcon_par;
|
|
|
|
|
|
|
|
ops->graphics = ops->save_graphics;
|
|
|
|
if (info->fbops->fb_debug_leave)
|
|
|
|
info->fbops->fb_debug_leave(info);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
static int fbcon_get_font(struct vc_data *vc, struct console_font *font)
|
|
|
|
{
|
|
|
|
u8 *fontdata = vc->vc_font.data;
|
|
|
|
u8 *data = font->data;
|
|
|
|
int i, j;
|
|
|
|
|
|
|
|
font->width = vc->vc_font.width;
|
|
|
|
font->height = vc->vc_font.height;
|
|
|
|
font->charcount = vc->vc_hi_font_mask ? 512 : 256;
|
|
|
|
if (!font->data)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (font->width <= 8) {
|
|
|
|
j = vc->vc_font.height;
|
2020-09-24 13:43:48 +00:00
|
|
|
if (font->charcount * j > FNTSIZE(fontdata))
|
|
|
|
return -EINVAL;
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
for (i = 0; i < font->charcount; i++) {
|
|
|
|
memcpy(data, fontdata, j);
|
|
|
|
memset(data + j, 0, 32 - j);
|
|
|
|
data += 32;
|
|
|
|
fontdata += j;
|
|
|
|
}
|
|
|
|
} else if (font->width <= 16) {
|
|
|
|
j = vc->vc_font.height * 2;
|
2020-09-24 13:43:48 +00:00
|
|
|
if (font->charcount * j > FNTSIZE(fontdata))
|
|
|
|
return -EINVAL;
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
for (i = 0; i < font->charcount; i++) {
|
|
|
|
memcpy(data, fontdata, j);
|
|
|
|
memset(data + j, 0, 64 - j);
|
|
|
|
data += 64;
|
|
|
|
fontdata += j;
|
|
|
|
}
|
|
|
|
} else if (font->width <= 24) {
|
2020-09-24 13:43:48 +00:00
|
|
|
if (font->charcount * (vc->vc_font.height * sizeof(u32)) > FNTSIZE(fontdata))
|
|
|
|
return -EINVAL;
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
for (i = 0; i < font->charcount; i++) {
|
|
|
|
for (j = 0; j < vc->vc_font.height; j++) {
|
|
|
|
*data++ = fontdata[0];
|
|
|
|
*data++ = fontdata[1];
|
|
|
|
*data++ = fontdata[2];
|
|
|
|
fontdata += sizeof(u32);
|
|
|
|
}
|
|
|
|
memset(data, 0, 3 * (32 - j));
|
|
|
|
data += 3 * (32 - j);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
j = vc->vc_font.height * 4;
|
2020-09-24 13:43:48 +00:00
|
|
|
if (font->charcount * j > FNTSIZE(fontdata))
|
|
|
|
return -EINVAL;
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
for (i = 0; i < font->charcount; i++) {
|
|
|
|
memcpy(data, fontdata, j);
|
|
|
|
memset(data + j, 0, 128 - j);
|
|
|
|
data += 128;
|
|
|
|
fontdata += j;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
fbcon: Fix vc attr at deinit
fbcon can deal with vc_hi_font_mask (the upper 256 chars) and adjust
the vc attrs dynamically when vc_hi_font_mask is changed at
fbcon_init(). When the vc_hi_font_mask is set, it remaps the attrs in
the existing console buffer with one bit shift up (for 9 bits), while
it remaps with one bit shift down (for 8 bits) when the value is
cleared. It works fine as long as the font gets updated after fbcon
was initialized.
However, we hit a bizarre problem when the console is switched to
another fb driver (typically from vesafb or efifb to drmfb). At
switching to the new fb driver, we temporarily rebind the console to
the dummy console, then rebind to the new driver. During the
switching, we leave the modified attrs as is. Thus, the new fbcon
takes over the old buffer as if it were to contain 8 bits chars
(although the attrs are still shifted for 9 bits), and effectively
this results in the yellow color texts instead of the original white
color, as found in the bugzilla entry below.
An easy fix for this is to re-adjust the attrs before leaving the
fbcon at con_deinit callback. Since the code to adjust the attrs is
already present in the current fbcon code, in this patch, we simply
factor out the relevant code, and call it from fbcon_deinit().
Bugzilla: https://bugzilla.suse.com/show_bug.cgi?id=1000619
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
2017-01-11 16:09:50 +00:00
|
|
|
/* set/clear vc_hi_font_mask and update vc attrs accordingly */
|
|
|
|
static void set_vc_hi_font(struct vc_data *vc, bool set)
|
2005-04-16 22:20:36 +00:00
|
|
|
{
|
fbcon: Fix vc attr at deinit
fbcon can deal with vc_hi_font_mask (the upper 256 chars) and adjust
the vc attrs dynamically when vc_hi_font_mask is changed at
fbcon_init(). When the vc_hi_font_mask is set, it remaps the attrs in
the existing console buffer with one bit shift up (for 9 bits), while
it remaps with one bit shift down (for 8 bits) when the value is
cleared. It works fine as long as the font gets updated after fbcon
was initialized.
However, we hit a bizarre problem when the console is switched to
another fb driver (typically from vesafb or efifb to drmfb). At
switching to the new fb driver, we temporarily rebind the console to
the dummy console, then rebind to the new driver. During the
switching, we leave the modified attrs as is. Thus, the new fbcon
takes over the old buffer as if it were to contain 8 bits chars
(although the attrs are still shifted for 9 bits), and effectively
this results in the yellow color texts instead of the original white
color, as found in the bugzilla entry below.
An easy fix for this is to re-adjust the attrs before leaving the
fbcon at con_deinit callback. Since the code to adjust the attrs is
already present in the current fbcon code, in this patch, we simply
factor out the relevant code, and call it from fbcon_deinit().
Bugzilla: https://bugzilla.suse.com/show_bug.cgi?id=1000619
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
2017-01-11 16:09:50 +00:00
|
|
|
if (!set) {
|
2005-04-16 22:20:36 +00:00
|
|
|
vc->vc_hi_font_mask = 0;
|
|
|
|
if (vc->vc_can_do_color) {
|
|
|
|
vc->vc_complement_mask >>= 1;
|
|
|
|
vc->vc_s_complement_mask >>= 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ++Edmund: reorder the attribute bits */
|
|
|
|
if (vc->vc_can_do_color) {
|
|
|
|
unsigned short *cp =
|
|
|
|
(unsigned short *) vc->vc_origin;
|
|
|
|
int count = vc->vc_screenbuf_size / 2;
|
|
|
|
unsigned short c;
|
|
|
|
for (; count > 0; count--, cp++) {
|
|
|
|
c = scr_readw(cp);
|
|
|
|
scr_writew(((c & 0xfe00) >> 1) |
|
|
|
|
(c & 0xff), cp);
|
|
|
|
}
|
|
|
|
c = vc->vc_video_erase_char;
|
|
|
|
vc->vc_video_erase_char =
|
|
|
|
((c & 0xfe00) >> 1) | (c & 0xff);
|
|
|
|
vc->vc_attr >>= 1;
|
|
|
|
}
|
fbcon: Fix vc attr at deinit
fbcon can deal with vc_hi_font_mask (the upper 256 chars) and adjust
the vc attrs dynamically when vc_hi_font_mask is changed at
fbcon_init(). When the vc_hi_font_mask is set, it remaps the attrs in
the existing console buffer with one bit shift up (for 9 bits), while
it remaps with one bit shift down (for 8 bits) when the value is
cleared. It works fine as long as the font gets updated after fbcon
was initialized.
However, we hit a bizarre problem when the console is switched to
another fb driver (typically from vesafb or efifb to drmfb). At
switching to the new fb driver, we temporarily rebind the console to
the dummy console, then rebind to the new driver. During the
switching, we leave the modified attrs as is. Thus, the new fbcon
takes over the old buffer as if it were to contain 8 bits chars
(although the attrs are still shifted for 9 bits), and effectively
this results in the yellow color texts instead of the original white
color, as found in the bugzilla entry below.
An easy fix for this is to re-adjust the attrs before leaving the
fbcon at con_deinit callback. Since the code to adjust the attrs is
already present in the current fbcon code, in this patch, we simply
factor out the relevant code, and call it from fbcon_deinit().
Bugzilla: https://bugzilla.suse.com/show_bug.cgi?id=1000619
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
2017-01-11 16:09:50 +00:00
|
|
|
} else {
|
2005-04-16 22:20:36 +00:00
|
|
|
vc->vc_hi_font_mask = 0x100;
|
|
|
|
if (vc->vc_can_do_color) {
|
|
|
|
vc->vc_complement_mask <<= 1;
|
|
|
|
vc->vc_s_complement_mask <<= 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ++Edmund: reorder the attribute bits */
|
|
|
|
{
|
|
|
|
unsigned short *cp =
|
|
|
|
(unsigned short *) vc->vc_origin;
|
|
|
|
int count = vc->vc_screenbuf_size / 2;
|
|
|
|
unsigned short c;
|
|
|
|
for (; count > 0; count--, cp++) {
|
|
|
|
unsigned short newc;
|
|
|
|
c = scr_readw(cp);
|
|
|
|
if (vc->vc_can_do_color)
|
|
|
|
newc =
|
|
|
|
((c & 0xff00) << 1) | (c &
|
|
|
|
0xff);
|
|
|
|
else
|
|
|
|
newc = c & ~0x100;
|
|
|
|
scr_writew(newc, cp);
|
|
|
|
}
|
|
|
|
c = vc->vc_video_erase_char;
|
|
|
|
if (vc->vc_can_do_color) {
|
|
|
|
vc->vc_video_erase_char =
|
|
|
|
((c & 0xff00) << 1) | (c & 0xff);
|
|
|
|
vc->vc_attr <<= 1;
|
2008-10-14 19:12:02 +00:00
|
|
|
} else
|
2005-04-16 22:20:36 +00:00
|
|
|
vc->vc_video_erase_char = c & ~0x100;
|
|
|
|
}
|
|
|
|
}
|
fbcon: Fix vc attr at deinit
fbcon can deal with vc_hi_font_mask (the upper 256 chars) and adjust
the vc attrs dynamically when vc_hi_font_mask is changed at
fbcon_init(). When the vc_hi_font_mask is set, it remaps the attrs in
the existing console buffer with one bit shift up (for 9 bits), while
it remaps with one bit shift down (for 8 bits) when the value is
cleared. It works fine as long as the font gets updated after fbcon
was initialized.
However, we hit a bizarre problem when the console is switched to
another fb driver (typically from vesafb or efifb to drmfb). At
switching to the new fb driver, we temporarily rebind the console to
the dummy console, then rebind to the new driver. During the
switching, we leave the modified attrs as is. Thus, the new fbcon
takes over the old buffer as if it were to contain 8 bits chars
(although the attrs are still shifted for 9 bits), and effectively
this results in the yellow color texts instead of the original white
color, as found in the bugzilla entry below.
An easy fix for this is to re-adjust the attrs before leaving the
fbcon at con_deinit callback. Since the code to adjust the attrs is
already present in the current fbcon code, in this patch, we simply
factor out the relevant code, and call it from fbcon_deinit().
Bugzilla: https://bugzilla.suse.com/show_bug.cgi?id=1000619
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
2017-01-11 16:09:50 +00:00
|
|
|
}
|
|
|
|
|
fbcon: Avoid using FNTCHARCNT() and hard-coded built-in font charcount
For user-provided fonts, the framebuffer layer is using a magic
negative-indexing macro, FNTCHARCNT(), to keep track of their number of
characters:
#define FNTCHARCNT(fd) (((int *)(fd))[-3])
For built-in fonts, it is using hard-coded values (256). This results in
something like the following:
map.length = (ops->p->userfont) ?
FNTCHARCNT(ops->p->fontdata) : 256;
This is unsatisfactory. In fact, there is already a `charcount` field in
our virtual console descriptor (see `struct console_font` inside `struct
vc_data`), let us use it:
map.length = vc->vc_font.charcount;
Recently we added a `charcount` field to `struct font_desc`. Use it to set
`vc->vc_font.charcount` properly. The idea is:
- We only use FNTCHARCNT() on `vc->vc_font.data` and `p->fontdata`.
Assume FNTCHARCNT() is working as intended;
- Whenever `vc->vc_font.data` is set, also set `vc->vc_font.charcount`
properly;
- We can now replace `FNTCHARCNT(vc->vc_font.data)` with
`vc->vc_font.charcount`;
- Since `p->fontdata` always point to the same font data buffer with
`vc->vc_font.data`, we can also replace `FNTCHARCNT(p->fontdata)` with
`vc->vc_font.charcount`.
In conclusion, set `vc->vc_font.charcount` properly in fbcon_startup(),
fbcon_init(), fbcon_set_disp() and fbcon_do_set_font(), then replace
FNTCHARCNT() with `vc->vc_font.charcount`. No more if-else between
negative-indexing macros and hard-coded values.
Do not include <linux/font.h> in fbcon_rotate.c and tileblit.c, since they
no longer need it.
Depends on patch "Fonts: Add charcount field to font_desc".
Suggested-by: Daniel Vetter <daniel@ffwll.ch>
Signed-off-by: Peilin Ye <yepeilin.cs@gmail.com>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/e460a5780e54e3022661d5f09555144583b4cc59.1605169912.git.yepeilin.cs@gmail.com
2020-11-12 12:15:22 +00:00
|
|
|
static int fbcon_do_set_font(struct vc_data *vc, int w, int h, int charcount,
|
fbcon: Fix vc attr at deinit
fbcon can deal with vc_hi_font_mask (the upper 256 chars) and adjust
the vc attrs dynamically when vc_hi_font_mask is changed at
fbcon_init(). When the vc_hi_font_mask is set, it remaps the attrs in
the existing console buffer with one bit shift up (for 9 bits), while
it remaps with one bit shift down (for 8 bits) when the value is
cleared. It works fine as long as the font gets updated after fbcon
was initialized.
However, we hit a bizarre problem when the console is switched to
another fb driver (typically from vesafb or efifb to drmfb). At
switching to the new fb driver, we temporarily rebind the console to
the dummy console, then rebind to the new driver. During the
switching, we leave the modified attrs as is. Thus, the new fbcon
takes over the old buffer as if it were to contain 8 bits chars
(although the attrs are still shifted for 9 bits), and effectively
this results in the yellow color texts instead of the original white
color, as found in the bugzilla entry below.
An easy fix for this is to re-adjust the attrs before leaving the
fbcon at con_deinit callback. Since the code to adjust the attrs is
already present in the current fbcon code, in this patch, we simply
factor out the relevant code, and call it from fbcon_deinit().
Bugzilla: https://bugzilla.suse.com/show_bug.cgi?id=1000619
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
2017-01-11 16:09:50 +00:00
|
|
|
const u8 * data, int userfont)
|
|
|
|
{
|
2022-04-05 21:03:21 +00:00
|
|
|
struct fb_info *info = fbcon_info_from_console(vc->vc_num);
|
fbcon: Fix vc attr at deinit
fbcon can deal with vc_hi_font_mask (the upper 256 chars) and adjust
the vc attrs dynamically when vc_hi_font_mask is changed at
fbcon_init(). When the vc_hi_font_mask is set, it remaps the attrs in
the existing console buffer with one bit shift up (for 9 bits), while
it remaps with one bit shift down (for 8 bits) when the value is
cleared. It works fine as long as the font gets updated after fbcon
was initialized.
However, we hit a bizarre problem when the console is switched to
another fb driver (typically from vesafb or efifb to drmfb). At
switching to the new fb driver, we temporarily rebind the console to
the dummy console, then rebind to the new driver. During the
switching, we leave the modified attrs as is. Thus, the new fbcon
takes over the old buffer as if it were to contain 8 bits chars
(although the attrs are still shifted for 9 bits), and effectively
this results in the yellow color texts instead of the original white
color, as found in the bugzilla entry below.
An easy fix for this is to re-adjust the attrs before leaving the
fbcon at con_deinit callback. Since the code to adjust the attrs is
already present in the current fbcon code, in this patch, we simply
factor out the relevant code, and call it from fbcon_deinit().
Bugzilla: https://bugzilla.suse.com/show_bug.cgi?id=1000619
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
2017-01-11 16:09:50 +00:00
|
|
|
struct fbcon_ops *ops = info->fbcon_par;
|
2019-05-28 09:02:39 +00:00
|
|
|
struct fbcon_display *p = &fb_display[vc->vc_num];
|
fbcon: Fix vc attr at deinit
fbcon can deal with vc_hi_font_mask (the upper 256 chars) and adjust
the vc attrs dynamically when vc_hi_font_mask is changed at
fbcon_init(). When the vc_hi_font_mask is set, it remaps the attrs in
the existing console buffer with one bit shift up (for 9 bits), while
it remaps with one bit shift down (for 8 bits) when the value is
cleared. It works fine as long as the font gets updated after fbcon
was initialized.
However, we hit a bizarre problem when the console is switched to
another fb driver (typically from vesafb or efifb to drmfb). At
switching to the new fb driver, we temporarily rebind the console to
the dummy console, then rebind to the new driver. During the
switching, we leave the modified attrs as is. Thus, the new fbcon
takes over the old buffer as if it were to contain 8 bits chars
(although the attrs are still shifted for 9 bits), and effectively
this results in the yellow color texts instead of the original white
color, as found in the bugzilla entry below.
An easy fix for this is to re-adjust the attrs before leaving the
fbcon at con_deinit callback. Since the code to adjust the attrs is
already present in the current fbcon code, in this patch, we simply
factor out the relevant code, and call it from fbcon_deinit().
Bugzilla: https://bugzilla.suse.com/show_bug.cgi?id=1000619
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
2017-01-11 16:09:50 +00:00
|
|
|
int resize;
|
|
|
|
char *old_data = NULL;
|
|
|
|
|
|
|
|
resize = (w != vc->vc_font.width) || (h != vc->vc_font.height);
|
|
|
|
if (p->userfont)
|
|
|
|
old_data = vc->vc_font.data;
|
|
|
|
vc->vc_font.data = (void *)(p->fontdata = data);
|
|
|
|
if ((p->userfont = userfont))
|
|
|
|
REFCOUNT(data)++;
|
|
|
|
vc->vc_font.width = w;
|
|
|
|
vc->vc_font.height = h;
|
fbcon: Avoid using FNTCHARCNT() and hard-coded built-in font charcount
For user-provided fonts, the framebuffer layer is using a magic
negative-indexing macro, FNTCHARCNT(), to keep track of their number of
characters:
#define FNTCHARCNT(fd) (((int *)(fd))[-3])
For built-in fonts, it is using hard-coded values (256). This results in
something like the following:
map.length = (ops->p->userfont) ?
FNTCHARCNT(ops->p->fontdata) : 256;
This is unsatisfactory. In fact, there is already a `charcount` field in
our virtual console descriptor (see `struct console_font` inside `struct
vc_data`), let us use it:
map.length = vc->vc_font.charcount;
Recently we added a `charcount` field to `struct font_desc`. Use it to set
`vc->vc_font.charcount` properly. The idea is:
- We only use FNTCHARCNT() on `vc->vc_font.data` and `p->fontdata`.
Assume FNTCHARCNT() is working as intended;
- Whenever `vc->vc_font.data` is set, also set `vc->vc_font.charcount`
properly;
- We can now replace `FNTCHARCNT(vc->vc_font.data)` with
`vc->vc_font.charcount`;
- Since `p->fontdata` always point to the same font data buffer with
`vc->vc_font.data`, we can also replace `FNTCHARCNT(p->fontdata)` with
`vc->vc_font.charcount`.
In conclusion, set `vc->vc_font.charcount` properly in fbcon_startup(),
fbcon_init(), fbcon_set_disp() and fbcon_do_set_font(), then replace
FNTCHARCNT() with `vc->vc_font.charcount`. No more if-else between
negative-indexing macros and hard-coded values.
Do not include <linux/font.h> in fbcon_rotate.c and tileblit.c, since they
no longer need it.
Depends on patch "Fonts: Add charcount field to font_desc".
Suggested-by: Daniel Vetter <daniel@ffwll.ch>
Signed-off-by: Peilin Ye <yepeilin.cs@gmail.com>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/e460a5780e54e3022661d5f09555144583b4cc59.1605169912.git.yepeilin.cs@gmail.com
2020-11-12 12:15:22 +00:00
|
|
|
vc->vc_font.charcount = charcount;
|
|
|
|
if (vc->vc_hi_font_mask && charcount == 256)
|
fbcon: Fix vc attr at deinit
fbcon can deal with vc_hi_font_mask (the upper 256 chars) and adjust
the vc attrs dynamically when vc_hi_font_mask is changed at
fbcon_init(). When the vc_hi_font_mask is set, it remaps the attrs in
the existing console buffer with one bit shift up (for 9 bits), while
it remaps with one bit shift down (for 8 bits) when the value is
cleared. It works fine as long as the font gets updated after fbcon
was initialized.
However, we hit a bizarre problem when the console is switched to
another fb driver (typically from vesafb or efifb to drmfb). At
switching to the new fb driver, we temporarily rebind the console to
the dummy console, then rebind to the new driver. During the
switching, we leave the modified attrs as is. Thus, the new fbcon
takes over the old buffer as if it were to contain 8 bits chars
(although the attrs are still shifted for 9 bits), and effectively
this results in the yellow color texts instead of the original white
color, as found in the bugzilla entry below.
An easy fix for this is to re-adjust the attrs before leaving the
fbcon at con_deinit callback. Since the code to adjust the attrs is
already present in the current fbcon code, in this patch, we simply
factor out the relevant code, and call it from fbcon_deinit().
Bugzilla: https://bugzilla.suse.com/show_bug.cgi?id=1000619
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
2017-01-11 16:09:50 +00:00
|
|
|
set_vc_hi_font(vc, false);
|
fbcon: Avoid using FNTCHARCNT() and hard-coded built-in font charcount
For user-provided fonts, the framebuffer layer is using a magic
negative-indexing macro, FNTCHARCNT(), to keep track of their number of
characters:
#define FNTCHARCNT(fd) (((int *)(fd))[-3])
For built-in fonts, it is using hard-coded values (256). This results in
something like the following:
map.length = (ops->p->userfont) ?
FNTCHARCNT(ops->p->fontdata) : 256;
This is unsatisfactory. In fact, there is already a `charcount` field in
our virtual console descriptor (see `struct console_font` inside `struct
vc_data`), let us use it:
map.length = vc->vc_font.charcount;
Recently we added a `charcount` field to `struct font_desc`. Use it to set
`vc->vc_font.charcount` properly. The idea is:
- We only use FNTCHARCNT() on `vc->vc_font.data` and `p->fontdata`.
Assume FNTCHARCNT() is working as intended;
- Whenever `vc->vc_font.data` is set, also set `vc->vc_font.charcount`
properly;
- We can now replace `FNTCHARCNT(vc->vc_font.data)` with
`vc->vc_font.charcount`;
- Since `p->fontdata` always point to the same font data buffer with
`vc->vc_font.data`, we can also replace `FNTCHARCNT(p->fontdata)` with
`vc->vc_font.charcount`.
In conclusion, set `vc->vc_font.charcount` properly in fbcon_startup(),
fbcon_init(), fbcon_set_disp() and fbcon_do_set_font(), then replace
FNTCHARCNT() with `vc->vc_font.charcount`. No more if-else between
negative-indexing macros and hard-coded values.
Do not include <linux/font.h> in fbcon_rotate.c and tileblit.c, since they
no longer need it.
Depends on patch "Fonts: Add charcount field to font_desc".
Suggested-by: Daniel Vetter <daniel@ffwll.ch>
Signed-off-by: Peilin Ye <yepeilin.cs@gmail.com>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/e460a5780e54e3022661d5f09555144583b4cc59.1605169912.git.yepeilin.cs@gmail.com
2020-11-12 12:15:22 +00:00
|
|
|
else if (!vc->vc_hi_font_mask && charcount == 512)
|
fbcon: Fix vc attr at deinit
fbcon can deal with vc_hi_font_mask (the upper 256 chars) and adjust
the vc attrs dynamically when vc_hi_font_mask is changed at
fbcon_init(). When the vc_hi_font_mask is set, it remaps the attrs in
the existing console buffer with one bit shift up (for 9 bits), while
it remaps with one bit shift down (for 8 bits) when the value is
cleared. It works fine as long as the font gets updated after fbcon
was initialized.
However, we hit a bizarre problem when the console is switched to
another fb driver (typically from vesafb or efifb to drmfb). At
switching to the new fb driver, we temporarily rebind the console to
the dummy console, then rebind to the new driver. During the
switching, we leave the modified attrs as is. Thus, the new fbcon
takes over the old buffer as if it were to contain 8 bits chars
(although the attrs are still shifted for 9 bits), and effectively
this results in the yellow color texts instead of the original white
color, as found in the bugzilla entry below.
An easy fix for this is to re-adjust the attrs before leaving the
fbcon at con_deinit callback. Since the code to adjust the attrs is
already present in the current fbcon code, in this patch, we simply
factor out the relevant code, and call it from fbcon_deinit().
Bugzilla: https://bugzilla.suse.com/show_bug.cgi?id=1000619
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
2017-01-11 16:09:50 +00:00
|
|
|
set_vc_hi_font(vc, true);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
if (resize) {
|
[PATCH] fbcon: Console Rotation - Prepare fbcon for console rotation
This patch series implements generic code to rotate the console at 90, 180,
and 270 degrees. The implementation is completely done in the framebuffer
console level, thus no changes to the framebuffer layer or to the drivers
are needed.
Console rotation is required by some Sharp-based devices where the natural
orientation of the display is not at 0 degrees. Also, users that have
displays that can pivot will benefit by having a console in portrait mode
if they so desire.
The choice to implement the code in the console layer rather than in the
framebuffer layer is due to the following reasons:
- it's fast
- it does not require driver changes
- it can coexist with devices that can rotate the display at the hardware level
- it complements graphics applications that can do display rotation
The changes to core fbcon are minimal-- recognition of the console
rotation angle so it can swap directions, origins and axes (xres vs yres,
xpanstep vs ypanstep, xoffset vs yoffset, etc) and storage of the rotation
angle per display. The bulk of the code that does the actual drawing to the
screen are placed in separate files. Each angle of rotation has separate
methods (bmove, clear, putcs, cursor, update_start which is derived from
update_var, and clear_margins). To mimimize processing time, the fontdata
are pre-rotated at each console switch (only if the font or the angle has
changed).
The option can be compiled out (CONFIG_FRAMEBUFFER_CONSOLE_ROTATION = n) if
rotation is not needed.
Choosing the rotation angle can be done in several ways:
1. boot option fbcon=rotate:n, where
n = 0 - normal
n = 1 - 90 degrees (clockwise)
n = 2 - 180 degrees (upside down)
n = 3 - 270 degrees (counterclockwise)
2. echo n > /sys/class/graphics/fb[num]/con_rotate
where n is the same as described above. It sets the angle of rotation
of the current console
3 echo n > /sys/class/graphics/fb[num]/con_rotate_all
where n is the same as described above. Globally sets the angle of
rotation.
GOTCHAS:
The option, especially at angles of 90 and 270 degrees, will exercise
the least used code of drivers. Namely, at these angles, panning is done
in the x-axis, so it can reveal bugs in the driver if xpanstep is set
incorrectly. A workaround is to set xpanstep = 0.
Secondly, at these angles, the framebuffer memory access can be
unaligned if (fontheight * bpp) % 32 ~= 0 which can reveal bugs in the drivers
imageblit, fillrect and copyarea functions. (I think cfbfillrect may have
this buglet). A workaround is to use a standard 8x16 font.
Speed:
The scrolling speed difference between 0 and 180 degrees is minimal,
somewhere areound 1-2%. At 90 or 270 degress, speed drops down to a vicinity
of 30-40%. This is understandable because the blit direction is across the
framebuffer "direction." Scrolling will be helped at these angles if xpanstep
is not equal to zero, use of 8x16 fonts, and setting xres_virtual >= xres * 2.
Note: The code is tested on little-endian only, so I don't know if it will
work in big-endian. Please let me know, it will take only less than a minute
of your time.
This patch prepares fbcon for console rotation and contains the following
changes:
- add rotate field in struct fbcon_ops to keep fbcon's current rotation
angle
- add con_rotate field in struct display to store per-display rotation angle
- create a private copy of the current var to fbcon. This will prevent
fbcon from directly manipulating info->var, especially the fields xoffset,
yoffset and vmode.
- add ability to swap pertinent axes (xres, yres; xpanstep, ypanstep; etc)
depending on the rotation angle
- change global update_var() (function that sets the screen start address)
as an fbcon method update_start. This is required because the axes, start
offset, and/or direction can be reversed depending on the rotation angle.
- add fbcon method rotate_font() which will rotate each character bitmap to
the correct angle of rotation.
- add fbcon boot option 'rotate' to select the angle of rotation at bootime.
Currently does nothing until all patches are applied.
Signed-off-by: Antonino Daplas <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-11-09 05:39:09 +00:00
|
|
|
int cols, rows;
|
|
|
|
|
|
|
|
cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
|
|
|
|
rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
|
|
|
|
cols /= w;
|
|
|
|
rows /= h;
|
|
|
|
vc_resize(vc, cols, rows);
|
2016-06-23 11:34:35 +00:00
|
|
|
} else if (con_is_visible(vc)
|
2005-04-16 22:20:36 +00:00
|
|
|
&& vc->vc_mode == KD_TEXT) {
|
|
|
|
fbcon_clear_margins(vc, 0);
|
|
|
|
update_screen(vc);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (old_data && (--REFCOUNT(old_data) == 0))
|
|
|
|
kfree(old_data - FONT_EXTRA_WORDS * sizeof(int));
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* User asked to set font; we are guaranteed that
|
|
|
|
* a) width and height are in range 1..32
|
|
|
|
* b) charcount does not exceed 512
|
|
|
|
* but lets not assume that, since someone might someday want to use larger
|
|
|
|
* fonts. And charcount of 512 is small for unicode support.
|
|
|
|
*
|
|
|
|
* However, user space gives the font in 32 rows , regardless of
|
|
|
|
* actual font height. So a new API is needed if support for larger fonts
|
|
|
|
* is ever implemented.
|
|
|
|
*/
|
|
|
|
|
2018-02-27 00:04:20 +00:00
|
|
|
static int fbcon_set_font(struct vc_data *vc, struct console_font *font,
|
|
|
|
unsigned int flags)
|
2005-04-16 22:20:36 +00:00
|
|
|
{
|
2022-04-05 21:03:21 +00:00
|
|
|
struct fb_info *info = fbcon_info_from_console(vc->vc_num);
|
2005-04-16 22:20:36 +00:00
|
|
|
unsigned charcount = font->charcount;
|
|
|
|
int w = font->width;
|
|
|
|
int h = font->height;
|
|
|
|
int size;
|
|
|
|
int i, csum;
|
|
|
|
u8 *new_data, *data = font->data;
|
2020-07-31 16:33:11 +00:00
|
|
|
int pitch = PITCH(font->width);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
/* Is there a reason why fbconsole couldn't handle any charcount >256?
|
|
|
|
* If not this check should be changed to charcount < 256 */
|
|
|
|
if (charcount != 256 && charcount != 512)
|
|
|
|
return -EINVAL;
|
|
|
|
|
2022-06-25 10:56:49 +00:00
|
|
|
/* font bigger than screen resolution ? */
|
|
|
|
if (w > FBCON_SWAP(info->var.rotate, info->var.xres, info->var.yres) ||
|
|
|
|
h > FBCON_SWAP(info->var.rotate, info->var.yres, info->var.xres))
|
|
|
|
return -EINVAL;
|
|
|
|
|
2007-05-08 07:39:11 +00:00
|
|
|
/* Make sure drawing engine can handle the font */
|
|
|
|
if (!(info->pixmap.blit_x & (1 << (font->width - 1))) ||
|
|
|
|
!(info->pixmap.blit_y & (1 << (font->height - 1))))
|
|
|
|
return -EINVAL;
|
2007-05-08 07:39:19 +00:00
|
|
|
|
|
|
|
/* Make sure driver can handle the font length */
|
|
|
|
if (fbcon_invalid_charcount(info, charcount))
|
|
|
|
return -EINVAL;
|
2007-05-08 07:39:11 +00:00
|
|
|
|
2020-07-31 16:33:11 +00:00
|
|
|
size = CALC_FONTSZ(h, pitch, charcount);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
new_data = kmalloc(FONT_EXTRA_WORDS * sizeof(int) + size, GFP_USER);
|
|
|
|
|
|
|
|
if (!new_data)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
fbcon: Avoid using FNTCHARCNT() and hard-coded built-in font charcount
For user-provided fonts, the framebuffer layer is using a magic
negative-indexing macro, FNTCHARCNT(), to keep track of their number of
characters:
#define FNTCHARCNT(fd) (((int *)(fd))[-3])
For built-in fonts, it is using hard-coded values (256). This results in
something like the following:
map.length = (ops->p->userfont) ?
FNTCHARCNT(ops->p->fontdata) : 256;
This is unsatisfactory. In fact, there is already a `charcount` field in
our virtual console descriptor (see `struct console_font` inside `struct
vc_data`), let us use it:
map.length = vc->vc_font.charcount;
Recently we added a `charcount` field to `struct font_desc`. Use it to set
`vc->vc_font.charcount` properly. The idea is:
- We only use FNTCHARCNT() on `vc->vc_font.data` and `p->fontdata`.
Assume FNTCHARCNT() is working as intended;
- Whenever `vc->vc_font.data` is set, also set `vc->vc_font.charcount`
properly;
- We can now replace `FNTCHARCNT(vc->vc_font.data)` with
`vc->vc_font.charcount`;
- Since `p->fontdata` always point to the same font data buffer with
`vc->vc_font.data`, we can also replace `FNTCHARCNT(p->fontdata)` with
`vc->vc_font.charcount`.
In conclusion, set `vc->vc_font.charcount` properly in fbcon_startup(),
fbcon_init(), fbcon_set_disp() and fbcon_do_set_font(), then replace
FNTCHARCNT() with `vc->vc_font.charcount`. No more if-else between
negative-indexing macros and hard-coded values.
Do not include <linux/font.h> in fbcon_rotate.c and tileblit.c, since they
no longer need it.
Depends on patch "Fonts: Add charcount field to font_desc".
Suggested-by: Daniel Vetter <daniel@ffwll.ch>
Signed-off-by: Peilin Ye <yepeilin.cs@gmail.com>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/e460a5780e54e3022661d5f09555144583b4cc59.1605169912.git.yepeilin.cs@gmail.com
2020-11-12 12:15:22 +00:00
|
|
|
memset(new_data, 0, FONT_EXTRA_WORDS * sizeof(int));
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
new_data += FONT_EXTRA_WORDS * sizeof(int);
|
|
|
|
FNTSIZE(new_data) = size;
|
|
|
|
REFCOUNT(new_data) = 0; /* usage counter */
|
|
|
|
for (i=0; i< charcount; i++) {
|
|
|
|
memcpy(new_data + i*h*pitch, data + i*32*pitch, h*pitch);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Since linux has a nice crc32 function use it for counting font
|
|
|
|
* checksums. */
|
|
|
|
csum = crc32(0, new_data, size);
|
|
|
|
|
|
|
|
FNTSUM(new_data) = csum;
|
|
|
|
/* Check if the same font is on some other console already */
|
2006-06-26 07:27:09 +00:00
|
|
|
for (i = first_fb_vc; i <= last_fb_vc; i++) {
|
2005-04-16 22:20:36 +00:00
|
|
|
struct vc_data *tmp = vc_cons[i].d;
|
|
|
|
|
|
|
|
if (fb_display[i].userfont &&
|
|
|
|
fb_display[i].fontdata &&
|
|
|
|
FNTSUM(fb_display[i].fontdata) == csum &&
|
|
|
|
FNTSIZE(fb_display[i].fontdata) == size &&
|
|
|
|
tmp->vc_font.width == w &&
|
|
|
|
!memcmp(fb_display[i].fontdata, new_data, size)) {
|
|
|
|
kfree(new_data - FONT_EXTRA_WORDS * sizeof(int));
|
2005-09-13 08:25:44 +00:00
|
|
|
new_data = (u8 *)fb_display[i].fontdata;
|
2005-04-16 22:20:36 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
fbcon: Avoid using FNTCHARCNT() and hard-coded built-in font charcount
For user-provided fonts, the framebuffer layer is using a magic
negative-indexing macro, FNTCHARCNT(), to keep track of their number of
characters:
#define FNTCHARCNT(fd) (((int *)(fd))[-3])
For built-in fonts, it is using hard-coded values (256). This results in
something like the following:
map.length = (ops->p->userfont) ?
FNTCHARCNT(ops->p->fontdata) : 256;
This is unsatisfactory. In fact, there is already a `charcount` field in
our virtual console descriptor (see `struct console_font` inside `struct
vc_data`), let us use it:
map.length = vc->vc_font.charcount;
Recently we added a `charcount` field to `struct font_desc`. Use it to set
`vc->vc_font.charcount` properly. The idea is:
- We only use FNTCHARCNT() on `vc->vc_font.data` and `p->fontdata`.
Assume FNTCHARCNT() is working as intended;
- Whenever `vc->vc_font.data` is set, also set `vc->vc_font.charcount`
properly;
- We can now replace `FNTCHARCNT(vc->vc_font.data)` with
`vc->vc_font.charcount`;
- Since `p->fontdata` always point to the same font data buffer with
`vc->vc_font.data`, we can also replace `FNTCHARCNT(p->fontdata)` with
`vc->vc_font.charcount`.
In conclusion, set `vc->vc_font.charcount` properly in fbcon_startup(),
fbcon_init(), fbcon_set_disp() and fbcon_do_set_font(), then replace
FNTCHARCNT() with `vc->vc_font.charcount`. No more if-else between
negative-indexing macros and hard-coded values.
Do not include <linux/font.h> in fbcon_rotate.c and tileblit.c, since they
no longer need it.
Depends on patch "Fonts: Add charcount field to font_desc".
Suggested-by: Daniel Vetter <daniel@ffwll.ch>
Signed-off-by: Peilin Ye <yepeilin.cs@gmail.com>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/e460a5780e54e3022661d5f09555144583b4cc59.1605169912.git.yepeilin.cs@gmail.com
2020-11-12 12:15:22 +00:00
|
|
|
return fbcon_do_set_font(vc, font->width, font->height, charcount, new_data, 1);
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int fbcon_set_def_font(struct vc_data *vc, struct console_font *font, char *name)
|
|
|
|
{
|
2022-04-05 21:03:21 +00:00
|
|
|
struct fb_info *info = fbcon_info_from_console(vc->vc_num);
|
2005-09-13 08:25:44 +00:00
|
|
|
const struct font_desc *f;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
if (!name)
|
2007-05-08 07:39:11 +00:00
|
|
|
f = get_default_font(info->var.xres, info->var.yres,
|
|
|
|
info->pixmap.blit_x, info->pixmap.blit_y);
|
2005-04-16 22:20:36 +00:00
|
|
|
else if (!(f = find_font(name)))
|
|
|
|
return -ENOENT;
|
|
|
|
|
|
|
|
font->width = f->width;
|
|
|
|
font->height = f->height;
|
fbcon: Avoid using FNTCHARCNT() and hard-coded built-in font charcount
For user-provided fonts, the framebuffer layer is using a magic
negative-indexing macro, FNTCHARCNT(), to keep track of their number of
characters:
#define FNTCHARCNT(fd) (((int *)(fd))[-3])
For built-in fonts, it is using hard-coded values (256). This results in
something like the following:
map.length = (ops->p->userfont) ?
FNTCHARCNT(ops->p->fontdata) : 256;
This is unsatisfactory. In fact, there is already a `charcount` field in
our virtual console descriptor (see `struct console_font` inside `struct
vc_data`), let us use it:
map.length = vc->vc_font.charcount;
Recently we added a `charcount` field to `struct font_desc`. Use it to set
`vc->vc_font.charcount` properly. The idea is:
- We only use FNTCHARCNT() on `vc->vc_font.data` and `p->fontdata`.
Assume FNTCHARCNT() is working as intended;
- Whenever `vc->vc_font.data` is set, also set `vc->vc_font.charcount`
properly;
- We can now replace `FNTCHARCNT(vc->vc_font.data)` with
`vc->vc_font.charcount`;
- Since `p->fontdata` always point to the same font data buffer with
`vc->vc_font.data`, we can also replace `FNTCHARCNT(p->fontdata)` with
`vc->vc_font.charcount`.
In conclusion, set `vc->vc_font.charcount` properly in fbcon_startup(),
fbcon_init(), fbcon_set_disp() and fbcon_do_set_font(), then replace
FNTCHARCNT() with `vc->vc_font.charcount`. No more if-else between
negative-indexing macros and hard-coded values.
Do not include <linux/font.h> in fbcon_rotate.c and tileblit.c, since they
no longer need it.
Depends on patch "Fonts: Add charcount field to font_desc".
Suggested-by: Daniel Vetter <daniel@ffwll.ch>
Signed-off-by: Peilin Ye <yepeilin.cs@gmail.com>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/e460a5780e54e3022661d5f09555144583b4cc59.1605169912.git.yepeilin.cs@gmail.com
2020-11-12 12:15:22 +00:00
|
|
|
return fbcon_do_set_font(vc, f->width, f->height, f->charcount, f->data, 0);
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static u16 palette_red[16];
|
|
|
|
static u16 palette_green[16];
|
|
|
|
static u16 palette_blue[16];
|
|
|
|
|
|
|
|
static struct fb_cmap palette_cmap = {
|
|
|
|
0, 16, palette_red, palette_green, palette_blue, NULL
|
|
|
|
};
|
|
|
|
|
2016-06-23 11:34:27 +00:00
|
|
|
static void fbcon_set_palette(struct vc_data *vc, const unsigned char *table)
|
2005-04-16 22:20:36 +00:00
|
|
|
{
|
2022-04-05 21:03:21 +00:00
|
|
|
struct fb_info *info = fbcon_info_from_console(vc->vc_num);
|
2005-04-16 22:20:36 +00:00
|
|
|
int i, j, k, depth;
|
|
|
|
u8 val;
|
|
|
|
|
|
|
|
if (fbcon_is_inactive(vc, info))
|
2016-06-23 11:34:27 +00:00
|
|
|
return;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2016-06-23 11:34:35 +00:00
|
|
|
if (!con_is_visible(vc))
|
2016-06-23 11:34:27 +00:00
|
|
|
return;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2005-09-09 20:04:37 +00:00
|
|
|
depth = fb_get_color_depth(&info->var, &info->fix);
|
2005-04-16 22:20:36 +00:00
|
|
|
if (depth > 3) {
|
|
|
|
for (i = j = 0; i < 16; i++) {
|
|
|
|
k = table[i];
|
|
|
|
val = vc->vc_palette[j++];
|
|
|
|
palette_red[k] = (val << 8) | val;
|
|
|
|
val = vc->vc_palette[j++];
|
|
|
|
palette_green[k] = (val << 8) | val;
|
|
|
|
val = vc->vc_palette[j++];
|
|
|
|
palette_blue[k] = (val << 8) | val;
|
|
|
|
}
|
|
|
|
palette_cmap.len = 16;
|
|
|
|
palette_cmap.start = 0;
|
|
|
|
/*
|
|
|
|
* If framebuffer is capable of less than 16 colors,
|
|
|
|
* use default palette of fbcon.
|
|
|
|
*/
|
|
|
|
} else
|
|
|
|
fb_copy_cmap(fb_default_cmap(1 << depth), &palette_cmap);
|
|
|
|
|
2016-06-23 11:34:27 +00:00
|
|
|
fb_set_cmap(&palette_cmap, info);
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
|
2020-08-18 08:56:51 +00:00
|
|
|
static u16 *fbcon_screen_pos(const struct vc_data *vc, int offset)
|
2005-04-16 22:20:36 +00:00
|
|
|
{
|
2020-09-07 18:45:27 +00:00
|
|
|
return (u16 *) (vc->vc_origin + offset);
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static unsigned long fbcon_getxy(struct vc_data *vc, unsigned long pos,
|
|
|
|
int *px, int *py)
|
|
|
|
{
|
|
|
|
unsigned long ret;
|
|
|
|
int x, y;
|
|
|
|
|
|
|
|
if (pos >= vc->vc_origin && pos < vc->vc_scr_end) {
|
|
|
|
unsigned long offset = (pos - vc->vc_origin) / 2;
|
|
|
|
|
|
|
|
x = offset % vc->vc_cols;
|
|
|
|
y = offset / vc->vc_cols;
|
|
|
|
ret = pos + (vc->vc_cols - x) * 2;
|
|
|
|
} else {
|
|
|
|
/* Should not happen */
|
|
|
|
x = y = 0;
|
|
|
|
ret = vc->vc_origin;
|
|
|
|
}
|
|
|
|
if (px)
|
|
|
|
*px = x;
|
|
|
|
if (py)
|
|
|
|
*py = y;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* As we might be inside of softback, we may work with non-contiguous buffer,
|
|
|
|
that's why we have to use a separate routine. */
|
|
|
|
static void fbcon_invert_region(struct vc_data *vc, u16 * p, int cnt)
|
|
|
|
{
|
|
|
|
while (cnt--) {
|
|
|
|
u16 a = scr_readw(p);
|
|
|
|
if (!vc->vc_can_do_color)
|
|
|
|
a ^= 0x0800;
|
|
|
|
else if (vc->vc_hi_font_mask == 0x100)
|
|
|
|
a = ((a) & 0x11ff) | (((a) & 0xe000) >> 4) |
|
|
|
|
(((a) & 0x0e00) << 4);
|
|
|
|
else
|
|
|
|
a = ((a) & 0x88ff) | (((a) & 0x7000) >> 4) |
|
|
|
|
(((a) & 0x0700) << 4);
|
|
|
|
scr_writew(a, p++);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-28 09:02:52 +00:00
|
|
|
void fbcon_suspended(struct fb_info *info)
|
2005-04-16 22:20:36 +00:00
|
|
|
{
|
|
|
|
struct vc_data *vc = NULL;
|
|
|
|
struct fbcon_ops *ops = info->fbcon_par;
|
|
|
|
|
|
|
|
if (!ops || ops->currcon < 0)
|
|
|
|
return;
|
|
|
|
vc = vc_cons[ops->currcon].d;
|
|
|
|
|
|
|
|
/* Clear cursor, restore saved data */
|
|
|
|
fbcon_cursor(vc, CM_ERASE);
|
|
|
|
}
|
|
|
|
|
2019-05-28 09:02:52 +00:00
|
|
|
void fbcon_resumed(struct fb_info *info)
|
2005-04-16 22:20:36 +00:00
|
|
|
{
|
|
|
|
struct vc_data *vc;
|
|
|
|
struct fbcon_ops *ops = info->fbcon_par;
|
|
|
|
|
|
|
|
if (!ops || ops->currcon < 0)
|
|
|
|
return;
|
|
|
|
vc = vc_cons[ops->currcon].d;
|
|
|
|
|
|
|
|
update_screen(vc);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void fbcon_modechanged(struct fb_info *info)
|
|
|
|
{
|
|
|
|
struct fbcon_ops *ops = info->fbcon_par;
|
|
|
|
struct vc_data *vc;
|
2019-05-28 09:02:39 +00:00
|
|
|
struct fbcon_display *p;
|
2005-04-16 22:20:36 +00:00
|
|
|
int rows, cols;
|
|
|
|
|
|
|
|
if (!ops || ops->currcon < 0)
|
|
|
|
return;
|
|
|
|
vc = vc_cons[ops->currcon].d;
|
[PATCH] fbcon: Console Rotation - Prepare fbcon for console rotation
This patch series implements generic code to rotate the console at 90, 180,
and 270 degrees. The implementation is completely done in the framebuffer
console level, thus no changes to the framebuffer layer or to the drivers
are needed.
Console rotation is required by some Sharp-based devices where the natural
orientation of the display is not at 0 degrees. Also, users that have
displays that can pivot will benefit by having a console in portrait mode
if they so desire.
The choice to implement the code in the console layer rather than in the
framebuffer layer is due to the following reasons:
- it's fast
- it does not require driver changes
- it can coexist with devices that can rotate the display at the hardware level
- it complements graphics applications that can do display rotation
The changes to core fbcon are minimal-- recognition of the console
rotation angle so it can swap directions, origins and axes (xres vs yres,
xpanstep vs ypanstep, xoffset vs yoffset, etc) and storage of the rotation
angle per display. The bulk of the code that does the actual drawing to the
screen are placed in separate files. Each angle of rotation has separate
methods (bmove, clear, putcs, cursor, update_start which is derived from
update_var, and clear_margins). To mimimize processing time, the fontdata
are pre-rotated at each console switch (only if the font or the angle has
changed).
The option can be compiled out (CONFIG_FRAMEBUFFER_CONSOLE_ROTATION = n) if
rotation is not needed.
Choosing the rotation angle can be done in several ways:
1. boot option fbcon=rotate:n, where
n = 0 - normal
n = 1 - 90 degrees (clockwise)
n = 2 - 180 degrees (upside down)
n = 3 - 270 degrees (counterclockwise)
2. echo n > /sys/class/graphics/fb[num]/con_rotate
where n is the same as described above. It sets the angle of rotation
of the current console
3 echo n > /sys/class/graphics/fb[num]/con_rotate_all
where n is the same as described above. Globally sets the angle of
rotation.
GOTCHAS:
The option, especially at angles of 90 and 270 degrees, will exercise
the least used code of drivers. Namely, at these angles, panning is done
in the x-axis, so it can reveal bugs in the driver if xpanstep is set
incorrectly. A workaround is to set xpanstep = 0.
Secondly, at these angles, the framebuffer memory access can be
unaligned if (fontheight * bpp) % 32 ~= 0 which can reveal bugs in the drivers
imageblit, fillrect and copyarea functions. (I think cfbfillrect may have
this buglet). A workaround is to use a standard 8x16 font.
Speed:
The scrolling speed difference between 0 and 180 degrees is minimal,
somewhere areound 1-2%. At 90 or 270 degress, speed drops down to a vicinity
of 30-40%. This is understandable because the blit direction is across the
framebuffer "direction." Scrolling will be helped at these angles if xpanstep
is not equal to zero, use of 8x16 fonts, and setting xres_virtual >= xres * 2.
Note: The code is tested on little-endian only, so I don't know if it will
work in big-endian. Please let me know, it will take only less than a minute
of your time.
This patch prepares fbcon for console rotation and contains the following
changes:
- add rotate field in struct fbcon_ops to keep fbcon's current rotation
angle
- add con_rotate field in struct display to store per-display rotation angle
- create a private copy of the current var to fbcon. This will prevent
fbcon from directly manipulating info->var, especially the fields xoffset,
yoffset and vmode.
- add ability to swap pertinent axes (xres, yres; xpanstep, ypanstep; etc)
depending on the rotation angle
- change global update_var() (function that sets the screen start address)
as an fbcon method update_start. This is required because the axes, start
offset, and/or direction can be reversed depending on the rotation angle.
- add fbcon method rotate_font() which will rotate each character bitmap to
the correct angle of rotation.
- add fbcon boot option 'rotate' to select the angle of rotation at bootime.
Currently does nothing until all patches are applied.
Signed-off-by: Antonino Daplas <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-11-09 05:39:09 +00:00
|
|
|
if (vc->vc_mode != KD_TEXT ||
|
2022-04-05 21:03:21 +00:00
|
|
|
fbcon_info_from_console(ops->currcon) != info)
|
2005-04-16 22:20:36 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
p = &fb_display[vc->vc_num];
|
2006-01-10 04:52:56 +00:00
|
|
|
set_blitting_type(vc, info);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2016-06-23 11:34:35 +00:00
|
|
|
if (con_is_visible(vc)) {
|
2005-04-16 22:20:36 +00:00
|
|
|
var_to_display(p, &info->var, info);
|
[PATCH] fbcon: Console Rotation - Prepare fbcon for console rotation
This patch series implements generic code to rotate the console at 90, 180,
and 270 degrees. The implementation is completely done in the framebuffer
console level, thus no changes to the framebuffer layer or to the drivers
are needed.
Console rotation is required by some Sharp-based devices where the natural
orientation of the display is not at 0 degrees. Also, users that have
displays that can pivot will benefit by having a console in portrait mode
if they so desire.
The choice to implement the code in the console layer rather than in the
framebuffer layer is due to the following reasons:
- it's fast
- it does not require driver changes
- it can coexist with devices that can rotate the display at the hardware level
- it complements graphics applications that can do display rotation
The changes to core fbcon are minimal-- recognition of the console
rotation angle so it can swap directions, origins and axes (xres vs yres,
xpanstep vs ypanstep, xoffset vs yoffset, etc) and storage of the rotation
angle per display. The bulk of the code that does the actual drawing to the
screen are placed in separate files. Each angle of rotation has separate
methods (bmove, clear, putcs, cursor, update_start which is derived from
update_var, and clear_margins). To mimimize processing time, the fontdata
are pre-rotated at each console switch (only if the font or the angle has
changed).
The option can be compiled out (CONFIG_FRAMEBUFFER_CONSOLE_ROTATION = n) if
rotation is not needed.
Choosing the rotation angle can be done in several ways:
1. boot option fbcon=rotate:n, where
n = 0 - normal
n = 1 - 90 degrees (clockwise)
n = 2 - 180 degrees (upside down)
n = 3 - 270 degrees (counterclockwise)
2. echo n > /sys/class/graphics/fb[num]/con_rotate
where n is the same as described above. It sets the angle of rotation
of the current console
3 echo n > /sys/class/graphics/fb[num]/con_rotate_all
where n is the same as described above. Globally sets the angle of
rotation.
GOTCHAS:
The option, especially at angles of 90 and 270 degrees, will exercise
the least used code of drivers. Namely, at these angles, panning is done
in the x-axis, so it can reveal bugs in the driver if xpanstep is set
incorrectly. A workaround is to set xpanstep = 0.
Secondly, at these angles, the framebuffer memory access can be
unaligned if (fontheight * bpp) % 32 ~= 0 which can reveal bugs in the drivers
imageblit, fillrect and copyarea functions. (I think cfbfillrect may have
this buglet). A workaround is to use a standard 8x16 font.
Speed:
The scrolling speed difference between 0 and 180 degrees is minimal,
somewhere areound 1-2%. At 90 or 270 degress, speed drops down to a vicinity
of 30-40%. This is understandable because the blit direction is across the
framebuffer "direction." Scrolling will be helped at these angles if xpanstep
is not equal to zero, use of 8x16 fonts, and setting xres_virtual >= xres * 2.
Note: The code is tested on little-endian only, so I don't know if it will
work in big-endian. Please let me know, it will take only less than a minute
of your time.
This patch prepares fbcon for console rotation and contains the following
changes:
- add rotate field in struct fbcon_ops to keep fbcon's current rotation
angle
- add con_rotate field in struct display to store per-display rotation angle
- create a private copy of the current var to fbcon. This will prevent
fbcon from directly manipulating info->var, especially the fields xoffset,
yoffset and vmode.
- add ability to swap pertinent axes (xres, yres; xpanstep, ypanstep; etc)
depending on the rotation angle
- change global update_var() (function that sets the screen start address)
as an fbcon method update_start. This is required because the axes, start
offset, and/or direction can be reversed depending on the rotation angle.
- add fbcon method rotate_font() which will rotate each character bitmap to
the correct angle of rotation.
- add fbcon boot option 'rotate' to select the angle of rotation at bootime.
Currently does nothing until all patches are applied.
Signed-off-by: Antonino Daplas <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-11-09 05:39:09 +00:00
|
|
|
cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
|
|
|
|
rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
|
|
|
|
cols /= vc->vc_font.width;
|
|
|
|
rows /= vc->vc_font.height;
|
2005-04-16 22:20:36 +00:00
|
|
|
vc_resize(vc, cols, rows);
|
|
|
|
updatescrollmode(p, info, vc);
|
|
|
|
scrollback_max = 0;
|
|
|
|
scrollback_current = 0;
|
2005-12-13 06:17:18 +00:00
|
|
|
|
|
|
|
if (!fbcon_is_inactive(vc, info)) {
|
|
|
|
ops->var.xoffset = ops->var.yoffset = p->yscroll = 0;
|
|
|
|
ops->update_start(info);
|
|
|
|
}
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
fbcon_set_palette(vc, color_table);
|
|
|
|
update_screen(vc);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-09-09 20:04:29 +00:00
|
|
|
static void fbcon_set_all_vcs(struct fb_info *info)
|
|
|
|
{
|
|
|
|
struct fbcon_ops *ops = info->fbcon_par;
|
|
|
|
struct vc_data *vc;
|
2019-05-28 09:02:39 +00:00
|
|
|
struct fbcon_display *p;
|
2007-05-08 07:38:40 +00:00
|
|
|
int i, rows, cols, fg = -1;
|
2005-09-09 20:04:29 +00:00
|
|
|
|
|
|
|
if (!ops || ops->currcon < 0)
|
|
|
|
return;
|
|
|
|
|
2006-06-26 07:27:09 +00:00
|
|
|
for (i = first_fb_vc; i <= last_fb_vc; i++) {
|
2005-09-09 20:04:29 +00:00
|
|
|
vc = vc_cons[i].d;
|
|
|
|
if (!vc || vc->vc_mode != KD_TEXT ||
|
2022-04-05 21:03:21 +00:00
|
|
|
fbcon_info_from_console(i) != info)
|
2005-09-09 20:04:29 +00:00
|
|
|
continue;
|
|
|
|
|
2016-06-23 11:34:35 +00:00
|
|
|
if (con_is_visible(vc)) {
|
2007-05-08 07:38:40 +00:00
|
|
|
fg = i;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2005-09-09 20:04:29 +00:00
|
|
|
p = &fb_display[vc->vc_num];
|
2006-01-10 04:52:56 +00:00
|
|
|
set_blitting_type(vc, info);
|
2005-09-09 20:04:29 +00:00
|
|
|
var_to_display(p, &info->var, info);
|
2008-10-16 05:03:57 +00:00
|
|
|
cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
|
|
|
|
rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
|
[PATCH] fbcon: Console Rotation - Prepare fbcon for console rotation
This patch series implements generic code to rotate the console at 90, 180,
and 270 degrees. The implementation is completely done in the framebuffer
console level, thus no changes to the framebuffer layer or to the drivers
are needed.
Console rotation is required by some Sharp-based devices where the natural
orientation of the display is not at 0 degrees. Also, users that have
displays that can pivot will benefit by having a console in portrait mode
if they so desire.
The choice to implement the code in the console layer rather than in the
framebuffer layer is due to the following reasons:
- it's fast
- it does not require driver changes
- it can coexist with devices that can rotate the display at the hardware level
- it complements graphics applications that can do display rotation
The changes to core fbcon are minimal-- recognition of the console
rotation angle so it can swap directions, origins and axes (xres vs yres,
xpanstep vs ypanstep, xoffset vs yoffset, etc) and storage of the rotation
angle per display. The bulk of the code that does the actual drawing to the
screen are placed in separate files. Each angle of rotation has separate
methods (bmove, clear, putcs, cursor, update_start which is derived from
update_var, and clear_margins). To mimimize processing time, the fontdata
are pre-rotated at each console switch (only if the font or the angle has
changed).
The option can be compiled out (CONFIG_FRAMEBUFFER_CONSOLE_ROTATION = n) if
rotation is not needed.
Choosing the rotation angle can be done in several ways:
1. boot option fbcon=rotate:n, where
n = 0 - normal
n = 1 - 90 degrees (clockwise)
n = 2 - 180 degrees (upside down)
n = 3 - 270 degrees (counterclockwise)
2. echo n > /sys/class/graphics/fb[num]/con_rotate
where n is the same as described above. It sets the angle of rotation
of the current console
3 echo n > /sys/class/graphics/fb[num]/con_rotate_all
where n is the same as described above. Globally sets the angle of
rotation.
GOTCHAS:
The option, especially at angles of 90 and 270 degrees, will exercise
the least used code of drivers. Namely, at these angles, panning is done
in the x-axis, so it can reveal bugs in the driver if xpanstep is set
incorrectly. A workaround is to set xpanstep = 0.
Secondly, at these angles, the framebuffer memory access can be
unaligned if (fontheight * bpp) % 32 ~= 0 which can reveal bugs in the drivers
imageblit, fillrect and copyarea functions. (I think cfbfillrect may have
this buglet). A workaround is to use a standard 8x16 font.
Speed:
The scrolling speed difference between 0 and 180 degrees is minimal,
somewhere areound 1-2%. At 90 or 270 degress, speed drops down to a vicinity
of 30-40%. This is understandable because the blit direction is across the
framebuffer "direction." Scrolling will be helped at these angles if xpanstep
is not equal to zero, use of 8x16 fonts, and setting xres_virtual >= xres * 2.
Note: The code is tested on little-endian only, so I don't know if it will
work in big-endian. Please let me know, it will take only less than a minute
of your time.
This patch prepares fbcon for console rotation and contains the following
changes:
- add rotate field in struct fbcon_ops to keep fbcon's current rotation
angle
- add con_rotate field in struct display to store per-display rotation angle
- create a private copy of the current var to fbcon. This will prevent
fbcon from directly manipulating info->var, especially the fields xoffset,
yoffset and vmode.
- add ability to swap pertinent axes (xres, yres; xpanstep, ypanstep; etc)
depending on the rotation angle
- change global update_var() (function that sets the screen start address)
as an fbcon method update_start. This is required because the axes, start
offset, and/or direction can be reversed depending on the rotation angle.
- add fbcon method rotate_font() which will rotate each character bitmap to
the correct angle of rotation.
- add fbcon boot option 'rotate' to select the angle of rotation at bootime.
Currently does nothing until all patches are applied.
Signed-off-by: Antonino Daplas <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-11-09 05:39:09 +00:00
|
|
|
cols /= vc->vc_font.width;
|
|
|
|
rows /= vc->vc_font.height;
|
2005-09-09 20:04:29 +00:00
|
|
|
vc_resize(vc, cols, rows);
|
|
|
|
}
|
2006-01-10 04:52:58 +00:00
|
|
|
|
2007-05-08 07:38:40 +00:00
|
|
|
if (fg != -1)
|
|
|
|
fbcon_modechanged(info);
|
2005-09-09 20:04:29 +00:00
|
|
|
}
|
|
|
|
|
2019-05-28 09:02:59 +00:00
|
|
|
|
|
|
|
void fbcon_update_vcs(struct fb_info *info, bool all)
|
|
|
|
{
|
|
|
|
if (all)
|
|
|
|
fbcon_set_all_vcs(info);
|
|
|
|
else
|
|
|
|
fbcon_modechanged(info);
|
|
|
|
}
|
2019-06-19 08:11:15 +00:00
|
|
|
EXPORT_SYMBOL(fbcon_update_vcs);
|
2019-05-28 09:02:59 +00:00
|
|
|
|
2022-06-25 11:00:34 +00:00
|
|
|
/* let fbcon check if it supports a new screen resolution */
|
|
|
|
int fbcon_modechange_possible(struct fb_info *info, struct fb_var_screeninfo *var)
|
|
|
|
{
|
|
|
|
struct fbcon_ops *ops = info->fbcon_par;
|
|
|
|
struct vc_data *vc;
|
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
WARN_CONSOLE_UNLOCKED();
|
|
|
|
|
|
|
|
if (!ops)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
/* prevent setting a screen size which is smaller than font size */
|
|
|
|
for (i = first_fb_vc; i <= last_fb_vc; i++) {
|
|
|
|
vc = vc_cons[i].d;
|
|
|
|
if (!vc || vc->vc_mode != KD_TEXT ||
|
|
|
|
registered_fb[con2fb_map[i]] != info)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (vc->vc_font.width > FBCON_SWAP(var->rotate, var->xres, var->yres) ||
|
|
|
|
vc->vc_font.height > FBCON_SWAP(var->rotate, var->yres, var->xres))
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL_GPL(fbcon_modechange_possible);
|
|
|
|
|
2019-05-28 09:02:53 +00:00
|
|
|
int fbcon_mode_deleted(struct fb_info *info,
|
|
|
|
struct fb_videomode *mode)
|
2005-04-16 22:20:36 +00:00
|
|
|
{
|
|
|
|
struct fb_info *fb_info;
|
2019-05-28 09:02:39 +00:00
|
|
|
struct fbcon_display *p;
|
2005-04-16 22:20:36 +00:00
|
|
|
int i, j, found = 0;
|
|
|
|
|
|
|
|
/* before deletion, ensure that mode is not in use */
|
|
|
|
for (i = first_fb_vc; i <= last_fb_vc; i++) {
|
|
|
|
j = con2fb_map[i];
|
|
|
|
if (j == -1)
|
|
|
|
continue;
|
2022-04-05 21:03:35 +00:00
|
|
|
fb_info = fbcon_registered_fb[j];
|
2005-04-16 22:20:36 +00:00
|
|
|
if (fb_info != info)
|
|
|
|
continue;
|
|
|
|
p = &fb_display[i];
|
|
|
|
if (!p || !p->mode)
|
|
|
|
continue;
|
|
|
|
if (fb_mode_is_equal(p->mode, mode)) {
|
|
|
|
found = 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return found;
|
|
|
|
}
|
|
|
|
|
2007-07-17 11:05:33 +00:00
|
|
|
#ifdef CONFIG_VT_HW_CONSOLE_BINDING
|
2019-05-28 09:02:48 +00:00
|
|
|
static void fbcon_unbind(void)
|
2007-07-17 11:05:33 +00:00
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
2013-01-25 00:28:18 +00:00
|
|
|
ret = do_unbind_con_driver(&fb_con, first_fb_vc, last_fb_vc,
|
2007-07-17 11:05:33 +00:00
|
|
|
fbcon_is_default);
|
2009-09-22 23:47:52 +00:00
|
|
|
|
|
|
|
if (!ret)
|
|
|
|
fbcon_has_console_bind = 0;
|
2007-07-17 11:05:33 +00:00
|
|
|
}
|
|
|
|
#else
|
2019-05-28 09:02:48 +00:00
|
|
|
static inline void fbcon_unbind(void) {}
|
2007-07-17 11:05:33 +00:00
|
|
|
#endif /* CONFIG_VT_HW_CONSOLE_BINDING */
|
|
|
|
|
2019-05-28 09:02:48 +00:00
|
|
|
void fbcon_fb_unbind(struct fb_info *info)
|
2007-07-17 11:05:33 +00:00
|
|
|
{
|
2022-04-05 21:03:28 +00:00
|
|
|
int i, new_idx = -1;
|
2019-05-28 09:02:48 +00:00
|
|
|
int idx = info->node;
|
2007-07-17 11:05:33 +00:00
|
|
|
|
2022-04-05 21:03:32 +00:00
|
|
|
console_lock();
|
2018-06-28 13:20:28 +00:00
|
|
|
|
2022-04-05 21:03:32 +00:00
|
|
|
if (!fbcon_has_console_bind) {
|
|
|
|
console_unlock();
|
2019-05-28 09:02:48 +00:00
|
|
|
return;
|
2022-04-05 21:03:32 +00:00
|
|
|
}
|
2009-09-22 23:47:52 +00:00
|
|
|
|
2007-07-17 11:05:33 +00:00
|
|
|
for (i = first_fb_vc; i <= last_fb_vc; i++) {
|
|
|
|
if (con2fb_map[i] != idx &&
|
|
|
|
con2fb_map[i] != -1) {
|
2018-12-20 18:13:09 +00:00
|
|
|
new_idx = con2fb_map[i];
|
2007-07-17 11:05:33 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (new_idx != -1) {
|
|
|
|
for (i = first_fb_vc; i <= last_fb_vc; i++) {
|
|
|
|
if (con2fb_map[i] == idx)
|
|
|
|
set_con2fb_map(i, new_idx, 0);
|
|
|
|
}
|
fbcon: Clean up fbcon data in fb_info on FB_EVENT_FB_UNBIND with 0 fbs
When FB_EVENT_FB_UNBIND is sent, fbcon has two paths, one path taken
when there is another frame buffer to switch any affected vcs to and
another path when there isn't.
In the case where there is another frame buffer to use,
fbcon_fb_unbind calls set_con2fb_map to remap all of the affected vcs
to the replacement frame buffer. set_con2fb_map will eventually call
con2fb_release_oldinfo when the last vcs gets unmapped from the old
frame buffer.
con2fb_release_oldinfo frees the fbcon data that is hooked off of the
fb_info structure, including the cursor timer.
In the case where there isn't another frame buffer to use,
fbcon_fb_unbind simply calls fbcon_unbind, which doesn't clear the
con2fb_map or free the fbcon data hooked from the fb_info
structure. In particular, it doesn't stop the cursor blink timer. When
the fb_info structure is then freed, we end up with a timer queue
pointing into freed memory and "bad things" start happening.
This patch first changes con2fb_release_oldinfo so that it can take a
NULL pointer for the new frame buffer, but still does all of the
deallocation and cursor timer cleanup.
Finally, the patch tries to replicate some of what set_con2fb_map does
by clearing the con2fb_map for the affected vcs and calling the
modified con2fb_release_info function to clean up the fb_info structure.
Signed-off-by: Keith Packard <keithp@keithp.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
2014-01-20 21:31:10 +00:00
|
|
|
} else {
|
2022-04-05 21:03:35 +00:00
|
|
|
struct fb_info *info = fbcon_registered_fb[idx];
|
fbcon: Clean up fbcon data in fb_info on FB_EVENT_FB_UNBIND with 0 fbs
When FB_EVENT_FB_UNBIND is sent, fbcon has two paths, one path taken
when there is another frame buffer to switch any affected vcs to and
another path when there isn't.
In the case where there is another frame buffer to use,
fbcon_fb_unbind calls set_con2fb_map to remap all of the affected vcs
to the replacement frame buffer. set_con2fb_map will eventually call
con2fb_release_oldinfo when the last vcs gets unmapped from the old
frame buffer.
con2fb_release_oldinfo frees the fbcon data that is hooked off of the
fb_info structure, including the cursor timer.
In the case where there isn't another frame buffer to use,
fbcon_fb_unbind simply calls fbcon_unbind, which doesn't clear the
con2fb_map or free the fbcon data hooked from the fb_info
structure. In particular, it doesn't stop the cursor blink timer. When
the fb_info structure is then freed, we end up with a timer queue
pointing into freed memory and "bad things" start happening.
This patch first changes con2fb_release_oldinfo so that it can take a
NULL pointer for the new frame buffer, but still does all of the
deallocation and cursor timer cleanup.
Finally, the patch tries to replicate some of what set_con2fb_map does
by clearing the con2fb_map for the affected vcs and calling the
modified con2fb_release_info function to clean up the fb_info structure.
Signed-off-by: Keith Packard <keithp@keithp.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
2014-01-20 21:31:10 +00:00
|
|
|
|
|
|
|
/* This is sort of like set_con2fb_map, except it maps
|
|
|
|
* the consoles to no device and then releases the
|
|
|
|
* oldinfo to free memory and cancel the cursor blink
|
|
|
|
* timer. I can imagine this just becoming part of
|
|
|
|
* set_con2fb_map where new_idx is -1
|
|
|
|
*/
|
|
|
|
for (i = first_fb_vc; i <= last_fb_vc; i++) {
|
|
|
|
if (con2fb_map[i] == idx) {
|
|
|
|
con2fb_map[i] = -1;
|
|
|
|
if (!search_fb_in_map(idx)) {
|
2022-04-05 21:03:28 +00:00
|
|
|
con2fb_release_oldinfo(vc_cons[i].d,
|
|
|
|
info, NULL);
|
fbcon: Clean up fbcon data in fb_info on FB_EVENT_FB_UNBIND with 0 fbs
When FB_EVENT_FB_UNBIND is sent, fbcon has two paths, one path taken
when there is another frame buffer to switch any affected vcs to and
another path when there isn't.
In the case where there is another frame buffer to use,
fbcon_fb_unbind calls set_con2fb_map to remap all of the affected vcs
to the replacement frame buffer. set_con2fb_map will eventually call
con2fb_release_oldinfo when the last vcs gets unmapped from the old
frame buffer.
con2fb_release_oldinfo frees the fbcon data that is hooked off of the
fb_info structure, including the cursor timer.
In the case where there isn't another frame buffer to use,
fbcon_fb_unbind simply calls fbcon_unbind, which doesn't clear the
con2fb_map or free the fbcon data hooked from the fb_info
structure. In particular, it doesn't stop the cursor blink timer. When
the fb_info structure is then freed, we end up with a timer queue
pointing into freed memory and "bad things" start happening.
This patch first changes con2fb_release_oldinfo so that it can take a
NULL pointer for the new frame buffer, but still does all of the
deallocation and cursor timer cleanup.
Finally, the patch tries to replicate some of what set_con2fb_map does
by clearing the con2fb_map for the affected vcs and calling the
modified con2fb_release_info function to clean up the fb_info structure.
Signed-off-by: Keith Packard <keithp@keithp.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
2014-01-20 21:31:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-05-28 09:02:48 +00:00
|
|
|
fbcon_unbind();
|
fbcon: Clean up fbcon data in fb_info on FB_EVENT_FB_UNBIND with 0 fbs
When FB_EVENT_FB_UNBIND is sent, fbcon has two paths, one path taken
when there is another frame buffer to switch any affected vcs to and
another path when there isn't.
In the case where there is another frame buffer to use,
fbcon_fb_unbind calls set_con2fb_map to remap all of the affected vcs
to the replacement frame buffer. set_con2fb_map will eventually call
con2fb_release_oldinfo when the last vcs gets unmapped from the old
frame buffer.
con2fb_release_oldinfo frees the fbcon data that is hooked off of the
fb_info structure, including the cursor timer.
In the case where there isn't another frame buffer to use,
fbcon_fb_unbind simply calls fbcon_unbind, which doesn't clear the
con2fb_map or free the fbcon data hooked from the fb_info
structure. In particular, it doesn't stop the cursor blink timer. When
the fb_info structure is then freed, we end up with a timer queue
pointing into freed memory and "bad things" start happening.
This patch first changes con2fb_release_oldinfo so that it can take a
NULL pointer for the new frame buffer, but still does all of the
deallocation and cursor timer cleanup.
Finally, the patch tries to replicate some of what set_con2fb_map does
by clearing the con2fb_map for the affected vcs and calling the
modified con2fb_release_info function to clean up the fb_info structure.
Signed-off-by: Keith Packard <keithp@keithp.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
2014-01-20 21:31:10 +00:00
|
|
|
}
|
2022-04-05 21:03:32 +00:00
|
|
|
|
|
|
|
console_unlock();
|
2007-07-17 11:05:33 +00:00
|
|
|
}
|
|
|
|
|
2019-05-28 09:02:41 +00:00
|
|
|
void fbcon_fb_unregistered(struct fb_info *info)
|
2006-06-26 07:27:09 +00:00
|
|
|
{
|
2009-03-31 22:25:18 +00:00
|
|
|
int i, idx;
|
2006-06-26 07:27:09 +00:00
|
|
|
|
2022-04-05 21:03:32 +00:00
|
|
|
console_lock();
|
2018-06-28 13:20:28 +00:00
|
|
|
|
2022-04-05 21:03:35 +00:00
|
|
|
fbcon_registered_fb[info->node] = NULL;
|
|
|
|
fbcon_num_registered_fb--;
|
|
|
|
|
2022-04-05 21:03:32 +00:00
|
|
|
if (deferred_takeover) {
|
|
|
|
console_unlock();
|
2019-05-28 09:02:41 +00:00
|
|
|
return;
|
2022-04-05 21:03:32 +00:00
|
|
|
}
|
2018-06-28 13:20:30 +00:00
|
|
|
|
2009-03-31 22:25:18 +00:00
|
|
|
idx = info->node;
|
2006-06-26 07:27:09 +00:00
|
|
|
for (i = first_fb_vc; i <= last_fb_vc; i++) {
|
|
|
|
if (con2fb_map[i] == idx)
|
|
|
|
con2fb_map[i] = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (idx == info_idx) {
|
|
|
|
info_idx = -1;
|
|
|
|
|
2022-04-05 21:03:35 +00:00
|
|
|
fbcon_for_each_registered_fb(i) {
|
2018-07-24 17:11:26 +00:00
|
|
|
info_idx = i;
|
|
|
|
break;
|
2006-06-26 07:27:09 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (info_idx != -1) {
|
|
|
|
for (i = first_fb_vc; i <= last_fb_vc; i++) {
|
|
|
|
if (con2fb_map[i] == -1)
|
|
|
|
con2fb_map[i] = info_idx;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-07-17 11:05:28 +00:00
|
|
|
if (primary_device == idx)
|
|
|
|
primary_device = -1;
|
|
|
|
|
2022-04-05 21:03:35 +00:00
|
|
|
if (!fbcon_num_registered_fb)
|
2013-01-25 00:28:18 +00:00
|
|
|
do_unregister_con_driver(&fb_con);
|
2022-04-05 21:03:32 +00:00
|
|
|
console_unlock();
|
2007-07-17 11:05:28 +00:00
|
|
|
}
|
|
|
|
|
2019-05-28 09:03:00 +00:00
|
|
|
void fbcon_remap_all(struct fb_info *info)
|
2010-02-01 05:38:10 +00:00
|
|
|
{
|
2019-05-28 09:03:00 +00:00
|
|
|
int i, idx = info->node;
|
2018-06-28 13:20:28 +00:00
|
|
|
|
2019-05-28 09:03:00 +00:00
|
|
|
console_lock();
|
2018-06-28 13:20:30 +00:00
|
|
|
if (deferred_takeover) {
|
|
|
|
for (i = first_fb_vc; i <= last_fb_vc; i++)
|
|
|
|
con2fb_map_boot[i] = idx;
|
|
|
|
fbcon_map_override();
|
2019-05-28 09:03:00 +00:00
|
|
|
console_unlock();
|
2018-06-28 13:20:30 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2010-02-01 05:38:10 +00:00
|
|
|
for (i = first_fb_vc; i <= last_fb_vc; i++)
|
|
|
|
set_con2fb_map(i, idx, 0);
|
|
|
|
|
|
|
|
if (con_is_bound(&fb_con)) {
|
|
|
|
printk(KERN_INFO "fbcon: Remapping primary device, "
|
|
|
|
"fb%i, to tty %i-%i\n", idx,
|
|
|
|
first_fb_vc + 1, last_fb_vc + 1);
|
|
|
|
info_idx = idx;
|
|
|
|
}
|
2019-05-28 09:03:00 +00:00
|
|
|
console_unlock();
|
2010-02-01 05:38:10 +00:00
|
|
|
}
|
|
|
|
|
2007-07-17 11:05:28 +00:00
|
|
|
#ifdef CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY
|
2007-07-17 11:05:32 +00:00
|
|
|
static void fbcon_select_primary(struct fb_info *info)
|
2007-07-17 11:05:28 +00:00
|
|
|
{
|
|
|
|
if (!map_override && primary_device == -1 &&
|
|
|
|
fb_is_primary_device(info)) {
|
2007-07-17 11:05:32 +00:00
|
|
|
int i;
|
2007-07-17 11:05:28 +00:00
|
|
|
|
2007-07-17 11:05:32 +00:00
|
|
|
printk(KERN_INFO "fbcon: %s (fb%i) is primary device\n",
|
|
|
|
info->fix.id, info->node);
|
2007-07-17 11:05:28 +00:00
|
|
|
primary_device = info->node;
|
|
|
|
|
2007-07-17 11:05:32 +00:00
|
|
|
for (i = first_fb_vc; i <= last_fb_vc; i++)
|
2007-07-17 11:05:28 +00:00
|
|
|
con2fb_map_boot[i] = primary_device;
|
|
|
|
|
2007-07-17 11:05:32 +00:00
|
|
|
if (con_is_bound(&fb_con)) {
|
|
|
|
printk(KERN_INFO "fbcon: Remapping primary device, "
|
|
|
|
"fb%i, to tty %i-%i\n", info->node,
|
|
|
|
first_fb_vc + 1, last_fb_vc + 1);
|
|
|
|
info_idx = primary_device;
|
2007-07-17 11:05:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
#else
|
2007-07-17 11:05:32 +00:00
|
|
|
static inline void fbcon_select_primary(struct fb_info *info)
|
2007-07-17 11:05:28 +00:00
|
|
|
{
|
2007-07-17 11:05:32 +00:00
|
|
|
return;
|
2006-06-26 07:27:09 +00:00
|
|
|
}
|
2007-07-17 11:05:28 +00:00
|
|
|
#endif /* CONFIG_FRAMEBUFFER_DETECT_PRIMARY */
|
2006-06-26 07:27:09 +00:00
|
|
|
|
2022-04-05 21:03:32 +00:00
|
|
|
static bool lockless_register_fb;
|
|
|
|
module_param_named_unsafe(lockless_register_fb, lockless_register_fb, bool, 0400);
|
|
|
|
MODULE_PARM_DESC(lockless_register_fb,
|
|
|
|
"Lockless framebuffer registration for debugging [default=off]");
|
|
|
|
|
2013-01-25 01:38:56 +00:00
|
|
|
/* called with console_lock held */
|
2022-04-13 08:21:28 +00:00
|
|
|
static int do_fb_registered(struct fb_info *info)
|
2005-04-16 22:20:36 +00:00
|
|
|
{
|
2009-03-31 22:25:18 +00:00
|
|
|
int ret = 0, i, idx;
|
2007-07-17 11:05:28 +00:00
|
|
|
|
2022-04-13 08:21:28 +00:00
|
|
|
WARN_CONSOLE_UNLOCKED();
|
2018-06-28 13:20:28 +00:00
|
|
|
|
2022-04-05 21:03:35 +00:00
|
|
|
fbcon_registered_fb[info->node] = info;
|
|
|
|
fbcon_num_registered_fb++;
|
|
|
|
|
2009-03-31 22:25:18 +00:00
|
|
|
idx = info->node;
|
2007-07-17 11:05:32 +00:00
|
|
|
fbcon_select_primary(info);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2018-06-28 13:20:30 +00:00
|
|
|
if (deferred_takeover) {
|
|
|
|
pr_info("fbcon: Deferring console take-over\n");
|
2022-04-13 08:21:28 +00:00
|
|
|
return 0;
|
2018-06-28 13:20:30 +00:00
|
|
|
}
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
if (info_idx == -1) {
|
2006-06-26 07:27:09 +00:00
|
|
|
for (i = first_fb_vc; i <= last_fb_vc; i++) {
|
2005-04-16 22:20:36 +00:00
|
|
|
if (con2fb_map_boot[i] == idx) {
|
|
|
|
info_idx = idx;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2006-06-26 07:27:09 +00:00
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
if (info_idx != -1)
|
2013-01-25 00:28:15 +00:00
|
|
|
ret = do_fbcon_takeover(1);
|
2005-04-16 22:20:36 +00:00
|
|
|
} else {
|
2006-06-26 07:27:09 +00:00
|
|
|
for (i = first_fb_vc; i <= last_fb_vc; i++) {
|
2007-07-17 11:05:32 +00:00
|
|
|
if (con2fb_map_boot[i] == idx)
|
2005-04-16 22:20:36 +00:00
|
|
|
set_con2fb_map(i, idx, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-13 08:21:28 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
int fbcon_fb_registered(struct fb_info *info)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
if (!lockless_register_fb)
|
|
|
|
console_lock();
|
|
|
|
else
|
|
|
|
atomic_inc(&ignore_console_lock_warning);
|
|
|
|
|
|
|
|
ret = do_fb_registered(info);
|
|
|
|
|
2022-04-05 21:03:32 +00:00
|
|
|
if (!lockless_register_fb)
|
|
|
|
console_unlock();
|
|
|
|
else
|
|
|
|
atomic_dec(&ignore_console_lock_warning);
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2019-05-28 09:02:55 +00:00
|
|
|
void fbcon_fb_blanked(struct fb_info *info, int blank)
|
2005-04-16 22:20:36 +00:00
|
|
|
{
|
|
|
|
struct fbcon_ops *ops = info->fbcon_par;
|
|
|
|
struct vc_data *vc;
|
|
|
|
|
|
|
|
if (!ops || ops->currcon < 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
vc = vc_cons[ops->currcon].d;
|
|
|
|
if (vc->vc_mode != KD_TEXT ||
|
2022-04-05 21:03:21 +00:00
|
|
|
fbcon_info_from_console(ops->currcon) != info)
|
2005-04-16 22:20:36 +00:00
|
|
|
return;
|
|
|
|
|
2016-06-23 11:34:35 +00:00
|
|
|
if (con_is_visible(vc)) {
|
2005-04-16 22:20:36 +00:00
|
|
|
if (blank)
|
|
|
|
do_blank_screen(0);
|
|
|
|
else
|
|
|
|
do_unblank_screen(0);
|
|
|
|
}
|
|
|
|
ops->blank_state = blank;
|
|
|
|
}
|
|
|
|
|
2019-05-28 09:02:53 +00:00
|
|
|
void fbcon_new_modelist(struct fb_info *info)
|
2005-04-16 22:20:36 +00:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
struct vc_data *vc;
|
|
|
|
struct fb_var_screeninfo var;
|
2007-02-12 08:55:19 +00:00
|
|
|
const struct fb_videomode *mode;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2006-06-26 07:27:09 +00:00
|
|
|
for (i = first_fb_vc; i <= last_fb_vc; i++) {
|
2022-04-05 21:03:21 +00:00
|
|
|
if (fbcon_info_from_console(i) != info)
|
2005-04-16 22:20:36 +00:00
|
|
|
continue;
|
|
|
|
if (!fb_display[i].mode)
|
|
|
|
continue;
|
|
|
|
vc = vc_cons[i].d;
|
|
|
|
display_to_var(&var, &fb_display[i]);
|
2005-11-07 09:00:47 +00:00
|
|
|
mode = fb_find_nearest_mode(fb_display[i].mode,
|
|
|
|
&info->modelist);
|
2005-04-16 22:20:36 +00:00
|
|
|
fb_videomode_to_var(&var, mode);
|
2007-07-17 11:05:32 +00:00
|
|
|
fbcon_set_disp(info, &var, vc->vc_num);
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-28 09:02:54 +00:00
|
|
|
void fbcon_get_requirement(struct fb_info *info,
|
|
|
|
struct fb_blit_caps *caps)
|
2007-05-08 07:39:37 +00:00
|
|
|
{
|
|
|
|
struct vc_data *vc;
|
|
|
|
|
|
|
|
if (caps->flags) {
|
2007-05-08 07:39:54 +00:00
|
|
|
int i, charcnt;
|
2007-05-08 07:39:37 +00:00
|
|
|
|
|
|
|
for (i = first_fb_vc; i <= last_fb_vc; i++) {
|
|
|
|
vc = vc_cons[i].d;
|
2007-05-08 07:39:54 +00:00
|
|
|
if (vc && vc->vc_mode == KD_TEXT &&
|
|
|
|
info->node == con2fb_map[i]) {
|
2007-05-08 07:39:37 +00:00
|
|
|
caps->x |= 1 << (vc->vc_font.width - 1);
|
|
|
|
caps->y |= 1 << (vc->vc_font.height - 1);
|
fbcon: Avoid using FNTCHARCNT() and hard-coded built-in font charcount
For user-provided fonts, the framebuffer layer is using a magic
negative-indexing macro, FNTCHARCNT(), to keep track of their number of
characters:
#define FNTCHARCNT(fd) (((int *)(fd))[-3])
For built-in fonts, it is using hard-coded values (256). This results in
something like the following:
map.length = (ops->p->userfont) ?
FNTCHARCNT(ops->p->fontdata) : 256;
This is unsatisfactory. In fact, there is already a `charcount` field in
our virtual console descriptor (see `struct console_font` inside `struct
vc_data`), let us use it:
map.length = vc->vc_font.charcount;
Recently we added a `charcount` field to `struct font_desc`. Use it to set
`vc->vc_font.charcount` properly. The idea is:
- We only use FNTCHARCNT() on `vc->vc_font.data` and `p->fontdata`.
Assume FNTCHARCNT() is working as intended;
- Whenever `vc->vc_font.data` is set, also set `vc->vc_font.charcount`
properly;
- We can now replace `FNTCHARCNT(vc->vc_font.data)` with
`vc->vc_font.charcount`;
- Since `p->fontdata` always point to the same font data buffer with
`vc->vc_font.data`, we can also replace `FNTCHARCNT(p->fontdata)` with
`vc->vc_font.charcount`.
In conclusion, set `vc->vc_font.charcount` properly in fbcon_startup(),
fbcon_init(), fbcon_set_disp() and fbcon_do_set_font(), then replace
FNTCHARCNT() with `vc->vc_font.charcount`. No more if-else between
negative-indexing macros and hard-coded values.
Do not include <linux/font.h> in fbcon_rotate.c and tileblit.c, since they
no longer need it.
Depends on patch "Fonts: Add charcount field to font_desc".
Suggested-by: Daniel Vetter <daniel@ffwll.ch>
Signed-off-by: Peilin Ye <yepeilin.cs@gmail.com>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/e460a5780e54e3022661d5f09555144583b4cc59.1605169912.git.yepeilin.cs@gmail.com
2020-11-12 12:15:22 +00:00
|
|
|
charcnt = vc->vc_font.charcount;
|
2007-05-08 07:39:37 +00:00
|
|
|
if (caps->len < charcnt)
|
|
|
|
caps->len = charcnt;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
vc = vc_cons[fg_console].d;
|
|
|
|
|
2007-05-08 07:39:54 +00:00
|
|
|
if (vc && vc->vc_mode == KD_TEXT &&
|
|
|
|
info->node == con2fb_map[fg_console]) {
|
|
|
|
caps->x = 1 << (vc->vc_font.width - 1);
|
|
|
|
caps->y = 1 << (vc->vc_font.height - 1);
|
fbcon: Avoid using FNTCHARCNT() and hard-coded built-in font charcount
For user-provided fonts, the framebuffer layer is using a magic
negative-indexing macro, FNTCHARCNT(), to keep track of their number of
characters:
#define FNTCHARCNT(fd) (((int *)(fd))[-3])
For built-in fonts, it is using hard-coded values (256). This results in
something like the following:
map.length = (ops->p->userfont) ?
FNTCHARCNT(ops->p->fontdata) : 256;
This is unsatisfactory. In fact, there is already a `charcount` field in
our virtual console descriptor (see `struct console_font` inside `struct
vc_data`), let us use it:
map.length = vc->vc_font.charcount;
Recently we added a `charcount` field to `struct font_desc`. Use it to set
`vc->vc_font.charcount` properly. The idea is:
- We only use FNTCHARCNT() on `vc->vc_font.data` and `p->fontdata`.
Assume FNTCHARCNT() is working as intended;
- Whenever `vc->vc_font.data` is set, also set `vc->vc_font.charcount`
properly;
- We can now replace `FNTCHARCNT(vc->vc_font.data)` with
`vc->vc_font.charcount`;
- Since `p->fontdata` always point to the same font data buffer with
`vc->vc_font.data`, we can also replace `FNTCHARCNT(p->fontdata)` with
`vc->vc_font.charcount`.
In conclusion, set `vc->vc_font.charcount` properly in fbcon_startup(),
fbcon_init(), fbcon_set_disp() and fbcon_do_set_font(), then replace
FNTCHARCNT() with `vc->vc_font.charcount`. No more if-else between
negative-indexing macros and hard-coded values.
Do not include <linux/font.h> in fbcon_rotate.c and tileblit.c, since they
no longer need it.
Depends on patch "Fonts: Add charcount field to font_desc".
Suggested-by: Daniel Vetter <daniel@ffwll.ch>
Signed-off-by: Peilin Ye <yepeilin.cs@gmail.com>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/e460a5780e54e3022661d5f09555144583b4cc59.1605169912.git.yepeilin.cs@gmail.com
2020-11-12 12:15:22 +00:00
|
|
|
caps->len = vc->vc_font.charcount;
|
2007-05-08 07:39:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-28 09:03:01 +00:00
|
|
|
int fbcon_set_con2fb_map_ioctl(void __user *argp)
|
2005-04-16 22:20:36 +00:00
|
|
|
{
|
2019-05-28 09:03:01 +00:00
|
|
|
struct fb_con2fbmap con2fb;
|
|
|
|
int ret;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2019-05-28 09:03:01 +00:00
|
|
|
if (copy_from_user(&con2fb, argp, sizeof(con2fb)))
|
|
|
|
return -EFAULT;
|
|
|
|
if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES)
|
|
|
|
return -EINVAL;
|
|
|
|
if (con2fb.framebuffer >= FB_MAX)
|
|
|
|
return -EINVAL;
|
2022-04-05 21:03:35 +00:00
|
|
|
if (!fbcon_registered_fb[con2fb.framebuffer])
|
2019-05-28 09:03:01 +00:00
|
|
|
request_module("fb%d", con2fb.framebuffer);
|
2022-04-05 21:03:35 +00:00
|
|
|
if (!fbcon_registered_fb[con2fb.framebuffer]) {
|
2019-05-28 09:03:01 +00:00
|
|
|
return -EINVAL;
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
2019-05-28 09:03:01 +00:00
|
|
|
|
|
|
|
console_lock();
|
|
|
|
ret = set_con2fb_map(con2fb.console - 1,
|
|
|
|
con2fb.framebuffer, 1);
|
|
|
|
console_unlock();
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2019-05-28 09:03:01 +00:00
|
|
|
int fbcon_get_con2fb_map_ioctl(void __user *argp)
|
|
|
|
{
|
|
|
|
struct fb_con2fbmap con2fb;
|
|
|
|
|
|
|
|
if (copy_from_user(&con2fb, argp, sizeof(con2fb)))
|
|
|
|
return -EFAULT;
|
|
|
|
if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
console_lock();
|
|
|
|
con2fb.framebuffer = con2fb_map[con2fb.console - 1];
|
|
|
|
console_unlock();
|
|
|
|
|
|
|
|
return copy_to_user(argp, &con2fb, sizeof(con2fb)) ? -EFAULT : 0;
|
|
|
|
}
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
/*
|
|
|
|
* The console `switch' structure for the frame buffer based console
|
|
|
|
*/
|
|
|
|
|
|
|
|
static const struct consw fb_con = {
|
|
|
|
.owner = THIS_MODULE,
|
|
|
|
.con_startup = fbcon_startup,
|
|
|
|
.con_init = fbcon_init,
|
|
|
|
.con_deinit = fbcon_deinit,
|
|
|
|
.con_clear = fbcon_clear,
|
|
|
|
.con_putc = fbcon_putc,
|
|
|
|
.con_putcs = fbcon_putcs,
|
|
|
|
.con_cursor = fbcon_cursor,
|
|
|
|
.con_scroll = fbcon_scroll,
|
|
|
|
.con_switch = fbcon_switch,
|
|
|
|
.con_blank = fbcon_blank,
|
|
|
|
.con_font_set = fbcon_set_font,
|
|
|
|
.con_font_get = fbcon_get_font,
|
|
|
|
.con_font_default = fbcon_set_def_font,
|
|
|
|
.con_set_palette = fbcon_set_palette,
|
|
|
|
.con_invert_region = fbcon_invert_region,
|
|
|
|
.con_screen_pos = fbcon_screen_pos,
|
|
|
|
.con_getxy = fbcon_getxy,
|
|
|
|
.con_resize = fbcon_resize,
|
2010-08-02 19:05:41 +00:00
|
|
|
.con_debug_enter = fbcon_debug_enter,
|
|
|
|
.con_debug_leave = fbcon_debug_leave,
|
2005-04-16 22:20:36 +00:00
|
|
|
};
|
|
|
|
|
2007-07-17 11:05:26 +00:00
|
|
|
static ssize_t store_rotate(struct device *device,
|
|
|
|
struct device_attribute *attr, const char *buf,
|
|
|
|
size_t count)
|
2006-06-26 07:27:05 +00:00
|
|
|
{
|
|
|
|
struct fb_info *info;
|
|
|
|
int rotate, idx;
|
|
|
|
char **last = NULL;
|
|
|
|
|
2011-01-25 23:07:35 +00:00
|
|
|
console_lock();
|
2006-06-26 07:27:05 +00:00
|
|
|
idx = con2fb_map[fg_console];
|
|
|
|
|
2022-04-05 21:03:35 +00:00
|
|
|
if (idx == -1 || fbcon_registered_fb[idx] == NULL)
|
2006-06-26 07:27:05 +00:00
|
|
|
goto err;
|
|
|
|
|
2022-04-05 21:03:35 +00:00
|
|
|
info = fbcon_registered_fb[idx];
|
2006-06-26 07:27:05 +00:00
|
|
|
rotate = simple_strtoul(buf, last, 0);
|
|
|
|
fbcon_rotate(info, rotate);
|
|
|
|
err:
|
2011-01-25 23:07:35 +00:00
|
|
|
console_unlock();
|
2006-06-26 07:27:05 +00:00
|
|
|
return count;
|
|
|
|
}
|
|
|
|
|
2007-07-17 11:05:26 +00:00
|
|
|
static ssize_t store_rotate_all(struct device *device,
|
|
|
|
struct device_attribute *attr,const char *buf,
|
|
|
|
size_t count)
|
2006-06-26 07:27:05 +00:00
|
|
|
{
|
|
|
|
struct fb_info *info;
|
|
|
|
int rotate, idx;
|
|
|
|
char **last = NULL;
|
|
|
|
|
2011-01-25 23:07:35 +00:00
|
|
|
console_lock();
|
2006-06-26 07:27:05 +00:00
|
|
|
idx = con2fb_map[fg_console];
|
|
|
|
|
2022-04-05 21:03:35 +00:00
|
|
|
if (idx == -1 || fbcon_registered_fb[idx] == NULL)
|
2006-06-26 07:27:05 +00:00
|
|
|
goto err;
|
|
|
|
|
2022-04-05 21:03:35 +00:00
|
|
|
info = fbcon_registered_fb[idx];
|
2006-06-26 07:27:05 +00:00
|
|
|
rotate = simple_strtoul(buf, last, 0);
|
|
|
|
fbcon_rotate_all(info, rotate);
|
|
|
|
err:
|
2011-01-25 23:07:35 +00:00
|
|
|
console_unlock();
|
2006-06-26 07:27:05 +00:00
|
|
|
return count;
|
|
|
|
}
|
|
|
|
|
2007-07-17 11:05:26 +00:00
|
|
|
static ssize_t show_rotate(struct device *device,
|
|
|
|
struct device_attribute *attr,char *buf)
|
2006-06-26 07:27:05 +00:00
|
|
|
{
|
|
|
|
struct fb_info *info;
|
|
|
|
int rotate = 0, idx;
|
|
|
|
|
2011-01-25 23:07:35 +00:00
|
|
|
console_lock();
|
2006-06-26 07:27:05 +00:00
|
|
|
idx = con2fb_map[fg_console];
|
|
|
|
|
2022-04-05 21:03:35 +00:00
|
|
|
if (idx == -1 || fbcon_registered_fb[idx] == NULL)
|
2006-06-26 07:27:05 +00:00
|
|
|
goto err;
|
|
|
|
|
2022-04-05 21:03:35 +00:00
|
|
|
info = fbcon_registered_fb[idx];
|
2006-06-26 07:27:05 +00:00
|
|
|
rotate = fbcon_get_rotate(info);
|
|
|
|
err:
|
2011-01-25 23:07:35 +00:00
|
|
|
console_unlock();
|
2021-11-30 00:05:08 +00:00
|
|
|
return sysfs_emit(buf, "%d\n", rotate);
|
2006-06-26 07:27:05 +00:00
|
|
|
}
|
|
|
|
|
2007-07-17 11:05:26 +00:00
|
|
|
static ssize_t show_cursor_blink(struct device *device,
|
|
|
|
struct device_attribute *attr, char *buf)
|
2007-07-17 11:05:26 +00:00
|
|
|
{
|
|
|
|
struct fb_info *info;
|
|
|
|
struct fbcon_ops *ops;
|
|
|
|
int idx, blink = -1;
|
|
|
|
|
2011-01-25 23:07:35 +00:00
|
|
|
console_lock();
|
2007-07-17 11:05:26 +00:00
|
|
|
idx = con2fb_map[fg_console];
|
|
|
|
|
2022-04-05 21:03:35 +00:00
|
|
|
if (idx == -1 || fbcon_registered_fb[idx] == NULL)
|
2007-07-17 11:05:26 +00:00
|
|
|
goto err;
|
|
|
|
|
2022-04-05 21:03:35 +00:00
|
|
|
info = fbcon_registered_fb[idx];
|
2007-07-17 11:05:26 +00:00
|
|
|
ops = info->fbcon_par;
|
|
|
|
|
|
|
|
if (!ops)
|
|
|
|
goto err;
|
|
|
|
|
2022-04-05 21:03:24 +00:00
|
|
|
blink = delayed_work_pending(&ops->cursor_work);
|
2007-07-17 11:05:26 +00:00
|
|
|
err:
|
2011-01-25 23:07:35 +00:00
|
|
|
console_unlock();
|
2021-11-30 00:05:08 +00:00
|
|
|
return sysfs_emit(buf, "%d\n", blink);
|
2007-07-17 11:05:26 +00:00
|
|
|
}
|
|
|
|
|
2007-07-17 11:05:26 +00:00
|
|
|
static ssize_t store_cursor_blink(struct device *device,
|
|
|
|
struct device_attribute *attr,
|
2007-07-17 11:05:26 +00:00
|
|
|
const char *buf, size_t count)
|
|
|
|
{
|
|
|
|
struct fb_info *info;
|
|
|
|
int blink, idx;
|
|
|
|
char **last = NULL;
|
|
|
|
|
2011-01-25 23:07:35 +00:00
|
|
|
console_lock();
|
2007-07-17 11:05:26 +00:00
|
|
|
idx = con2fb_map[fg_console];
|
|
|
|
|
2022-04-05 21:03:35 +00:00
|
|
|
if (idx == -1 || fbcon_registered_fb[idx] == NULL)
|
2007-07-17 11:05:26 +00:00
|
|
|
goto err;
|
|
|
|
|
2022-04-05 21:03:35 +00:00
|
|
|
info = fbcon_registered_fb[idx];
|
2007-07-17 11:05:26 +00:00
|
|
|
|
|
|
|
if (!info->fbcon_par)
|
|
|
|
goto err;
|
|
|
|
|
|
|
|
blink = simple_strtoul(buf, last, 0);
|
|
|
|
|
|
|
|
if (blink) {
|
|
|
|
fbcon_cursor_noblink = 0;
|
2022-04-05 21:03:24 +00:00
|
|
|
fbcon_add_cursor_work(info);
|
2007-07-17 11:05:26 +00:00
|
|
|
} else {
|
|
|
|
fbcon_cursor_noblink = 1;
|
2022-04-05 21:03:24 +00:00
|
|
|
fbcon_del_cursor_work(info);
|
2007-07-17 11:05:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
err:
|
2011-01-25 23:07:35 +00:00
|
|
|
console_unlock();
|
2007-07-17 11:05:26 +00:00
|
|
|
return count;
|
|
|
|
}
|
|
|
|
|
2007-07-17 11:05:26 +00:00
|
|
|
static struct device_attribute device_attrs[] = {
|
2006-06-26 07:27:05 +00:00
|
|
|
__ATTR(rotate, S_IRUGO|S_IWUSR, show_rotate, store_rotate),
|
|
|
|
__ATTR(rotate_all, S_IWUSR, NULL, store_rotate_all),
|
2007-07-17 11:05:26 +00:00
|
|
|
__ATTR(cursor_blink, S_IRUGO|S_IWUSR, show_cursor_blink,
|
|
|
|
store_cursor_blink),
|
2006-06-26 07:27:05 +00:00
|
|
|
};
|
|
|
|
|
2007-07-17 11:05:26 +00:00
|
|
|
static int fbcon_init_device(void)
|
2006-06-26 07:27:05 +00:00
|
|
|
{
|
2006-10-03 08:14:50 +00:00
|
|
|
int i, error = 0;
|
|
|
|
|
|
|
|
fbcon_has_sysfs = 1;
|
|
|
|
|
2007-07-17 11:05:26 +00:00
|
|
|
for (i = 0; i < ARRAY_SIZE(device_attrs); i++) {
|
|
|
|
error = device_create_file(fbcon_device, &device_attrs[i]);
|
2006-10-03 08:14:50 +00:00
|
|
|
|
|
|
|
if (error)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (error) {
|
|
|
|
while (--i >= 0)
|
2007-07-17 11:05:26 +00:00
|
|
|
device_remove_file(fbcon_device, &device_attrs[i]);
|
2006-10-03 08:14:50 +00:00
|
|
|
|
|
|
|
fbcon_has_sysfs = 0;
|
|
|
|
}
|
2006-06-26 07:27:05 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-06-28 13:20:30 +00:00
|
|
|
#ifdef CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER
|
2018-08-10 15:23:02 +00:00
|
|
|
static void fbcon_register_existing_fbs(struct work_struct *work)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
console_lock();
|
|
|
|
|
2022-04-05 21:03:31 +00:00
|
|
|
deferred_takeover = false;
|
|
|
|
logo_shown = FBCON_LOGO_DONTSHOW;
|
|
|
|
|
2022-04-05 21:03:35 +00:00
|
|
|
fbcon_for_each_registered_fb(i)
|
2022-04-13 08:21:28 +00:00
|
|
|
do_fb_registered(fbcon_registered_fb[i]);
|
2018-08-10 15:23:02 +00:00
|
|
|
|
|
|
|
console_unlock();
|
|
|
|
}
|
|
|
|
|
2018-06-28 13:20:30 +00:00
|
|
|
static struct notifier_block fbcon_output_nb;
|
2018-08-10 15:23:02 +00:00
|
|
|
static DECLARE_WORK(fbcon_deferred_takeover_work, fbcon_register_existing_fbs);
|
2018-06-28 13:20:30 +00:00
|
|
|
|
|
|
|
static int fbcon_output_notifier(struct notifier_block *nb,
|
|
|
|
unsigned long action, void *data)
|
|
|
|
{
|
|
|
|
WARN_CONSOLE_UNLOCKED();
|
|
|
|
|
|
|
|
pr_info("fbcon: Taking over console\n");
|
|
|
|
|
|
|
|
dummycon_unregister_output_notifier(&fbcon_output_nb);
|
|
|
|
|
2018-08-10 15:23:02 +00:00
|
|
|
/* We may get called in atomic context */
|
|
|
|
schedule_work(&fbcon_deferred_takeover_work);
|
2018-06-28 13:20:30 +00:00
|
|
|
|
|
|
|
return NOTIFY_OK;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2006-06-26 07:27:06 +00:00
|
|
|
static void fbcon_start(void)
|
2005-04-16 22:20:36 +00:00
|
|
|
{
|
2018-08-10 15:23:01 +00:00
|
|
|
WARN_CONSOLE_UNLOCKED();
|
|
|
|
|
|
|
|
#ifdef CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER
|
|
|
|
if (conswitchp != &dummy_con)
|
|
|
|
deferred_takeover = false;
|
|
|
|
|
2018-06-28 13:20:30 +00:00
|
|
|
if (deferred_takeover) {
|
2018-08-10 15:23:01 +00:00
|
|
|
fbcon_output_nb.notifier_call = fbcon_output_notifier;
|
|
|
|
dummycon_register_output_notifier(&fbcon_output_nb);
|
2018-06-28 13:20:30 +00:00
|
|
|
return;
|
|
|
|
}
|
2018-08-10 15:23:01 +00:00
|
|
|
#endif
|
2006-06-26 07:27:05 +00:00
|
|
|
}
|
|
|
|
|
fbcon: Make fbcon a built-time depency for fbdev
There's a bunch of folks who're trying to make printk less
contended and faster, but there's a problem: printk uses the
console_lock, and the console lock has become the BKL for all things
fbdev/fbcon, which in turn pulled in half the drm subsystem under that
lock. That's awkward.
There reasons for that is probably just a historical accident:
- fbcon is a runtime option of fbdev, i.e. at runtime you can pick
whether your fbdev driver instances are used as kernel consoles.
Unfortunately this wasn't implemented with some module option, but
through some module loading magic: As long as you don't load
fbcon.ko, there's no fbdev console support, but loading it (in any
order wrt fbdev drivers) will create console instances for all fbdev
drivers.
- This was implemented through a notifier chain. fbcon.ko enumerates
all fbdev instances at load time and also registers itself as
listener in the fbdev notifier. The fbdev core tries to register new
fbdev instances with fbcon using the notifier.
- On top of that the modifier chain is also used at runtime by the
fbdev subsystem to e.g. control backlights for panels.
- The problem is that the notifier puts a mutex locking context
between fbdev and fbcon, which mixes up the locking contexts for
both the runtime usage and the register time usage to notify fbcon.
And at runtime fbcon (through the fbdev core) might call into the
notifier from a printk critical section while console_lock is held.
- This means console_lock must be an outer lock for the entire fbdev
subsystem, which also means it must be acquired when registering a
new framebuffer driver as the outermost lock since we might call
into fbcon (through the notifier) which would result in a locking
inversion if fbcon would acquire the console_lock from its notifier
callback (which it needs to register the console).
- console_lock can be held anywhere, since printk can be called
anywhere, and through the above story, plus drm/kms being an fbdev
driver, we pull in a shocking amount of locking hiercharchy
underneath the console_lock. Which makes cleaning up printk really
hard (not even splitting console_lock into an rwsem is all that
useful due to this).
There's various ways to address this, but the cleanest would be to
make fbcon a compile-time option, where fbdev directly calls the fbcon
register functions from register_framebuffer, or dummy static inline
versions if fbcon is disabled. Maybe augmented with a runtime knob to
disable fbcon, if that's needed (for debugging perhaps).
But this could break some users who rely on the magic "loading
fbcon.ko enables/disables fbdev framebuffers at runtime" thing, even
if that's unlikely. Hence we must be careful:
1. Create a compile-time dependency between fbcon and fbdev in the
least minimal way. This is what this patch does.
2. Wait at least 1 year to give possible users time to scream about
how we broke their setup. Unlikely, since all distros make fbcon
compile-in, and embedded platforms only compile stuff they know they
need anyway. But still.
3. Convert the notifier to direct functions calls, with dummy static
inlines if fbcon is disabled. We'll still need the fb notifier for the
other uses (like backlights), but we can probably move it into the fb
core (atm it must be built-into vmlinux).
4. Push console_lock down the call-chain, until it is down in
console_register again.
5. Finally start to clean up and rework the printk/console locking.
For context of this saga see
commit 50e244cc793d511b86adea24972f3a7264cae114
Author: Alan Cox <alan@linux.intel.com>
Date: Fri Jan 25 10:28:15 2013 +1000
fb: rework locking to fix lock ordering on takeover
plus the pile of commits on top that tried to make this all work
without terminally upsetting lockdep. We've uncovered all this when
console_lock lockdep annotations where added in
commit daee779718a319ff9f83e1ba3339334ac650bb22
Author: Daniel Vetter <daniel.vetter@ffwll.ch>
Date: Sat Sep 22 19:52:11 2012 +0200
console: implement lockdep support for console_lock
On the patch itself:
- Switch CONFIG_FRAMEBUFFER_CONSOLE to be a boolean, using the overall
CONFIG_FB tristate to decided whether it should be a module or
built-in.
- At first I thought I could force the build depency with just a dummy
symbol that fbcon.ko exports and fb.ko uses. But that leads to a
module depency cycle (it works fine when built-in).
Since this tight binding is the entire goal the simplest solution is
to move all the fbcon modules (and there's a bunch of optinal
source-files which are each modules of their own, for no good
reason) into the overall fb.ko core module. That's a bit more than
what I would have liked to do in this patch, but oh well.
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Cc: Sergey Senozhatsky <sergey.senozhatsky.work@gmail.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Reviewed-by: Sean Paul <seanpaul@chromium.org>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
2017-08-01 15:32:07 +00:00
|
|
|
void __init fb_console_init(void)
|
2006-06-26 07:27:06 +00:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
2011-01-25 23:07:35 +00:00
|
|
|
console_lock();
|
2008-07-22 03:03:34 +00:00
|
|
|
fbcon_device = device_create(fb_class, NULL, MKDEV(0, 0), NULL,
|
|
|
|
"fbcon");
|
2006-06-26 07:27:06 +00:00
|
|
|
|
2007-07-17 11:05:26 +00:00
|
|
|
if (IS_ERR(fbcon_device)) {
|
|
|
|
printk(KERN_WARNING "Unable to create device "
|
2006-06-26 07:27:06 +00:00
|
|
|
"for fbcon; errno = %ld\n",
|
2007-07-17 11:05:26 +00:00
|
|
|
PTR_ERR(fbcon_device));
|
|
|
|
fbcon_device = NULL;
|
2006-06-26 07:27:06 +00:00
|
|
|
} else
|
2007-07-17 11:05:26 +00:00
|
|
|
fbcon_init_device();
|
2006-06-26 07:27:06 +00:00
|
|
|
|
|
|
|
for (i = 0; i < MAX_NR_CONSOLES; i++)
|
|
|
|
con2fb_map[i] = -1;
|
|
|
|
|
|
|
|
fbcon_start();
|
2018-08-10 15:23:01 +00:00
|
|
|
console_unlock();
|
2006-06-26 07:27:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef MODULE
|
|
|
|
|
2007-07-17 11:05:26 +00:00
|
|
|
static void __exit fbcon_deinit_device(void)
|
2006-06-26 07:27:06 +00:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
2006-10-03 08:14:50 +00:00
|
|
|
if (fbcon_has_sysfs) {
|
2007-07-17 11:05:26 +00:00
|
|
|
for (i = 0; i < ARRAY_SIZE(device_attrs); i++)
|
|
|
|
device_remove_file(fbcon_device, &device_attrs[i]);
|
2006-10-03 08:14:50 +00:00
|
|
|
|
|
|
|
fbcon_has_sysfs = 0;
|
|
|
|
}
|
2006-06-26 07:27:05 +00:00
|
|
|
}
|
|
|
|
|
fbcon: Make fbcon a built-time depency for fbdev
There's a bunch of folks who're trying to make printk less
contended and faster, but there's a problem: printk uses the
console_lock, and the console lock has become the BKL for all things
fbdev/fbcon, which in turn pulled in half the drm subsystem under that
lock. That's awkward.
There reasons for that is probably just a historical accident:
- fbcon is a runtime option of fbdev, i.e. at runtime you can pick
whether your fbdev driver instances are used as kernel consoles.
Unfortunately this wasn't implemented with some module option, but
through some module loading magic: As long as you don't load
fbcon.ko, there's no fbdev console support, but loading it (in any
order wrt fbdev drivers) will create console instances for all fbdev
drivers.
- This was implemented through a notifier chain. fbcon.ko enumerates
all fbdev instances at load time and also registers itself as
listener in the fbdev notifier. The fbdev core tries to register new
fbdev instances with fbcon using the notifier.
- On top of that the modifier chain is also used at runtime by the
fbdev subsystem to e.g. control backlights for panels.
- The problem is that the notifier puts a mutex locking context
between fbdev and fbcon, which mixes up the locking contexts for
both the runtime usage and the register time usage to notify fbcon.
And at runtime fbcon (through the fbdev core) might call into the
notifier from a printk critical section while console_lock is held.
- This means console_lock must be an outer lock for the entire fbdev
subsystem, which also means it must be acquired when registering a
new framebuffer driver as the outermost lock since we might call
into fbcon (through the notifier) which would result in a locking
inversion if fbcon would acquire the console_lock from its notifier
callback (which it needs to register the console).
- console_lock can be held anywhere, since printk can be called
anywhere, and through the above story, plus drm/kms being an fbdev
driver, we pull in a shocking amount of locking hiercharchy
underneath the console_lock. Which makes cleaning up printk really
hard (not even splitting console_lock into an rwsem is all that
useful due to this).
There's various ways to address this, but the cleanest would be to
make fbcon a compile-time option, where fbdev directly calls the fbcon
register functions from register_framebuffer, or dummy static inline
versions if fbcon is disabled. Maybe augmented with a runtime knob to
disable fbcon, if that's needed (for debugging perhaps).
But this could break some users who rely on the magic "loading
fbcon.ko enables/disables fbdev framebuffers at runtime" thing, even
if that's unlikely. Hence we must be careful:
1. Create a compile-time dependency between fbcon and fbdev in the
least minimal way. This is what this patch does.
2. Wait at least 1 year to give possible users time to scream about
how we broke their setup. Unlikely, since all distros make fbcon
compile-in, and embedded platforms only compile stuff they know they
need anyway. But still.
3. Convert the notifier to direct functions calls, with dummy static
inlines if fbcon is disabled. We'll still need the fb notifier for the
other uses (like backlights), but we can probably move it into the fb
core (atm it must be built-into vmlinux).
4. Push console_lock down the call-chain, until it is down in
console_register again.
5. Finally start to clean up and rework the printk/console locking.
For context of this saga see
commit 50e244cc793d511b86adea24972f3a7264cae114
Author: Alan Cox <alan@linux.intel.com>
Date: Fri Jan 25 10:28:15 2013 +1000
fb: rework locking to fix lock ordering on takeover
plus the pile of commits on top that tried to make this all work
without terminally upsetting lockdep. We've uncovered all this when
console_lock lockdep annotations where added in
commit daee779718a319ff9f83e1ba3339334ac650bb22
Author: Daniel Vetter <daniel.vetter@ffwll.ch>
Date: Sat Sep 22 19:52:11 2012 +0200
console: implement lockdep support for console_lock
On the patch itself:
- Switch CONFIG_FRAMEBUFFER_CONSOLE to be a boolean, using the overall
CONFIG_FB tristate to decided whether it should be a module or
built-in.
- At first I thought I could force the build depency with just a dummy
symbol that fbcon.ko exports and fb.ko uses. But that leads to a
module depency cycle (it works fine when built-in).
Since this tight binding is the entire goal the simplest solution is
to move all the fbcon modules (and there's a bunch of optinal
source-files which are each modules of their own, for no good
reason) into the overall fb.ko core module. That's a bit more than
what I would have liked to do in this patch, but oh well.
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Cc: Sergey Senozhatsky <sergey.senozhatsky.work@gmail.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Reviewed-by: Sean Paul <seanpaul@chromium.org>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
2017-08-01 15:32:07 +00:00
|
|
|
void __exit fb_console_exit(void)
|
2005-04-16 22:20:36 +00:00
|
|
|
{
|
2022-04-05 21:03:34 +00:00
|
|
|
#ifdef CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER
|
|
|
|
console_lock();
|
|
|
|
if (deferred_takeover)
|
|
|
|
dummycon_unregister_output_notifier(&fbcon_output_nb);
|
|
|
|
console_unlock();
|
|
|
|
|
|
|
|
cancel_work_sync(&fbcon_deferred_takeover_work);
|
|
|
|
#endif
|
|
|
|
|
2011-01-25 23:07:35 +00:00
|
|
|
console_lock();
|
2007-07-17 11:05:26 +00:00
|
|
|
fbcon_deinit_device();
|
|
|
|
device_destroy(fb_class, MKDEV(0, 0));
|
2022-04-05 21:03:34 +00:00
|
|
|
|
2013-05-08 18:14:39 +00:00
|
|
|
do_unregister_con_driver(&fb_con);
|
2011-01-25 23:07:35 +00:00
|
|
|
console_unlock();
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
#endif
|