All of lore.kernel.org
 help / color / mirror / Atom feed
From: Antonino Daplas <adaplas@pol.net>
To: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: otto.wyss@bluewin.ch, fbdev <linux-fbdev-devel@lists.sourceforge.net>
Subject: Re: Portrait display mode
Date: 12 Sep 2002 03:50:23 +0800	[thread overview]
Message-ID: <1031773864.562.3.camel@daplas> (raw)
In-Reply-To: <Pine.GSO.4.21.0209110837090.27524-100000@vervain.sonytel.be>

[-- Attachment #1: Type: text/plain, Size: 2189 bytes --]

On Wed, 2002-09-11 at 14:38, Geert Uytterhoeven wrote: 

> > > turnable display I rather see this feature implemented. I even may help but can
> > > spend much time. How difficult would it be?
> > > 
> > It should not be too difficult to add per-driver support once the
> 
> Can't this be moved up to generic code, so we don't have to modify all drivers?
> 
I have thought about that, but since the patch was preliminary, I chose
not to disrupt the framework yet.  The tricky part in making the support
generic is display panning. 

Here is my train of thought.  Moving support into fbgen might involve a
few assumptions.  Firstly, info->var is assumed to be device specific
(ie, it does not care about the orientation). Secondly, the display->var
as well as those received from other sources (such as in an ioctl call)
are partly device independent.  When a structure var is passed to the
driver, it will undergo conversion so the structure is sane from the
driver's perspective.  The same is done vice-versa.  I've introduced two
(exportable) functions, convert_var_to_physical(), and
convert_var_to_logical() that should do that.  

All fbops functions should be passed with device-specific var except for
fb_set_var since I'm not too sure where to look for specific entry
points for fb_set_var.  I guess fb_check_var and fb_pan_display are the
most critical ones, since the other fbops functions do not look at the
framelengths, nor the offsets. 

With the changes, drivers that support fbcon_accel and gen_* functions
should have support for console rotation automatically.  

For those that support fbcon_accel, but not gen_* functions, the driver
should not look at display->var anymore, but look instead into
info->var. If possible, use the convert_to_var functions when
passing/getting information to/from structure display. 

For those, that don't support fbcon_accel, behaviour should remain as
usual. 

I'm not too sure if this is the correct way of doing this, but it's the
best I can think of at the moment without causing very intrusive
changes. 

Attached is a patch (fb_rotate2.diff).  Please apply the patches I have
sent previously before applying this patch. 

Tony 



[-- Attachment #2: fb_rotate2.diff --]
[-- Type: text/x-patch, Size: 22504 bytes --]

diff -Naur linux-2.5.33/drivers/video/Config.in linux/drivers/video/Config.in
--- linux-2.5.33/drivers/video/Config.in	Wed Sep 11 18:28:40 2002
+++ linux/drivers/video/Config.in	Wed Sep 11 18:34:23 2002
@@ -227,7 +227,6 @@
       tristate '    24 bpp packed pixels support' CONFIG_FBCON_CFB24
       tristate '    32 bpp packed pixels support' CONFIG_FBCON_CFB32
       tristate '    Hardware acceleration support' CONFIG_FBCON_ACCEL
-      dep_tristate '    Console Display Rotation support' CONFIG_FBCON_ROTATE $CONFIG_FBCON_ACCEL	
       tristate '    Amiga bitplanes support' CONFIG_FBCON_AFB
       tristate '    Amiga interleaved bitplanes support' CONFIG_FBCON_ILBM
       tristate '    Atari interleaved bitplanes (2 planes) support' CONFIG_FBCON_IPLAN2P2
@@ -368,13 +367,6 @@
 	      "$CONFIG_FB_CLPS711X" = "m" -o "$CONFIG_FB_3DFX" = "m" -o \
 	      "$CONFIG_FB_RIVA" = "m" -o "$CONFIG_FB_SGIVW" = "m" ]; then 
 	    define_tristate CONFIG_FBCON_ACCEL m
-         fi       
-      fi
-      if [ "$CONFIG_FB_VESA" = "y" ]; then
-	 define_tristate CONFIG_FBCON_ROTATE y
-      else
-	 if [ "$CONFIG_FB_VESA" = "m" ]; then 
-	    define_tristate CONFIG_FBCON_ROTATE m
          fi       
       fi
       if [ "$CONFIG_FB_AMIGA" = "y" ]; then
diff -Naur linux-2.5.33/drivers/video/Makefile linux/drivers/video/Makefile
--- linux-2.5.33/drivers/video/Makefile	Wed Sep 11 18:28:49 2002
+++ linux/drivers/video/Makefile	Wed Sep 11 18:36:23 2002
@@ -68,7 +68,7 @@
 obj-$(CONFIG_FB_S3TRIO)           += S3triofb.o
 obj-$(CONFIG_FB_TGA)              += tgafb.o
 obj-$(CONFIG_FB_VESA)             += vesafb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o 
-obj-$(CONFIG_FB_VGA16)            += vga16fb.o fbcon-vga-planes.o
+obj-$(CONFIG_FB_VGA16)            += vga16fb.o fbcon-vga-planes.o 
 obj-$(CONFIG_FB_VIRGE)            += virgefb.o
 obj-$(CONFIG_FB_G364)             += g364fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
 obj-$(CONFIG_FB_FM2)              += fm2fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
@@ -117,8 +117,7 @@
 obj-$(CONFIG_FBCON_MFB)           += fbcon-mfb.o
 obj-$(CONFIG_FBCON_HGA)           += fbcon-hga.o
 obj-$(CONFIG_FBCON_STI)           += fbcon-sti.o
-obj-$(CONFIG_FBCON_ACCEL)	  += fbcon-accel.o
-obj-$(CONFIG_FBCON_ROTATE)	  += fbcon-rotate.o 
+obj-$(CONFIG_FBCON_ACCEL)	  += fbcon-accel.o fbcon-rotate.o
 
 include $(TOPDIR)/Rules.make
 
diff -Naur linux-2.5.33/drivers/video/cfbcopyarea.c linux/drivers/video/cfbcopyarea.c
--- linux-2.5.33/drivers/video/cfbcopyarea.c	Wed Sep 11 18:29:01 2002
+++ linux/drivers/video/cfbcopyarea.c	Wed Sep 11 18:30:53 2002
@@ -28,7 +28,6 @@
 #include <asm/io.h>
 #include <video/fbcon.h>
 
-#include "fbcon-rotate.h"
 
 #define LONG_MASK  (BITS_PER_LONG - 1)
 
@@ -329,12 +328,6 @@
 
 	vxres = p->var.xres_virtual;
 	vyres = p->var.yres_virtual;
-#ifdef FBCON_HAS_ROTATE
-	if (p->var.vmode & (FB_VMODE_ROTATE_CW | FB_VMODE_ROTATE_CCW)) {
-		vxres = p->var.yres_virtual;
-		vyres = p->var.xres_virtual;
-	}
-#endif
 
 	if (area->dx > vxres || 
 	    area->sx > vxres ||
diff -Naur linux-2.5.33/drivers/video/cfbfillrect.c linux/drivers/video/cfbfillrect.c
--- linux-2.5.33/drivers/video/cfbfillrect.c	Wed Sep 11 18:29:05 2002
+++ linux/drivers/video/cfbfillrect.c	Wed Sep 11 18:30:58 2002
@@ -22,8 +22,6 @@
 #include <asm/types.h>
 #include <video/fbcon.h>
 
-#include "fbcon-rotate.h"
-
 #if BITS_PER_LONG == 32
 #define FB_WRITEL fb_writel
 #define FB_READL  fb_readl
@@ -53,12 +51,6 @@
 
 	vxres = p->var.xres_virtual;
 	vyres = p->var.yres_virtual;
-#ifdef FBCON_HAS_ROTATE
-	if (p->var.vmode & (FB_VMODE_ROTATE_CW | FB_VMODE_ROTATE_CCW)) {
-		vxres = p->var.yres_virtual;
-		vyres = p->var.xres_virtual;
-	}
-#endif
 
 	if (!rect->width || !rect->height ||
 	    rect->dx > vxres ||
diff -Naur linux-2.5.33/drivers/video/cfbimgblt.c linux/drivers/video/cfbimgblt.c
--- linux-2.5.33/drivers/video/cfbimgblt.c	Wed Sep 11 18:28:56 2002
+++ linux/drivers/video/cfbimgblt.c	Wed Sep 11 18:30:48 2002
@@ -39,7 +39,6 @@
 #include <asm/types.h>
 
 #include <video/fbcon.h>
-#include "fbcon-rotate.h"
 
 #define DEBUG
 
@@ -298,12 +297,6 @@
 
 	vxres = p->var.xres_virtual;
 	vyres = p->var.yres_virtual;
-#ifdef FBCON_HAS_ROTATE
-	if (p->var.vmode & (FB_VMODE_ROTATE_CW | FB_VMODE_ROTATE_CCW)) {
-		vxres = p->var.yres_virtual;
-		vyres = p->var.xres_virtual;
-	}
-#endif
 
 	/* 
 	 * We could use hardware clipping but on many cards you get around hardware
diff -Naur linux-2.5.33/drivers/video/fbcon-rotate.c linux/drivers/video/fbcon-rotate.c
--- linux-2.5.33/drivers/video/fbcon-rotate.c	Wed Sep 11 18:33:04 2002
+++ linux/drivers/video/fbcon-rotate.c	Wed Sep 11 18:32:32 2002
@@ -114,9 +114,9 @@
 	struct fb_info *info = p->fb_info;
 	struct fb_copyarea area;
 
-	area.sx = info->var.yres_virtual - ((sy + height) * fontheight(p));
+	area.sx = info->var.xres_virtual - ((sy + height) * fontheight(p));
 	area.sy = sx * fontwidth(p);
-	area.dx = info->var.yres_virtual - ((dy + height) * fontheight(p));
+	area.dx = info->var.xres_virtual - ((dy + height) * fontheight(p));
 	area.dy = dx * fontwidth(p);
 	area.width = height * fontheight(p);
 	area.height  = width * fontwidth(p);
@@ -131,7 +131,7 @@
 	struct fb_fillrect region;
 
 	region.color = attr_bgcol_ec(p,vc);
-	region.dx = info->var.yres_virtual - ((sy + height) * fontheight(p));
+	region.dx = info->var.xres_virtual - ((sy + height) * fontheight(p));
 	region.dy = sx * fontwidth(p);
 	region.height = width * fontwidth(p);
 	region.width = height * fontheight(p);
@@ -150,7 +150,7 @@
 
 	image.fg_color = attr_fgcol(p, c);
 	image.bg_color = attr_bgcol(p, c);
-	image.dx = info->var.yres_virtual - ((yy * fontheight(p)) + fontheight(p));
+	image.dx = info->var.xres_virtual - ((yy * fontheight(p)) + fontheight(p));
 	image.dy = xx * fontwidth(p);
 	image.width = fontheight(p);
 	image.height = fontwidth(p);
@@ -170,7 +170,7 @@
 
 	image.fg_color = attr_fgcol(p, *s);
 	image.bg_color = attr_bgcol(p, *s);
-	image.dx = info->var.yres_virtual - ((yy * fontheight(p)) + fontheight(p));
+	image.dx = info->var.xres_virtual - ((yy * fontheight(p)) + fontheight(p));
 	image.dy = xx * fontwidth(p);
 	image.width = fontheight(p);
 	image.height = fontwidth(p);
@@ -188,7 +188,7 @@
 	struct fb_fillrect region;
 
 	region.color = attr_fgcol_ec(p, p->conp);
-	region.dx = info->var.yres_virtual - ((yy * fontheight(p)) + fontheight(p));
+	region.dx = info->var.xres_virtual - ((yy * fontheight(p)) + fontheight(p));
 	region.dy = xx * fontwidth(p);
 	region.width  = fontheight(p);
 	region.height = fontwidth(p); 
@@ -203,10 +203,10 @@
 	struct fb_info *info = p->fb_info;
 	unsigned int cw = fontwidth(p);
 	unsigned int ch = fontheight(p);
-	unsigned int rw = info->var.xres % cw;
-	unsigned int bh = info->var.yres % ch;
-	unsigned int rs = info->var.xres - rw;
-	unsigned int bs = info->var.yres - bh;
+	unsigned int rw = info->var.yres % cw;
+	unsigned int bh = info->var.xres % ch;
+	unsigned int rs = info->var.yres - rw;
+	unsigned int bs = info->var.xres - bh;
 	struct fb_fillrect region;
 
 	region.color = attr_bgcol_ec(p,vc);
@@ -214,15 +214,15 @@
 
 	if (rw && !bottom_only) {
 		region.dx = 0;
-		region.dy = info->var.xoffset + rs;
+		region.dy = info->var.yoffset + rs;
 		region.height  = rw;
 		region.width = info->var.yres_virtual;
 		info->fbops->fb_fillrect(info, &region); 
 	}
 
 	if (bh) {
-		region.dx = info->var.yres_virtual - (info->var.yoffset + bs + bh);
-		region.dy = info->var.xoffset;
+		region.dx = info->var.xres_virtual - (info->var.xoffset + bs + bh);
+		region.dy = info->var.yoffset;
                 region.width  = bh;
                 region.height = rs;
 		info->fbops->fb_fillrect(info, &region);
@@ -276,9 +276,9 @@
 	struct fb_copyarea area;
 
 	area.sx = sy * fontheight(p);
-	area.sy = info->var.xres_virtual - ((sx + width) * fontwidth(p));
+	area.sy = info->var.yres_virtual - ((sx + width) * fontwidth(p));
 	area.dx = dy * fontheight(p);
-	area.dy = info->var.xres_virtual - ((dx + width) * fontwidth(p));
+	area.dy = info->var.yres_virtual - ((dx + width) * fontwidth(p));
 	area.width = height * fontheight(p);
 	area.height  = width * fontwidth(p);
 
@@ -293,7 +293,7 @@
 
 	region.color = attr_bgcol_ec(p,vc);
 	region.dx = sy * fontheight(p);
-	region.dy = info->var.xres_virtual - ((sx + width)  *  fontwidth(p));
+	region.dy = info->var.yres_virtual - ((sx + width)  *  fontwidth(p));
 	region.height = width * fontwidth(p);
 	region.width = height * fontheight(p);
 	region.rop = ROP_COPY;
@@ -312,7 +312,7 @@
 	image.fg_color = attr_fgcol(p, c);
 	image.bg_color = attr_bgcol(p, c);
 	image.dx = yy * fontheight(p);
-	image.dy = info->var.xres_virtual - ((xx * fontwidth(p)) + fontwidth(p));
+	image.dy = info->var.yres_virtual - ((xx * fontwidth(p)) + fontwidth(p));
 	image.width = fontheight(p);
 	image.height = fontwidth(p);
 	image.data = fontcache + (c & charmask)*fontheight(p) * width;
@@ -332,7 +332,7 @@
 	image.fg_color = attr_fgcol(p, *s);
 	image.bg_color = attr_bgcol(p, *s);
 	image.dx = yy * fontheight(p);
-	image.dy = info->var.xres_virtual - ((xx * fontwidth(p)) + fontwidth(p));
+	image.dy = info->var.yres_virtual - ((xx * fontwidth(p)) + fontwidth(p));
 	image.width = fontheight(p);
 	image.height = fontwidth(p);
 	image.depth = 1;
@@ -350,7 +350,7 @@
 
 	region.color = attr_fgcol_ec(p, p->conp);
 	region.dx = yy * fontheight(p);
-	region.dy = info->var.xres_virtual - ((xx * fontwidth(p)) + fontwidth(p));
+	region.dy = info->var.yres_virtual - ((xx * fontwidth(p)) + fontwidth(p));
 	region.width  = fontheight(p);
 	region.height = fontwidth(p); 
 	region.rop = ROP_XOR;
@@ -364,10 +364,10 @@
 	struct fb_info *info = p->fb_info;
 	unsigned int cw = fontwidth(p);
 	unsigned int ch = fontheight(p);
-	unsigned int rw = info->var.xres % cw;
-	unsigned int bh = info->var.yres % ch;
-	unsigned int rs = info->var.xres - rw;
-	unsigned int bs = info->var.yres - bh;
+	unsigned int rw = info->var.yres % cw;
+	unsigned int bh = info->var.xres % ch;
+	unsigned int rs = info->var.yres - rw;
+	unsigned int bs = info->var.xres - bh;
 	struct fb_fillrect region;
 
 	region.color = attr_bgcol_ec(p,vc);
@@ -375,15 +375,15 @@
 
 	if (rw && !bottom_only) {
 		region.dx = 0;
-		region.dy = info->var.xres_virtual - (info->var.xoffset + rs + rw);
+		region.dy = info->var.yres_virtual - (info->var.yoffset + rs + rw);
 		region.height  = rw;
 		region.width = info->var.yres_virtual;
 		info->fbops->fb_fillrect(info, &region); 
 	}
 
 	if (bh) {
-		region.dx = info->var.yoffset + bs;
-		region.dy = info->var.xres_virtual - (info->var.xoffset + rs + rw);
+		region.dx = info->var.xoffset + bs;
+		region.dy = info->var.yres_virtual - (info->var.yoffset + rs + rw);
                 region.width  = bh;
                 region.height = rs;
 		info->fbops->fb_fillrect(info, &region);
diff -Naur linux-2.5.33/drivers/video/fbcon-rotate.h linux/drivers/video/fbcon-rotate.h
--- linux-2.5.33/drivers/video/fbcon-rotate.h	Wed Sep 11 18:33:06 2002
+++ linux/drivers/video/fbcon-rotate.h	Wed Sep 11 18:32:35 2002
@@ -7,16 +7,6 @@
 
 #include <linux/config.h>
 
-#ifdef MODULE
-#if defined(CONFIG_FBCON_ROTATE) || defined(CONFIG_FBCON_ROTATE_MODULE)
-#define FBCON_HAS_ROTATE
-#endif
-#else
-#if defined(CONFIG_FBCON_ROTATE)
-#define FBCON_HAS_ROTATE
-#endif
-#endif
-
 extern struct display_switch fbcon_rr;
 extern void fbcon_rr_setup(struct display *p);
 extern void fbcon_rr_bmove(struct display *p, int sy, int sx, int dy,
diff -Naur linux-2.5.33/drivers/video/fbgen.c linux/drivers/video/fbgen.c
--- linux-2.5.33/drivers/video/fbgen.c	Wed Sep 11 18:28:35 2002
+++ linux/drivers/video/fbgen.c	Wed Sep 11 18:30:23 2002
@@ -31,37 +31,119 @@
 #include "fbcon-accel.h"
 #include "fbcon-rotate.h"
 
+#define SWAP(x,y,z) do { (z) = (x); (x) = (y); (y) = (z); } while(0)
+
+void convert_var_to_phys(struct fb_var_screeninfo *var)
+{
+#ifdef FBCON_HAS_ACCEL
+	u32 tmp, xoffset, yoffset;
+	
+	switch (var->vmode & FB_ROTATE_MASK) {
+	case FB_VMODE_ROTATE_CW:
+		xoffset = var->yres_virtual - (var->yres + var->yoffset);
+		yoffset = var->xoffset;
+		var->xoffset = xoffset;
+		var->yoffset = yoffset;
+		SWAP(var->xres, var->yres, tmp);
+		SWAP(var->xres_virtual, var->yres_virtual, tmp);
+		break;
+	case FB_VMODE_ROTATE_CCW:
+		xoffset = var->yoffset;
+		yoffset = var->xres_virtual - (var->xres + var->xoffset);
+		var->xoffset = xoffset;
+		var->yoffset = yoffset;
+		SWAP(var->xres, var->yres, tmp);
+		SWAP(var->xres_virtual, var->yres_virtual, tmp);
+		break;
+	case FB_VMODE_ROTATE_UD:
+		var->xoffset = var->xres_virtual - (var->xres + var->xoffset);
+		var->yoffset = var->yres_virtual - (var->yres + var->yoffset);
+		break;
+	}
+#endif
+}
+
+/*
+ * convert var from what hardware actually sees
+ */
+void convert_var_to_logical(struct fb_var_screeninfo *var)
+{
+#ifdef FBCON_HAS_ACCEL
+	u32 tmp, xoffset, yoffset;
+
+	switch (var->vmode & FB_ROTATE_MASK) {
+	case FB_VMODE_ROTATE_CW:
+		xoffset = var->yoffset;
+		yoffset = var->xres_virtual - (var->xres + var->xoffset);
+		var->xoffset = xoffset;
+		var->yoffset = yoffset;
+		SWAP(var->xres, var->yres, tmp);
+		SWAP(var->xres_virtual, var->yres_virtual, tmp);
+		break;
+	case FB_VMODE_ROTATE_CCW:
+		xoffset = var->yres_virtual - (var->yres + var->yoffset);
+		yoffset = var->xoffset;
+		var->xoffset = xoffset;
+		var->yoffset = yoffset;
+		SWAP(var->xres, var->yres, tmp);
+		SWAP(var->xres_virtual, var->yres_virtual, tmp);
+		break;
+	case FB_VMODE_ROTATE_UD:
+		var->xoffset = var->xres_virtual - (var->xres + var->xoffset);
+		var->yoffset = var->yres_virtual - (var->yres + var->yoffset);
+		break;
+	}
+#endif
+}		
+
 int gen_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
 {
-	int err;
+	int err, xoffset, yoffset, vmode, activate; 
 
+	/*
+	 * FIXME: VESAFB crashes when switching orientation and
+	 * xoffset/yoffset is not zero. This is what changevar
+	 * does anyway.
+	 */
+	var->xoffset = 0;
+	var->yoffset = 0;
+	convert_var_to_phys(var);
+	xoffset = var->xoffset;
+	yoffset = var->yoffset;
 	if (con < 0 || (memcmp(&info->var, var, sizeof(struct fb_var_screeninfo)))) {
 		if (!info->fbops->fb_check_var) {
-			*var = info->var;
-			return 0;
+			activate = var->activate;
+			vmode = var->vmode;
+			*var = info->var; 
+			var->vmode &= ~FB_ROTATE_MASK;
+			var->vmode |= vmode & FB_ROTATE_MASK;
+			var->activate &= ~FB_ACTIVATE_MASK;
+			var->activate |= activate & FB_ACTIVATE_MASK;
 		}
-		
-		if ((err = info->fbops->fb_check_var(var, info)))
+		else if ((err = info->fbops->fb_check_var(var, info))) 
 			return err;
-
+			
 		if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
+			var->xoffset = xoffset;
+			var->yoffset = yoffset;
 			info->var = *var;
 			
 			if (con == info->currcon) {
 				if (info->fbops->fb_set_par)
 					info->fbops->fb_set_par(info);
 
-				if (info->fbops->fb_pan_display)
+				if (info->fbops->fb_pan_display) {
 					info->fbops->fb_pan_display(&info->var, con, info);
-
+				}
 				gen_set_disp(con, info);
 				fb_set_cmap(&info->cmap, 1, info);
 			}
-		
+
 			if (info->changevar)
 				info->changevar(con);
 		}
 	}
+	convert_var_to_logical(var);
 	return 0;
 }
 
@@ -139,13 +221,16 @@
 		display->dispsw_data = info->pseudo_palette;
 	}
 	display->var = info->var;
+	convert_var_to_logical(&display->var);
 
 	/*
 	 * If we are setting all the virtual consoles, also set
 	 * the defaults used to create new consoles.
 	 */
-	if (con < 0 || info->var.activate & FB_ACTIVATE_ALL)
-		info->disp->var = info->var;	
+	if (con < 0 || info->var.activate & FB_ACTIVATE_ALL) {
+		info->disp->var = info->var;
+		convert_var_to_logical(&info->disp->var);
+	}
 
 	if (info->var.bits_per_pixel == 24) {
 #ifdef FBCON_HAS_CFB24
@@ -157,7 +242,6 @@
 
 #ifdef FBCON_HAS_ACCEL
 	display->scrollmode = SCROLL_YNOMOVE;
-#ifdef FBCON_HAS_ROTATE
 	if (info->var.vmode & FB_VMODE_ROTATE_CW)
 		display->dispsw = &fbcon_rr;
 	else if (info->var.vmode & FB_VMODE_ROTATE_CCW)
@@ -165,7 +249,6 @@
 	else if (info->var.vmode & FB_VMODE_ROTATE_UD)
 		display->dispsw = &fbcon_ud;
 	else 
-#endif /* FBCON_HAS_ROTATE */
 		display->dispsw = &fbcon_accel;
 #else
 	display->dispsw = &fbcon_dummy;
@@ -201,11 +284,14 @@
 	int err;
     
 	if (con == info->currcon) {
+		convert_var_to_phys(&disp->var);
 		info->var.xoffset = disp->var.xoffset;
 		info->var.yoffset = disp->var.yoffset;
 		info->var.vmode	= disp->var.vmode;	
 		if (info->fbops->fb_pan_display) {
-			if ((err = info->fbops->fb_pan_display(&info->var, con, info)))
+			err = info->fbops->fb_pan_display(&info->var, con, info);
+			convert_var_to_logical(&disp->var);
+			if (err) 
 				return err;
 		}
 	}	
@@ -224,6 +310,7 @@
 		 * Save the old colormap and graphics mode.
 		 */
 		disp->var = info->var;
+		convert_var_to_logical(&disp->var);
 		if (disp->cmap.len)
 			fb_copy_cmap(&info->cmap, &disp->cmap, 0);
 	}
@@ -292,5 +379,7 @@
 EXPORT_SYMBOL(gen_update_var);
 EXPORT_SYMBOL(gen_switch);
 EXPORT_SYMBOL(fbgen_blank);
+EXPORT_SYMBOL(convert_var_to_logical);
+EXPORT_SYMBOL(convert_var_to_phys);
 
 MODULE_LICENSE("GPL");
diff -Naur linux-2.5.33/drivers/video/fbmem.c linux/drivers/video/fbmem.c
--- linux-2.5.33/drivers/video/fbmem.c	Wed Sep 11 18:28:43 2002
+++ linux/drivers/video/fbmem.c	Wed Sep 11 18:37:54 2002
@@ -476,7 +476,9 @@
 		return -ENODEV;
 	switch (cmd) {
 	case FBIOGET_VSCREENINFO:
-		return copy_to_user((void *) arg, &info->var,
+		var = info->var;
+		convert_var_to_logical(&var);
+		return copy_to_user((void *) arg, &var,
 				    sizeof(var)) ? -EFAULT : 0;
 	case FBIOPUT_VSCREENINFO:
 		if (copy_from_user(&var, (void *) arg, sizeof(var)))
@@ -504,8 +506,10 @@
 			return -EFAULT;
 		if (fb->fb_pan_display == NULL)
 			return (var.xoffset || var.yoffset) ? -EINVAL : 0;
+		convert_var_to_phys(&var);
 		if ((i=fb->fb_pan_display(&var, PROC_CONSOLE(info), info)))
 			return i;
+		convert_var_to_logical(&var);
 		if (copy_to_user((void *) arg, &var, sizeof(var)))
 			return -EFAULT;
 		return i;
diff -Naur linux-2.5.33/drivers/video/vesafb.c linux/drivers/video/vesafb.c
--- linux-2.5.33/drivers/video/vesafb.c	Wed Sep 11 18:29:11 2002
+++ linux/drivers/video/vesafb.c	Wed Sep 11 18:31:02 2002
@@ -27,8 +27,6 @@
 
 #include <video/fbcon.h>
 
-#include "fbcon-rotate.h"
-
 #define dac_reg	(0x3c8)
 #define dac_val	(0x3c9)
 
@@ -64,18 +62,12 @@
 static void            (*pmi_start)(void);
 static void            (*pmi_pal)(void);
 
-#ifdef FBCON_HAS_ROTATE
-static u32             xres;
-static u32             yres;
-static u32             vxres;
-static u32             vyres;
-#endif
 /* --------------------------------------------------------------------- */
 
 static int vesafb_pan_display(struct fb_var_screeninfo *var, int con,
                               struct fb_info *info)
 {
-	int offset, depth = (var->bits_per_pixel + 7)/8;
+	int offset;
 
 	if (!ypan)
 		return -EINVAL;
@@ -86,18 +78,6 @@
 	if ((ypan==1) && var->yoffset+var->yres > var->yres_virtual)
 		return -EINVAL;
 
-#ifdef FBCON_HAS_ROTATE
-	if (var->vmode & FB_VMODE_ROTATE_CW) 
-		offset = ((var->xoffset * info->fix.line_length) +
-			  ((var->yres_virtual - (var->yoffset + var->yres))) * depth) / 4;
-	else if (var->vmode & FB_VMODE_ROTATE_CCW)
-		offset = (((var->xres_virtual - (var->xoffset + var->xres)) * info->fix.line_length) +
-			  (var->yoffset * depth)) / 4;
-	else if (var->vmode & FB_VMODE_ROTATE_UD) 
-		offset = (((var->yres_virtual - (var->yoffset + var->yres)) * info->fix.line_length) +
-			  ((var->xres_virtual - (var->xoffset + var->xres))) * depth) / 4;
-	else
-#endif
 		offset = (var->yoffset * info->fix.line_length + var->xoffset) / 4;
 
         __asm__ __volatile__(
@@ -193,43 +173,11 @@
     return 0;
 }
 
-static int vesafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
-{
-#ifdef FBCON_HAS_ROTATE
-	u32 vmode;
-
-	vmode = var->vmode;
-	*var = info->var;
-	if (vmode & (FB_VMODE_ROTATE_CW | FB_VMODE_ROTATE_CCW)) {
-		var->xres = yres;
-		var->yres = xres;
-		var->xres_virtual = vyres;
-		var->yres_virtual = vxres;
-	}
-	else {
-		var->xres = xres;
-		var->yres = yres;
-		var->xres_virtual = vxres;
-		var->yres_virtual = vyres;
-	}		
-	vmode &= FB_ROTATE_MASK;
-	vmode |= info->var.vmode & ~FB_ROTATE_MASK;
-	var->vmode = vmode;
-#else
-	*var = info->var;
-#endif
-
-	var->xoffset = 0;
-	var->yoffset = 0;
-	return 0;
-}
-
 static struct fb_ops vesafb_ops = {
 	.owner		= THIS_MODULE,
 	.fb_set_var	= gen_set_var,
 	.fb_get_cmap	= gen_get_cmap,
 	.fb_set_cmap	= gen_set_cmap,
-	.fb_check_var   = vesafb_check_var,
 	.fb_setcolreg	= vesafb_setcolreg,
 	.fb_pan_display	= vesafb_pan_display,
 	.fb_fillrect	= cfb_fillrect,
@@ -352,19 +300,6 @@
 		ypan = 0;
 	}
 	
-#ifdef FBCON_HAS_ROTATE
-	xres = vesafb_defined.xres;
-	yres = vesafb_defined.yres;
-	vxres = vesafb_defined.xres_virtual;
-	vyres = vesafb_defined.yres_virtual;
-	if (vesafb_defined.vmode & (FB_VMODE_ROTATE_CW | FB_VMODE_ROTATE_CCW)) {
-		vesafb_defined.xres = yres;
-		vesafb_defined.yres = xres;
-		vesafb_defined.xres_virtual = vyres;
-		vesafb_defined.yres_virtual = vxres;
-	}
-#endif
-
 	/* some dummy values for timing to make fbset happy */
 	vesafb_defined.pixclock     = 10000000 / vesafb_defined.xres * 1000 / vesafb_defined.yres;
 	vesafb_defined.left_margin  = (vesafb_defined.xres / 8) & 0xf8;
diff -Naur linux-2.5.33/include/linux/fb.h linux/include/linux/fb.h
--- linux-2.5.33/include/linux/fb.h	Wed Sep 11 18:29:57 2002
+++ linux/include/linux/fb.h	Wed Sep 11 18:32:01 2002
@@ -419,6 +419,8 @@
 extern int fb_blank(int blank, struct fb_info *info);
 extern int gen_switch(int con, struct fb_info *info);
 extern void gen_set_disp(int con, struct fb_info *info);
+extern void convert_var_to_logical(struct fb_var_screeninfo *var);
+extern void convert_var_to_phys(struct fb_var_screeninfo *var);
 
 /* drivers/video/fbmem.c */
 extern int register_framebuffer(struct fb_info *fb_info);

  reply	other threads:[~2002-09-11 19:49 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-09-10 20:44 Portrait display mode Otto Wyss
2002-09-10 22:22 ` Antonino Daplas
2002-09-11  6:38   ` Geert Uytterhoeven
2002-09-11 19:50     ` Antonino Daplas [this message]
2002-09-11 20:18   ` Otto Wyss
2002-09-12 17:36     ` Antonino Daplas
     [not found]     ` <1031850411.1810.0.camel@daplas>
     [not found]       ` <3D84D045.404EA715@bluewin.ch>
2002-09-16  3:07         ` Antonino Daplas
2002-09-17 17:50           ` Otto Wyss
2002-09-17 20:13             ` Antonino Daplas

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1031773864.562.3.camel@daplas \
    --to=adaplas@pol.net \
    --cc=geert@linux-m68k.org \
    --cc=linux-fbdev-devel@lists.sourceforge.net \
    --cc=otto.wyss@bluewin.ch \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.