linux-fbdev.vger.kernel.org archive mirror
 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).