From: "Antonino A. Daplas" <adaplas@hotpop.com>
To: James Simmons <jsimmons@infradead.org>
Cc: Andrew Morton <akpm@osdl.org>,
Linux Fbdev development list
<linux-fbdev-devel@lists.sourceforge.net>
Subject: [PATCH 3/3] [FBDEV]: Hardware State Notification
Date: Tue, 22 Jun 2004 06:39:26 +0800 [thread overview]
Message-ID: <200406220639.26576.adaplas@hotpop.com> (raw)
Hi,
**This patch is more of an RFC. BenH probably has similar code.
This patch adds a method (con_notify) that will notify console drivers of
impending console switches, passing them with the about-to-be-old (last)
vc structure and about-to-be-new (wanted) vc structure. The console
drivers can then elect to pass selected information to low-level drivers.
This is important to fbcon so it can detect a switch from a graphics console to a
text console and vice versa. This will give underlying drivers a chance to update
its hardware state. This is added via the method fbcon_state_switch(). Fbcon
will, however, do a set_par if the _state_switch method is not availabe and if
switching from a KD_GRAPHICS console.
Also updated rivafb to take advantage of this method. With this, switching
to/from X with XFree86/Org nv driver works. Usually it hangs without the
option usefbdev, or gets a Sig11 if with option usefbdev.
(Unfortunately it doesn't work for nVidia's binary nvidia driver, switching to
the console is possible, switching back to X will hang the machine).
Diff is against linux-2.6.7-mm1
Tony
Signed-off-by: Antonino Daplas <adaplas@pol.net>
diff -Naur linux-2.6.7-mm1-orig/drivers/char/vt.c linux-2.6.7-mm1/drivers/char/vt.c
--- linux-2.6.7-mm1-orig/drivers/char/vt.c 2004-06-21 13:26:48.000000000 +0000
+++ linux-2.6.7-mm1/drivers/char/vt.c 2004-06-21 18:02:33.000000000 +0000
@@ -617,6 +617,9 @@
hide_cursor(currcons);
if (fg_console != new_console) {
struct vc_data **display = vc_cons[new_console].d->vc_display_fg;
+ if (sw->con_notify)
+ sw->con_notify(vc_cons[fg_console].d,
+ vc_cons[new_console].d);
old_console = (*display) ? (*display)->vc_num : fg_console;
*display = vc_cons[new_console].d;
fg_console = new_console;
diff -Naur linux-2.6.7-mm1-orig/drivers/video/console/fbcon.c linux-2.6.7-mm1/drivers/video/console/fbcon.c
--- linux-2.6.7-mm1-orig/drivers/video/console/fbcon.c 2004-06-21 18:01:10.000000000 +0000
+++ linux-2.6.7-mm1/drivers/video/console/fbcon.c 2004-06-21 22:24:55.108534784 +0000
@@ -2428,6 +2428,31 @@
return 0;
}
+static void fbcon_notify(struct vc_data *old_vc, struct vc_data *new_vc)
+{
+ struct fb_info *old_info = registered_fb[(int) con2fb_map[old_vc->vc_num]];
+ struct fb_info *new_info = registered_fb[(int) con2fb_map[new_vc->vc_num]];
+ int old_vcmode = vt_cons[old_vc->vc_num]->vc_mode;
+ int new_vcmode = vt_cons[new_vc->vc_num]->vc_mode;
+
+ if (old_info != new_info || vt_cons[old_vc->vc_num]->vc_mode !=
+ vt_cons[new_vc->vc_num]->vc_mode) {
+ if (old_info && old_info->fbops->fb_state_switch)
+ old_info->fbops->fb_state_switch(old_info, 1,
+ (old_vcmode == KD_GRAPHICS) ? 1 : 0);
+ /*
+ * If old console is in graphics, we call a set_par by default
+ */
+ else if (old_vcmode == KD_GRAPHICS && old_info &&
+ old_info->fbops->fb_set_par)
+ old_info->fbops->fb_set_par(old_info);
+
+ if (new_info && new_info->fbops->fb_state_switch)
+ new_info->fbops->fb_state_switch(new_info, 0,
+ (new_vcmode == KD_GRAPHICS) ? 1 : 0);
+ }
+}
+
/*
* The console `switch' structure for the frame buffer based console
*/
@@ -2453,6 +2478,7 @@
.con_screen_pos = fbcon_screen_pos,
.con_getxy = fbcon_getxy,
.con_resize = fbcon_resize,
+ .con_notify = fbcon_notify,
};
static struct notifier_block fbcon_event_notifier = {
diff -Naur linux-2.6.7-mm1-orig/drivers/video/riva/fbdev.c linux-2.6.7-mm1/drivers/video/riva/fbdev.c
--- linux-2.6.7-mm1-orig/drivers/video/riva/fbdev.c 2004-06-21 13:27:47.000000000 +0000
+++ linux-2.6.7-mm1/drivers/video/riva/fbdev.c 2004-06-21 18:02:18.000000000 +0000
@@ -498,6 +498,8 @@
u32 b, tmp;
u32 *data = (u32 *)data8;
+ memset_io(par->riva.CURSOR, 0, MAX_CURS * MAX_CURS * 2);
+
for (i = 0; i < h; i++) {
b = *data++;
reverse_order(&b);
@@ -1444,8 +1446,8 @@
static inline void convert_bgcolor_16(u32 *col)
{
- *col = ((*col & 0x00007C00) << 9)
- | ((*col & 0x000003E0) << 6)
+ *col = ((*col & 0x0000F800) << 8)
+ | ((*col & 0x00007E0) << 5)
| ((*col & 0x0000001F) << 3)
| 0xFF000000;
mb();
@@ -1573,27 +1575,29 @@
par->riva.PRAMDAC[0x0000300/4] = temp;
}
- if (cursor->set & FB_CUR_SETSIZE) {
- info->cursor.image.height = cursor->image.height;
- info->cursor.image.width = cursor->image.width;
- memset_io(par->riva.CURSOR, 0, MAX_CURS * MAX_CURS * 2);
- }
-
if (cursor->set & FB_CUR_SETCMAP) {
info->cursor.image.bg_color = cursor->image.bg_color;
info->cursor.image.fg_color = cursor->image.fg_color;
}
+ if (cursor->set & FB_CUR_SETSIZE) {
+ info->cursor.image.height = cursor->image.height;
+ info->cursor.image.width = cursor->image.width;
+ }
+
if (cursor->set & (FB_CUR_SETSHAPE | FB_CUR_SETCMAP | FB_CUR_SETCUR)) {
+ info->cursor.image.data = cursor->image.data;
+ }
+
+ if (info->cursor.enable) {
u32 bg_idx = info->cursor.image.bg_color;
u32 fg_idx = info->cursor.image.fg_color;
u32 s_pitch = (info->cursor.image.width+7) >> 3;
u32 d_pitch = MAX_CURS/8;
- u8 *dat = (u8 *) cursor->image.data;
+ u8 *dat = (u8 *) info->cursor.image.data;
u8 *msk = (u8 *) info->cursor.mask;
u8 src[64];
-
- info->cursor.image.data = cursor->image.data;
+
switch (info->cursor.rop) {
case ROP_XOR:
for (i = 0; i < s_pitch * info->cursor.image.height;
@@ -1624,9 +1628,9 @@
rivafb_load_cursor_image(par, data, bg, fg,
info->cursor.image.width,
info->cursor.image.height);
- }
- if (info->cursor.enable)
+
par->riva.ShowHideCursor(&par->riva, 1);
+ }
return 0;
}
@@ -1638,6 +1642,31 @@
return 0;
}
+static void rivafb_state_switch(struct fb_info *info, int out, int graphics)
+{
+ struct riva_par *par = (struct riva_par *) info->par;
+
+ if (out) {
+ if (!graphics)
+ par->save_state = par->initial_state;
+ } else {
+ if (graphics) {
+ par->riva.LockUnlock(&par->riva, 0);
+ riva_load_state(par, &par->save_state);
+ par->riva.LockUnlock(&par->riva, 1);
+ } else {
+ riva_common_setup(par);
+ RivaGetConfig(&par->riva, par->Chipset);
+ /* vgaHWunlock() + riva unlock (0x7F) */
+ CRTCout(par, 0x11, 0xFF);
+ par->riva.LockUnlock(&par->riva, 0);
+
+ info->fbops->fb_set_par(info);
+ }
+ }
+ par->reset = 1;
+}
+
/* ------------------------------------------------------------------------- *
*
* initialization helper functions
@@ -1659,6 +1688,7 @@
.fb_imageblit = rivafb_imageblit,
.fb_cursor = rivafb_cursor,
.fb_sync = rivafb_sync,
+ .fb_state_switch= rivafb_state_switch,
};
static int __devinit riva_set_fbinfo(struct fb_info *info)
@@ -1758,10 +1788,18 @@
#else
/* XXX use other methods later */
#ifdef CONFIG_FB_RIVA_I2C
+ int i;
+
struct riva_par *par = (struct riva_par *) info->par;
riva_create_i2c_busses(par);
- riva_probe_i2c_connector(par, 1, &par->EDID);
+ for (i = par->bus; i >= 1; i--) {
+ riva_probe_i2c_connector(par, i, &par->EDID);
+ if (par->EDID) {
+ printk("rivafb: Found EDID Block from BUS %i\n", i);
+ break;
+ }
+ }
riva_delete_i2c_busses(par);
#endif
#endif
@@ -1872,6 +1910,7 @@
goto err_out_free_nv3_pramin;
}
rivafb_fix.accel = FB_ACCEL_NV3;
+ default_par->bus = 1;
break;
case NV_ARCH_04:
case NV_ARCH_10:
@@ -1879,6 +1918,7 @@
default_par->riva.PCRTC0 = (unsigned *)(default_par->ctrl_base + 0x00600000);
default_par->riva.PRAMIN = (unsigned *)(default_par->ctrl_base + 0x00710000);
rivafb_fix.accel = FB_ACCEL_NV4;
+ default_par->bus = 2;
break;
}
@@ -1997,6 +2037,8 @@
iounmap((caddr_t)par->riva.PRAMIN);
release_mem_region(info->fix.smem_start + 0x00C00000, 0x00008000);
}
+ if (info->monspecs.modedb)
+ fb_destroy_modedb(info->monspecs.modedb);
kfree(info->pixmap.addr);
kfree(par);
kfree(info);
diff -Naur linux-2.6.7-mm1-orig/drivers/video/riva/rivafb.h linux-2.6.7-mm1/drivers/video/riva/rivafb.h
--- linux-2.6.7-mm1-orig/drivers/video/riva/rivafb.h 2004-06-21 13:27:47.000000000 +0000
+++ linux-2.6.7-mm1/drivers/video/riva/rivafb.h 2004-06-21 18:02:22.000000000 +0000
@@ -50,6 +50,7 @@
struct riva_regs initial_state; /* initial startup video mode */
struct riva_regs current_state;
+ struct riva_regs save_state;
struct vgastate state;
atomic_t ref_count;
u32 cursor_data[32 * 32/4];
@@ -60,6 +61,8 @@
Bool SecondCRTC;
int FlatPanel;
struct pci_dev *pdev;
+ int bus;
+ int reset;
#ifdef CONFIG_MTRR
struct { int vram; int vram_valid; } mtrr;
#endif
diff -Naur linux-2.6.7-mm1-orig/include/linux/console.h linux-2.6.7-mm1/include/linux/console.h
--- linux-2.6.7-mm1-orig/include/linux/console.h 2004-06-21 13:27:00.000000000 +0000
+++ linux-2.6.7-mm1/include/linux/console.h 2004-06-21 18:03:12.000000000 +0000
@@ -50,6 +50,7 @@
void (*con_invert_region)(struct vc_data *, u16 *, int);
u16 *(*con_screen_pos)(struct vc_data *, int);
unsigned long (*con_getxy)(struct vc_data *, unsigned long, int *, int *);
+ void (*con_notify)(struct vc_data *, struct vc_data *);
};
extern const struct consw *conswitchp;
-------------------------------------------------------
This SF.Net email sponsored by Black Hat Briefings & Training.
Attend Black Hat Briefings & Training, Las Vegas July 24-29 -
digital self defense, top technical experts, no vendor pitches,
unmatched networking opportunities. Visit www.blackhat.com
next reply other threads:[~2004-06-21 22:37 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2004-06-21 22:39 Antonino A. Daplas [this message]
2004-06-21 22:51 ` [PATCH 3/3] [FBDEV]: Hardware State Notification Antonino A. Daplas
2004-06-23 16:02 ` Benjamin Herrenschmidt
2004-06-23 23:50 ` Antonino A. Daplas
2004-06-24 2:35 ` Benjamin Herrenschmidt
2004-06-24 20:46 ` Antonino A. Daplas
2004-06-28 22:09 ` Benjamin Herrenschmidt
2004-06-28 22:48 ` Antonino A. Daplas
2004-06-29 0:55 ` Benjamin Herrenschmidt
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=200406220639.26576.adaplas@hotpop.com \
--to=adaplas@hotpop.com \
--cc=adaplas@pol.net \
--cc=akpm@osdl.org \
--cc=jsimmons@infradead.org \
--cc=linux-fbdev-devel@lists.sourceforge.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.