lkml.org 
[lkml]   [1998]   [Aug]   [8]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[patch #2] vesafb: panning and palette changes using bios
On Fri, 7 Aug 1998, Alex Buell wrote:

> > Next step ahead: vesafb uses the protected mode interface for palette
> > changes too.
>
> Does it only does this on initialisation?

No, for all palette changes. This should make gfx boards which have not
the standard vga palette registers (MediaGX?) work with vesafb. Here is
the patch (against vanilla 2.1.115).

Gerd


BTW: Is there any way to disable virtual display in XF68_FBDev? With ypan
enabled I get a 1024x4096 sized virtual screen. This is annonying,
becauce some x11 apps center dialog-boxes on the (virtual) screen,
and now you have to scroll down alot to find it...
I've tried to add "virtual 1024 768" to XF86Config, but it did'nt
work :-(

-----------------------------------------------------------------
Binary files kernel/2.1.115/Documentation/fb/.vesafb.txt.swp and linux/Documentation/fb/.vesafb.txt.swp differ
diff -urN kernel/2.1.115/Documentation/fb/vesafb.txt linux/Documentation/fb/vesafb.txt
--- kernel/2.1.115/Documentation/fb/vesafb.txt Thu Jul 30 23:04:01 1998
+++ linux/Documentation/fb/vesafb.txt Sat Aug 8 11:13:18 1998
@@ -30,37 +30,56 @@
==============

Switching modes is done using the vga=... boot parameter. Read
-Documentation/svga.txt for details. With vesafb both text and
-graphics modes work. Text modes are handled by vgafb, graphic modes
-by the new vesafb.c.
+Documentation/svga.txt for details.

-The graphic modes are not in the list which you get if you boot with
+You should compile in both vgacon (for text mode) and vesafb (for
+graphics mode). Which of them takes over the console depends on
+whenever the specified mode is text or graphics.
+
+The graphic modes are NOT in the list which you get if you boot with
vga=ask and hit return. Here are some mode numbers:

- | 640x480 800x600 1024x768
-----+---------------------------
-256 | 0x101 0x103 0x105
-32k | 0x110 0x113 0x116
-64k | 0x111 0x114 0x117
-16M | 0x112 0x115 0x118
-
-Note 1: this are the VESA mode numbers. The video mode select code
- expects 0x200 + VESA mode number.
-Note 2: lilo can't handle hex, for booting with "vga=??" you have to
- transform the numbers to decimal.
-
-
-Speed it up!
-============
-
-Check /usr/src/linux/Documentation/mtrr.txt, enabling write-combining
-for the framebuffer memory gives a performance boost.
-
-There are two ways to do console scrolling: redraw the screen
-completely, or by copying around the video memory. You can select one
-of them using the kernel command line: video=vesa:redraw or
-video=vesa:memmove. redraw is the default, becauce this one works
-faster on my box.
+ | 640x480 800x600 1024x768 1280x1024
+----+-------------------------------------
+256 | 0x101 0x103 0x105 0x107
+32k | 0x110 0x113 0x116 0x119
+64k | 0x111 0x114 0x117 0x11A
+16M | 0x112 0x115 0x118 0x11B
+
+This are the VESA mode numbers. The video mode select code expects
+0x200 + VESA mode number. Therefore you have to enter "305" at the
+"vga=ask" prompt to boot into 1024x768x8.
+
+If this does'nt work, this might be becauce your BIOS does not support
+linear framebuffers or becauce it does'nt support this mode at all.
+Even if your board does, it might be the BIOS does not. VESA BIOS
+Extentions v2.0 are required, 1.2 is NOT sufficient. You'll get a
+"bad mode number" message if something goes wrong.
+
+Note: LILO can't handle hex, for booting directly with "vga=mode-number"
+ you have to transform the numbers to decimal.
+
+
+Configuration
+=============
+
+You can pass kernel command line options to vesafb with
+"video=vesa:option1". Multiple options should be separated
+by comma. Accepted options:
+
+invers - no comment...
+redraw - scroll by redrawing the affected part of the screen
+ (default).
+ypan - enable display panning using the VESA protected mode
+ interface. This enables the Shift-PgUp scrollback
+ thing and greatly speeds up fullscreen scrolling.
+ It is slower than "redraw" when scrolling only a halve
+ screen.
+ywrap - If your gfx board supports wrap-around, use this one
+ instead of ypan.
+nopal - Don't use the protected mode interface for palette
+ changes. vesafb will use the standard vga registers
+ instead.


Have fun!
diff -urN kernel/2.1.115/arch/i386/boot/video.S linux/arch/i386/boot/video.S
--- kernel/2.1.115/arch/i386/boot/video.S Thu Jul 30 23:03:41 1998
+++ linux/arch/i386/boot/video.S Mon Jul 27 23:09:06 1998
@@ -85,6 +85,9 @@
#define PARAM_LFB_SIZE 0x1c
#define PARAM_LFB_LINELENGTH 0x24
#define PARAM_LFB_COLORS 0x26
+#define PARAM_VESAPM_SEG 0x2e
+#define PARAM_VESAPM_OFF 0x30
+#define PARAM_LFB_PAGES 0x32

! Define DO_STORE according to CONFIG_VIDEO_RETAIN
#ifdef CONFIG_VIDEO_RETAIN
@@ -236,13 +239,14 @@
seg fs
mov [PARAM_LFB_DEPTH],ax

- mov eax,(di+40)
+ mov al,(di+29)
+ mov ah,#0
seg fs
- mov [PARAM_LFB_BASE],eax
+ mov [PARAM_LFB_PAGES],ax

- mov eax,(di+44)
+ mov eax,(di+40)
seg fs
- mov [PARAM_LFB_SIZE],eax
+ mov [PARAM_LFB_BASE],eax

mov eax,(di+31)
seg fs
@@ -251,7 +255,30 @@
mov eax,(di+35)
seg fs
mov [PARAM_LFB_COLORS+4],eax
-
+
+ ! get video mem size
+ lea di,modelist+1024
+ mov ax,#0x4f00
+ int 0x10
+
+ xor eax,eax
+ mov ax,(di+18)
+ seg fs
+ mov [PARAM_LFB_SIZE],eax
+
+ ! get protected mode interface informations
+ mov ax,#0x4f0a
+ xor bx,bx
+ xor di,di
+ int 0x10
+ cmp ax,#0x004f
+ jnz no_pm
+ seg fs
+ mov [PARAM_VESAPM_SEG],es
+ seg fs
+ mov [PARAM_VESAPM_OFF],di
+
+no_pm:
ret

!
diff -urN kernel/2.1.115/drivers/video/vesafb.c linux/drivers/video/vesafb.c
--- kernel/2.1.115/drivers/video/vesafb.c Mon Aug 3 00:33:31 1998
+++ linux/drivers/video/vesafb.c Sat Aug 8 10:05:42 1998
@@ -21,8 +21,10 @@
#include <linux/selection.h>
#include <linux/ioport.h>
#include <linux/init.h>
+#include <linux/config.h>

#include <asm/io.h>
+#include <asm/mtrr.h>

#include "fbcon.h"
#include "fbcon-cfb8.h"
@@ -75,19 +77,18 @@

static struct display disp;
static struct fb_info fb_info;
-static struct { u_char red, green, blue, pad; } palette[256];
+static struct { u_char blue, green, red, pad; } palette[256];

-static int inverse = 0;
+static int inverse = 0;
+static int currcon = 0;

-static int currcon = 0;
+static int pmi_setpal = 1; /* pmi for palette changes ??? */
+static int ypan = 0;
+static int ywrap = 0;
+static unsigned short *pmi_base = 0;
+static void (*pmi_start)(void);
+static void (*pmi_pal)(void);

-/* --------------------------------------------------------------------- */
-/* speed up scrolling */
-
-#define USE_REDRAW 1
-#define USE_MEMMOVE 2
-
-static int vesafb_scroll = USE_REDRAW;
static struct display_switch vesafb_sw;

/* --------------------------------------------------------------------- */
@@ -111,8 +112,38 @@
return(0);
}

-static int fb_update_var(int con, struct fb_info *info)
+static int vesafb_pan_display(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info)
+{
+ int offset;
+
+ if (var->xoffset)
+ return -EINVAL;
+ if (ypan && var->yoffset+var->yres > var->yres_virtual)
+ return -EINVAL;
+ if (ywrap && var->yoffset > var->yres_virtual)
+ return -EINVAL;
+
+ /* printk("vesafb: pan: x,y=%d,%d\n",var->xoffset,var->yoffset); */
+ offset = (var->yoffset * video_linelength + var->xoffset) / 4;
+
+ __asm__ __volatile__(
+ "call *(%%edi)"
+ : /* no return value */
+ : "a" (0x4f07), /* EAX */
+ "b" (0), /* EBX */
+ "c" (offset), /* ECX */
+ "d" (offset >> 16), /* EDX */
+ "D" (&pmi_start)); /* EDI */
+ return 0;
+}
+
+static int vesafb_update_var(int con, struct fb_info *info)
{
+ if (con == currcon && (ywrap || ypan)) {
+ struct fb_var_screeninfo *var = &fb_display[currcon].var;
+ return vesafb_pan_display(var,con,info);
+ }
return 0;
}

@@ -126,9 +157,9 @@
fix->smem_len=video_size;
fix->type = video_type;
fix->visual = video_visual;
- fix->xpanstep=0;
- fix->ypanstep=0;
- fix->ywrapstep=0;
+ fix->xpanstep = 0;
+ fix->ypanstep = (ywrap || ypan) ? 1 : 0;
+ fix->ywrapstep = ywrap ? 1 : 0;
fix->line_length=video_linelength;
return 0;
}
@@ -191,7 +222,7 @@
}
memcpy(&vesafb_sw, sw, sizeof(*sw));
display->dispsw = &vesafb_sw;
- if (vesafb_scroll == USE_REDRAW) {
+ if (!ypan && !ywrap) {
display->scrollmode = SCROLL_YREDRAW;
vesafb_sw.bmove = fbcon_redraw_bmove;
}
@@ -222,6 +253,27 @@
return 0;
}

+static void vesa_setpalette(int regno)
+{
+ if (pmi_setpal) {
+ __asm__ __volatile__(
+ "call *(%%esi)"
+ : /* no return value */
+ : "a" (0x4f09), /* EAX */
+ "b" (0), /* EBX */
+ "c" (1), /* ECX */
+ "d" (regno), /* EDX */
+ "D" (palette+regno), /* EDI */
+ "S" (&pmi_pal)); /* ESI */
+ } else {
+ /* without protected mode interface, try VGA registers... */
+ outb_p(regno, dac_reg);
+ outb_p(palette[regno].red, dac_val);
+ outb_p(palette[regno].green, dac_val);
+ outb_p(palette[regno].blue, dac_val);
+ }
+}
+
static int vesa_setcolreg(unsigned regno, unsigned red, unsigned green,
unsigned blue, unsigned transp,
struct fb_info *fb_info)
@@ -243,11 +295,7 @@
switch (video_bpp) {
#ifdef FBCON_HAS_CFB8
case 8:
- /* Hmm, can we do it _always_ this way ??? */
- outb_p(regno, dac_reg);
- outb_p(red, dac_val);
- outb_p(green, dac_val);
- outb_p(blue, dac_val);
+ vesa_setpalette(regno);
break;
#endif
#ifdef FBCON_HAS_CFB16
@@ -317,13 +365,6 @@
return 0;
}

-static int vesafb_pan_display(struct fb_var_screeninfo *var, int con,
- struct fb_info *info)
-{
- /* no panning */
- return -EINVAL;
-}
-
static int vesafb_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg, int con,
struct fb_info *info)
@@ -360,9 +401,13 @@
if (! strcmp(this_opt, "inverse"))
inverse=1;
else if (! strcmp(this_opt, "redraw"))
- vesafb_scroll = USE_REDRAW;
- else if (! strcmp(this_opt, "memmove"))
- vesafb_scroll = USE_MEMMOVE;
+ ywrap=0,ypan=0;
+ else if (! strcmp(this_opt, "ypan"))
+ ywrap=0,ypan=1;
+ else if (! strcmp(this_opt, "ywrap"))
+ ywrap=1,ypan=0;
+ else if (! strcmp(this_opt, "nopal"))
+ pmi_setpal=0;
else if (!strncmp(this_opt, "font:", 5))
strcpy(fb_info.fontname, this_opt+5);
}
@@ -378,6 +423,7 @@
currcon = con;
/* Install new colormap */
do_install_cmap(con, info);
+ vesafb_update_var(con,info);
return 0;
}

@@ -400,24 +446,57 @@
video_width = screen_info.lfb_width;
video_height = screen_info.lfb_height;
video_linelength = screen_info.lfb_linelength;
- video_size = video_linelength * video_height /* screen_info.lfb_size */;
+ video_size = screen_info.lfb_size * 65536;
video_visual = (video_bpp == 8) ?
FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
video_vbase = ioremap((unsigned long)video_base, video_size);

- printk("vesafb: %dx%dx%d, linelength=%d\n",
- video_width, video_height, video_bpp, video_linelength);
- printk("vesafb: framebuffer at 0x%p, mapped to 0x%p, size %d\n",
- video_base, video_vbase, video_size);
- if (vesafb_scroll == USE_REDRAW) printk("vesafb: scrolling=redraw\n");
- if (vesafb_scroll == USE_MEMMOVE) printk("vesafb: scrolling=memmove\n");
-
+ printk("vesafb: framebuffer at 0x%p, mapped to 0x%p, size %dk\n",
+ video_base, video_vbase, video_size/1024);
+ printk("vesafb: mode is %dx%dx%d, linelength=%d, pages=%d\n",
+ video_width, video_height, video_bpp, video_linelength, screen_info.pages);
+
+ if (screen_info.vesapm_seg) {
+ printk("vesafb: protected mode interface info at %04x:%04x\n",
+ screen_info.vesapm_seg,screen_info.vesapm_off);
+ }
+
+ if (screen_info.vesapm_seg < 0xc000)
+ ywrap = ypan = pmi_setpal = 0; /* not available or some DOS TSR ... */
+
+ if (ypan || ywrap || pmi_setpal) {
+ pmi_base = (unsigned short*)(__PAGE_OFFSET+((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off);
+ pmi_start = (void*)((char*)pmi_base + pmi_base[1]);
+ pmi_pal = (void*)((char*)pmi_base + pmi_base[2]);
+ printk("vesafb: pmi: set display start = %p, set palette = %p\n",pmi_start,pmi_pal);
+ if (pmi_base[3]) {
+ printk("vesafb: pmi: ports = ");
+ for (i = pmi_base[3]/2; pmi_base[i] != 0xffff; i++)
+ printk("%x ",pmi_base[i]);
+ printk(", memory = ");
+ for (i++; pmi_base[i] != 0xffff; i+=3)
+ printk("%lx+%x ",
+ ((unsigned long)pmi_base[i]<<16)
+ + pmi_base[i+1], pmi_base[i+3]);
+ printk("\n");
+ }
+ }
+
vesafb_defined.xres=video_width;
vesafb_defined.yres=video_height;
vesafb_defined.xres_virtual=video_width;
- vesafb_defined.yres_virtual=video_height;
+ vesafb_defined.yres_virtual=video_size / video_linelength;
vesafb_defined.bits_per_pixel=video_bpp;

+ if ((ypan || ywrap) && vesafb_defined.yres_virtual > video_height) {
+ printk("vesafb: scrolling: %s using protected mode interface, yres_virtual=%d\n",
+ ywrap ? "ywrap" : "ypan",vesafb_defined.yres_virtual);
+ } else {
+ printk("vesafb: scrolling: redraw\n");
+ vesafb_defined.yres_virtual = video_height;
+ ypan = ywrap = 0;
+ }
+
if (video_bpp > 8) {
vesafb_defined.red.offset = screen_info.red_pos;
vesafb_defined.red.length = screen_info.red_size;
@@ -451,6 +530,9 @@
video_cmap_len = 256;
}
request_region(0x3c0, 32, "vga+");
+#ifdef CONFIG_MTRR
+ mtrr_add((unsigned long)video_base, video_size, MTRR_TYPE_WRCOMB, 1);
+#endif

strcpy(fb_info.modename, "VESA VGA");
fb_info.changevar = NULL;
@@ -458,7 +540,7 @@
fb_info.fbops = &vesafb_ops;
fb_info.disp=&disp;
fb_info.switch_con=&vesafb_switch;
- fb_info.updatevar=&fb_update_var;
+ fb_info.updatevar=&vesafb_update_var;
fb_info.blank=&vesafb_blank;
vesafb_set_disp(-1);

diff -urN kernel/2.1.115/include/linux/tty.h linux/include/linux/tty.h
--- kernel/2.1.115/include/linux/tty.h Fri Aug 7 22:06:16 1998
+++ linux/include/linux/tty.h Fri Aug 7 22:10:14 1998
@@ -87,7 +87,10 @@
unsigned char blue_pos; /* 0x2b */
unsigned char rsvd_size; /* 0x2c */
unsigned char rsvd_pos; /* 0x2d */
- /* 0x2e -- 0x3f reserved for future expansion */
+ unsigned short vesapm_seg; /* 0x2e */
+ unsigned short vesapm_off; /* 0x30 */
+ unsigned short pages; /* 0x32 */
+ /* 0x34 -- 0x3f reserved for future expansion */
};

extern struct screen_info screen_info;


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.altern.org/andrebalsa/doc/lkml-faq.html

\
 
 \ /
  Last update: 2005-03-22 13:43    [W:0.557 / U:0.036 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site