patch-2.2.14 linux/drivers/video/atyfb.c
Next file: linux/drivers/video/bwtwofb.c
Previous file: linux/drivers/video/Config.in
Back to the patch index
Back to the overall index
- Lines: 225
- Date:
Tue Jan 4 10:12:22 2000
- Orig file:
v2.2.13/linux/drivers/video/atyfb.c
- Orig date:
Tue Jan 4 11:10:39 2000
diff -u --recursive --new-file v2.2.13/linux/drivers/video/atyfb.c linux/drivers/video/atyfb.c
@@ -1,4 +1,4 @@
-/* $Id: atyfb.c,v 1.106.2.4 1999/09/02 06:34:46 paulus Exp $
+/* $Id: atyfb.c,v 1.106.2.6 1999/10/14 08:44:47 davem Exp $
* linux/drivers/video/atyfb.c -- Frame buffer device for ATI Mach64
*
* Copyright (C) 1997-1998 Geert Uytterhoeven
@@ -89,7 +89,6 @@
*/
#undef DEBUG
-
#define GUI_RESERVE 0x00001000
@@ -227,8 +226,8 @@
} fbcon_cmap;
u8 blitter_may_be_busy;
#ifdef __sparc__
- u8 open;
u8 mmaped;
+ int open;
int vtconsole;
int consolecnt;
#endif
@@ -1896,10 +1895,8 @@
struct fb_info_aty *fb = (struct fb_info_aty *)info;
if (user) {
- if (fb->open)
- return -EBUSY;
+ fb->open++;
fb->mmaped = 0;
- fb->open = 1;
fb->vtconsole = -1;
} else {
fb->consolecnt++;
@@ -1909,17 +1906,54 @@
return(0);
}
+struct fb_var_screeninfo default_var = {
+ /* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */
+ 640, 480, 640, 480, 0, 0, 8, 0,
+ {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+ 0, 0, -1, -1, 0, 39722, 48, 16, 33, 10, 96, 2,
+ 0, FB_VMODE_NONINTERLACED
+};
+
static int atyfb_release(struct fb_info *info, int user)
{
#ifdef __sparc__
struct fb_info_aty *fb = (struct fb_info_aty *)info;
if (user) {
- if (fb->vtconsole != -1)
- vt_cons[fb->vtconsole]->vc_mode = KD_TEXT;
- fb->open = 0;
- fb->mmaped = 0;
- fb->vtconsole = -1;
+ fb->open--;
+ udelay(1000);
+ wait_for_idle(fb);
+ if (!fb->open) {
+ int was_mmaped = fb->mmaped;
+
+ fb->mmaped = 0;
+ if (fb->vtconsole != -1)
+ vt_cons[fb->vtconsole]->vc_mode = KD_TEXT;
+ fb->vtconsole = -1;
+
+ if (was_mmaped) {
+ struct fb_var_screeninfo var;
+
+ /* Now reset the default display config, we have no
+ * idea what the program(s) which mmap'd the chip did
+ * to the configuration, nor whether it restored it
+ * correctly.
+ */
+ var = default_var;
+ if (noaccel)
+ var.accel_flags &= ~FB_ACCELF_TEXT;
+ else
+ var.accel_flags |= FB_ACCELF_TEXT;
+ if (var.yres == var.yres_virtual) {
+ u32 vram = (fb->total_vram - (PAGE_SIZE << 2));
+ var.yres_virtual = ((vram * 8) / var.bits_per_pixel) /
+ var.xres_virtual;
+ if (var.yres_virtual < var.yres)
+ var.yres_virtual = var.yres;
+ }
+ atyfb_set_var(&var, -1, &fb->fb_info);
+ }
+ }
} else {
fb->consolecnt--;
}
@@ -1982,15 +2016,6 @@
}
-struct fb_var_screeninfo default_var = {
- /* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */
- 640, 480, 640, 480, 0, 0, 8, 0,
- {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
- 0, 0, -1, -1, 0, 39722, 48, 16, 33, 10, 96, 2,
- 0, FB_VMODE_NONINTERLACED
-};
-
-
/*
* Get the Fixed Part of the Display
*/
@@ -3909,47 +3934,65 @@
{
struct fb_info_aty *info;
unsigned int pm;
-
+
for (info = first_display; info != NULL; info = info->next) {
struct fb_fix_screeninfo fix;
int nb;
-
+
atyfb_get_fix(&fix, fg_console, (struct fb_info *)info);
nb = fb_display[fg_console].var.yres * fix.line_length;
switch (when) {
+ case PBOOK_SLEEP_REQUEST:
+ info->save_framebuffer = vmalloc(nb);
+ break;
+ case PBOOK_SLEEP_REJECT:
+ if (info->save_framebuffer) {
+ vfree(info->save_framebuffer);
+ info->save_framebuffer = 0;
+ }
+ break;
case PBOOK_SLEEP_NOW:
+ if (info->blitter_may_be_busy)
+ wait_for_idle(info);
/* Stop accel engine (stop bus mastering) */
if (info->current_par.accel_flags & FB_ACCELF_TEXT)
reset_engine(info);
-#if 1
+
/* Backup fb content */
- info->save_framebuffer = vmalloc(nb);
if (info->save_framebuffer)
memcpy(info->save_framebuffer,
(void *)info->frame_buffer, nb);
-#endif
- /* Blank display and LCD */
- atyfbcon_blank(VESA_POWERDOWN+1, (struct fb_info *)info);
-
- /* Set chip to "suspend" mode. Note: There's an HW bug in the
- chip which prevents proper resync on wakeup with automatic
- power management, we handle suspend manually using the
- following (weird) sequence described by ATI. Note2:
+
+ /* Blank display and LCD */
+ atyfbcon_blank(VESA_POWERDOWN+1, (struct fb_info *)info);
+
+ /* Set chip to "suspend" mode. Note: There's a HW bug
+ in the chip which prevents proper resync on wakeup
+ with automatic power management, we handle suspend
+ manually using the following (weird) sequence
+ described by ATI.
+ Note2:
We could enable this for all Rage LT Pro chip ids */
- if ((Gx == LG_CHIP_ID) || (Gx == LT_CHIP_ID) || (Gx == LP_CHIP_ID)) {
+ if ((Gx == LG_CHIP_ID) || (Gx == LT_CHIP_ID)
+ || (Gx == LP_CHIP_ID)) {
pm = aty_ld_le32(POWER_MANAGEMENT, info);
pm &= ~PWR_MGT_ON;
aty_st_le32(POWER_MANAGEMENT, pm, info);
pm = aty_ld_le32(POWER_MANAGEMENT, info);
+ mdelay(1);
pm &= ~(PWR_BLON | AUTO_PWR_UP);
pm |= SUSPEND_NOW;
aty_st_le32(POWER_MANAGEMENT, pm, info);
pm = aty_ld_le32(POWER_MANAGEMENT, info);
+ mdelay(1);
pm |= PWR_MGT_ON;
aty_st_le32(POWER_MANAGEMENT, pm, info);
do {
pm = aty_ld_le32(POWER_MANAGEMENT, info);
+ /* Fix a problem with revision 4c50 of the chip */
+ if (Gx == LP_CHIP_ID)
+ break;
} while ((pm & PWR_MGT_STATUS_MASK) != PWR_MGT_STATUS_SUSPEND);
mdelay(500);
}
@@ -3961,18 +4004,23 @@
pm &= ~PWR_MGT_ON;
aty_st_le32(POWER_MANAGEMENT, pm, info);
pm = aty_ld_le32(POWER_MANAGEMENT, info);
+ mdelay(1);
pm |= (PWR_BLON | AUTO_PWR_UP);
pm &= ~SUSPEND_NOW;
aty_st_le32(POWER_MANAGEMENT, pm, info);
pm = aty_ld_le32(POWER_MANAGEMENT, info);
+ mdelay(1);
pm |= PWR_MGT_ON;
aty_st_le32(POWER_MANAGEMENT, pm, info);
do {
pm = aty_ld_le32(POWER_MANAGEMENT, info);
+ /* Fix a problem with revision 4c50 of the chip */
+ if (Gx == LP_CHIP_ID)
+ break;
} while ((pm & PWR_MGT_STATUS_MASK) != 0);
mdelay(500);
}
-#if 1
+
/* Restore fb content */
if (info->save_framebuffer) {
memcpy((void *)info->frame_buffer,
@@ -3980,7 +4028,7 @@
vfree(info->save_framebuffer);
info->save_framebuffer = 0;
}
-#endif
+
/* Restore display */
atyfb_set_par(&info->current_par, info);
atyfbcon_blank(0, (struct fb_info *)info);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)