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

Reply via email to