Skip to content

Commit a3f781a

Browse files
hdellerdanvet
authored andcommitted
fbcon: Add option to enable legacy hardware acceleration
Add a config option CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION to enable bitblt and fillrect hardware acceleration in the framebuffer console. If disabled, such acceleration will not be used, even if it is supported by the graphics hardware driver. If you plan to use DRM as your main graphics output system, you should disable this option since it will prevent compiling in code which isn't used later on when DRM takes over. For all other configurations, e.g. if none of your graphic cards support DRM (yet), DRM isn't available for your architecture, or you can't be sure that the graphic card in the target system will support DRM, you most likely want to enable this option. In the non-accelerated case (e.g. when DRM is used), the inlined fb_scrollmode() function is hardcoded to return SCROLL_REDRAW and as such the compiler is able to optimize much unneccesary code away. In this v3 patch version I additionally changed the GETVYRES() and GETVXRES() macros to take a pointer to the fbcon_display struct. This fixes the build when console rotation is enabled and helps the compiler again to optimize out code. Signed-off-by: Helge Deller <[email protected]> Cc: [email protected] # v5.10+ Signed-off-by: Helge Deller <[email protected]> Signed-off-by: Daniel Vetter <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent 87ab9f6 commit a3f781a

File tree

7 files changed

+84
-34
lines changed

7 files changed

+84
-34
lines changed

drivers/video/console/Kconfig

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,26 @@ config FRAMEBUFFER_CONSOLE
7878
help
7979
Low-level framebuffer-based console driver.
8080

81+
config FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION
82+
bool "Enable legacy fbcon hardware acceleration code"
83+
depends on FRAMEBUFFER_CONSOLE
84+
default y if PARISC
85+
default n
86+
help
87+
This option enables the fbcon (framebuffer text-based) hardware
88+
acceleration for graphics drivers which were written for the fbdev
89+
graphics interface.
90+
91+
On modern machines, on mainstream machines (like x86-64) or when
92+
using a modern Linux distribution those fbdev drivers usually aren't used.
93+
So enabling this option wouldn't have any effect, which is why you want
94+
to disable this option on such newer machines.
95+
96+
If you compile this kernel for older machines which still require the
97+
fbdev drivers, you may want to say Y.
98+
99+
If unsure, select n.
100+
81101
config FRAMEBUFFER_CONSOLE_DETECT_PRIMARY
82102
bool "Map the console to the primary display device"
83103
depends on FRAMEBUFFER_CONSOLE

drivers/video/fbdev/core/fbcon.c

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1136,11 +1136,13 @@ static void fbcon_init(struct vc_data *vc, int init)
11361136

11371137
ops->graphics = 0;
11381138

1139+
#ifdef CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION
11391140
if ((cap & FBINFO_HWACCEL_COPYAREA) &&
11401141
!(cap & FBINFO_HWACCEL_DISABLED))
11411142
p->scrollmode = SCROLL_MOVE;
11421143
else /* default to something safe */
11431144
p->scrollmode = SCROLL_REDRAW;
1145+
#endif
11441146

11451147
/*
11461148
* ++guenther: console.c:vc_allocate() relies on initializing
@@ -1705,7 +1707,7 @@ static bool fbcon_scroll(struct vc_data *vc, unsigned int t, unsigned int b,
17051707
count = vc->vc_rows;
17061708
if (logo_shown >= 0)
17071709
goto redraw_up;
1708-
switch (p->scrollmode) {
1710+
switch (fb_scrollmode(p)) {
17091711
case SCROLL_MOVE:
17101712
fbcon_redraw_blit(vc, info, p, t, b - t - count,
17111713
count);
@@ -1795,7 +1797,7 @@ static bool fbcon_scroll(struct vc_data *vc, unsigned int t, unsigned int b,
17951797
count = vc->vc_rows;
17961798
if (logo_shown >= 0)
17971799
goto redraw_down;
1798-
switch (p->scrollmode) {
1800+
switch (fb_scrollmode(p)) {
17991801
case SCROLL_MOVE:
18001802
fbcon_redraw_blit(vc, info, p, b - 1, b - t - count,
18011803
-count);
@@ -1946,12 +1948,12 @@ static void fbcon_bmove_rec(struct vc_data *vc, struct fbcon_display *p, int sy,
19461948
height, width);
19471949
}
19481950

1949-
static void updatescrollmode(struct fbcon_display *p,
1951+
static void updatescrollmode_accel(struct fbcon_display *p,
19501952
struct fb_info *info,
19511953
struct vc_data *vc)
19521954
{
1955+
#ifdef CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION
19531956
struct fbcon_ops *ops = info->fbcon_par;
1954-
int fh = vc->vc_font.height;
19551957
int cap = info->flags;
19561958
u16 t = 0;
19571959
int ypan = FBCON_SWAP(ops->rotate, info->fix.ypanstep,
@@ -1972,12 +1974,6 @@ static void updatescrollmode(struct fbcon_display *p,
19721974
int fast_imageblit = (cap & FBINFO_HWACCEL_IMAGEBLIT) &&
19731975
!(cap & FBINFO_HWACCEL_DISABLED);
19741976

1975-
p->vrows = vyres/fh;
1976-
if (yres > (fh * (vc->vc_rows + 1)))
1977-
p->vrows -= (yres - (fh * vc->vc_rows)) / fh;
1978-
if ((yres % fh) && (vyres % fh < yres % fh))
1979-
p->vrows--;
1980-
19811977
if (good_wrap || good_pan) {
19821978
if (reading_fast || fast_copyarea)
19831979
p->scrollmode = good_wrap ?
@@ -1991,6 +1987,27 @@ static void updatescrollmode(struct fbcon_display *p,
19911987
else
19921988
p->scrollmode = SCROLL_REDRAW;
19931989
}
1990+
#endif
1991+
}
1992+
1993+
static void updatescrollmode(struct fbcon_display *p,
1994+
struct fb_info *info,
1995+
struct vc_data *vc)
1996+
{
1997+
struct fbcon_ops *ops = info->fbcon_par;
1998+
int fh = vc->vc_font.height;
1999+
int yres = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
2000+
int vyres = FBCON_SWAP(ops->rotate, info->var.yres_virtual,
2001+
info->var.xres_virtual);
2002+
2003+
p->vrows = vyres/fh;
2004+
if (yres > (fh * (vc->vc_rows + 1)))
2005+
p->vrows -= (yres - (fh * vc->vc_rows)) / fh;
2006+
if ((yres % fh) && (vyres % fh < yres % fh))
2007+
p->vrows--;
2008+
2009+
/* update scrollmode in case hardware acceleration is used */
2010+
updatescrollmode_accel(p, info, vc);
19942011
}
19952012

19962013
#define PITCH(w) (((w) + 7) >> 3)
@@ -2148,7 +2165,7 @@ static int fbcon_switch(struct vc_data *vc)
21482165

21492166
updatescrollmode(p, info, vc);
21502167

2151-
switch (p->scrollmode) {
2168+
switch (fb_scrollmode(p)) {
21522169
case SCROLL_WRAP_MOVE:
21532170
scrollback_phys_max = p->vrows - vc->vc_rows;
21542171
break;

drivers/video/fbdev/core/fbcon.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@ struct fbcon_display {
2929
/* Filled in by the low-level console driver */
3030
const u_char *fontdata;
3131
int userfont; /* != 0 if fontdata kmalloc()ed */
32-
u_short scrollmode; /* Scroll Method */
32+
#ifdef CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION
33+
u_short scrollmode; /* Scroll Method, use fb_scrollmode() */
34+
#endif
3335
u_short inverse; /* != 0 text black on white as default */
3436
short yscroll; /* Hardware scrolling */
3537
int vrows; /* number of virtual rows */
@@ -208,6 +210,17 @@ static inline int attr_col_ec(int shift, struct vc_data *vc,
208210
#define SCROLL_REDRAW 0x004
209211
#define SCROLL_PAN_REDRAW 0x005
210212

213+
static inline u_short fb_scrollmode(struct fbcon_display *fb)
214+
{
215+
#ifdef CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION
216+
return fb->scrollmode;
217+
#else
218+
/* hardcoded to SCROLL_REDRAW if acceleration was disabled. */
219+
return SCROLL_REDRAW;
220+
#endif
221+
}
222+
223+
211224
#ifdef CONFIG_FB_TILEBLITTING
212225
extern void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info);
213226
#endif

drivers/video/fbdev/core/fbcon_ccw.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ static void ccw_bmove(struct vc_data *vc, struct fb_info *info, int sy,
6565
{
6666
struct fbcon_ops *ops = info->fbcon_par;
6767
struct fb_copyarea area;
68-
u32 vyres = GETVYRES(ops->p->scrollmode, info);
68+
u32 vyres = GETVYRES(ops->p, info);
6969

7070
area.sx = sy * vc->vc_font.height;
7171
area.sy = vyres - ((sx + width) * vc->vc_font.width);
@@ -83,7 +83,7 @@ static void ccw_clear(struct vc_data *vc, struct fb_info *info, int sy,
8383
struct fbcon_ops *ops = info->fbcon_par;
8484
struct fb_fillrect region;
8585
int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
86-
u32 vyres = GETVYRES(ops->p->scrollmode, info);
86+
u32 vyres = GETVYRES(ops->p, info);
8787

8888
region.color = attr_bgcol_ec(bgshift,vc,info);
8989
region.dx = sy * vc->vc_font.height;
@@ -140,7 +140,7 @@ static void ccw_putcs(struct vc_data *vc, struct fb_info *info,
140140
u32 cnt, pitch, size;
141141
u32 attribute = get_attribute(info, scr_readw(s));
142142
u8 *dst, *buf = NULL;
143-
u32 vyres = GETVYRES(ops->p->scrollmode, info);
143+
u32 vyres = GETVYRES(ops->p, info);
144144

145145
if (!ops->fontbuffer)
146146
return;
@@ -229,7 +229,7 @@ static void ccw_cursor(struct vc_data *vc, struct fb_info *info, int mode,
229229
int attribute, use_sw = vc->vc_cursor_type & CUR_SW;
230230
int err = 1, dx, dy;
231231
char *src;
232-
u32 vyres = GETVYRES(ops->p->scrollmode, info);
232+
u32 vyres = GETVYRES(ops->p, info);
233233

234234
if (!ops->fontbuffer)
235235
return;
@@ -387,7 +387,7 @@ static int ccw_update_start(struct fb_info *info)
387387
{
388388
struct fbcon_ops *ops = info->fbcon_par;
389389
u32 yoffset;
390-
u32 vyres = GETVYRES(ops->p->scrollmode, info);
390+
u32 vyres = GETVYRES(ops->p, info);
391391
int err;
392392

393393
yoffset = (vyres - info->var.yres) - ops->var.xoffset;

drivers/video/fbdev/core/fbcon_cw.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ static void cw_bmove(struct vc_data *vc, struct fb_info *info, int sy,
5050
{
5151
struct fbcon_ops *ops = info->fbcon_par;
5252
struct fb_copyarea area;
53-
u32 vxres = GETVXRES(ops->p->scrollmode, info);
53+
u32 vxres = GETVXRES(ops->p, info);
5454

5555
area.sx = vxres - ((sy + height) * vc->vc_font.height);
5656
area.sy = sx * vc->vc_font.width;
@@ -68,7 +68,7 @@ static void cw_clear(struct vc_data *vc, struct fb_info *info, int sy,
6868
struct fbcon_ops *ops = info->fbcon_par;
6969
struct fb_fillrect region;
7070
int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
71-
u32 vxres = GETVXRES(ops->p->scrollmode, info);
71+
u32 vxres = GETVXRES(ops->p, info);
7272

7373
region.color = attr_bgcol_ec(bgshift,vc,info);
7474
region.dx = vxres - ((sy + height) * vc->vc_font.height);
@@ -125,7 +125,7 @@ static void cw_putcs(struct vc_data *vc, struct fb_info *info,
125125
u32 cnt, pitch, size;
126126
u32 attribute = get_attribute(info, scr_readw(s));
127127
u8 *dst, *buf = NULL;
128-
u32 vxres = GETVXRES(ops->p->scrollmode, info);
128+
u32 vxres = GETVXRES(ops->p, info);
129129

130130
if (!ops->fontbuffer)
131131
return;
@@ -212,7 +212,7 @@ static void cw_cursor(struct vc_data *vc, struct fb_info *info, int mode,
212212
int attribute, use_sw = vc->vc_cursor_type & CUR_SW;
213213
int err = 1, dx, dy;
214214
char *src;
215-
u32 vxres = GETVXRES(ops->p->scrollmode, info);
215+
u32 vxres = GETVXRES(ops->p, info);
216216

217217
if (!ops->fontbuffer)
218218
return;
@@ -369,7 +369,7 @@ static void cw_cursor(struct vc_data *vc, struct fb_info *info, int mode,
369369
static int cw_update_start(struct fb_info *info)
370370
{
371371
struct fbcon_ops *ops = info->fbcon_par;
372-
u32 vxres = GETVXRES(ops->p->scrollmode, info);
372+
u32 vxres = GETVXRES(ops->p, info);
373373
u32 xoffset;
374374
int err;
375375

drivers/video/fbdev/core/fbcon_rotate.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@
1212
#define _FBCON_ROTATE_H
1313

1414
#define GETVYRES(s,i) ({ \
15-
(s == SCROLL_REDRAW || s == SCROLL_MOVE) ? \
15+
(fb_scrollmode(s) == SCROLL_REDRAW || fb_scrollmode(s) == SCROLL_MOVE) ? \
1616
(i)->var.yres : (i)->var.yres_virtual; })
1717

1818
#define GETVXRES(s,i) ({ \
19-
(s == SCROLL_REDRAW || s == SCROLL_MOVE || !(i)->fix.xpanstep) ? \
19+
(fb_scrollmode(s) == SCROLL_REDRAW || fb_scrollmode(s) == SCROLL_MOVE || !(i)->fix.xpanstep) ? \
2020
(i)->var.xres : (i)->var.xres_virtual; })
2121

2222

drivers/video/fbdev/core/fbcon_ud.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ static void ud_bmove(struct vc_data *vc, struct fb_info *info, int sy,
5050
{
5151
struct fbcon_ops *ops = info->fbcon_par;
5252
struct fb_copyarea area;
53-
u32 vyres = GETVYRES(ops->p->scrollmode, info);
54-
u32 vxres = GETVXRES(ops->p->scrollmode, info);
53+
u32 vyres = GETVYRES(ops->p, info);
54+
u32 vxres = GETVXRES(ops->p, info);
5555

5656
area.sy = vyres - ((sy + height) * vc->vc_font.height);
5757
area.sx = vxres - ((sx + width) * vc->vc_font.width);
@@ -69,8 +69,8 @@ static void ud_clear(struct vc_data *vc, struct fb_info *info, int sy,
6969
struct fbcon_ops *ops = info->fbcon_par;
7070
struct fb_fillrect region;
7171
int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
72-
u32 vyres = GETVYRES(ops->p->scrollmode, info);
73-
u32 vxres = GETVXRES(ops->p->scrollmode, info);
72+
u32 vyres = GETVYRES(ops->p, info);
73+
u32 vxres = GETVXRES(ops->p, info);
7474

7575
region.color = attr_bgcol_ec(bgshift,vc,info);
7676
region.dy = vyres - ((sy + height) * vc->vc_font.height);
@@ -162,8 +162,8 @@ static void ud_putcs(struct vc_data *vc, struct fb_info *info,
162162
u32 mod = vc->vc_font.width % 8, cnt, pitch, size;
163163
u32 attribute = get_attribute(info, scr_readw(s));
164164
u8 *dst, *buf = NULL;
165-
u32 vyres = GETVYRES(ops->p->scrollmode, info);
166-
u32 vxres = GETVXRES(ops->p->scrollmode, info);
165+
u32 vyres = GETVYRES(ops->p, info);
166+
u32 vxres = GETVXRES(ops->p, info);
167167

168168
if (!ops->fontbuffer)
169169
return;
@@ -259,8 +259,8 @@ static void ud_cursor(struct vc_data *vc, struct fb_info *info, int mode,
259259
int attribute, use_sw = vc->vc_cursor_type & CUR_SW;
260260
int err = 1, dx, dy;
261261
char *src;
262-
u32 vyres = GETVYRES(ops->p->scrollmode, info);
263-
u32 vxres = GETVXRES(ops->p->scrollmode, info);
262+
u32 vyres = GETVYRES(ops->p, info);
263+
u32 vxres = GETVXRES(ops->p, info);
264264

265265
if (!ops->fontbuffer)
266266
return;
@@ -410,8 +410,8 @@ static int ud_update_start(struct fb_info *info)
410410
{
411411
struct fbcon_ops *ops = info->fbcon_par;
412412
int xoffset, yoffset;
413-
u32 vyres = GETVYRES(ops->p->scrollmode, info);
414-
u32 vxres = GETVXRES(ops->p->scrollmode, info);
413+
u32 vyres = GETVYRES(ops->p, info);
414+
u32 vxres = GETVXRES(ops->p, info);
415415
int err;
416416

417417
xoffset = vxres - info->var.xres - ops->var.xoffset;

0 commit comments

Comments
 (0)