* Re: [Linux-fbdev-devel] [PATCH] FBDev: vga16fb port
@ 2002-12-04 10:38 Petr Vandrovec
0 siblings, 0 replies; 22+ messages in thread
From: Petr Vandrovec @ 2002-12-04 10:38 UTC (permalink / raw)
To: Antonino Daplas
Cc: James Simmons, linux-fbdev-devel, Linux Kernel Mailing List,
luther
On 4 Dec 02 at 17:08, Antonino Daplas wrote:
> On Wed, 2002-12-04 at 12:32, Sven Luther wrote:
> > On Tue, Dec 03, 2002 at 05:22:35PM +0500, Antonino Daplas wrote:
> > > > 2) The ability to go back to vga text mode on close of /dev/fb.
> > > > Yes fbdev/fbcon supports that now.
> > >
> > > I'll take a stab at writing VGA save/restore routines which hopefully is
> > > generic enough to be used by various hardware. No promises though, VGA
> > > programming gives me a headache :(
> >
> > BTW, i am writing a fbdev for a card where the docs tell me to disable
> > vga output before enabling graphical output. Does i need to do this in
> > the fbdev i write, or is it already handled by the vga layer, or
> > whatever ?
>
> Most cards with a VGA core needs to disable the VGA output before going
> to graphics mode. Disabling VGA output is hardware specific, and is
> usually automatic when you go to graphics mode.
>
> Because James wrote the fb framework to be very modular, then you must
> be careful to save/restore the initial video state when loading or
> unloading. Theoretically, a driver should load, but not go to graphics
> mode immediately. Only upon a call to xxxfb_set_par() should the driver
> do so. Before going to graphics mode, that's were you save the initial
> state. Have a reference count or something to keep track of the number
> of users, and when this reference count becomes zero, restore the
> initial state. You should be able to do this by hooking these routines
> in fb_open() and fb_release().
FYI, I'm not going to support any hardware restoration on last fb_release,
nor hardware init only after first fb_open in matroxfb. Either you want
this driver, or not. Besides that I do not see any reason to have such
code, matroxfb provides multiple framebuffers, and to get them
all work, hardware must be in known state, it is impossible to program
only half of chip and expect that it will somehow work. It will crash,
lock your PCI bus, or even commits suicide.
And I'm sure that other possible solution, that opening /dev/fb1
(or /dev/videoX or /dev/dri/mga) will cause your vgacon picture to
disappear, violates principle of least surprise.
Best regards,
Petr Vandrovec
vandrove@vc.cvut.cz
^ permalink raw reply [flat|nested] 22+ messages in thread* [PATCH] FBDev: vga16fb port
@ 2002-11-28 7:24 Antonino Daplas
2002-12-02 20:31 ` [Linux-fbdev-devel] " James Simmons
0 siblings, 1 reply; 22+ messages in thread
From: Antonino Daplas @ 2002-11-28 7:24 UTC (permalink / raw)
To: Linux Fbdev development list; +Cc: Linux Kernel Mailing List
[-- Attachment #1: Type: text/plain, Size: 187 bytes --]
Attached is a patch against 2.5.49 + James Simmons' latest fbdev.diff.
Added support for logo drawing.
Fixed vga16fb_imageblit() limitation of 8-pixel wide bitmap blitting
only.
Tony
[-- Attachment #2: vga16fb.diff --]
[-- Type: text/x-patch, Size: 6370 bytes --]
diff -Naur linux-2.5.49/drivers/video/vga16fb.c linux/drivers/video/vga16fb.c
--- linux-2.5.49/drivers/video/vga16fb.c 2002-11-28 06:44:07.000000000 +0000
+++ linux/drivers/video/vga16fb.c 2002-11-28 06:47:06.000000000 +0000
@@ -1062,8 +1062,10 @@
}
} else {
line_ofs = info->fix.line_length - area->width;
- dest = info->screen_base + area->dx + area->width + (area->dy + height - 1) * info->fix.line_length;
- src = info->screen_base + area->sx + area->width + (area->sy + height - 1) * info->fix.line_length;
+ dest = info->screen_base + area->dx + area->width +
+ (area->dy + height - 1) * info->fix.line_length;
+ src = info->screen_base + area->sx + area->width +
+ (area->sy + height - 1) * info->fix.line_length;
while (height--) {
for (x = 0; x < area->width; x++) {
--src;
@@ -1147,8 +1149,10 @@
dst += line_ofs;
}
} else {
- dst = info->screen_base + (area->dx/8) + width + (area->dy + height - 1) * info->fix.line_length;
- src = info->screen_base + (area->sx/8) + width + (area->sy + height - 1) * info->fix.line_length;
+ dst = info->screen_base + (area->dx/8) + width +
+ (area->dy + height - 1) * info->fix.line_length;
+ src = info->screen_base + (area->sx/8) + width +
+ (area->sy + height - 1) * info->fix.line_length;
while (height--) {
for (x = 0; x < width; x++) {
dst--;
@@ -1222,65 +1226,123 @@
setindex(oldindex);
}
-void vga16fb_imageblit(struct fb_info *info, struct fb_image *image)
+void vga_imageblit_expand(struct fb_info *info, struct fb_image *image)
{
- char *where = info->screen_base + (image->dx/image->width) + image->dy * info->fix.line_length;
+ char *where = info->screen_base + (image->dx/8) +
+ image->dy * info->fix.line_length;
struct vga16fb_par *par = (struct vga16fb_par *) info->par;
- u8 *cdat = image->data;
- int y;
+ u8 *cdat = image->data, *dst;
+ int x, y;
switch (info->fix.type) {
- case FB_TYPE_VGA_PLANES:
- if (info->fix.type_aux == FB_AUX_VGA_PLANES_VGA4) {
- if (par->isVGA) {
- setmode(2);
- setop(0);
- setsr(0xf);
- setcolor(image->fg_color);
- selectmask();
+ case FB_TYPE_VGA_PLANES:
+ if (info->fix.type_aux == FB_AUX_VGA_PLANES_VGA4) {
+ if (par->isVGA) {
+ setmode(2);
+ setop(0);
+ setsr(0xf);
+ setcolor(image->fg_color);
+ selectmask();
+
+ setmask(0xff);
+ writeb(image->bg_color, where);
+ rmb();
+ readb(where); /* fill latches */
+ setmode(3);
+ wmb();
+ for (y = 0; y < image->height; y++) {
+ dst = where;
+ for (x = image->width/8; x--;)
+ writeb(*cdat++, dst++);
+ where += info->fix.line_length;
+ }
+ wmb();
+ } else {
+ setmode(0);
+ setop(0);
+ setsr(0xf);
+ setcolor(image->bg_color);
+ selectmask();
+
+ setmask(0xff);
+ for (y = 0; y < image->height; y++) {
+ dst = where;
+ for (x=image->width/8; x--;){
+ rmw(dst);
+ setcolor(image->fg_color);
+ selectmask();
+ if (*cdat) {
+ setmask(*cdat++);
+ rmw(dst++);
+ }
+ }
+ where += info->fix.line_length;
+ }
+ }
+ } else
+ vga_8planes_imageblit(info, image);
+ break;
+#ifdef FBCON_HAS_VGA
+ case FB_TYPE_TEXT:
+ break;
+#endif
+ case FB_TYPE_PACKED_PIXELS:
+ default:
+ cfb_imageblit(info, image);
+ break;
+ }
+}
- setmask(0xff);
- writeb(image->bg_color, where);
- rmb();
- readb(where); /* fill latches */
- setmode(3);
- wmb();
- for (y = 0; y < image->height; y++, where += info->fix.line_length)
- writeb(cdat[y], where);
- wmb();
- } else {
- setmode(0);
- setop(0);
- setsr(0xf);
- setcolor(image->bg_color);
- selectmask();
+void vga_imageblit_color(struct fb_info *info, struct fb_image *image)
+{
+ /*
+ * Draw logo
+ */
+ struct vga16fb_par *par = (struct vga16fb_par *) info->par;
+ char *where = info->screen_base + image->dy * info->fix.line_length +
+ image->dx/8;
+ char *cdat = image->data, *dst;
+ int x, y;
- setmask(0xff);
- for (y = 0; y < image->height; y++, where += info->fix.line_length)
- rmw(where);
+ switch (info->fix.type) {
+ case FB_TYPE_VGA_PLANES:
+ if (info->fix.type_aux == FB_AUX_VGA_PLANES_VGA4 &&
+ par->isVGA) {
+ setsr(0xf);
+ setop(0);
+ setmode(0);
+
+ for (y = 0; y < image->height; y++) {
+ for (x = 0; x < image->width; x++) {
+ dst = where + x/8;
- where -= info->fix.line_length * y;
- setcolor(image->fg_color);
+ setcolor(*cdat);
selectmask();
- for (y = 0; y < image->height; y++, where += info->fix.line_length)
- if (cdat[y]) {
- setmask(cdat[y]);
- rmw(where);
- }
+ setmask(1 << (7 - (x % 8)));
+ fb_readb(dst);
+ fb_writeb(0, dst);
+
+ cdat++;
}
- } else
- vga_8planes_imageblit(info, image);
- break;
-#ifdef FBCON_HAS_VGA
- case FB_TYPE_TEXT:
- break;
-#endif
- case FB_TYPE_PACKED_PIXELS:
- default:
- cfb_imageblit(info, image);
- break;
+ where += info->fix.line_length;
+ }
+ }
+ break;
+ case FB_TYPE_PACKED_PIXELS:
+ cfb_imageblit(info, image);
+ break;
+ default:
+ break;
}
}
+
+void vga16fb_imageblit(struct fb_info *info, struct fb_image *image)
+{
+ if (image->depth == 1)
+ vga_imageblit_expand(info, image);
+ else if (image->depth == info->var.bits_per_pixel)
+ vga_imageblit_color(info, image);
+}
static struct fb_ops vga16fb_ops = {
.owner = THIS_MODULE,
@@ -1292,6 +1354,7 @@
.fb_fillrect = vga16fb_fillrect,
.fb_copyarea = vga16fb_copyarea,
.fb_imageblit = vga16fb_imageblit,
+ .fb_cursor = soft_cursor,
};
int vga16fb_setup(char *options)
@@ -1343,6 +1406,11 @@
i = (vga16fb_defined.bits_per_pixel == 8) ? 256 : 16;
fb_alloc_cmap(&vga16fb.cmap, i, 0);
+ if (vga16fb_check_var(&vga16fb.var, &vga16fb))
+ return -EINVAL;
+
+ vga16fb_update_fix(&vga16fb);
+
if (register_framebuffer(&vga16fb) < 0) {
iounmap(vga16fb.screen_base);
return -EINVAL;
^ permalink raw reply [flat|nested] 22+ messages in thread* Re: [Linux-fbdev-devel] [PATCH] FBDev: vga16fb port 2002-11-28 7:24 Antonino Daplas @ 2002-12-02 20:31 ` James Simmons 2002-12-03 12:22 ` Antonino Daplas 2002-12-03 20:49 ` Antonino Daplas 0 siblings, 2 replies; 22+ messages in thread From: James Simmons @ 2002-12-02 20:31 UTC (permalink / raw) To: Antonino Daplas; +Cc: Linux Fbdev development list, Linux Kernel Mailing List > Attached is a patch against 2.5.49 + James Simmons' latest fbdev.diff. > > Added support for logo drawing. > Fixed vga16fb_imageblit() limitation of 8-pixel wide bitmap blitting > only. Applied and tested :-=) The only weird thing is it drew the logo twice when I don't have a SMP laptop. It works other than that. P.S Things I like to get done for the vga16fb driver. 1) Its own read and write functions to fake a linear framebuffer. 2) The ability to go back to vga text mode on close of /dev/fb. Yes fbdev/fbcon supports that now. ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [Linux-fbdev-devel] [PATCH] FBDev: vga16fb port 2002-12-02 20:31 ` [Linux-fbdev-devel] " James Simmons @ 2002-12-03 12:22 ` Antonino Daplas 2002-12-03 15:47 ` Alan Cox 2002-12-04 7:32 ` Sven Luther 2002-12-03 20:49 ` Antonino Daplas 1 sibling, 2 replies; 22+ messages in thread From: Antonino Daplas @ 2002-12-03 12:22 UTC (permalink / raw) To: James Simmons; +Cc: Linux Fbdev development list, Linux Kernel Mailing List On Tue, 2002-12-03 at 01:31, James Simmons wrote: > > > Attached is a patch against 2.5.49 + James Simmons' latest fbdev.diff. > > > > Added support for logo drawing. > > Fixed vga16fb_imageblit() limitation of 8-pixel wide bitmap blitting > > only. > > Applied and tested :-=) The only weird thing is it drew the logo twice > when I don't have a SMP laptop. It works other than that. > Should be expected if the fbcon_show_logo() patch did not take. I'm resubmitting another patch in one of my replies. > P.S > Things I like to get done for the vga16fb driver. > > 1) Its own read and write functions to fake a linear framebuffer. Should be doable with fb_write and fb_read, but with mmap, the app still needs to know the VGA format. > 2) The ability to go back to vga text mode on close of /dev/fb. > Yes fbdev/fbcon supports that now. I'll take a stab at writing VGA save/restore routines which hopefully is generic enough to be used by various hardware. No promises though, VGA programming gives me a headache :( Tony ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [Linux-fbdev-devel] [PATCH] FBDev: vga16fb port 2002-12-03 12:22 ` Antonino Daplas @ 2002-12-03 15:47 ` Alan Cox 2002-12-03 20:50 ` Antonino Daplas 2002-12-03 22:02 ` James Simmons 2002-12-04 7:32 ` Sven Luther 1 sibling, 2 replies; 22+ messages in thread From: Alan Cox @ 2002-12-03 15:47 UTC (permalink / raw) To: Antonino Daplas Cc: James Simmons, Linux Fbdev development list, Linux Kernel Mailing List On Tue, 2002-12-03 at 12:22, Antonino Daplas wrote: > > Things I like to get done for the vga16fb driver. > > > > 1) Its own read and write functions to fake a linear framebuffer. > Should be doable with fb_write and fb_read, but with mmap, the app still > needs to know the VGA format. I question whether thats something that belongs anywhere near the kernel. Ben Pfaff wrote a fine library for vga16 hackery (BOGL) and it combines very nicely with the fb driver. > > 2) The ability to go back to vga text mode on close of /dev/fb. > > Yes fbdev/fbcon supports that now. > > I'll take a stab at writing VGA save/restore routines which hopefully is > generic enough to be used by various hardware. No promises though, VGA > programming gives me a headache :( You can pull the code out of the old svgalib library. Since its not doing any card specific stuff the generic vga->text restore ought to do the right thing. ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [Linux-fbdev-devel] [PATCH] FBDev: vga16fb port 2002-12-03 15:47 ` Alan Cox @ 2002-12-03 20:50 ` Antonino Daplas 2002-12-03 22:01 ` James Simmons 2002-12-03 22:02 ` James Simmons 1 sibling, 1 reply; 22+ messages in thread From: Antonino Daplas @ 2002-12-03 20:50 UTC (permalink / raw) To: Alan Cox Cc: James Simmons, Linux Fbdev development list, Linux Kernel Mailing List On Tue, 2002-12-03 at 20:47, Alan Cox wrote: > On Tue, 2002-12-03 at 12:22, Antonino Daplas wrote: > > > Things I like to get done for the vga16fb driver. > > > > > > 1) Its own read and write functions to fake a linear framebuffer. > > Should be doable with fb_write and fb_read, but with mmap, the app still > > needs to know the VGA format. > > I question whether thats something that belongs anywhere near the > kernel. Ben Pfaff wrote a fine library for vga16 hackery (BOGL) and it > combines very nicely with the fb driver. I kinda agree with this. Most fb apps use mmap to access the framebuffer, so it's almost impossible to fake a linear framebuffer from a planar one. > > > > 2) The ability to go back to vga text mode on close of /dev/fb. > > > Yes fbdev/fbcon supports that now. > > > > I'll take a stab at writing VGA save/restore routines which hopefully is > > generic enough to be used by various hardware. No promises though, VGA > > programming gives me a headache :( > > You can pull the code out of the old svgalib library. Since its not > doing any card specific stuff the generic vga->text restore ought to do > the right thing. > Thanks for the info. I think I'll review this one to see what I missed. Tony ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [Linux-fbdev-devel] [PATCH] FBDev: vga16fb port 2002-12-03 20:50 ` Antonino Daplas @ 2002-12-03 22:01 ` James Simmons 0 siblings, 0 replies; 22+ messages in thread From: James Simmons @ 2002-12-03 22:01 UTC (permalink / raw) To: Antonino Daplas Cc: Alan Cox, Linux Fbdev development list, Linux Kernel Mailing List > > I question whether thats something that belongs anywhere near the > > kernel. Ben Pfaff wrote a fine library for vga16 hackery (BOGL) and it > > combines very nicely with the fb driver. > I kinda agree with this. Most fb apps use mmap to access the > framebuffer, so it's almost impossible to fake a linear framebuffer from > a planar one. Okay. Then that idea is scrapped. ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [Linux-fbdev-devel] [PATCH] FBDev: vga16fb port 2002-12-03 15:47 ` Alan Cox 2002-12-03 20:50 ` Antonino Daplas @ 2002-12-03 22:02 ` James Simmons 2002-12-04 3:19 ` Tomas Szepe 1 sibling, 1 reply; 22+ messages in thread From: James Simmons @ 2002-12-03 22:02 UTC (permalink / raw) To: Alan Cox Cc: Antonino Daplas, Linux Fbdev development list, Linux Kernel Mailing List > I question whether thats something that belongs anywhere near the > kernel. Ben Pfaff wrote a fine library for vga16 hackery (BOGL) and it > combines very nicely with the fb driver. Out of curiousity where is this library. ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [Linux-fbdev-devel] [PATCH] FBDev: vga16fb port 2002-12-03 22:02 ` James Simmons @ 2002-12-04 3:19 ` Tomas Szepe 0 siblings, 0 replies; 22+ messages in thread From: Tomas Szepe @ 2002-12-04 3:19 UTC (permalink / raw) To: James Simmons Cc: Antonino Daplas, Linux Fbdev development list, Linux Kernel Mailing List > > > I question whether thats something that belongs anywhere near the > > kernel. Ben Pfaff wrote a fine library for vga16 hackery (BOGL) and it > > combines very nicely with the fb driver. > > Out of curiousity where is this library. http://packages.qa.debian.org/b/bogl.html http://http.us.debian.org/debian/pool/main/b/bogl/bogl_0.1.10-3.tar.gz -- Tomas Szepe <szepe@pinerecords.com> ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [Linux-fbdev-devel] [PATCH] FBDev: vga16fb port 2002-12-03 12:22 ` Antonino Daplas 2002-12-03 15:47 ` Alan Cox @ 2002-12-04 7:32 ` Sven Luther 2002-12-04 12:08 ` Antonino Daplas 1 sibling, 1 reply; 22+ messages in thread From: Sven Luther @ 2002-12-04 7:32 UTC (permalink / raw) To: Antonino Daplas Cc: James Simmons, Linux Fbdev development list, Linux Kernel Mailing List On Tue, Dec 03, 2002 at 05:22:35PM +0500, Antonino Daplas wrote: > > 2) The ability to go back to vga text mode on close of /dev/fb. > > Yes fbdev/fbcon supports that now. > > I'll take a stab at writing VGA save/restore routines which hopefully is > generic enough to be used by various hardware. No promises though, VGA > programming gives me a headache :( BTW, i am writing a fbdev for a card where the docs tell me to disable vga output before enabling graphical output. Does i need to do this in the fbdev i write, or is it already handled by the vga layer, or whatever ? Friendly, Sven Luther ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [Linux-fbdev-devel] [PATCH] FBDev: vga16fb port 2002-12-04 7:32 ` Sven Luther @ 2002-12-04 12:08 ` Antonino Daplas 2002-12-04 10:28 ` Sven Luther 0 siblings, 1 reply; 22+ messages in thread From: Antonino Daplas @ 2002-12-04 12:08 UTC (permalink / raw) To: Sven Luther Cc: James Simmons, Linux Fbdev development list, Linux Kernel Mailing List On Wed, 2002-12-04 at 12:32, Sven Luther wrote: > On Tue, Dec 03, 2002 at 05:22:35PM +0500, Antonino Daplas wrote: > > > 2) The ability to go back to vga text mode on close of /dev/fb. > > > Yes fbdev/fbcon supports that now. > > > > I'll take a stab at writing VGA save/restore routines which hopefully is > > generic enough to be used by various hardware. No promises though, VGA > > programming gives me a headache :( > > BTW, i am writing a fbdev for a card where the docs tell me to disable > vga output before enabling graphical output. Does i need to do this in > the fbdev i write, or is it already handled by the vga layer, or > whatever ? Most cards with a VGA core needs to disable the VGA output before going to graphics mode. Disabling VGA output is hardware specific, and is usually automatic when you go to graphics mode. Because James wrote the fb framework to be very modular, then you must be careful to save/restore the initial video state when loading or unloading. Theoretically, a driver should load, but not go to graphics mode immediately. Only upon a call to xxxfb_set_par() should the driver do so. Before going to graphics mode, that's were you save the initial state. Have a reference count or something to keep track of the number of users, and when this reference count becomes zero, restore the initial state. You should be able to do this by hooking these routines in fb_open() and fb_release(). The one I submitted (and a revised one I'm going to submit soon) should be able to restore the VGA text/graphics mode. Complement this with your hardware's extended state save and restore routines and you should be able to load/use/unload your driver repeatedly :-). Tony Tony ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [Linux-fbdev-devel] [PATCH] FBDev: vga16fb port 2002-12-04 12:08 ` Antonino Daplas @ 2002-12-04 10:28 ` Sven Luther 2002-12-04 17:27 ` Antonino Daplas 0 siblings, 1 reply; 22+ messages in thread From: Sven Luther @ 2002-12-04 10:28 UTC (permalink / raw) To: Antonino Daplas Cc: Sven Luther, James Simmons, Linux Fbdev development list, Linux Kernel Mailing List On Wed, Dec 04, 2002 at 05:08:53PM +0500, Antonino Daplas wrote: > On Wed, 2002-12-04 at 12:32, Sven Luther wrote: > > On Tue, Dec 03, 2002 at 05:22:35PM +0500, Antonino Daplas wrote: > > > > 2) The ability to go back to vga text mode on close of /dev/fb. > > > > Yes fbdev/fbcon supports that now. > > > > > > I'll take a stab at writing VGA save/restore routines which hopefully is > > > generic enough to be used by various hardware. No promises though, VGA > > > programming gives me a headache :( > > > > BTW, i am writing a fbdev for a card where the docs tell me to disable > > vga output before enabling graphical output. Does i need to do this in > > the fbdev i write, or is it already handled by the vga layer, or > > whatever ? > > Most cards with a VGA core needs to disable the VGA output before going > to graphics mode. Disabling VGA output is hardware specific, and is > usually automatic when you go to graphics mode. So there is no common zqy of doing this, my docs say something about a vga control register zhich is accesses trough the sequencer regs. Does vgafb (or textmode or whatever) not call this when giving the hand to the fbdev ? > Because James wrote the fb framework to be very modular, then you must > be careful to save/restore the initial video state when loading or > unloading. Theoretically, a driver should load, but not go to graphics > mode immediately. Only upon a call to xxxfb_set_par() should the driver > do so. Before going to graphics mode, that's were you save the initial > state. Have a reference count or something to keep track of the number > of users, and when this reference count becomes zero, restore the > initial state. You should be able to do this by hooking these routines > in fb_open() and fb_release(). Mmm, what about interaction with X ? X also does a save/restore of the previous (text) mode, when a X driver is _not_ fbdev aware, it will save/restore the things twice, right ? > The one I submitted (and a revised one I'm going to submit soon) should > be able to restore the VGA text/graphics mode. Complement this with > your hardware's extended state save and restore routines and you should > be able to load/use/unload your driver repeatedly :-). Ok, i will try. Friendlmy Sven Luther ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [Linux-fbdev-devel] [PATCH] FBDev: vga16fb port 2002-12-04 10:28 ` Sven Luther @ 2002-12-04 17:27 ` Antonino Daplas 2002-12-04 16:47 ` Sven Luther 0 siblings, 1 reply; 22+ messages in thread From: Antonino Daplas @ 2002-12-04 17:27 UTC (permalink / raw) To: Sven Luther Cc: James Simmons, Linux Fbdev development list, Linux Kernel Mailing List On Wed, 2002-12-04 at 15:28, Sven Luther wrote: > > > > Most cards with a VGA core needs to disable the VGA output before going > > to graphics mode. Disabling VGA output is hardware specific, and is > > usually automatic when you go to graphics mode. > > So there is no common zqy of doing this, my docs say something about a > vga control register zhich is accesses trough the sequencer regs. Does > vgafb (or textmode or whatever) not call this when giving the hand to > the fbdev ? No, when a video card goes to graphics mode, it's up to the driver to program the registers. vgacon/vga16fb only touches the standard VGA registers (crtc[25], attr[21], seq[5], gfx[9], misc[1]). Usage is pretty much uniform across all hardware. Any registers past those indices are considered extended registers and usage is hardware specific. In graphics mode, you will probably use both the standard and the extended registers, and disabling the VGA mode/enabling graphics mode is most probably in one of the extended registers. > > > Because James wrote the fb framework to be very modular, then you must > > be careful to save/restore the initial video state when loading or > > unloading. Theoretically, a driver should load, but not go to graphics > > mode immediately. Only upon a call to xxxfb_set_par() should the driver > > do so. Before going to graphics mode, that's were you save the initial > > state. Have a reference count or something to keep track of the number > > of users, and when this reference count becomes zero, restore the > > initial state. You should be able to do this by hooking these routines > > in fb_open() and fb_release(). > > Mmm, what about interaction with X ? X also does a save/restore of the > previous (text) mode, when a X driver is _not_ fbdev aware, it will > save/restore the things twice, right ? > Not twice just the current mode it was in when X launched, although it always assumes text mode. Same thing for fbdev, it should only restore the state when reference count becomes zero. If the framebuffer console is loaded, the reference count will never be zero unless it is unloaded. If the framebuffer console is not loaded, the only time you will save and restore the state is when some fb-based application attempts to open/close /dev/fbx. > > The one I submitted (and a revised one I'm going to submit soon) should > > be able to restore the VGA text/graphics mode. Complement this with > > your hardware's extended state save and restore routines and you should > > be able to load/use/unload your driver repeatedly :-). > > Ok, i will try. This is optional though. You can still adopt the 2.4 method of always setting the video mode. Just take note that fbdev can be loaded without fbcon, and if you get into graphics mode without fbcon, you just messed up your user's console. I think this can be avoided by munging the configuration file (ie, always depend on fbcon and make your module unsafe to unload). Tony ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [Linux-fbdev-devel] [PATCH] FBDev: vga16fb port 2002-12-04 17:27 ` Antonino Daplas @ 2002-12-04 16:47 ` Sven Luther 2002-12-05 1:04 ` Antonino Daplas 0 siblings, 1 reply; 22+ messages in thread From: Sven Luther @ 2002-12-04 16:47 UTC (permalink / raw) To: Antonino Daplas Cc: Sven Luther, James Simmons, Linux Fbdev development list, Linux Kernel Mailing List On Wed, Dec 04, 2002 at 10:27:21PM +0500, Antonino Daplas wrote: > On Wed, 2002-12-04 at 15:28, Sven Luther wrote: > > > > > > Most cards with a VGA core needs to disable the VGA output before going > > > to graphics mode. Disabling VGA output is hardware specific, and is > > > usually automatic when you go to graphics mode. > > > > So there is no common zqy of doing this, my docs say something about a > > vga control register zhich is accesses trough the sequencer regs. Does > > vgafb (or textmode or whatever) not call this when giving the hand to > > the fbdev ? > No, when a video card goes to graphics mode, it's up to the driver to > program the registers. vgacon/vga16fb only touches the standard VGA So we will have a repeat of the exact same code snipplet in all the drivers ? I thought the new API was about having all the common code in common and not duplicated in all the drivers. Could we have at least a gen_disable_vga function or something such that we could call ? > registers (crtc[25], attr[21], seq[5], gfx[9], misc[1]). Usage is pretty Well, i need to disable the vga output in seq[5], more exactly bit 3 called "enable VGA display", need to be reset. > much uniform across all hardware. Any registers past those indices are > considered extended registers and usage is hardware specific. In > graphics mode, you will probably use both the standard and the extended > registers, and disabling the VGA mode/enabling graphics mode is most > probably in one of the extended registers. Err, it is seq[5], called VGAControlRegister, so it is beyond the standard seq registers (seq[0] to seq[5]), right ? > > > Because James wrote the fb framework to be very modular, then you must > > > be careful to save/restore the initial video state when loading or > > > unloading. Theoretically, a driver should load, but not go to graphics > > > mode immediately. Only upon a call to xxxfb_set_par() should the driver > > > do so. Before going to graphics mode, that's were you save the initial > > > state. Have a reference count or something to keep track of the number > > > of users, and when this reference count becomes zero, restore the > > > initial state. You should be able to do this by hooking these routines > > > in fb_open() and fb_release(). > > > > Mmm, what about interaction with X ? X also does a save/restore of the > > previous (text) mode, when a X driver is _not_ fbdev aware, it will > > save/restore the things twice, right ? > > > Not twice just the current mode it was in when X launched, although it > always assumes text mode. Same thing for fbdev, it should only restore Well, but fbdev will save its state and X will save it again, so the saving done in the X driver is not all that important, and i could ignore it at first if i already have an fbdev. Does this also apply to vesafb ? > the state when reference count becomes zero. If the framebuffer console > is loaded, the reference count will never be zero unless it is > unloaded. If the framebuffer console is not loaded, the only time you > will save and restore the state is when some fb-based application > attempts to open/close /dev/fbx. Ok, ... > > > The one I submitted (and a revised one I'm going to submit soon) should > > > be able to restore the VGA text/graphics mode. Complement this with > > > your hardware's extended state save and restore routines and you should > > > be able to load/use/unload your driver repeatedly :-). > > > > Ok, i will try. > > This is optional though. You can still adopt the 2.4 method of always > setting the video mode. Just take note that fbdev can be loaded without > fbcon, and if you get into graphics mode without fbcon, you just messed > up your user's console. I think this can be avoided by munging the > configuration file (ie, always depend on fbcon and make your module > unsafe to unload). Anyway, i need to play with it some and experiment before i can do more comments. Friendly, Sven Luther ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [Linux-fbdev-devel] [PATCH] FBDev: vga16fb port 2002-12-04 16:47 ` Sven Luther @ 2002-12-05 1:04 ` Antonino Daplas 2002-12-05 17:35 ` James Simmons 0 siblings, 1 reply; 22+ messages in thread From: Antonino Daplas @ 2002-12-05 1:04 UTC (permalink / raw) To: Sven Luther Cc: James Simmons, Linux Fbdev development list, Linux Kernel Mailing List On Wed, 2002-12-04 at 21:47, Sven Luther wrote: > > > So there is no common zqy of doing this, my docs say something about a > > > vga control register zhich is accesses trough the sequencer regs. Does > > > vgafb (or textmode or whatever) not call this when giving the hand to > > > the fbdev ? > > No, when a video card goes to graphics mode, it's up to the driver to > > program the registers. vgacon/vga16fb only touches the standard VGA > > So we will have a repeat of the exact same code snipplet in all the > drivers ? I thought the new API was about having all the common code in > common and not duplicated in all the drivers. Could we have at least a > gen_disable_vga function or something such that we could call ? Not exactly. Different hardware programs those registers differently. Ie, vga will probably program the crtc regs for 640x400@60. Your hardware can probably do better than that. So the code cannot be shared. However, saving and restoring the standard VGA regs can be common. > > > registers (crtc[25], attr[21], seq[5], gfx[9], misc[1]). Usage is pretty > > Well, i need to disable the vga output in seq[5], more exactly bit 3 > called "enable VGA display", need to be reset. > [...] > > Err, it is seq[5], called VGAControlRegister, so it is beyond the > standard seq registers (seq[0] to seq[5]), right ? I meant seq[0] to seq[4] are standard VGA regs. So seq[5] is extended. It's VGAControlRegister in your hardware, it's not used in mine. > [...] > > > Mmm, what about interaction with X ? X also does a save/restore of the > > > previous (text) mode, when a X driver is _not_ fbdev aware, it will > > > save/restore the things twice, right ? > > > > > Not twice just the current mode it was in when X launched, although it > > always assumes text mode. Same thing for fbdev, it should only restore > > Well, but fbdev will save its state and X will save it again, so the > saving done in the X driver is not all that important, and i could > ignore it at first if i already have an fbdev. If X is running in native mode then it has to save the register state. Otherwise you cannot switch to a console. If X is running on top of fbdev, then state restore/saves are done using fb_set_var and fb_get_var. The registers are not touched, that's the purpose of fbdev. If you are running vgacon, fbdev, and native X, then yes, fbdev and X has to do a save of their initial state. > > Does this also apply to vesafb ? Not too sure about this. vesa requires real-mode initialization. Either you do this at boot time, or fake a real-mode environment like what X does. > > > the state when reference count becomes zero. If the framebuffer console > > is loaded, the reference count will never be zero unless it is > > unloaded. If the framebuffer console is not loaded, the only time you > > will save and restore the state is when some fb-based application > > attempts to open/close /dev/fbx. > > Ok, ... > [...] Tony ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [Linux-fbdev-devel] [PATCH] FBDev: vga16fb port 2002-12-05 1:04 ` Antonino Daplas @ 2002-12-05 17:35 ` James Simmons 2002-12-05 18:03 ` Sven Luther 0 siblings, 1 reply; 22+ messages in thread From: James Simmons @ 2002-12-05 17:35 UTC (permalink / raw) To: Antonino Daplas Cc: Sven Luther, Linux Fbdev development list, Linux Kernel Mailing List > If X is running in native mode then it has to save the register state. > Otherwise you cannot switch to a console. If X is running on top of > fbdev, then state restore/saves are done using fb_set_var and > fb_get_var. The registers are not touched, that's the purpose of fbdev. > > If you are running vgacon, fbdev, and native X, then yes, fbdev and X > has to do a save of their initial state. Not really. When X closes /dev/fb then fb_release is called which if the driver supports it will switch back to text mode. The exception is firmware based fbdev drivers like vesafb and offb. > > Does this also apply to vesafb ? > Not too sure about this. vesa requires real-mode initialization. Either > you do this at boot time, or fake a real-mode environment like what X > does. X has to reset the vidoe hardware back to the state that matches what the VESA mode was. Other wise it will mess you your system. P.S X on VESA fb always foobars my system when I exit X. ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [Linux-fbdev-devel] [PATCH] FBDev: vga16fb port 2002-12-05 17:35 ` James Simmons @ 2002-12-05 18:03 ` Sven Luther 2002-12-05 20:37 ` James Simmons 0 siblings, 1 reply; 22+ messages in thread From: Sven Luther @ 2002-12-05 18:03 UTC (permalink / raw) To: James Simmons Cc: Antonino Daplas, Sven Luther, Linux Fbdev development list, Linux Kernel Mailing List On Thu, Dec 05, 2002 at 05:35:56PM +0000, James Simmons wrote: > > > If X is running in native mode then it has to save the register state. > > Otherwise you cannot switch to a console. If X is running on top of > > fbdev, then state restore/saves are done using fb_set_var and > > fb_get_var. The registers are not touched, that's the purpose of fbdev. > > > > If you are running vgacon, fbdev, and native X, then yes, fbdev and X > > has to do a save of their initial state. > > Not really. When X closes /dev/fb then fb_release is called which if the That supposes X is fbdev aware (either using the fbdev driver or the UseFBDev option), right ? What if X knows nothing about fbdev, it will try restoring stuff as if it was in text mode. > driver supports it will switch back to text mode. The exception is > firmware based fbdev drivers like vesafb and offb. > > > > Does this also apply to vesafb ? > > Not too sure about this. vesa requires real-mode initialization. Either > > you do this at boot time, or fake a real-mode environment like what X > > does. > > X has to reset the vidoe hardware back to the state that matches what the > VESA mode was. Other wise it will mess you your system. > > P.S > > X on VESA fb always foobars my system when I exit X. With which driver ? (i am happily running the vesa X driver on top of vesafb without problems). Friendly, Sven Luther ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [Linux-fbdev-devel] [PATCH] FBDev: vga16fb port 2002-12-05 18:03 ` Sven Luther @ 2002-12-05 20:37 ` James Simmons 2002-12-05 20:44 ` Sven Luther 0 siblings, 1 reply; 22+ messages in thread From: James Simmons @ 2002-12-05 20:37 UTC (permalink / raw) To: Sven Luther Cc: Antonino Daplas, Linux Fbdev development list, Linux Kernel Mailing List > > Not really. When X closes /dev/fb then fb_release is called which if the > > That supposes X is fbdev aware (either using the fbdev driver or the > UseFBDev option), right ? What if X knows nothing about fbdev, it will > try restoring stuff as if it was in text mode. That is what X will try. > > X on VESA fb always foobars my system when I exit X. > > With which driver ? (i am happily running the vesa X driver on top of > vesafb without problems). G400 X server 4.0.2 ontop of VESA framebuffer. ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [Linux-fbdev-devel] [PATCH] FBDev: vga16fb port 2002-12-05 20:37 ` James Simmons @ 2002-12-05 20:44 ` Sven Luther 2002-12-06 0:50 ` James Simmons 2002-12-06 1:36 ` Antonino Daplas 0 siblings, 2 replies; 22+ messages in thread From: Sven Luther @ 2002-12-05 20:44 UTC (permalink / raw) To: James Simmons Cc: Sven Luther, Antonino Daplas, Linux Fbdev development list, Linux Kernel Mailing List On Thu, Dec 05, 2002 at 08:37:08PM +0000, James Simmons wrote: > > > > Not really. When X closes /dev/fb then fb_release is called which if the > > > > That supposes X is fbdev aware (either using the fbdev driver or the > > UseFBDev option), right ? What if X knows nothing about fbdev, it will > > try restoring stuff as if it was in text mode. > > That is what X will try. Mmm, is it enough for X to just save/restore the registers it modifies ? Also, i suppose if i am comming from fbdev, what X saves or restores does not really count, since fbdev knows what relevant thing to save. Still i sense that there may be some issues involved here, especially if you switch from text mode to fbdev or between fbdevs while not in X. > > > X on VESA fb always foobars my system when I exit X. > > > > With which driver ? (i am happily running the vesa X driver on top of > > vesafb without problems). > > G400 X server 4.0.2 ontop of VESA framebuffer. And i suppose the VESA driver will work, right ? Friendly, Sven Luther ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [Linux-fbdev-devel] [PATCH] FBDev: vga16fb port 2002-12-05 20:44 ` Sven Luther @ 2002-12-06 0:50 ` James Simmons 2002-12-06 1:36 ` Antonino Daplas 1 sibling, 0 replies; 22+ messages in thread From: James Simmons @ 2002-12-06 0:50 UTC (permalink / raw) To: Sven Luther Cc: Antonino Daplas, Linux Fbdev development list, Linux Kernel Mailing List > > G400 X server 4.0.2 ontop of VESA framebuffer. > > And i suppose the VESA driver will work, right ? I haven't tried it but I assume it does. ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [Linux-fbdev-devel] [PATCH] FBDev: vga16fb port 2002-12-05 20:44 ` Sven Luther 2002-12-06 0:50 ` James Simmons @ 2002-12-06 1:36 ` Antonino Daplas 1 sibling, 0 replies; 22+ messages in thread From: Antonino Daplas @ 2002-12-06 1:36 UTC (permalink / raw) To: Sven Luther Cc: James Simmons, Linux Fbdev development list, Linux Kernel Mailing List On Fri, 2002-12-06 at 01:44, Sven Luther wrote: > On Thu, Dec 05, 2002 at 08:37:08PM +0000, James Simmons wrote: > > > > > > Not really. When X closes /dev/fb then fb_release is called which if the > > > > > > That supposes X is fbdev aware (either using the fbdev driver or the > > > UseFBDev option), right ? What if X knows nothing about fbdev, it will > > > try restoring stuff as if it was in text mode. > > > > That is what X will try. > > Mmm, is it enough for X to just save/restore the registers it modifies ? > Life will be easy if native X does that always. However, it does not always restore all the registers it modifies. Common example, the cursor registers. If fbdev is also using a hardware cursor, you will see X's cursor replacing your console's block cursor when switching from X to the console. Some ATI cards freezes the system when native X and fbdev are running concurrently. James, Without the set_var hook 2.5 as is in 2.4, this will become more of a problem. Most drivers in 2.4 refreshes their registers during set_var. > Also, i suppose if i am comming from fbdev, what X saves or restores > does not really count, since fbdev knows what relevant thing to save. Yes, the same thing too if the X driver supports Option "Usefbdev". Instead of restoring the hardware registers, X (or XFBdev) will call fb_set_var to restore fbcon's state. > > Still i sense that there may be some issues involved here, especially > if you switch from text mode to fbdev or between fbdevs while not in X. > State saves and restores are pertinent only for state changes within a single card. Ie, the state of the vga core and the graphics state. Thus, this is relevant to vgacon, vga16fb, the native fbdev driver, and of course X since all can coexist in one card. I have already run vgacon, vga16fb and native fbdev simultaneously already. Fortunately, the X driver was nice too, so I was able to run X also. In multiple fbdev's with each on it's own hardware, this does not matter since the state of the other hopefully does not affect the other. The only problem I can think of is that one card is the primary (thus with an active vga core) and the others are non primary (thus with an inactive vga core). If the non-primary drivers are not careful, they may attempt to save/restore the VGA state that they have no business of knowing. There can be several solutions to this: 1. There is probably a flag somewhere that says that the hardware's vga core is inactive, and if so, do not attempt to save/restore the state.. 2. Most hardware with a vga core most probably has the VGA registers memory mapped. If this is the case, all it needs to do is fill up fb_vgastate.vgabase, and the save/restore module will instead do mmio instead of pio, leaving the actual VGA registers untouched. Tony ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [Linux-fbdev-devel] [PATCH] FBDev: vga16fb port 2002-12-02 20:31 ` [Linux-fbdev-devel] " James Simmons 2002-12-03 12:22 ` Antonino Daplas @ 2002-12-03 20:49 ` Antonino Daplas 2002-12-04 23:44 ` James Simmons 1 sibling, 1 reply; 22+ messages in thread From: Antonino Daplas @ 2002-12-03 20:49 UTC (permalink / raw) To: James Simmons; +Cc: Linux Fbdev development list, Linux Kernel Mailing List [-- Attachment #1: Type: text/plain, Size: 1215 bytes --] On Tue, 2002-12-03 at 01:31, James Simmons wrote: James, > 2) The ability to go back to vga text mode on close of /dev/fb. > Yes fbdev/fbcon supports that now. > Here's a preliminary and highly unpolished patch for saving and restoring the initial vga state. The module allows saving/restoring of specific hardware states (vga fonts/character maps, color map, and/or video mode) by specifying different flags. Most hardware probably will just need restoring of the initial video mode though. Hopefully, it should be generic enough to complement device specific state save and restore routines. For testing purposes, I also patched vga16fb.c to use the module during fb_open and fb_release. Try loading vga16fb, and when opened, the video mode will change. On close, the state of vgacon should be restored. I have tested this with two different VGA cards, and both seems to work quite well. However, color map and character map state restores are still untested. Note that the module still makes assumptions that may not be necessarily correct for all hardware (ie vga base is at 0xa0000). Secondly, there's no check if the card is in VGA mode, EGA mode, or graphics mode. Please review. Tony [-- Attachment #2: vgastate.diff --] [-- Type: text/x-patch, Size: 20028 bytes --] diff -Naur linux-2.5.50-js/drivers/video/Makefile linux/drivers/video/Makefile --- linux-2.5.50-js/drivers/video/Makefile 2002-12-03 19:55:25.000000000 +0000 +++ linux/drivers/video/Makefile 2002-12-03 19:57:14.000000000 +0000 @@ -6,7 +6,7 @@ # This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'. export-objs := fbmem.o fbcmap.o fbmon.o modedb.o softcursor.o cfbfillrect.o \ - cfbcopyarea.o cfbimgblt.o cyber2000fb.o + cfbcopyarea.o cfbimgblt.o vgastate.o cyber2000fb.o # Each configuration option enables a list of files. @@ -50,7 +50,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 cfbfillrect.o cfbcopyarea.o cfbimgblt.o +obj-$(CONFIG_FB_VGA16) += vga16fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o vgastate.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 diff -Naur linux-2.5.50-js/drivers/video/vga16fb.c linux/drivers/video/vga16fb.c --- linux-2.5.50-js/drivers/video/vga16fb.c 2002-12-03 19:55:29.000000000 +0000 +++ linux/drivers/video/vga16fb.c 2002-12-03 19:56:45.000000000 +0000 @@ -7,7 +7,8 @@ * * This file is subject to the terms and conditions of the GNU General * Public License. See the file COPYING in the main directory of this - * archive for more details. */ + * archive for more details. + */ #include <linux/module.h> #include <linux/kernel.h> @@ -22,7 +23,7 @@ #include <linux/init.h> #include <asm/io.h> -#include "vga.h" +#include "vgastate.h" #define GRAPHICS_ADDR_REG VGA_GFX_I /* Graphics address register. */ #define GRAPHICS_DATA_REG VGA_GFX_D /* Graphics data register. */ @@ -69,6 +70,8 @@ unsigned char ModeControl; /* CRT-Controller:17h */ unsigned char ClockingMode; /* Seq-Controller:01h */ } vga_state; + struct fb_vgastate state; + atomic_t ref_count; int palette_blanked, vesa_blanked, mode, isVGA; u8 misc, pel_msk, vss, clkdiv; u8 crtc[VGA_CRT_C]; @@ -295,6 +298,34 @@ #define FAIL(X) return -EINVAL +static int vga16fb_open(struct fb_info *info, int user) +{ + struct vga16fb_par *par = (struct vga16fb_par *) info->par; + int cnt = atomic_read(&par->ref_count); + + if (!cnt) { + memset(&par->state, 0, sizeof(struct fb_vgastate)); + par->state.flags = 8; + fb_save_vga(&par->state); + } + atomic_inc(&par->ref_count); + return 0; +} + +static int vga16fb_release(struct fb_info *info, int user) +{ + struct vga16fb_par *par = (struct vga16fb_par *) info->par; + int cnt = atomic_read(&par->ref_count); + + if (!cnt) + return -EINVAL; + if (cnt == 1) + fb_restore_vga(&par->state); + atomic_dec(&par->ref_count); + + return 0; +} + static int vga16fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) { @@ -1346,6 +1377,8 @@ static struct fb_ops vga16fb_ops = { .owner = THIS_MODULE, + .fb_open = vga16fb_open, + .fb_release = vga16fb_release, .fb_check_var = vga16fb_check_var, .fb_set_par = vga16fb_set_par, .fb_setcolreg = vga16fb_setcolreg, diff -Naur linux-2.5.50-js/drivers/video/vgastate.c linux/drivers/video/vgastate.c --- linux-2.5.50-js/drivers/video/vgastate.c 1970-01-01 00:00:00.000000000 +0000 +++ linux/drivers/video/vgastate.c 2002-12-03 19:56:54.000000000 +0000 @@ -0,0 +1,425 @@ +/* + * linux/include/video/vgastate.c -- VGA state save/restore + * + * Copyright 2002 James Simmons + * + * Copyright history from vga16fb.c: + * Copyright 1999 Ben Pfaff and Petr Vandrovec + * Based on VGA info at http://www.goodnet.com/~tinara/FreeVGA/home.htm + * Based on VESA framebuffer (c) 1998 Gerd Knorr + * + * This file is subject to the terms and conditions of the GNU General + * Public License. See the file COPYING in the main directory of this + * archive for more details. + * + */ +#include <linux/config.h> +#include <linux/module.h> +#include <linux/slab.h> +#include "vgastate.h" + +static inline unsigned char vga_rcrtcs(caddr_t regbase, unsigned short iobase, + unsigned char reg) +{ + vga_w(regbase, iobase + 0x4, reg); + return vga_r(regbase, iobase + 0x5); +} + +static inline void vga_wcrtcs(caddr_t regbase, unsigned short iobase, + unsigned char reg, unsigned char val) +{ + vga_w(regbase, iobase + 0x4, reg); + vga_w(regbase, iobase + 0x5, val); +} + +static void save_vga_text(struct fb_vgastate *state) +{ + int i; + u8 misc, attr10, gr4, gr5, gr6, seq2, seq4, seq1; + + /* if in graphics mode, no need to save */ + attr10 = vga_rattr(state->vgabase, 0x10); + if (attr10 & 1) + return; + + /* blank screen */ + seq1 = vga_rseq(state->vgabase, VGA_SEQ_CLOCK_MODE); + vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x1); + vga_wseq(state->vgabase, VGA_SEQ_CLOCK_MODE, seq1 | 1 << 5); + vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x3); + + misc = vga_r(state->vgabase, VGA_MIS_R); + gr4 = vga_rgfx(state->vgabase, VGA_GFX_PLANE_READ); + gr5 = vga_rgfx(state->vgabase, VGA_GFX_MODE); + gr6 = vga_rgfx(state->vgabase, VGA_GFX_MISC); + seq2 = vga_rseq(state->vgabase, VGA_SEQ_PLANE_WRITE); + seq4 = vga_rseq(state->vgabase, VGA_SEQ_MEMORY_MODE); + + /* force graphics mode */ + vga_w(state->vgabase, VGA_MIS_W, misc | 1); + + /* save font 0 */ + if (state->flags & VGA_SAVE_FONT0) { + vga_wseq(state->vgabase, VGA_SEQ_PLANE_WRITE, 0x4); + vga_wseq(state->vgabase, VGA_SEQ_MEMORY_MODE, 0x6); + vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, 0x2); + vga_wgfx(state->vgabase, VGA_GFX_MODE, 0x0); + vga_wgfx(state->vgabase, VGA_GFX_MISC, 0x5); + for (i = 0; i < 8 * 8192; i++) + state->vga_text0[i] = vga_r(state->fbbase, i); + } + /* save font 1 */ + if (state->flags & VGA_SAVE_FONT1) { + vga_wseq(state->vgabase, VGA_SEQ_PLANE_WRITE, 0x8); + vga_wseq(state->vgabase, VGA_SEQ_MEMORY_MODE, 0x6); + vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, 0x3); + vga_wgfx(state->vgabase, VGA_GFX_MODE, 0x0); + vga_wgfx(state->vgabase, VGA_GFX_MISC, 0x5); + for (i = 0; i < 8 * 8192; i++) + state->vga_text1[i] = vga_r(state->fbbase, i); + } + /* save font 2 */ + if (state->flags & VGA_SAVE_TEXT) { + vga_wseq(state->vgabase, VGA_SEQ_PLANE_WRITE, 0x1); + vga_wseq(state->vgabase, VGA_SEQ_MEMORY_MODE, 0x6); + vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, 0x0); + vga_wgfx(state->vgabase, VGA_GFX_MODE, 0x0); + vga_wgfx(state->vgabase, VGA_GFX_MISC, 0x5); + for (i = 0; i < 2 * 8192; i++) + state->vga_text2[i] = vga_r(state->fbbase, i); + + vga_wseq(state->vgabase, VGA_SEQ_PLANE_WRITE, 0x2); + vga_wseq(state->vgabase, VGA_SEQ_MEMORY_MODE, 0x6); + vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, 0x1); + vga_wgfx(state->vgabase, VGA_GFX_MODE, 0x0); + vga_wgfx(state->vgabase, VGA_GFX_MISC, 0x5); + for (i = 0; i < 2 * 8192; i++) + state->vga_text2[i] = vga_r(state->fbbase + 2 * 8192, i); + } + + /* restore regs */ + vga_wattr(state->vgabase, 0x10, attr10); + vga_wseq(state->vgabase, VGA_SEQ_PLANE_WRITE, seq2); + vga_wseq(state->vgabase, VGA_SEQ_MEMORY_MODE, seq4); + vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, gr4); + vga_wgfx(state->vgabase, VGA_GFX_MODE, gr5); + vga_wgfx(state->vgabase, VGA_GFX_MISC, gr6); + vga_w(state->vgabase, VGA_MIS_W, misc); + + /* unblank screen */ + vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x1); + vga_wseq(state->vgabase, VGA_SEQ_CLOCK_MODE, seq1 & ~(1 << 5)); + vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x3); +} + +static void restore_vga_text(struct fb_vgastate *state) +{ + int i; + u8 misc, attr10, gr1, gr3, gr4, gr5, gr6, gr8; + u8 seq2, seq4, seq1; + + /* blank screen */ + seq1 = vga_rseq(state->vgabase, VGA_SEQ_CLOCK_MODE); + vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x1); + vga_wseq(state->vgabase, VGA_SEQ_CLOCK_MODE, seq1 | 1 << 5); + vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x3); + + misc = vga_r(state->vgabase, VGA_MIS_R); + attr10 = vga_rattr(state->vgabase, 0x10); + gr1 = vga_rgfx(state->vgabase, VGA_GFX_SR_ENABLE); + gr3 = vga_rgfx(state->vgabase, VGA_GFX_DATA_ROTATE); + gr4 = vga_rgfx(state->vgabase, VGA_GFX_PLANE_READ); + gr5 = vga_rgfx(state->vgabase, VGA_GFX_MODE); + gr6 = vga_rgfx(state->vgabase, VGA_GFX_MISC); + gr8 = vga_rgfx(state->vgabase, VGA_GFX_BIT_MASK); + seq2 = vga_rseq(state->vgabase, VGA_SEQ_PLANE_WRITE); + seq4 = vga_rseq(state->vgabase, VGA_SEQ_MEMORY_MODE); + + /* force graphics mode */ + vga_w(state->vgabase, VGA_MIS_W, misc | 1); + + if (state->depth == 4) { + vga_wgfx(state->vgabase, VGA_GFX_DATA_ROTATE, 0x0); + vga_wgfx(state->vgabase, VGA_GFX_BIT_MASK, 0xff); + vga_wgfx(state->vgabase, VGA_GFX_SR_ENABLE, 0x00); + } + /* restore font 0 */ + if (state->flags & VGA_SAVE_FONT0) { + vga_wseq(state->vgabase, VGA_SEQ_PLANE_WRITE, 0x4); + vga_wseq(state->vgabase, VGA_SEQ_MEMORY_MODE, 0x6); + vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, 0x2); + vga_wgfx(state->vgabase, VGA_GFX_MODE, 0x0); + vga_wgfx(state->vgabase, VGA_GFX_MISC, 0x5); + for (i = 0; i < 8 * 8192; i++) + vga_w(state->fbbase, i, state->vga_text0[i]); + } + /* restore font 1 */ + if (state->flags & VGA_SAVE_FONT1) { + vga_wseq(state->vgabase, VGA_SEQ_PLANE_WRITE, 0x8); + vga_wseq(state->vgabase, VGA_SEQ_MEMORY_MODE, 0x6); + vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, 0x3); + vga_wgfx(state->vgabase, VGA_GFX_MODE, 0x0); + vga_wgfx(state->vgabase, VGA_GFX_MISC, 0x5); + for (i = 0; i < 8 * 8192; i++) + vga_w(state->fbbase, i, state->vga_text1[i]); + } + /* restore font 2 */ + if (state->flags & VGA_SAVE_TEXT) { + vga_wseq(state->vgabase, VGA_SEQ_PLANE_WRITE, 0x1); + vga_wseq(state->vgabase, VGA_SEQ_MEMORY_MODE, 0x6); + vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, 0x0); + vga_wgfx(state->vgabase, VGA_GFX_MODE, 0x0); + vga_wgfx(state->vgabase, VGA_GFX_MISC, 0x5); + for (i = 0; i < 2 * 8192; i++) + vga_w(state->fbbase, i, state->vga_text2[i]); + + vga_wseq(state->vgabase, VGA_SEQ_PLANE_WRITE, 0x2); + vga_wseq(state->vgabase, VGA_SEQ_MEMORY_MODE, 0x6); + vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, 0x1); + vga_wgfx(state->vgabase, VGA_GFX_MODE, 0x0); + vga_wgfx(state->vgabase, VGA_GFX_MISC, 0x5); + for (i = 0; i < 2 * 8192; i++) + vga_w(state->fbbase + 2 * 8192, i, state->vga_text2[i]); + } + + /* restore regs */ + vga_w(state->vgabase, VGA_MIS_W, misc); + vga_wattr(state->vgabase, 0x10, attr10); + vga_wgfx(state->vgabase, VGA_GFX_SR_ENABLE, gr1); + vga_wgfx(state->vgabase, VGA_GFX_DATA_ROTATE, gr3); + vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, gr4); + vga_wgfx(state->vgabase, VGA_GFX_MODE, gr5); + vga_wgfx(state->vgabase, VGA_GFX_MISC, gr6); + vga_wgfx(state->vgabase, VGA_GFX_BIT_MASK, gr8); + vga_wseq(state->vgabase, VGA_SEQ_PLANE_WRITE, seq2); + vga_wseq(state->vgabase, VGA_SEQ_MEMORY_MODE, seq4); + + /* unblank screen */ + vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x1); + vga_wseq(state->vgabase, VGA_SEQ_CLOCK_MODE, seq1 & ~(1 << 5)); + vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x3); +} + +static void save_vga_mode(struct fb_vgastate *state) +{ + unsigned short iobase; + int i; + + state->misc = vga_r(state->vgabase, VGA_MIS_R); + if (state->misc & 1) + iobase = 0x3d0; + else + iobase = 0x3b0; + + for (i = 0; i < state->num_crtc; i++) + state->crtc[i] = vga_rcrtcs(state->vgabase, iobase, i); + + vga_r(state->vgabase, iobase + 0xa); + vga_w(state->vgabase, VGA_ATT_W, 0x00); + for (i = 0; i < state->num_attr; i++) { + vga_r(state->vgabase, iobase + 0xa); + state->attr[i] = vga_rattr(state->vgabase, i); + } + vga_r(state->vgabase, iobase + 0xa); + vga_w(state->vgabase, VGA_ATT_W, 0x20); + + for (i = 0; i < state->num_gfx; i++) + state->gfx[i] = vga_rgfx(state->vgabase, i); + + for (i = 0; i < state->num_seq; i++) + state->seq[i] = vga_rseq(state->vgabase, i); +} + +static void restore_vga_mode(struct fb_vgastate *state) +{ + unsigned short iobase; + int i; + + vga_w(state->vgabase, VGA_MIS_W, state->misc); + + if (state->misc & 1) + iobase = 0x3d0; + else + iobase = 0x3b0; + + vga_io_wseq(0x00, 0x01); + vga_io_wseq(VGA_SEQ_CLOCK_MODE, state->seq[VGA_SEQ_CLOCK_MODE] | 0x20); + + for (i = 2; i < state->num_seq; i++) + vga_wseq(state->vgabase, i, state->seq[i]); + + vga_io_wseq(0x00, 0x03); + + /* unprotect vga regs */ + vga_wcrtcs(state->vgabase, iobase, 17, state->crtc[17] & ~0x80); + for (i = 0; i < state->num_crtc; i++) + vga_wcrtcs(state->vgabase, iobase, i, state->crtc[i]); + + for (i = 0; i < state->num_gfx; i++) + vga_wgfx(state->vgabase, i, state->gfx[i]); + + vga_r(state->vgabase, iobase + 0xa); + vga_w(state->vgabase, VGA_ATT_W, 0x00); + for (i = 0; i < state->num_attr; i++) { + vga_r(state->vgabase, iobase + 0xa); + vga_wattr(state->vgabase, i, state->attr[i]); + } + + vga_io_wseq(VGA_SEQ_CLOCK_MODE, state->seq[VGA_SEQ_CLOCK_MODE]); + + vga_r(state->vgabase, iobase + 0xa); + vga_w(state->vgabase, VGA_ATT_W, 0x20); +} + +static void save_vga_cmap(struct fb_vgastate *state) +{ + int i; + + vga_w(state->vgabase, VGA_PEL_MSK, 0xff); + + /* assumes DAC is readable and writable */ + vga_w(state->vgabase, VGA_PEL_IR, 0x00); + for (i = 0; i < 768; i++) + state->vga_cmap[i] = vga_r(state->vgabase, VGA_PEL_D); +} + +static void restore_vga_cmap(struct fb_vgastate *state) +{ + int i; + + vga_w(state->vgabase, VGA_PEL_MSK, 0xff); + + vga_w(state->vgabase, VGA_PEL_IW, 0x00); + for (i = 0; i < 768; i++) + vga_w(state->vgabase, VGA_PEL_D, state->vga_cmap[i]); +} + +static void vga_cleanup(struct fb_vgastate *state) +{ + if (state->vga_text0) + kfree(state->vga_text0); + if (state->vga_text1) + kfree(state->vga_text1); + if (state->vga_text2) + kfree(state->vga_text2); + if (state->fbbase) + iounmap(state->fbbase); + if (state->vga_cmap) + kfree(state->vga_cmap); + if (state->attr) + kfree(state->attr); + if (state->crtc) + kfree(state->crtc); + if (state->gfx) + kfree(state->gfx); + if (state->seq) + kfree(state->seq); +} + +int fb_save_vga(struct fb_vgastate *state) +{ + state->vga_text0 = NULL; + state->vga_text1 = NULL; + state->vga_text2 = NULL; + state->vga_cmap = NULL; + state->attr = NULL; + state->crtc = NULL; + state->gfx = NULL; + state->seq = NULL; + + if (state->flags & VGA_SAVE_CMAP) { + state->vga_cmap = kmalloc(768, GFP_KERNEL); + if (!state->vga_cmap) { + vga_cleanup(state); + return 1; + } + save_vga_cmap(state); + } + + if (state->flags & VGA_SAVE_MODE) { + if (state->num_attr < 21) + state->num_attr = 21; + if (state->num_crtc < 25) + state->num_crtc = 25; + if (state->num_gfx < 9) + state->num_gfx = 9; + if (state->num_seq < 5) + state->num_seq = 5; + state->attr = kmalloc(state->num_attr, GFP_KERNEL); + state->crtc = kmalloc(state->num_crtc, GFP_KERNEL); + state->gfx = kmalloc(state->num_gfx, GFP_KERNEL); + state->seq = kmalloc(state->num_seq, GFP_KERNEL); + if (!state->attr || !state->crtc || !state->gfx || + !state->seq) { + vga_cleanup(state); + return 1; + } + save_vga_mode(state); + } + + if (state->flags & VGA_SAVE_FONT0) { + state->vga_text0 = kmalloc(8192 * 8, GFP_KERNEL); + if (!state->vga_text0) { + vga_cleanup(state); + return 1; + } + } + if (state->flags & VGA_SAVE_FONT1) { + state->vga_text1 = kmalloc(8192 * 8, GFP_KERNEL); + if (!state->vga_text1) { + vga_cleanup(state); + return 1; + } + } + if (state->flags & VGA_SAVE_TEXT) { + state->vga_text2 = kmalloc(8192 * 4, GFP_KERNEL); + if (!state->vga_text2) { + vga_cleanup(state); + return 1; + } + } + if (state->flags & VGA_SAVE_FONTS) { + state->fbbase = ioremap(0xA0000, 8 * 8192); + if (!state->fbbase) { + vga_cleanup(state); + return 1; + } + save_vga_text(state); + iounmap(state->fbbase); + state->fbbase = NULL; + } + return 0; +} + +int fb_restore_vga (struct fb_vgastate *state) +{ + if (state->flags & VGA_SAVE_MODE) + restore_vga_mode(state); + + if (state->flags & VGA_SAVE_FONTS) { + state->fbbase = ioremap(0xA0000, 8 * 8192); + if (!state->fbbase) { + vga_cleanup(state); + return 1; + } + restore_vga_text(state); + } + if (state->flags & VGA_SAVE_CMAP) + restore_vga_cmap(state); + + vga_cleanup(state); + return 0; +} + +#ifdef MODULE +int init_module(void) { return 0; }; +void cleanup_module(void) {}; +#endif + +EXPORT_SYMBOL(fb_save_vga); +EXPORT_SYMBOL(fb_restore_vga); + +MODULE_AUTHOR("James Simmons <jsimmons@users.sf.net>"); +MODULE_DESCRIPTION("VGA State Save/Restore"); +MODULE_LICENSE("GPL"); + diff -Naur linux-2.5.50-js/drivers/video/vgastate.h linux/drivers/video/vgastate.h --- linux-2.5.50-js/drivers/video/vgastate.h 1970-01-01 00:00:00.000000000 +0000 +++ linux/drivers/video/vgastate.h 2002-12-03 19:56:59.000000000 +0000 @@ -0,0 +1,62 @@ +/* + * linux/include/video/vgasate.h -- VGA state save/restore header file + * + * Copyright 2002 James Simmons + * + * Copyright history from vga16fb.c: + * Copyright 1999 Ben Pfaff and Petr Vandrovec + * Based on VGA info at http://www.goodnet.com/~tinara/FreeVGA/home.htm + * Based on VESA framebuffer (c) 1998 Gerd Knorr + * Partly based on XFree86's vgHW.c. + * + * This file is subject to the terms and conditions of the GNU General + * Public License. See the file COPYING in the main directory of this + * archive for more details. + * + */ +#ifndef __vgastate_h__ +#define __vgastate_h__ + +#include <linux/slab.h> +#include "vga.h" + +#define VGA_SAVE_FONT0 1 /* save/restore font 1 */ +#define VGA_SAVE_FONT1 2 /* save/restore font 2 */ +#define VGA_SAVE_TEXT 4 /* save text character map */ +#define VGA_SAVE_FONTS 7 /* save/restore all fonts */ +#define VGA_SAVE_MODE 8 /* save/restore video mode */ +#define VGA_SAVE_CMAP 16 /* save/restore color map/DAC*/ + +/* + * To save/restore the vga state, create the vga_state structure and + * initialize the "flags" field, at least. VGA_SAVE_MODE should be enough for + * most hardware. Pass the structure to fb_save_vga() when reference count + * increases, and to fb_restore_vga() when reference count becomes zero + * + * Assumes vga screen base is at 0xA0000. + */ + +struct fb_vgastate { + int flags; /* what state/s to save (see VGA_SAVE_*) */ + int depth; /* current fb depth, not so important */ + int num_attr; /* number of attribute registers, 0 for default */ + int num_crtc; /* number of crtc register, 0 for default */ + int num_gfx; /* number of gr registers, 0 for default */ + int num_seq; /* number of seq registers, 0 for default */ + caddr_t fbbase; /* leave as is, will be filled up */ + caddr_t vgabase; /* if not NULL, will do mmio instead of port io */ + u8 *vga_text0; /* leave as is, will be filled up */ + u8 *vga_text1; /* leave as is, will be filled up */ + u8 *vga_text2; /* leave as is, will be filled up */ + u8 *vga_cmap; /* leave as is, will be filled up */ + u8 *attr; /* leave as is, will be filled up */ + u8 *crtc; /* leave as is, will be filled up */ + u8 *gfx; /* leave as is, will be filled up */ + u8 *seq; /* leave as is, will be filled up */ + u8 misc; /* leave as is, will be filled up */ +}; + +extern int fb_save_vga(struct fb_vgastate *state); +extern int fb_restore_vga(struct fb_vgastate *state); + +#endif /* __vgastate_h__ */ ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [Linux-fbdev-devel] [PATCH] FBDev: vga16fb port 2002-12-03 20:49 ` Antonino Daplas @ 2002-12-04 23:44 ` James Simmons 0 siblings, 0 replies; 22+ messages in thread From: James Simmons @ 2002-12-04 23:44 UTC (permalink / raw) To: Antonino Daplas; +Cc: Linux Fbdev development list, Linux Kernel Mailing List > Here's a preliminary and highly unpolished patch for saving and > restoring the initial vga state. Totally awesome!!! About a year ago I also manged to do this while working on the ruby linuxconsole project. I'm glad to see it resurrected again!!!! Looking at the code I see both of us have the same ideas. MS: (n) 1. A debilitating and surprisingly widespread affliction that renders the sufferer barely able to perform the simplest task. 2. A disease. James Simmons [jsimmons@users.sf.net] ____/| fbdev/console/gfx developer \ o.O| http://www.linux-fbdev.org =(_)= http://linuxgfx.sourceforge.net U http://linuxconsole.sourceforge.net ^ permalink raw reply [flat|nested] 22+ messages in thread
end of thread, other threads:[~2002-12-06 1:36 UTC | newest] Thread overview: 22+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2002-12-04 10:38 [Linux-fbdev-devel] [PATCH] FBDev: vga16fb port Petr Vandrovec -- strict thread matches above, loose matches on Subject: below -- 2002-11-28 7:24 Antonino Daplas 2002-12-02 20:31 ` [Linux-fbdev-devel] " James Simmons 2002-12-03 12:22 ` Antonino Daplas 2002-12-03 15:47 ` Alan Cox 2002-12-03 20:50 ` Antonino Daplas 2002-12-03 22:01 ` James Simmons 2002-12-03 22:02 ` James Simmons 2002-12-04 3:19 ` Tomas Szepe 2002-12-04 7:32 ` Sven Luther 2002-12-04 12:08 ` Antonino Daplas 2002-12-04 10:28 ` Sven Luther 2002-12-04 17:27 ` Antonino Daplas 2002-12-04 16:47 ` Sven Luther 2002-12-05 1:04 ` Antonino Daplas 2002-12-05 17:35 ` James Simmons 2002-12-05 18:03 ` Sven Luther 2002-12-05 20:37 ` James Simmons 2002-12-05 20:44 ` Sven Luther 2002-12-06 0:50 ` James Simmons 2002-12-06 1:36 ` Antonino Daplas 2002-12-03 20:49 ` Antonino Daplas 2002-12-04 23:44 ` James Simmons
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).