This functionally undoes 39aead8373b3 ("fbcon: Disable accelerated scrolling"), but behind the FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION option.
References: https://lore.kernel.org/dri-devel/feea8303-2b83-fc36-972c-4fc8ad723...@gmx.de/ Fixes: 39aead8373b3 ("fbcon: Disable accelerated scrolling") Cc: Helge Deller <del...@gmx.de> Cc: <sta...@vger.kernel.org> # v5.11+ Cc: Claudio Suarez <c...@net-c.es> Cc: Dave Airlie <airl...@gmail.com> Cc: Jani Nikula <jani.nik...@linux.intel.com> Cc: Linus Torvalds <torva...@linux-foundation.org> Cc: Linux Fbdev development list <linux-fb...@vger.kernel.org> Cc: Pavel Machek <pa...@ucw.cz> Cc: Sam Ravnborg <s...@ravnborg.org> Cc: Greg Kroah-Hartman <gre...@linuxfoundation.org> Cc: Javier Martinez Canillas <javi...@redhat.com> Cc: DRI Development <dri-de...@lists.freedesktop.org> Cc: Linux Kernel Mailing List <linux-ker...@vger.kernel.org> Cc: Claudio Suarez <c...@net-c.es> Cc: Tomi Valkeinen <tomi.valkei...@ti.com> Cc: Geert Uytterhoeven <ge...@linux-m68k.org> Cc: Thomas Zimmermann <tzimmerm...@suse.de> Cc: Daniel Vetter <daniel.vet...@intel.com> Cc: Sven Schnelle <sv...@stackframe.org> Cc: Gerd Hoffmann <kra...@redhat.com> Signed-off-by: Daniel Vetter <daniel.vet...@intel.com> --- drivers/video/fbdev/core/fbcon.c | 48 ++++++++++++++++++++++++++++---- 1 file changed, 42 insertions(+), 6 deletions(-) diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c index 2ff90061c7f3..39dc18a5de86 100644 --- a/drivers/video/fbdev/core/fbcon.c +++ b/drivers/video/fbdev/core/fbcon.c @@ -1125,13 +1125,15 @@ static void fbcon_init(struct vc_data *vc, int init) ops->graphics = 0; - /* - * No more hw acceleration for fbcon. - * - * FIXME: Garbage collect all the now dead code after sufficient time - * has passed. - */ +#ifdef CONFIG_FRAMEBUFFER_CONSOLE_ROTATION + if ((info->flags & FBINFO_HWACCEL_COPYAREA) && + !(info->flags & FBINFO_HWACCEL_DISABLED)) + p->scrollmode = SCROLL_MOVE; + else /* default to something safe */ + p->scrollmode = SCROLL_REDRAW; +#else p->scrollmode = SCROLL_REDRAW; +#endif /* * ++guenther: console.c:vc_allocate() relies on initializing @@ -1971,15 +1973,49 @@ static void updatescrollmode(struct fbcon_display *p, { struct fbcon_ops *ops = info->fbcon_par; int fh = vc->vc_font.height; + 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); 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); + 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); 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--; + + 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; + } + +#ifndef CONFIG_FRAMEBUFFER_CONSOLE_ROTATION + p->scrollmode = SCROLL_REDRAW; +#endif } #define PITCH(w) (((w) + 7) >> 3) -- 2.33.0