From: Antonino Daplas <adaplas@pol.net>
To: James Simmons <jsimmons@infradead.org>,
Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Linux Fbdev development list <linux-fbdev-devel@lists.sourceforge.net>
Subject: [PATCH 4/5]: i810fb fixes
Date: 16 Feb 2003 14:08:55 +0800 [thread overview]
Message-ID: <1045375698.1823.77.camel@localhost.localdomain> (raw)
[-- Attachment #1: Type: text/plain, Size: 296 bytes --]
Attached is a patch (linux-2.5.61 + James' fbdev.diff) to update i810fb:
1. added suspend/resume hooks to pci_driver. This is needed to
save/recover GART mappings during suspends/resumes. These are also
necessary for swsusp (software suspend) to work.
2. Fix compilation warnings.
Tony
[-- Attachment #2: i810fb2.diff --]
[-- Type: text/x-patch, Size: 12515 bytes --]
diff -Naur linux-2.5.61-fbdev/drivers/video/i810/i810.h linux-2.5.61-ad/drivers/video/i810/i810.h
--- linux-2.5.61-fbdev/drivers/video/i810/i810.h 2003-02-16 00:55:52.000000000 +0000
+++ linux-2.5.61-ad/drivers/video/i810/i810.h 2003-02-16 04:50:15.000000000 +0000
@@ -256,6 +256,7 @@
drm_agp_t *drm_agp;
atomic_t use_count;
u32 pseudo_palette[17];
+ u32 pci_state[16];
unsigned long mmio_start_phys;
u8 *mmio_start_virtual;
u32 cursor_reset;
@@ -273,6 +274,7 @@
u32 depth;
u32 blit_bpp;
u32 ovract;
+ u32 cur_state;
int mtrr_reg;
u16 bltcntl;
u8 interlace;
diff -Naur linux-2.5.61-fbdev/drivers/video/i810/i810_accel.c linux-2.5.61-ad/drivers/video/i810/i810_accel.c
--- linux-2.5.61-fbdev/drivers/video/i810/i810_accel.c 2003-02-16 00:55:52.000000000 +0000
+++ linux-2.5.61-ad/drivers/video/i810/i810_accel.c 2003-02-16 04:50:11.000000000 +0000
@@ -315,19 +315,19 @@
i810_writel(IRING + 12, mmio, tmp);
}
-void i810fb_fillrect(struct fb_info *p, const struct fb_fillrect *rect)
+void i810fb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
{
- struct i810fb_par *par = (struct i810fb_par *) p->par;
+ struct i810fb_par *par = (struct i810fb_par *) info->par;
u32 dx, dy, width, height, dest, rop = 0, color = 0;
- if (!p->var.accel_flags || par->dev_flags & LOCKUP ||
+ if (!info->var.accel_flags || par->dev_flags & LOCKUP ||
par->depth == 4)
- return cfb_fillrect(p, rect);
+ return cfb_fillrect(info, rect);
if (par->depth == 1)
color = rect->color;
else
- color = ((u32 *) (p->pseudo_palette))[rect->color];
+ color = ((u32 *) (info->pseudo_palette))[rect->color];
rop = i810fb_rop[rect->rop];
@@ -336,19 +336,19 @@
dy = rect->dy;
height = rect->height;
- dest = p->fix.smem_start + (dy * p->fix.line_length) + dx;
- color_blit(width, height, p->fix.line_length, dest, rop, color,
+ dest = info->fix.smem_start + (dy * info->fix.line_length) + dx;
+ color_blit(width, height, info->fix.line_length, dest, rop, color,
par->blit_bpp, par);
}
-void i810fb_copyarea(struct fb_info *p, struct fb_copyarea *region)
+void i810fb_copyarea(struct fb_info *info, const struct fb_copyarea *region)
{
- struct i810fb_par *par = (struct i810fb_par *) p->par;
+ struct i810fb_par *par = (struct i810fb_par *) info->par;
u32 sx, sy, dx, dy, pitch, width, height, src, dest, xdir;
- if (!p->var.accel_flags || par->dev_flags & LOCKUP ||
+ if (!info->var.accel_flags || par->dev_flags & LOCKUP ||
par->depth == 4)
- return cfb_copyarea(p, region);
+ return cfb_copyarea(info, region);
dx = region->dx * par->depth;
sx = region->sx * par->depth;
@@ -366,66 +366,68 @@
dx += width - 1;
}
if (dy <= sy) {
- pitch = p->fix.line_length;
+ pitch = info->fix.line_length;
}
else {
- pitch = (-(p->fix.line_length)) & 0xFFFF;
+ pitch = (-(info->fix.line_length)) & 0xFFFF;
sy += height - 1;
dy += height - 1;
}
- src = p->fix.smem_start + (sy * p->fix.line_length) + sx;
- dest = p->fix.smem_start + (dy * p->fix.line_length) + dx;
+ src = info->fix.smem_start + (sy * info->fix.line_length) + sx;
+ dest = info->fix.smem_start + (dy * info->fix.line_length) + dx;
source_copy_blit(width, height, pitch, xdir, src, dest,
PAT_COPY_ROP, par->blit_bpp, par);
}
-void i810fb_imageblit(struct fb_info *p, struct fb_image *image)
+void i810fb_imageblit(struct fb_info *info, const struct fb_image *image)
{
- struct i810fb_par *par = (struct i810fb_par *) p->par;
+ struct i810fb_par *par = (struct i810fb_par *) info->par;
u32 fg = 0, bg = 0, s_pitch, d_pitch, size, offset, dst, i, j;
u8 *s_addr, *d_addr;
- if (!p->var.accel_flags || par->dev_flags & LOCKUP ||
- par->depth == 4 || image->depth != 1)
- return cfb_imageblit(p, image);
+ if (!info->var.accel_flags || par->dev_flags & LOCKUP ||
+ par->depth == 4 || image->depth != 0)
+ return cfb_imageblit(info, image);
- switch (p->var.bits_per_pixel) {
+ switch (info->var.bits_per_pixel) {
case 8:
fg = image->fg_color;
bg = image->bg_color;
break;
case 16:
case 24:
- fg = ((u32 *)(p->pseudo_palette))[image->fg_color];
- bg = ((u32 *)(p->pseudo_palette))[image->bg_color];
+ fg = ((u32 *)(info->pseudo_palette))[image->fg_color];
+ bg = ((u32 *)(info->pseudo_palette))[image->bg_color];
break;
}
- dst = p->fix.smem_start + (image->dy * p->fix.line_length) +
+ dst = info->fix.smem_start + (image->dy * info->fix.line_length) +
(image->dx * par->depth);
s_pitch = (image->width+7)/8;
d_pitch = (s_pitch + 1) & ~1;
-
- size = (d_pitch * image->height) + 7;
- size &= ~7;
-
- if (image->width & 15) {
+ size = d_pitch * image->height;
+ if (s_pitch != d_pitch || size & 7) {
+ size += 7;
+ size &= ~7;
offset = get_buffer_offset(size, par);
d_addr = par->pixmap.virtual + offset;
- s_addr = image->data;
+ s_addr = (u8 *) image->data;
- for (i = image->height; i--; ) {
- for (j = 0; j < s_pitch; j++)
- i810_writeb(j, d_addr, s_addr[j]);
- s_addr += s_pitch;
- d_addr += d_pitch;
+ if (s_pitch == d_pitch) {
+ memcpy_toio(d_addr, s_addr, s_pitch * image->height);
+ } else {
+ for (i = image->height; i--; ) {
+ for (j = 0; j < s_pitch; j++)
+ i810_writeb(j, d_addr, s_addr[j]);
+ s_addr += s_pitch;
+ d_addr += d_pitch;
+ }
}
-
mono_src_copy_blit(image->width * par->depth, image->height,
- p->fix.line_length, size/8, par->blit_bpp,
- PAT_COPY_ROP, dst,
+ info->fix.line_length, size/8,
+ par->blit_bpp, PAT_COPY_ROP, dst,
par->pixmap.physical + offset,
bg, fg, par);
}
@@ -434,18 +436,18 @@
*/
else {
mono_src_copy_imm_blit(image->width * par->depth,
- image->height, p->fix.line_length,
+ image->height, info->fix.line_length,
size/4, par->blit_bpp,
PAT_COPY_ROP, dst, (u32 *) image->data,
bg, fg, par);
}
}
-int i810fb_sync(struct fb_info *p)
+int i810fb_sync(struct fb_info *info)
{
- struct i810fb_par *par = (struct i810fb_par *) p->par;
+ struct i810fb_par *par = (struct i810fb_par *) info->par;
- if (!p->var.accel_flags || par->dev_flags & LOCKUP)
+ if (!info->var.accel_flags || par->dev_flags & LOCKUP)
return 0;
return wait_for_engine_idle(par);
diff -Naur linux-2.5.61-fbdev/drivers/video/i810/i810_main.c linux-2.5.61-ad/drivers/video/i810/i810_main.c
--- linux-2.5.61-fbdev/drivers/video/i810/i810_main.c 2003-02-16 00:55:52.000000000 +0000
+++ linux-2.5.61-ad/drivers/video/i810/i810_main.c 2003-02-16 04:50:11.000000000 +0000
@@ -1437,6 +1437,68 @@
};
/***********************************************************************
+ * Power Management *
+ ***********************************************************************/
+static int i810fb_suspend(struct pci_dev *dev, u32 state)
+{
+ struct fb_info *info = pci_get_drvdata(dev);
+ struct i810fb_par *par = (struct i810fb_par *) info->par;
+ int blank = 0, prev_state = par->cur_state;
+
+ if (state == prev_state)
+ return 0;
+
+ par->cur_state = state;
+
+ switch (state) {
+ case 1:
+ blank = VESA_VSYNC_SUSPEND;
+ break;
+ case 2:
+ blank = VESA_HSYNC_SUSPEND;
+ break;
+ case 3:
+ blank = VESA_POWERDOWN;
+ break;
+ default:
+ return -EINVAL;
+ }
+ info->fbops->fb_blank(blank, info);
+
+ if (!prev_state) {
+ par->drm_agp->unbind_memory(par->i810_gtt.i810_fb_memory);
+ par->drm_agp->unbind_memory(par->i810_gtt.i810_cursor_memory);
+ pci_disable_device(dev);
+ }
+ pci_save_state(dev, par->pci_state);
+ pci_set_power_state(dev, state);
+
+ return 0;
+}
+
+static int i810fb_resume(struct pci_dev *dev)
+{
+ struct fb_info *info = pci_get_drvdata(dev);
+ struct i810fb_par *par = (struct i810fb_par *) info->par;
+
+ if (par->cur_state == 0)
+ return 0;
+
+ pci_restore_state(dev, par->pci_state);
+ pci_set_power_state(dev, 0);
+ pci_enable_device(dev);
+ par->drm_agp->bind_memory(par->i810_gtt.i810_fb_memory,
+ par->fb.offset);
+ par->drm_agp->bind_memory(par->i810_gtt.i810_cursor_memory,
+ par->cursor_heap.offset);
+
+ info->fbops->fb_blank(VESA_NO_BLANKING, info);
+
+ par->cur_state = 0;
+
+ return 0;
+}
+/***********************************************************************
* AGP resource allocation *
***********************************************************************/
@@ -1469,13 +1531,13 @@
par->fb.offset = v_offset_default << 20;
par->fb.offset >>= 12;
- par->iring.offset = par->fb.offset + (par->fb.size >> 12);
- par->iring.size = RINGBUFFER_SIZE;
-
- par->pixmap.offset = par->iring.offset + (RINGBUFFER_SIZE >> 12);
+ par->pixmap.offset = par->fb.offset + (par->fb.size >> 12);
par->pixmap.size = PIXMAP_SIZE;
- par->cursor_heap.offset = par->pixmap.offset + (PIXMAP_SIZE >> 12);
+ par->iring.offset = par->pixmap.offset + (PIXMAP_SIZE >> 12);
+ par->iring.size = RINGBUFFER_SIZE;
+
+ par->cursor_heap.offset = par->iring.offset + (RINGBUFFER_SIZE >> 12);
par->cursor_heap.size = 4096;
}
@@ -1817,12 +1879,16 @@
vfreq = hfreq/(info->var.yres + info->var.upper_margin +
info->var.vsync_len + info->var.lower_margin);
- printk("fb: %s v%d.%d.%d%s, (c) Tony Daplas\n"
- " Video RAM : %dK\n"
- " Mode : %dx%d-%dbpp@%dHz\n",
+ printk("I810FB: fb%d : %s v%d.%d.%d%s\n"
+ "I810FB: Video RAM : %dK\n"
+ "I810FB: Monitor : H: %d-%d KHz V: %d-%d Hz\n"
+ "I810FB: Mode : %dx%d-%dbpp@%dHz\n",
+ minor(info->node),
i810_pci_list[entry->driver_data],
VERSION_MAJOR, VERSION_MINOR, VERSION_TEENIE, BRANCH_VERSION,
- (int) par->fb.size>>10, info->var.xres,
+ (int) par->fb.size>>10, info->monspecs.hfmin/1000,
+ info->monspecs.hfmax/1000, info->monspecs.vfmin,
+ info->monspecs.vfmax, info->var.xres,
info->var.yres, info->var.bits_per_pixel, vfreq);
return 0;
}
@@ -1893,7 +1959,10 @@
return -ENODEV;
}
- return (pci_module_init(&i810fb_driver));
+ if (pci_register_driver(&i810fb_driver) > 0)
+ return 0;
+ pci_unregister_driver(&i810fb_driver);
+ return -ENODEV;
}
#endif
@@ -1909,7 +1978,10 @@
hsync1 *= 1000;
hsync2 *= 1000;
- return (pci_module_init(&i810fb_driver));
+ if (pci_register_driver(&i810fb_driver) > 0)
+ return 0;
+ pci_unregister_driver(&i810fb_driver);
+ return -ENODEV;
}
MODULE_PARM(vram, "i");
diff -Naur linux-2.5.61-fbdev/drivers/video/i810/i810_main.h linux-2.5.61-ad/drivers/video/i810/i810_main.h
--- linux-2.5.61-fbdev/drivers/video/i810/i810_main.h 2003-02-16 00:55:52.000000000 +0000
+++ linux-2.5.61-ad/drivers/video/i810/i810_main.h 2003-02-16 04:50:15.000000000 +0000
@@ -43,12 +43,16 @@
static int __init i810fb_init_pci (struct pci_dev *dev,
const struct pci_device_id *entry);
static void __exit i810fb_remove_pci(struct pci_dev *dev);
+static int i810fb_resume(struct pci_dev *dev);
+static int i810fb_suspend(struct pci_dev *dev, u32 state);
static struct pci_driver i810fb_driver = {
.name = "i810fb",
.id_table = i810fb_pci_tbl,
.probe = i810fb_init_pci,
.remove = __exit_p(i810fb_remove_pci),
+ .suspend = i810fb_suspend,
+ .resume = i810fb_resume,
};
static int i810_init __initdata = 0;
@@ -121,9 +125,11 @@
extern void i810fb_fill_var_timings(struct fb_var_screeninfo *var);
/* Accelerated Functions */
-extern void i810fb_fillrect (struct fb_info *p, const struct fb_fillrect *rect);
-extern void i810fb_copyarea (struct fb_info *p, struct fb_copyarea *region);
-extern void i810fb_imageblit(struct fb_info *p, struct fb_image *image);
+extern void i810fb_fillrect (struct fb_info *p,
+ const struct fb_fillrect *rect);
+extern void i810fb_copyarea (struct fb_info *p,
+ const struct fb_copyarea *region);
+extern void i810fb_imageblit(struct fb_info *p, const struct fb_image *image);
extern int i810fb_sync (struct fb_info *p);
extern void i810fb_init_ringbuffer (struct i810fb_par *par);
next reply other threads:[~2003-02-16 6:10 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2003-02-16 6:08 Antonino Daplas [this message]
2003-02-16 16:39 ` [PATCH 4/5]: i810fb fixes James Simmons
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=1045375698.1823.77.camel@localhost.localdomain \
--to=adaplas@pol.net \
--cc=geert@linux-m68k.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.