* Resource management.
@ 2005-02-21 19:11 James Simmons
2005-02-21 22:53 ` Antonino A. Daplas
0 siblings, 1 reply; 16+ messages in thread
From: James Simmons @ 2005-02-21 19:11 UTC (permalink / raw)
To: Antonino A. Daplas; +Cc: Geert Uytterhoeven, Linux Fbdev development list
Hi!
This is my first run at the resource management code. Comments are
welcomed :-)
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/Makefile fbdev-2.6/drivers/video/Makefile
--- linus-2.6/drivers/video/Makefile 2005-02-21 10:38:42.000000000 -0800
+++ fbdev-2.6/drivers/video/Makefile 2005-02-17 14:26:42.000000000 -0800
@@ -8,7 +8,7 @@
obj-$(CONFIG_LOGO) += logo/
obj-$(CONFIG_SYSFS) += backlight/
-obj-$(CONFIG_FB) += fbmem.o fbmon.o fbcmap.o fbsysfs.o modedb.o softcursor.o
+obj-$(CONFIG_FB) += fbmem.o fbmon.o fbcmap.o fbsysfs.o modedb.o resmgt.o softcursor.o
# Only include macmodes.o if we have FB support and are PPC
ifeq ($(CONFIG_FB),y)
obj-$(CONFIG_PPC) += macmodes.o
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/console/bitblit.c fbdev-2.6/drivers/video/console/bitblit.c
--- linus-2.6/drivers/video/console/bitblit.c 2005-02-21 10:38:47.000000000 -0800
+++ fbdev-2.6/drivers/video/console/bitblit.c 2005-02-18 10:35:23.000000000 -0800
@@ -114,12 +114,13 @@
void (*move_aligned)(struct fb_info *info, struct fb_pixmap *buf,
u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch,
u32 height);
+ struct fb_pixmap *pad = fb_find_resource("scratchpad", &info->resources);
unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
unsigned int width = (vc->vc_font.width + 7) >> 3;
unsigned int cellsize = vc->vc_font.height * width;
- unsigned int maxcnt = info->pixmap.size/cellsize;
- unsigned int scan_align = info->pixmap.scan_align - 1;
- unsigned int buf_align = info->pixmap.buf_align - 1;
+ unsigned int maxcnt = pad->size/cellsize;
+ unsigned int scan_align = pad->scan_align - 1;
+ unsigned int buf_align = pad->buf_align - 1;
unsigned int shift_low = 0, mod = vc->vc_font.width % 8;
unsigned int shift_high = 8, pitch, cnt, size, k;
unsigned int idx = vc->vc_font.width >> 3;
@@ -141,7 +142,7 @@
image.height = vc->vc_font.height;
image.depth = 1;
- if (info->pixmap.outbuf && info->pixmap.inbuf) {
+ if (pad->outbuf && pad->inbuf) {
move_aligned = fb_iomove_buf_aligned;
move_unaligned = fb_iomove_buf_unaligned;
} else {
@@ -159,7 +160,7 @@
pitch &= ~scan_align;
size = pitch * image.height + buf_align;
size &= ~buf_align;
- dst = fb_get_buffer_offset(info, &info->pixmap, size);
+ dst = fb_get_buffer_offset(info, pad, size);
image.data = dst;
if (mod) {
while (k--) {
@@ -171,9 +172,9 @@
src = buf;
}
- move_unaligned(info, &info->pixmap, dst, pitch,
- src, idx, image.height,
- shift_high, shift_low, mod);
+ move_unaligned(info, pad, dst, pitch, src, idx,
+ image.height, shift_high, shift_low,
+ mod);
shift_low += mod;
dst += (shift_low >= 8) ? width : width - 1;
shift_low &= 7;
@@ -189,8 +190,7 @@
src = buf;
}
- move_aligned(info, &info->pixmap, dst, pitch,
- src, idx, image.height);
+ move_aligned(info, pad, dst, pitch, src, idx, image.height);
dst += width;
}
}
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/console/tileblit.c fbdev-2.6/drivers/video/console/tileblit.c
--- linus-2.6/drivers/video/console/tileblit.c 2005-02-21 10:38:47.000000000 -0800
+++ fbdev-2.6/drivers/video/console/tileblit.c 2005-02-18 10:35:42.000000000 -0800
@@ -56,9 +56,10 @@
const unsigned short *s, int count, int yy, int xx,
int fg, int bg)
{
- struct fb_tileblit blit;
+ struct fb_pixmap *pad = fb_find_resource("scratchpad", &info->resources);
unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
int size = sizeof(u32) * count, i;
+ struct fb_tileblit blit;
blit.sx = xx;
blit.sy = yy;
@@ -67,7 +68,7 @@
blit.fg = fg;
blit.bg = bg;
blit.length = count;
- blit.indices = (u32 *) fb_get_buffer_offset(info, &info->pixmap, size);
+ blit.indices = (u32 *) fb_get_buffer_offset(info, pad, size);
for (i = 0; i < count; i++)
blit.indices[i] = (u32)(scr_readw(s++) & charmask);
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/fbmem.c fbdev-2.6/drivers/video/fbmem.c
--- linus-2.6/drivers/video/fbmem.c 2005-01-24 09:43:47.000000000 -0800
+++ fbdev-2.6/drivers/video/fbmem.c 2005-02-21 10:31:38.000000000 -0800
@@ -52,8 +52,6 @@
* Frame buffer device initialization and setup routines
*/
-#define FBPIXMAPSIZE (1024 * 8)
-
static struct notifier_block *fb_notifier_list;
struct fb_info *registered_fb[FB_MAX];
int num_registered_fb;
@@ -77,134 +75,6 @@
}
EXPORT_SYMBOL(fb_get_color_depth);
-/*
- * Drawing helpers.
- */
-void fb_iomove_buf_aligned(struct fb_info *info, struct fb_pixmap *buf,
- u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch,
- u32 height)
-{
- int i;
-
- for (i = height; i--; ) {
- buf->outbuf(info, dst, src, s_pitch);
- src += s_pitch;
- dst += d_pitch;
- }
-}
-
-void fb_sysmove_buf_aligned(struct fb_info *info, struct fb_pixmap *buf,
- u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch,
- u32 height)
-{
- int i, j;
-
- for (i = height; i--; ) {
- for (j = 0; j < s_pitch; j++)
- dst[j] = src[j];
- src += s_pitch;
- dst += d_pitch;
- }
-}
-
-void fb_iomove_buf_unaligned(struct fb_info *info, struct fb_pixmap *buf,
- u8 *dst, u32 d_pitch, u8 *src, u32 idx,
- u32 height, u32 shift_high, u32 shift_low,
- u32 mod)
-{
- u8 mask = (u8) (0xfff << shift_high), tmp;
- int i, j;
-
- for (i = height; i--; ) {
- for (j = 0; j < idx; j++) {
- tmp = buf->inbuf(info, dst+j);
- tmp &= mask;
- tmp |= *src >> shift_low;
- buf->outbuf(info, dst+j, &tmp, 1);
- tmp = *src << shift_high;
- buf->outbuf(info, dst+j+1, &tmp, 1);
- src++;
- }
- tmp = buf->inbuf(info, dst+idx);
- tmp &= mask;
- tmp |= *src >> shift_low;
- buf->outbuf(info, dst+idx, &tmp, 1);
- if (shift_high < mod) {
- tmp = *src << shift_high;
- buf->outbuf(info, dst+idx+1, &tmp, 1);
- }
- src++;
- dst += d_pitch;
- }
-}
-
-void fb_sysmove_buf_unaligned(struct fb_info *info, struct fb_pixmap *buf,
- u8 *dst, u32 d_pitch, u8 *src, u32 idx,
- u32 height, u32 shift_high, u32 shift_low,
- u32 mod)
-{
- u8 mask = (u8) (0xfff << shift_high), tmp;
- int i, j;
-
- for (i = height; i--; ) {
- for (j = 0; j < idx; j++) {
- tmp = dst[j];
- tmp &= mask;
- tmp |= *src >> shift_low;
- dst[j] = tmp;
- tmp = *src << shift_high;
- dst[j+1] = tmp;
- src++;
- }
- tmp = dst[idx];
- tmp &= mask;
- tmp |= *src >> shift_low;
- dst[idx] = tmp;
- if (shift_high < mod) {
- tmp = *src << shift_high;
- dst[idx+1] = tmp;
- }
- src++;
- dst += d_pitch;
- }
-}
-
-/*
- * we need to lock this section since fb_cursor
- * may use fb_imageblit()
- */
-char* fb_get_buffer_offset(struct fb_info *info, struct fb_pixmap *buf, u32 size)
-{
- u32 align = buf->buf_align - 1, offset;
- char *addr = buf->addr;
-
- /* If IO mapped, we need to sync before access, no sharing of
- * the pixmap is done
- */
- if (buf->flags & FB_PIXMAP_IO) {
- if (info->fbops->fb_sync && (buf->flags & FB_PIXMAP_SYNC))
- info->fbops->fb_sync(info);
- return addr;
- }
-
- /* See if we fit in the remaining pixmap space */
- offset = buf->offset + align;
- offset &= ~align;
- if (offset + size > buf->size) {
- /* We do not fit. In order to be able to re-use the buffer,
- * we must ensure no asynchronous DMA'ing or whatever operation
- * is in progress, we sync for that.
- */
- if (info->fbops->fb_sync && (buf->flags & FB_PIXMAP_SYNC))
- info->fbops->fb_sync(info);
- offset = 0;
- }
- buf->offset = offset + size;
- addr += offset;
-
- return addr;
-}
-
#ifdef CONFIG_LOGO
#include <linux/linux_logo.h>
@@ -1075,18 +945,8 @@
/* Not fatal */
printk(KERN_WARNING "Unable to create class_device for framebuffer %d; errno = %ld\n", i, PTR_ERR(c));
}
-
- if (fb_info->pixmap.addr == NULL) {
- fb_info->pixmap.addr = kmalloc(FBPIXMAPSIZE, GFP_KERNEL);
- if (fb_info->pixmap.addr) {
- fb_info->pixmap.size = FBPIXMAPSIZE;
- fb_info->pixmap.buf_align = 1;
- fb_info->pixmap.scan_align = 1;
- fb_info->pixmap.access_align = 4;
- fb_info->pixmap.flags = FB_PIXMAP_DEFAULT;
- }
- }
- fb_info->pixmap.offset = 0;
+
+ fb_init_resources(fb_info);
if (!fb_info->modelist.prev ||
!fb_info->modelist.next ||
@@ -1128,9 +988,7 @@
if (!registered_fb[i])
return -EINVAL;
devfs_remove("fb/%d", i);
-
- if (fb_info->pixmap.addr && (fb_info->pixmap.flags & FB_PIXMAP_DEFAULT))
- kfree(fb_info->pixmap.addr);
+ fb_release_resources(&fb_info->resources);
fb_destroy_modelist(&fb_info->modelist);
registered_fb[i]=NULL;
num_registered_fb--;
@@ -1308,11 +1166,6 @@
EXPORT_SYMBOL(fb_set_var);
EXPORT_SYMBOL(fb_blank);
EXPORT_SYMBOL(fb_pan_display);
-EXPORT_SYMBOL(fb_get_buffer_offset);
-EXPORT_SYMBOL(fb_iomove_buf_unaligned);
-EXPORT_SYMBOL(fb_iomove_buf_aligned);
-EXPORT_SYMBOL(fb_sysmove_buf_unaligned);
-EXPORT_SYMBOL(fb_sysmove_buf_aligned);
EXPORT_SYMBOL(fb_set_suspend);
EXPORT_SYMBOL(fb_register_client);
EXPORT_SYMBOL(fb_unregister_client);
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/neofb.c fbdev-2.6/drivers/video/neofb.c
--- linus-2.6/drivers/video/neofb.c 2005-02-21 10:38:44.000000000 -0800
+++ fbdev-2.6/drivers/video/neofb.c 2005-02-18 14:55:58.000000000 -0800
@@ -1472,10 +1472,11 @@
static void
neo2200_imageblit(struct fb_info *info, const struct fb_image *image)
{
+ struct fb_pixmap *pad = fb_find_resource("drawable", &info->resources);
struct neofb_par *par = (struct neofb_par *) info->par;
int s_pitch = (image->width * image->depth + 7) >> 3;
- int scan_align = info->pixmap.scan_align - 1;
- int buf_align = info->pixmap.buf_align - 1;
+ int scan_align = pad->scan_align - 1;
+ int buf_align = pad->buf_align - 1;
int bltCntl_flags, d_pitch, data_len;
// The data is padded for the hardware
@@ -1728,8 +1729,6 @@
static int __devinit neo_map_video(struct fb_info *info,
struct pci_dev *dev, int video_len)
{
- //unsigned long addr;
-
DBG("neo_map_video");
info->fix.smem_start = pci_resource_start(dev, 0);
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/resmgt.c fbdev-2.6/drivers/video/resmgt.c
--- linus-2.6/drivers/video/resmgt.c 1969-12-31 16:00:00.000000000 -0800
+++ fbdev-2.6/drivers/video/resmgt.c 2005-02-18 12:23:43.000000000 -0800
@@ -0,0 +1,279 @@
+/*
+ * linux/drivers/video/resmgt.c -- Manages the resources of a graphics card.
+ *
+ * Copyright (C) 2005 James Simmons <jsimmons@www.infradead.org>
+ *
+ * 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/module.h>
+#include <linux/fb.h>
+
+#undef DEBUG
+
+#ifdef DEBUG
+#define DPRINTK(fmt, args...) printk("modedb %s: " fmt, __FUNCTION__ , ## args)
+#else
+#define DPRINTK(fmt, args...)
+#endif
+
+#define FBPIXMAPSIZE (1024 * 8)
+
+/*
+ * Data padding functions.
+ */
+void fb_sysmove_buf_aligned(struct fb_info *info, struct fb_pixmap *buf,
+ u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch,
+ u32 height)
+{
+ int i, j;
+
+ for (i = height; i--; ) {
+ for (j = 0; j < s_pitch; j++)
+ dst[j] = src[j];
+ src += s_pitch;
+ dst += d_pitch;
+ }
+}
+EXPORT_SYMBOL(fb_sysmove_buf_aligned);
+
+void fb_sysmove_buf_unaligned(struct fb_info *info, struct fb_pixmap *buf,
+ u8 *dst, u32 d_pitch, u8 *src, u32 idx, u32 height,
+ u32 shift_high, u32 shift_low, u32 mod)
+{
+ u8 mask = (u8) (0xfff << shift_high), tmp;
+ int i, j;
+
+ for (i = height; i--; ) {
+ for (j = 0; j < idx; j++) {
+ tmp = dst[j];
+ tmp &= mask;
+ tmp |= *src >> shift_low;
+ dst[j] = tmp;
+ tmp = *src << shift_high;
+ dst[j+1] = tmp;
+ src++;
+ }
+ tmp = dst[idx];
+ tmp &= mask;
+ tmp |= *src >> shift_low;
+ dst[idx] = tmp;
+ if (shift_high < mod) {
+ tmp = *src << shift_high;
+ dst[idx+1] = tmp;
+ }
+ src++;
+ dst += d_pitch;
+ }
+}
+EXPORT_SYMBOL(fb_sysmove_buf_unaligned);
+
+void fb_iomove_buf_aligned(struct fb_info *info, struct fb_pixmap *pad,
+ u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch,
+ u32 height)
+{
+ int i;
+
+ for (i = height; i--; ) {
+ pad->outbuf(info, dst, src, s_pitch);
+ src += s_pitch;
+ dst += d_pitch;
+ }
+}
+EXPORT_SYMBOL(fb_iomove_buf_aligned);
+
+void fb_iomove_buf_unaligned(struct fb_info *info, struct fb_pixmap *pad,
+ u8 *dst, u32 d_pitch, u8 *src, u32 idx, u32 height,
+ u32 shift_high, u32 shift_low, u32 mod)
+{
+ u8 mask = (u8) (0xfff << shift_high), tmp;
+ u8 __iomem *buf;
+ int i, j;
+
+ for (i = height; i--; ) {
+ for (j = 0; j < idx; j++) {
+ buf = pad->inbuf(info, dst+j, 1);
+ tmp = *buf;
+ tmp &= mask;
+ tmp |= *src >> shift_low;
+ pad->outbuf(info, dst+j, &tmp, 1);
+ tmp = *src << shift_high;
+ pad->outbuf(info, dst+j+1, &tmp, 1);
+ src++;
+ }
+ buf = pad->inbuf(info, dst+idx, 1);
+ tmp = *buf;
+ tmp &= mask;
+ tmp |= *src >> shift_low;
+ pad->outbuf(info, dst+idx, &tmp, 1);
+ if (shift_high < mod) {
+ tmp = *src << shift_high;
+ pad->outbuf(info, dst+idx+1, &tmp, 1);
+ }
+ src++;
+ dst += d_pitch;
+ }
+}
+EXPORT_SYMBOL(fb_iomove_buf_unaligned);
+
+/*
+ * we need to lock this section since fb_cursor
+ * may use fb_imageblit()
+ */
+char* fb_get_buffer_offset(struct fb_info *info, struct fb_pixmap *buf, u32 size)
+{
+ u32 align = buf->buf_align - 1, offset;
+ char *addr = buf->addr;
+
+ /* If IO mapped, we need to sync before access, no sharing of
+ * the pixmap is done
+ */
+ if (buf->flags & FB_PIXMAP_IO) {
+ if (info->fbops->fb_sync && (buf->flags & FB_PIXMAP_SYNC))
+ info->fbops->fb_sync(info);
+ return addr;
+ }
+
+ /* See if we fit in the remaining pixmap space */
+ offset = buf->offset + align;
+ offset &= ~align;
+ if (offset + size > buf->size) {
+ /* We do not fit. In order to be able to re-use the buffer,
+ * we must ensure no asynchronous DMA'ing or whatever operation
+ * is in progress, we sync for that.
+ */
+ if (info->fbops->fb_sync && (buf->flags & FB_PIXMAP_SYNC))
+ info->fbops->fb_sync(info);
+ offset = 0;
+ }
+ buf->offset = offset + size;
+ addr += offset;
+ return addr;
+}
+EXPORT_SYMBOL(fb_get_buffer_offset);
+
+struct graphics_resource {
+ struct fb_pixmap *resource;
+ struct list_head list;
+};
+
+struct fb_pixmap * fb_find_resource(const char *name, struct list_head *head)
+{
+ struct graphics_resource *rlist = NULL;
+ struct fb_pixmap *resource;
+ struct list_head *pos;
+
+ list_for_each(pos, head) {
+ rlist = list_entry(pos, struct graphics_resource, list);
+ resource = rlist->resource;
+ if (!strncmp(resource->name, name, strlen(name)))
+ return rlist->resource;
+ }
+ return NULL;
+}
+
+int fb_add_resource(struct fb_pixmap *res, struct list_head *head)
+{
+ struct fb_pixmap *resource = fb_find_resource(res->name, head);
+ struct graphics_resource *rlist = NULL;
+
+ if (resource)
+ return 1;
+ rlist = kmalloc(sizeof(struct graphics_resource), GFP_KERNEL);
+ if (!rlist)
+ return -ENOMEM;
+ rlist->resource = res;
+ list_add(&rlist->list, head);
+ return 0;
+}
+
+int fb_remove_resource(struct fb_pixmap *resource, struct list_head *head)
+{
+ struct graphics_resource *rlist;
+ struct list_head *pos, *n;
+
+ if (!resource)
+ return 0;
+
+ list_for_each_safe(pos, n, head) {
+ rlist = list_entry(pos, struct graphics_resource, list);
+ if (!strncmp(resource->name, rlist->resource->name, strlen(rlist->resource->name))) {
+ if (rlist->resource->addr && (rlist->resource->flags & FB_PIXMAP_DEFAULT))
+ kfree(rlist->resource->addr);
+ kfree(rlist->resource);
+ list_del(pos);
+ kfree(pos);
+ }
+ }
+ return 0;
+}
+
+int fb_init_resources(struct fb_info *info)
+{
+ int size = sizeof(struct fb_pixmap) + FBPIXMAPSIZE;
+ struct fb_pixmap *pad, *buf;
+ char *p;
+
+ if (!info->resources.prev || !info->resources.next ||
+ list_empty(&info->resources))
+ INIT_LIST_HEAD(&info->resources);
+
+ // First we create our drawing pad
+ pad = fb_find_resource("scratchpad", &info->resources);
+ if (!pad) {
+ // Next we create our scratch pad.
+ p = kmalloc(size, GFP_KERNEL);
+ if (!p)
+ return -ENOMEM;
+ memset(p, 0, size);
+
+ pad = (struct fb_pixmap *) p;
+ pad->addr = p + sizeof(struct fb_pixmap);
+ strcpy(pad->name, "scratchpad");
+ pad->size = FBPIXMAPSIZE;
+ pad->buf_align = 1;
+ pad->scan_align = 1;
+ pad->access_align = 4;
+ pad->flags = FB_PIXMAP_DEFAULT;
+ pad->offset = 0;
+ fb_add_resource(pad, &info->resources);
+ }
+ // Now we create the framebuffer drawable surface
+ p = kmalloc(sizeof(struct fb_pixmap), GFP_KERNEL);
+ if (!p) {
+ fb_remove_resource(pad, &info->resources);
+ return -ENOMEM;
+ }
+ memset(p, 0, sizeof(struct fb_pixmap));
+ buf = (struct fb_pixmap *) p;
+ strcpy(buf->name, "drawable");
+ buf->addr = info->screen_base;
+ if (info->screen_size)
+ buf->size = info->screen_size;
+ else
+ buf->size = info->fix.smem_len;
+ buf->buf_align = pad->buf_align;
+ buf->scan_align = pad->scan_align;
+ buf->access_align = pad->access_align;
+ buf->flags = FB_PIXMAP_IO;
+ buf->offset = 0;
+ fb_add_resource(buf, &info->resources);
+ return 0;
+}
+
+void fb_release_resources(struct list_head *head)
+{
+ struct graphics_resource *rlist;
+ struct list_head *pos, *n;
+
+ list_for_each_safe(pos, n, head) {
+ rlist = list_entry(pos, struct graphics_resource, list);
+ if (rlist->resource->addr && (rlist->resource->flags & FB_PIXMAP_DEFAULT))
+ kfree(rlist->resource->addr);
+ kfree(rlist->resource);
+ list_del(pos);
+ kfree(pos);
+ }
+}
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/riva/fbdev.c fbdev-2.6/drivers/video/riva/fbdev.c
--- linus-2.6/drivers/video/riva/fbdev.c 2005-02-21 10:38:49.000000000 -0800
+++ fbdev-2.6/drivers/video/riva/fbdev.c 2005-02-21 09:22:04.000000000 -0800
@@ -1166,6 +1166,7 @@
static int rivafb_set_par(struct fb_info *info)
{
+ struct fb_pixmap *pad = fb_find_resource("scratchpad", &info->resources);
struct riva_par *par = (struct riva_par *) info->par;
NVTRACE_ENTER();
@@ -1182,9 +1183,9 @@
FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
if (info->flags & FBINFO_HWACCEL_DISABLED)
- info->pixmap.scan_align = 1;
+ pad->scan_align = 1;
else
- info->pixmap.scan_align = 4;
+ pad->scan_align = 4;
NVTRACE_LEAVE();
return 0;
}
@@ -1580,6 +1581,7 @@
*/
static int rivafb_cursor(struct fb_info *info, struct fb_cursor *cursor)
{
+ struct fb_pixmap *pad = fb_find_resource("scratchpad", &info->resources);
struct riva_par *par = (struct riva_par *) info->par;
u8 data[MAX_CURS * MAX_CURS/8];
u16 fg, bg;
@@ -1637,9 +1639,8 @@
break;
}
- fb_sysmove_buf_aligned(info, &info->pixmap, data,
- d_pitch, src, s_pitch,
- cursor->image.height);
+ fb_sysmove_buf_aligned(info, pad, data, d_pitch,
+ src, s_pitch, cursor->image.height);
bg = ((info->cmap.red[bg_idx] & 0xf8) << 7) |
((info->cmap.green[bg_idx] & 0xf8) << 2) |
@@ -1725,10 +1726,6 @@
cmap_len = riva_get_cmap_len(&info->var);
fb_alloc_cmap(&info->cmap, cmap_len, 0);
-
- info->pixmap.size = 8 * 1024;
- info->pixmap.buf_align = 4;
- info->pixmap.flags = FB_PIXMAP_SYSTEM;
info->var.yres_virtual = -1;
NVTRACE_LEAVE();
return (rivafb_check_var(&info->var, info));
@@ -1901,8 +1898,10 @@
const struct pci_device_id *ent)
{
struct riva_par *default_par;
+ struct fb_pixmap *pad;
struct fb_info *info;
- int ret;
+ int size, ret;
+ char *p;
NVTRACE_ENTER();
assert(pd != NULL);
@@ -1916,12 +1915,25 @@
default_par = (struct riva_par *) info->par;
default_par->pdev = pd;
- info->pixmap.addr = kmalloc(8 * 1024, GFP_KERNEL);
- if (info->pixmap.addr == NULL) {
+ // We have special needs for writing to the framebuffer.
+ INIT_LIST_HEAD(&info->resources);
+ size = sizeof(struct fb_pixmap) + 1024*8;
+ p = kmalloc(size, GFP_KERNEL);
+ if (!p) {
ret = -ENOMEM;
goto err_framebuffer_release;
}
- memset(info->pixmap.addr, 0, 8 * 1024);
+ memset(p, 0, size);
+ pad = (struct fb_pixmap *) p;
+ pad->addr = p + sizeof(struct fb_pixmap);
+ strcpy(pad->name, "scratchpad");
+ pad->size = 8*1024;
+ pad->buf_align = 4;
+ pad->scan_align = 1;
+ pad->access_align = 4;
+ pad->flags = FB_PIXMAP_DEFAULT;
+ pad->offset = 0;
+ fb_add_resource(pad, &info->resources);
ret = pci_enable_device(pd);
if (ret < 0) {
@@ -2091,7 +2103,7 @@
err_disable_device:
pci_disable_device(pd);
err_free_pixmap:
- kfree(info->pixmap.addr);
+ fb_add_resource(pad, &info->resources);
err_framebuffer_release:
framebuffer_release(info);
err_ret:
@@ -2126,7 +2138,7 @@
iounmap(par->riva.PRAMIN);
pci_release_regions(pd);
pci_disable_device(pd);
- kfree(info->pixmap.addr);
+ fb_release_resources(&info->resources);
framebuffer_release(info);
pci_set_drvdata(pd, NULL);
NVTRACE_LEAVE();
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/softcursor.c fbdev-2.6/drivers/video/softcursor.c
--- linus-2.6/drivers/video/softcursor.c 2005-02-21 10:38:44.000000000 -0800
+++ fbdev-2.6/drivers/video/softcursor.c 2005-02-18 10:57:01.000000000 -0800
@@ -19,8 +19,9 @@
int soft_cursor(struct fb_info *info, struct fb_cursor *cursor)
{
- unsigned int scan_align = info->pixmap.scan_align - 1;
- unsigned int buf_align = info->pixmap.buf_align - 1;
+ struct fb_pixmap *pad = fb_find_resource("scratchpad", &info->resources);
+ unsigned int scan_align = pad->scan_align - 1;
+ unsigned int buf_align = pad->buf_align - 1;
unsigned int i, size, dsize, s_pitch, d_pitch;
struct fb_image *image;
u8 *dst, *src;
@@ -41,7 +42,7 @@
size = d_pitch * image->height + buf_align;
size &= ~buf_align;
- dst = fb_get_buffer_offset(info, &info->pixmap, size);
+ dst = fb_get_buffer_offset(info, pad, size);
if (cursor->enable) {
switch (cursor->rop) {
@@ -57,18 +58,16 @@
}
} else
memcpy(src, image->data, dsize);
-
- if (info->pixmap.outbuf)
- fb_iomove_buf_aligned(info, &info->pixmap, dst, d_pitch, src,
+
+ if (pad->outbuf)
+ fb_iomove_buf_aligned(info, pad, dst, d_pitch, src,
s_pitch, image->height);
else
- fb_sysmove_buf_aligned(info, &info->pixmap, dst, d_pitch, src,
+ fb_sysmove_buf_aligned(info, pad, dst, d_pitch, src,
s_pitch, image->height);
-
image->data = dst;
info->fbops->fb_imageblit(info, image);
kfree(src);
-
return 0;
}
diff -urN -X /home/jsimmons/dontdiff linus-2.6/include/linux/fb.h fbdev-2.6/include/linux/fb.h
--- linus-2.6/include/linux/fb.h 2005-02-21 10:40:46.000000000 -0800
+++ fbdev-2.6/include/linux/fb.h 2005-02-18 12:00:40.000000000 -0800
@@ -514,6 +514,7 @@
#define FB_PIXMAP_SYNC 256 /* set if GPU can DMA */
struct fb_pixmap {
+ char name[16]; /* Name of the resource */
u8 *addr; /* pointer to memory */
u32 size; /* size of buffer in bytes */
u32 offset; /* current offset to buffer */
@@ -523,7 +524,7 @@
u32 flags; /* see FB_PIXMAP_* */
/* access methods */
void (*outbuf)(struct fb_info *info, u8 *addr, u8 *src, unsigned int size);
- u8 (*inbuf) (struct fb_info *info, u8 *addr);
+ u8* (*inbuf) (struct fb_info *info, u8 *addr, unsigned int size);
};
@@ -707,11 +708,10 @@
struct fb_var_screeninfo var; /* Current var */
struct fb_fix_screeninfo fix; /* Current fix */
struct fb_monspecs monspecs; /* Current Monitor specs */
+ struct list_head resources; /* Graphics resources */
+ struct list_head modelist; /* mode list */
struct work_struct queue; /* Framebuffer event queue */
- struct fb_pixmap pixmap; /* Image hardware mapper */
- struct fb_pixmap sprite; /* Cursor hardware mapper */
struct fb_cmap cmap; /* Current cmap */
- struct list_head modelist; /* mode list */
struct fb_ops *fbops;
struct device *device;
#ifdef CONFIG_FB_TILEBLITTING
@@ -807,6 +807,14 @@
extern int unregister_framebuffer(struct fb_info *fb_info);
extern int fb_prepare_logo(struct fb_info *fb_info);
extern int fb_show_logo(struct fb_info *fb_info);
+extern void fb_set_suspend(struct fb_info *info, int state);
+extern int fb_get_color_depth(struct fb_info *info);
+extern int fb_get_options(char *name, char **option);
+
+extern struct fb_info *registered_fb[FB_MAX];
+extern int num_registered_fb;
+
+/* drivers/video/resmgt.c */
extern char* fb_get_buffer_offset(struct fb_info *info, struct fb_pixmap *buf, u32 size);
extern void fb_iomove_buf_unaligned(struct fb_info *info, struct fb_pixmap *buf,
u8 *dst, u32 d_pitch, u8 *src, u32 idx,
@@ -820,12 +828,11 @@
extern void fb_sysmove_buf_aligned(struct fb_info *info, struct fb_pixmap *buf,
u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch,
u32 height);
-extern void fb_set_suspend(struct fb_info *info, int state);
-extern int fb_get_color_depth(struct fb_info *info);
-extern int fb_get_options(char *name, char **option);
-
-extern struct fb_info *registered_fb[FB_MAX];
-extern int num_registered_fb;
+void fb_release_resources(struct list_head *head);
+int fb_remove_resource(struct fb_pixmap *resource, struct list_head *head);
+int fb_add_resource(struct fb_pixmap *resource, struct list_head *head);
+struct fb_pixmap* fb_find_resource(const char *name, struct list_head *head);
+int fb_init_resources(struct fb_info *info);
/* drivers/video/fbsysfs.c */
extern struct fb_info *framebuffer_alloc(size_t size, struct device *dev);
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Resource management.
2005-02-21 19:11 Resource management James Simmons
@ 2005-02-21 22:53 ` Antonino A. Daplas
2005-02-21 23:25 ` James Simmons
0 siblings, 1 reply; 16+ messages in thread
From: Antonino A. Daplas @ 2005-02-21 22:53 UTC (permalink / raw)
To: James Simmons; +Cc: Geert Uytterhoeven, Linux Fbdev development list
On Tuesday 22 February 2005 03:11, James Simmons wrote:
> Hi!
>
> This is my first run at the resource management code. Comments are
> welcomed :-)
>
Hi James,
Where is this going to? What I see are performance penalties. For each
putcs and cursor, it has to call fb_find_resource() which walks the linked list
looking for a resource using strncmp().
What's the goal here?
Tony
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Resource management.
2005-02-21 22:53 ` Antonino A. Daplas
@ 2005-02-21 23:25 ` James Simmons
2005-02-22 1:01 ` Jon Smirl
` (2 more replies)
0 siblings, 3 replies; 16+ messages in thread
From: James Simmons @ 2005-02-21 23:25 UTC (permalink / raw)
To: adaplas; +Cc: Linux Fbdev development list, James Simmons, Geert Uytterhoeven
> On Tuesday 22 February 2005 03:11, James Simmons wrote:
> > Hi!
> >
> > This is my first run at the resource management code. Comments are
> > welcomed :-)
> >
>
> Hi James,
>
> Where is this going to? What I see are performance penalties. For each
> putcs and cursor, it has to call fb_find_resource() which walks the linked list
> looking for a resource using strncmp().
>
> What's the goal here?
So we don't end up with a struct fb_info constantly growing with struct
fb_pixmaps. At present we have pixmap and sprite in struct fb_info. In the
future we will have more. I need to create a pixmap for the framebuffer
itself. This way we can have hooks for inbuf and outbuf to deal with
issues of devices that have hardware restriction when writing to the
framebuffer. The classic example is the Epson135X chipsets. You can only
write/read 16 bits at a time with the framebuffer. Also in the future I
plan to add DMA support. One approach to this is pci_pools. This would
require multiple fb_pixmaps. One for each area for DMA you request. Of
course we could have a static array of struct fb_pixmaps but there is no
guarantee that the orders will be the same for each driver.
Do you see any other solution to this then?
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Resource management.
2005-02-21 23:25 ` James Simmons
@ 2005-02-22 1:01 ` Jon Smirl
2005-02-22 3:53 ` James Simmons
2005-02-22 13:25 ` Antonino A. Daplas
2005-02-22 14:06 ` Antonino A. Daplas
2 siblings, 1 reply; 16+ messages in thread
From: Jon Smirl @ 2005-02-22 1:01 UTC (permalink / raw)
To: linux-fbdev-devel; +Cc: adaplas, James Simmons, Geert Uytterhoeven
On Mon, 21 Feb 2005 23:25:15 +0000 (GMT), James Simmons
<jsimmons@www.infradead.org> wrote:
> So we don't end up with a struct fb_info constantly growing with struct
> fb_pixmaps. At present we have pixmap and sprite in struct fb_info. In the
> future we will have more. I need to create a pixmap for the framebuffer
> itself. This way we can have hooks for inbuf and outbuf to deal with
> issues of devices that have hardware restriction when writing to the
> framebuffer. The classic example is the Epson135X chipsets. You can only
> write/read 16 bits at a time with the framebuffer. Also in the future I
> plan to add DMA support. One approach to this is pci_pools. This would
> require multiple fb_pixmaps. One for each area for DMA you request. Of
> course we could have a static array of struct fb_pixmaps but there is no
> guarantee that the orders will be the same for each driver.
>
> Do you see any other solution to this then?
You could build this inside of the DRM framework which already
supports DMA and memory management. DRM doesn't really know anything
about 3D, it just knows how to send commands to the graphics hardware.
It's the mesa layer in user space that knows about 3D.
There is a lot of code inside DRM to stop a DRM user from using the
DMA hardware to play with kernel memory and gain root priv. fbdev will
need the same protection if it starts using DMA.
--
Jon Smirl
jonsmirl@gmail.com
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Resource management.
2005-02-22 1:01 ` Jon Smirl
@ 2005-02-22 3:53 ` James Simmons
2005-02-22 4:46 ` [Linux-fbdev-devel] " Dave Airlie
0 siblings, 1 reply; 16+ messages in thread
From: James Simmons @ 2005-02-22 3:53 UTC (permalink / raw)
To: Jon Smirl
Cc: Linux Fbdev development list, adaplas, dri-devel, xorg,
Geert Uytterhoeven, Linux Kernel Mailing List
> > Do you see any other solution to this then?
>
> You could build this inside of the DRM framework which already
> supports DMA and memory management. DRM doesn't really know anything
> about 3D, it just knows how to send commands to the graphics hardware.
> It's the mesa layer in user space that knows about 3D.
>
> There is a lot of code inside DRM to stop a DRM user from using the
> DMA hardware to play with kernel memory and gain root priv. fbdev will
> need the same protection if it starts using DMA.
I have CC the dri list to discuss the issues. I have looked at the DRI
code. I know merging dri and fbdev infrastructres has been discussed
before. There are a few issues that have always prevented this. Now
I'm going to go over the issues.
1. Lots of work that would take lots of time. To my knowledge all fbdev
developers work in there spare free time. No one does this for a
living.
2. Sharing of headers. The dri headers are isolated in the drm directory.
I totally understand why :-) It makes merging easier for them. The
disadvantage is no one in the fbdev can use them easily :-(
3. DRM has way to much functionality for most embedded devices. I have
talked to embedded guys before and they want a simple api to work with.
By default DRM builds in everything. A simple api mean alot to those
guys. Plus the extra built in code bloat takes up to much space which
is precious on embedded devices. If a devices doesn't support dma then
the dma code doesn't need to be built in.
4. Which comes to the next point. The code is not modular enough. Take
drm_bufs.c. Everything is a ioctl function. This has a few disadvantages.
One is the fbdev layer couldn't just link into it so fbcon could use
it. The second is it's not easy to take advantage of things like sysfs.
If you could untangle the code somewhat it would make life so much
easier. That would include making life easier for OS ports.
5. The license issue. The DRI code is GPL and additional rights. What is that?
For the fbdev layer we would need a layer on top of the drm data
structures because we need to know things in the kernel to draw images
for font characters i.e how much byte padding is need for images.
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [Linux-fbdev-devel] Resource management.
2005-02-22 3:53 ` James Simmons
@ 2005-02-22 4:46 ` Dave Airlie
2005-02-22 5:13 ` James Simmons
2005-02-22 5:23 ` Jon Smirl
0 siblings, 2 replies; 16+ messages in thread
From: Dave Airlie @ 2005-02-22 4:46 UTC (permalink / raw)
To: James Simmons
Cc: Jon Smirl, Linux Fbdev development list, adaplas, dri-devel, xorg,
Geert Uytterhoeven, Linux Kernel Mailing List
>
> 1. Lots of work that would take lots of time. To my knowledge all fbdev
> developers work in there spare free time. No one does this for a
> living.
So do most of the drm developers, I know I do and Jon Smirl does, and
Eric Anholt does and I think us three have been the largest
contributers apart from new driver submissions...
> 2. Sharing of headers. The dri headers are isolated in the drm directory.
> I totally understand why :-) It makes merging easier for them. The
> disadvantage is no one in the fbdev can use them easily :-(
I plan to move them in 2.6.12 maybe .. it might be 2.6.13 by the time
I get around to it, just some minor issues.. Arjan asked me for this
ages ago as well...
> 3. DRM has way to much functionality for most embedded devices. I have
> talked to embedded guys before and they want a simple api to work with.
> By default DRM builds in everything. A simple api mean alot to those
> guys. Plus the extra built in code bloat takes up to much space which
> is precious on embedded devices. If a devices doesn't support dma then
> the dma code doesn't need to be built in.
Well crap on that, the old DRM didn't build everything in people
complained aw this code is too messy, build everything in, now you
want to revert? damn you all!!! :-), I understand I'm just saying we
can't have it both ways.. and too be honest I'm an embedded person and
I just want it to work, with a Linux kernel you rarely get to an every
byte counts embedded env, of if you are you aren't using the stock
Linus kernel....
>
> 4. Which comes to the next point. The code is not modular enough. Take
> drm_bufs.c. Everything is a ioctl function. This has a few disadvantages.
> One is the fbdev layer couldn't just link into it so fbcon could use
> it. The second is it's not easy to take advantage of things like sysfs.
> If you could untangle the code somewhat it would make life so much
> easier. That would include making life easier for OS ports.
the reason we can't take advantage of sysfs or anything like it is
that we can't bind to the PCI device as we break things.. this is the
root of a lot of our problems...
>
> 5. The license issue. The DRI code is GPL and additional rights. What is that?
Nope the drm code is BSD... there should be no GPL anywhere near it...
it is GPL in the kernel as of course it is imported into a GPL work..
but the code is available for BSD uses....
Jon's last plan - was like to have a radeon basic module, with fb and
drm personalities and in fact any number of personalities..taking
radeon as example:
base module : hotplug, reset, monitor probing, memory management, CP
programming and locking.
fb: adds accelerated fb functions using CP locking.
drm: adds drm functionality on top of base module, drm ioctl interfaces etc..
I've looked at Alans ideas on a vga_class driver and have decided they
are unworkable due to the massive initial changes they involve in
*every* fb/drm driver in the kernel, I cannot undertake a work of that
magnitude without fb people being involved and the chances of breaking
a lot of stuff.. maybe a 2.7 thing but I don't think we'll ever have a
2.7 for this stuff...
What I do think though is that ideas of a the vga class driver could
be made into a helper module that the base graphics driver uses to do
some standard things, like reset and stuff..
I'm hoping to get a better handle on these ideas and write something
up.. but they are mostly Jons ideas better presented :-)
Dave.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Resource management.
2005-02-22 4:46 ` [Linux-fbdev-devel] " Dave Airlie
@ 2005-02-22 5:13 ` James Simmons
2005-02-22 5:59 ` [Linux-fbdev-devel] " Jon Smirl
2005-02-22 5:23 ` Jon Smirl
1 sibling, 1 reply; 16+ messages in thread
From: James Simmons @ 2005-02-22 5:13 UTC (permalink / raw)
To: Dave Airlie
Cc: James Simmons, Jon Smirl, Linux Fbdev development list, adaplas,
dri-devel, xorg, Geert Uytterhoeven, Linux Kernel Mailing List
> > 1. Lots of work that would take lots of time. To my knowledge all fbdev
> > developers work in there spare free time. No one does this for a
> > living.
>
> So do most of the drm developers, I know I do and Jon Smirl does, and
> Eric Anholt does and I think us three have been the largest
> contributers apart from new driver submissions...
Ug :-( That is sad!!!
> > 2. Sharing of headers. The dri headers are isolated in the drm directory.
> > I totally understand why :-) It makes merging easier for them. The
> > disadvantage is no one in the fbdev can use them easily :-(
>
> I plan to move them in 2.6.12 maybe .. it might be 2.6.13 by the time
> I get around to it, just some minor issues.. Arjan asked me for this
> ages ago as well...
Okay. Where will they go? include/video ?
> > 3. DRM has way to much functionality for most embedded devices. I have
> > talked to embedded guys before and they want a simple api to work with.
> > By default DRM builds in everything. A simple api mean alot to those
> > guys. Plus the extra built in code bloat takes up to much space which
> > is precious on embedded devices. If a devices doesn't support dma then
> > the dma code doesn't need to be built in.
>
> Well crap on that, the old DRM didn't build everything in people
> complained aw this code is too messy, build everything in, now you
> want to revert? damn you all!!! :-),
Ha Ha. I didn't know the history.
> I understand I'm just saying we
> can't have it both ways.. and too be honest I'm an embedded person and
> I just want it to work, with a Linux kernel you rarely get to an every
> byte counts embedded env, of if you are you aren't using the stock
> Linus kernel....
I can live with this issue as long it would not increase the complexity of
framebuffer only devices. Simple api is very important to me. The current
fbdev api is designed to be very simple for the most common cases. It can
get complex tho with exotic hardware.
> > 4. Which comes to the next point. The code is not modular enough. Take
> > drm_bufs.c. Everything is a ioctl function. This has a few disadvantages.
> > One is the fbdev layer couldn't just link into it so fbcon could use
> > it. The second is it's not easy to take advantage of things like sysfs.
> > If you could untangle the code somewhat it would make life so much
> > easier. That would include making life easier for OS ports.
>
> the reason we can't take advantage of sysfs or anything like it is
> that we can't bind to the PCI device as we break things.. this is the
> root of a lot of our problems...
Is this because you want to be OS portable? This makes things very very
hard to merge. Fbdev attempts to take advantage the most powerful linux
kernel features.
> > 5. The license issue. The DRI code is GPL and additional rights. What is that?
> Nope the drm code is BSD... there should be no GPL anywhere near it...
> it is GPL in the kernel as of course it is imported into a GPL work..
> but the code is available for BSD uses....
If it is GPL in the kernel then that is fine. We can work with that. I
don't care about userland code.
> Jon's last plan - was like to have a radeon basic module, with fb and
> drm personalities and in fact any number of personalities..taking
> radeon as example:
> base module : hotplug, reset, monitor probing, memory management, CP
> programming and locking.
> fb: adds accelerated fb functions using CP locking.
> drm: adds drm functionality on top of base module, drm ioctl interfaces etc..
That will be a huge amount of work! BTW what does CP stand for?
> I've looked at Alans ideas on a vga_class driver and have decided they
> are unworkable due to the massive initial changes they involve in
> *every* fb/drm driver in the kernel, I cannot undertake a work of that
> magnitude without fb people being involved and the chances of breaking
> a lot of stuff.. maybe a 2.7 thing but I don't think we'll ever have a
> 2.7 for this stuff...
>
> What I do think though is that ideas of a the vga class driver could
> be made into a helper module that the base graphics driver uses to do
> some standard things, like reset and stuff..
>
> I'm hoping to get a better handle on these ideas and write something
> up.. but they are mostly Jons ideas better presented :-)
As for the VGA class driver. We already have something like that for the
fbdev layer. Take a look at vgastate.c. It was written originally so you
could go from vgacon to fbdev without fbcon and back to vgacon state
again. It also has common functions for all the drivers to work with. I
already asked Jon to merge his work with that code. That code could also
be very useful for vgacon in the future. We need vga core management in
the kernel.
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [Linux-fbdev-devel] Resource management.
2005-02-22 4:46 ` [Linux-fbdev-devel] " Dave Airlie
2005-02-22 5:13 ` James Simmons
@ 2005-02-22 5:23 ` Jon Smirl
2005-02-22 17:23 ` James Simmons
1 sibling, 1 reply; 16+ messages in thread
From: Jon Smirl @ 2005-02-22 5:23 UTC (permalink / raw)
To: Dave Airlie
Cc: James Simmons, Linux Fbdev development list, adaplas, dri-devel,
xorg, Geert Uytterhoeven, Linux Kernel Mailing List
On Tue, 22 Feb 2005 15:46:03 +1100, Dave Airlie <airlied@gmail.com> wrote:
> >
> > 1. Lots of work that would take lots of time. To my knowledge all fbdev
> > developers work in there spare free time. No one does this for a
> > living.
>
> So do most of the drm developers, I know I do and Jon Smirl does, and
> Eric Anholt does and I think us three have been the largest
> contributers apart from new driver submissions...
As far as I know none of the significant contributors on either fbdev
or DRM are being paid to work on the project.
> > 2. Sharing of headers. The dri headers are isolated in the drm directory.
> > I totally understand why :-) It makes merging easier for them. The
> > disadvantage is no one in the fbdev can use them easily :-(
>
> I plan to move them in 2.6.12 maybe .. it might be 2.6.13 by the time
> I get around to it, just some minor issues.. Arjan asked me for this
> ages ago as well...
I'd like to take this further and move the stuff in drivers/video to
drivers/video/fb and then
move drm from drivers/char/drm to drivers/video/drm. I'd also like to
consolidate drm and fbdev Kconfig menus.
> > 3. DRM has way to much functionality for most embedded devices. I have
> > talked to embedded guys before and they want a simple api to work with.
> > By default DRM builds in everything. A simple api mean alot to those
> > guys. Plus the extra built in code bloat takes up to much space which
> > is precious on embedded devices. If a devices doesn't support dma then
> > the dma code doesn't need to be built in.
>
> Well crap on that, the old DRM didn't build everything in people
> complained aw this code is too messy, build everything in, now you
> want to revert? damn you all!!! :-), I understand I'm just saying we
> can't have it both ways.. and too be honest I'm an embedded person and
> I just want it to work, with a Linux kernel you rarely get to an every
> byte counts embedded env, of if you are you aren't using the stock
> Linus kernel....
If you removed the EXPORT_SYMBOLs and compiled everything in, won't
the compiler just eliminate the dead code for you?
PCI Express is a big reason for the new core/personality split. There
are Nforce4 motherboards now with 16 16x sockets. That means you can
plug 16 different video cards in if you want. The days of a single AGP
slot are over. If someone will send me one (with the four Opteron
chips) I'll write drivers for it.
> > 4. Which comes to the next point. The code is not modular enough. Take
> > drm_bufs.c. Everything is a ioctl function. This has a few disadvantages.
> > One is the fbdev layer couldn't just link into it so fbcon could use
> > it. The second is it's not easy to take advantage of things like sysfs.
> > If you could untangle the code somewhat it would make life so much
> > easier. That would include making life easier for OS ports.
>
> the reason we can't take advantage of sysfs or anything like it is
> that we can't bind to the PCI device as we break things.. this is the
> root of a lot of our problems...
This not binding to the PCI device has to be fixed. DRM can not
support hotplug or suspend/resume without a device to bind to.
> Jon's last plan - was like to have a radeon basic module, with fb and
> drm personalities and in fact any number of personalities..taking
> radeon as example:
> base module : hotplug, reset, monitor probing, memory management, CP
> programming and locking.
> fb: adds accelerated fb functions using CP locking.
> drm: adds drm functionality on top of base module, drm ioctl interfaces etc..
I have already coded most of this up and it works for me.
Unfortunately I derived it from the DRM codebase instead of the fbdev
one. fbdev has changed too much in the last six months to allow a
simple merge. Now I'm regenerating patches against fbdev using my
prior code.
A smaller step is to just treat radeonfb as the base module. This will
eat up extra memory for x86 users and they will complain, but we can
split it into three pieces later.
I think good first step would simply be to get DRM and fbdev both into
drivers/video and get the DRM h files into include/linux.
> I've looked at Alans ideas on a vga_class driver and have decided they
> are unworkable due to the massive initial changes they involve in
> *every* fb/drm driver in the kernel, I cannot undertake a work of that
> magnitude without fb people being involved and the chances of breaking
> a lot of stuff.. maybe a 2.7 thing but I don't think we'll ever have a
> 2.7 for this stuff...
My head hurts thinking about how much editing this would involve.
> What I do think though is that ideas of a the vga class driver could
> be made into a helper module that the base graphics driver uses to do
> some standard things, like reset and stuff..
>
> I'm hoping to get a better handle on these ideas and write something
> up.. but they are mostly Jons ideas better presented :-)
>
> Dave.
>
--
Jon Smirl
jonsmirl@gmail.com
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
--
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [Linux-fbdev-devel] Resource management.
2005-02-22 5:13 ` James Simmons
@ 2005-02-22 5:59 ` Jon Smirl
0 siblings, 0 replies; 16+ messages in thread
From: Jon Smirl @ 2005-02-22 5:59 UTC (permalink / raw)
To: James Simmons
Cc: Dave Airlie, James Simmons, Linux Fbdev development list, adaplas,
dri-devel, xorg, Geert Uytterhoeven, Linux Kernel Mailing List
On Tue, 22 Feb 2005 05:13:07 +0000 (GMT), James Simmons
<jsimmons@www.infradead.org> wrote:
> > > 4. Which comes to the next point. The code is not modular enough. Take
> > > drm_bufs.c. Everything is a ioctl function. This has a few disadvantages.
> > > One is the fbdev layer couldn't just link into it so fbcon could use
> > > it. The second is it's not easy to take advantage of things like sysfs.
> > > If you could untangle the code somewhat it would make life so much
> > > easier. That would include making life easier for OS ports.
> >
> > the reason we can't take advantage of sysfs or anything like it is
> > that we can't bind to the PCI device as we break things.. this is the
> > root of a lot of our problems...
>
> Is this because you want to be OS portable? This makes things very very
> hard to merge. Fbdev attempts to take advantage the most powerful linux
> kernel features.
My turn to laugh! It's because Linux only allow one driver to bind to
the device and fbdev has already bound to it. We have done
siginificant work to DRM to try and work around this (stealth mode)
but the right solution is to have a common base driver.
--
Jon Smirl
jonsmirl@gmail.com
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
--
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Resource management.
2005-02-21 23:25 ` James Simmons
2005-02-22 1:01 ` Jon Smirl
@ 2005-02-22 13:25 ` Antonino A. Daplas
2005-02-22 14:06 ` Antonino A. Daplas
2 siblings, 0 replies; 16+ messages in thread
From: Antonino A. Daplas @ 2005-02-22 13:25 UTC (permalink / raw)
To: James Simmons, adaplas
Cc: Linux Fbdev development list, James Simmons, Geert Uytterhoeven
On Tuesday 22 February 2005 07:25, James Simmons wrote:
> > On Tuesday 22 February 2005 03:11, James Simmons wrote:
> > > Hi!
> > >
> > > This is my first run at the resource management code. Comments are
> > > welcomed :-)
> >
> > Hi James,
> >
> > Where is this going to? What I see are performance penalties. For each
> > putcs and cursor, it has to call fb_find_resource() which walks the
> > linked list looking for a resource using strncmp().
> >
> > What's the goal here?
>
> So we don't end up with a struct fb_info constantly growing with struct
> fb_pixmaps. At present we have pixmap and sprite in struct fb_info. In the
> future we will have more. I need to create a pixmap for the framebuffer
> itself. This way we can have hooks for inbuf and outbuf to deal with
> issues of devices that have hardware restriction when writing to the
> framebuffer. The classic example is the Epson135X chipsets. You can only
> write/read 16 bits at a time with the framebuffer. Also in the future I
> plan to add DMA support. One approach to this is pci_pools. This would
> require multiple fb_pixmaps. One for each area for DMA you request. Of
> course we could have a static array of struct fb_pixmaps but there is no
> guarantee that the orders will be the same for each driver.
>
> Do you see any other solution to this then?
The structure fb_pixmap was designed originally as a kind of scratchpad, ie,
this is where each character map is consolidated into a single image before
writing to the framebuffer. Of course, this structure is not restricted to
that role only, but it can be used in different ways, as long as its
function as a scratchpad is kept in mind. The only thing we need to know is
where this scratchpad is located, is it in system RAM or some kind of IO
memory, and we already have support for that. In short, it was never meant
as an accessor to different areas of the graphics aperture. which is the
reason I'm not too keen on info->sprite.
In the example you cited, the epson problem can be easily solved by
creating an epson-specific fb_read/write.
However, if you are trying to add features to fbdev, like video overlay,
textures and the like, then that is a different problem altogether and
requires a new interface/architecture. Extending the function of structure
fb_pixmap will just complicate things even more by blurring its role as
a simple scratchpad area.
Tony
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Resource management.
2005-02-21 23:25 ` James Simmons
2005-02-22 1:01 ` Jon Smirl
2005-02-22 13:25 ` Antonino A. Daplas
@ 2005-02-22 14:06 ` Antonino A. Daplas
2005-02-24 19:57 ` James Simmons
2 siblings, 1 reply; 16+ messages in thread
From: Antonino A. Daplas @ 2005-02-22 14:06 UTC (permalink / raw)
To: James Simmons, adaplas
Cc: Linux Fbdev development list, James Simmons, Geert Uytterhoeven
On Tuesday 22 February 2005 07:25, James Simmons wrote:
> > On Tuesday 22 February 2005 03:11, James Simmons wrote:
> > > Hi!
> > >
> > > This is my first run at the resource management code. Comments are
> > > welcomed :-)
> >
> > Hi James,
> >
> > Where is this going to? What I see are performance penalties. For each
> > putcs and cursor, it has to call fb_find_resource() which walks the
> > linked list looking for a resource using strncmp().
> >
> > What's the goal here?
>
> So we don't end up with a struct fb_info constantly growing with struct
> fb_pixmaps. At present we have pixmap and sprite in struct fb_info. In the
> future we will have more. I need to create a pixmap for the framebuffer
> itself. This way we can have hooks for inbuf and outbuf to deal with
> issues of devices that have hardware restriction when writing to the
> framebuffer. The classic example is the Epson135X chipsets. You can only
> write/read 16 bits at a time with the framebuffer. Also in the future I
> plan to add DMA support. One approach to this is pci_pools. This would
> require multiple fb_pixmaps. One for each area for DMA you request. Of
> course we could have a static array of struct fb_pixmaps but there is no
> guarantee that the orders will be the same for each driver.
>
> Do you see any other solution to this then?
If you intend to insist on doing this, this is my proposal:
The linked list of resources per fb_info can be kept. However, instead
of doing an fb_find_resource() per call to putcs and cursor, this can
be done only once, during initialization of fbcon or set_con2fb_map.
This resource can then be stored in an fbcon-private area.
The advantage of this is that fbcon will only look for the resource that
it needs, ie "scratchpad" but not, for example, "overlay". Similarly,
a user video application can totally ignore "scratchpad" but will search for
"overlay". Secondly, the performance penalty suffered by the your initial
patch will be eliminated. We also eliminate one or two more fields in
fb_info directly accessed by fbcon.
Also, instead of storing the resource type as a string, why not use a
constant?
Tony
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Resource management.
2005-02-22 5:23 ` Jon Smirl
@ 2005-02-22 17:23 ` James Simmons
2005-02-22 18:59 ` [Linux-fbdev-devel] " Alex Deucher
0 siblings, 1 reply; 16+ messages in thread
From: James Simmons @ 2005-02-22 17:23 UTC (permalink / raw)
To: Jon Smirl
Cc: Dave Airlie, James Simmons, Linux Fbdev development list, adaplas,
dri-devel, xorg, Geert Uytterhoeven, Linux Kernel Mailing List
> As far as I know none of the significant contributors on either fbdev
> or DRM are being paid to work on the project.
So I have noticed. There is much to do but no real man power. We are
talking about this merging but at our rate it will take 5 years to happen.
We don't have the man power to do this. So I'm not going to bother
merging. Its all pipe dreams here.
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [Linux-fbdev-devel] Resource management.
2005-02-22 17:23 ` James Simmons
@ 2005-02-22 18:59 ` Alex Deucher
0 siblings, 0 replies; 16+ messages in thread
From: Alex Deucher @ 2005-02-22 18:59 UTC (permalink / raw)
To: James Simmons
Cc: Jon Smirl, Dave Airlie, James Simmons,
Linux Fbdev development list, adaplas, dri-devel, xorg,
Geert Uytterhoeven, Linux Kernel Mailing List
On Tue, 22 Feb 2005 17:23:03 +0000 (GMT), James Simmons
<jsimmons@www.infradead.org> wrote:
>
> > As far as I know none of the significant contributors on either fbdev
> > or DRM are being paid to work on the project.
>
> So I have noticed. There is much to do but no real man power. We are
> talking about this merging but at our rate it will take 5 years to happen.
> We don't have the man power to do this. So I'm not going to bother
> merging. Its all pipe dreams here.
>
>
with that attitude it's never gonna happen. I work almost exclusively
on X, but once we get at least one sample driver done (probably
radeon, I would be more than happy to devote my limited development
resources to the new drm/fb super driver. Right now the kernel FB
drivers have no benefit for me so I don't use/develop them. The drm
just works and I'm more interested in the crtc/modes/outputs handling
than the command processor control stuff. I think a lot of X
developers (and porobably IHVs) will get on board when this happens.
X is undermanned as well, but we've managed to do a pretty good job of
supported a lot of features on a fair number of cards.
Alex
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
--
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Resource management.
2005-02-22 14:06 ` Antonino A. Daplas
@ 2005-02-24 19:57 ` James Simmons
2005-02-24 23:05 ` Antonino A. Daplas
0 siblings, 1 reply; 16+ messages in thread
From: James Simmons @ 2005-02-24 19:57 UTC (permalink / raw)
To: adaplas; +Cc: Linux Fbdev development list, James Simmons, Geert Uytterhoeven
> If you intend to insist on doing this, this is my proposal:
>
> The linked list of resources per fb_info can be kept. However, instead
> of doing an fb_find_resource() per call to putcs and cursor, this can
> be done only once, during initialization of fbcon or set_con2fb_map.
> This resource can then be stored in an fbcon-private area.
I fixed this in my latest work. Alot of cleanups has happened. Still a few
issues to work out.
> The advantage of this is that fbcon will only look for the resource that
> it needs, ie "scratchpad" but not, for example, "overlay". Similarly,
> a user video application can totally ignore "scratchpad" but will search for
> "overlay". Secondly, the performance penalty suffered by the your initial
> patch will be eliminated. We also eliminate one or two more fields in
> fb_info directly accessed by fbcon.
I removed the scratch pad. We use the data reflecting the "drawable"
properties.
> Also, instead of storing the resource type as a string, why not use a
> constant?
We would run out very fast. Plus we would need a index field in the case
we have more than one of the same kind.
Here is the latest work.
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/Makefile fbdev-2.6/drivers/video/Makefile
--- linus-2.6/drivers/video/Makefile 2005-02-24 10:39:32.000000000 -0800
+++ fbdev-2.6/drivers/video/Makefile 2005-02-17 14:26:42.000000000 -0800
@@ -8,7 +8,7 @@
obj-$(CONFIG_LOGO) += logo/
obj-$(CONFIG_SYSFS) += backlight/
-obj-$(CONFIG_FB) += fbmem.o fbmon.o fbcmap.o fbsysfs.o modedb.o softcursor.o
+obj-$(CONFIG_FB) += fbmem.o fbmon.o fbcmap.o fbsysfs.o modedb.o resmgt.o softcursor.o
# Only include macmodes.o if we have FB support and are PPC
ifeq ($(CONFIG_FB),y)
obj-$(CONFIG_PPC) += macmodes.o
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/console/bitblit.c fbdev-2.6/drivers/video/console/bitblit.c
--- linus-2.6/drivers/video/console/bitblit.c 2005-02-24 10:39:35.000000000 -0800
+++ fbdev-2.6/drivers/video/console/bitblit.c 2005-02-24 10:00:30.000000000 -0800
@@ -107,25 +107,20 @@
const unsigned short *s, int count, int yy, int xx,
int fg, int bg)
{
- void (*move_unaligned)(struct fb_info *info, struct fb_pixmap *buf,
- u8 *dst, u32 d_pitch, u8 *src, u32 idx,
- u32 height, u32 shift_high, u32 shift_low,
- u32 mod);
- void (*move_aligned)(struct fb_info *info, struct fb_pixmap *buf,
- u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch,
- u32 height);
+ struct fbcon_ops *ops = (struct fbcon_ops *) info->fbcon_par;
unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
unsigned int width = (vc->vc_font.width + 7) >> 3;
unsigned int cellsize = vc->vc_font.height * width;
- unsigned int maxcnt = info->pixmap.size/cellsize;
- unsigned int scan_align = info->pixmap.scan_align - 1;
- unsigned int buf_align = info->pixmap.buf_align - 1;
+ struct fb_pixmap *pad = info->pad;
+ unsigned int maxcnt = pad->size/cellsize;
+ unsigned int scan_align = pad->scan_align - 1;
+ unsigned int buf_align = pad->buf_align - 1;
unsigned int shift_low = 0, mod = vc->vc_font.width % 8;
unsigned int shift_high = 8, pitch, cnt, size, k;
unsigned int idx = vc->vc_font.width >> 3;
unsigned int attribute = get_attribute(info, scr_readw(s));
- struct fb_image image;
u8 *src, *dst, *buf = NULL;
+ struct fb_image image;
if (attribute) {
buf = kmalloc(cellsize, GFP_KERNEL);
@@ -141,13 +136,6 @@
image.height = vc->vc_font.height;
image.depth = 1;
- if (info->pixmap.outbuf && info->pixmap.inbuf) {
- move_aligned = fb_iomove_buf_aligned;
- move_unaligned = fb_iomove_buf_unaligned;
- } else {
- move_aligned = fb_sysmove_buf_aligned;
- move_unaligned = fb_sysmove_buf_unaligned;
- }
while (count) {
if (count > maxcnt)
cnt = k = maxcnt;
@@ -159,7 +147,7 @@
pitch &= ~scan_align;
size = pitch * image.height + buf_align;
size &= ~buf_align;
- dst = fb_get_buffer_offset(info, &info->pixmap, size);
+ dst = ops->scratch_pad;
image.data = dst;
if (mod) {
while (k--) {
@@ -171,9 +159,9 @@
src = buf;
}
- move_unaligned(info, &info->pixmap, dst, pitch,
- src, idx, image.height,
- shift_high, shift_low, mod);
+ fb_pad_unaligned_buffer(info, dst, pitch, src, idx,
+ image.height, shift_high, shift_low,
+ mod);
shift_low += mod;
dst += (shift_low >= 8) ? width : width - 1;
shift_low &= 7;
@@ -189,8 +177,7 @@
src = buf;
}
- move_aligned(info, &info->pixmap, dst, pitch,
- src, idx, image.height);
+ fb_pad_aligned_buffer(info, dst, pitch, src, idx, image.height);
dst += width;
}
}
@@ -238,12 +225,12 @@
static void bit_cursor(struct vc_data *vc, struct fb_info *info,
struct display *p, int mode, int fg, int bg)
{
- struct fb_cursor cursor;
struct fbcon_ops *ops = (struct fbcon_ops *) info->fbcon_par;
unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
int w = (vc->vc_font.width + 7) >> 3, c;
int y = real_y(p, vc->vc_y);
int attribute, use_sw = (vc->vc_cursor_type & 0x10);
+ struct fb_cursor cursor;
char *src;
cursor.set = 0;
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/console/fbcon.c fbdev-2.6/drivers/video/console/fbcon.c
--- linus-2.6/drivers/video/console/fbcon.c 2005-02-24 10:39:35.000000000 -0800
+++ fbdev-2.6/drivers/video/console/fbcon.c 2005-02-24 09:59:37.000000000 -0800
@@ -507,9 +507,10 @@
static int con2fb_acquire_newinfo(struct vc_data *vc, struct fb_info *info,
int unit, int oldidx)
{
+ int size = sizeof(struct fbcon_ops) + FBPIXMAPSIZE, err = 0;
struct fbcon_ops *ops = NULL;
- int err = 0;
-
+ char *p;
+
if (!try_module_get(info->fbops->owner))
err = -ENODEV;
@@ -518,13 +519,15 @@
err = -ENODEV;
if (!err) {
- ops = kmalloc(sizeof(struct fbcon_ops), GFP_KERNEL);
- if (!ops)
+ p = kmalloc(size, GFP_KERNEL);
+ if (!p)
err = -ENOMEM;
}
if (!err) {
- memset(ops, 0, sizeof(struct fbcon_ops));
+ memset(p, 0, size);
+ ops = (struct fbcon_ops *) p;
+ ops->scratch_pad = p + sizeof(struct fbcon_ops);
info->fbcon_par = ops;
set_blitting_type(vc, info, NULL);
}
@@ -533,7 +536,6 @@
con2fb_map[unit] = oldidx;
module_put(info->fbops->owner);
}
-
return err;
}
@@ -720,17 +722,17 @@
static const char *fbcon_startup(void)
{
+ int rows, cols, size = sizeof(struct fbcon_ops) + FBPIXMAPSIZE;
const char *display_desc = "frame buffer device";
struct display *p = &fb_display[fg_console];
struct vc_data *vc = vc_cons[fg_console].d;
struct font_desc *font = NULL;
- struct module *owner;
struct fb_info *info = NULL;
struct fbcon_ops *ops;
- int rows, cols;
- int irqres;
+ struct module *owner;
+ int irqres = 1;
+ char *q;
- irqres = 1;
/*
* If num_registered_fb is zero, this is a call for the dummy part.
* The frame buffer devices weren't initialized yet.
@@ -753,13 +755,15 @@
return NULL;
}
- ops = kmalloc(sizeof(struct fbcon_ops), GFP_KERNEL);
- if (!ops) {
+ q = kmalloc(size, GFP_KERNEL);
+ if (!q) {
module_put(owner);
return NULL;
}
- memset(ops, 0, sizeof(struct fbcon_ops));
+ memset(q, 0, size);
+ ops = (struct fbcon_ops *) q;
+ ops->scratch_pad = q + sizeof(struct fbcon_ops);
ops->currcon = -1;
info->fbcon_par = ops;
set_blitting_type(vc, info, NULL);
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/console/fbcon.h fbdev-2.6/drivers/video/console/fbcon.h
--- linus-2.6/drivers/video/console/fbcon.h 2005-02-24 10:39:35.000000000 -0800
+++ fbdev-2.6/drivers/video/console/fbcon.h 2005-02-23 16:23:26.000000000 -0800
@@ -48,6 +48,8 @@
struct fb_videomode *mode;
};
+#define FBPIXMAPSIZE (1024 * 8)
+
struct fbcon_ops {
void (*bmove)(struct vc_data *vc, struct fb_info *info, int sy,
int sx, int dy, int dx, int height, int width);
@@ -67,7 +69,8 @@
int cursor_flash;
int cursor_reset;
int blank_state;
- char *cursor_data;
+ char *cursor_data;
+ char *scratch_pad;
};
/*
* Attribute Decoding
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/console/tileblit.c fbdev-2.6/drivers/video/console/tileblit.c
--- linus-2.6/drivers/video/console/tileblit.c 2005-02-24 10:39:36.000000000 -0800
+++ fbdev-2.6/drivers/video/console/tileblit.c 2005-02-23 17:44:59.000000000 -0800
@@ -56,9 +56,10 @@
const unsigned short *s, int count, int yy, int xx,
int fg, int bg)
{
- struct fb_tileblit blit;
unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
+ struct fb_pixmap *pad = info->pad;
int size = sizeof(u32) * count, i;
+ struct fb_tileblit blit;
blit.sx = xx;
blit.sy = yy;
@@ -67,7 +68,7 @@
blit.fg = fg;
blit.bg = bg;
blit.length = count;
- blit.indices = (u32 *) fb_get_buffer_offset(info, &info->pixmap, size);
+ blit.indices = (u32 *) fb_get_buffer_offset(info, pad, size);
for (i = 0; i < count; i++)
blit.indices[i] = (u32)(scr_readw(s++) & charmask);
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/fbmem.c fbdev-2.6/drivers/video/fbmem.c
--- linus-2.6/drivers/video/fbmem.c 2005-01-24 09:43:47.000000000 -0800
+++ fbdev-2.6/drivers/video/fbmem.c 2005-02-23 18:53:35.000000000 -0800
@@ -52,8 +52,6 @@
* Frame buffer device initialization and setup routines
*/
-#define FBPIXMAPSIZE (1024 * 8)
-
static struct notifier_block *fb_notifier_list;
struct fb_info *registered_fb[FB_MAX];
int num_registered_fb;
@@ -77,134 +75,6 @@
}
EXPORT_SYMBOL(fb_get_color_depth);
-/*
- * Drawing helpers.
- */
-void fb_iomove_buf_aligned(struct fb_info *info, struct fb_pixmap *buf,
- u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch,
- u32 height)
-{
- int i;
-
- for (i = height; i--; ) {
- buf->outbuf(info, dst, src, s_pitch);
- src += s_pitch;
- dst += d_pitch;
- }
-}
-
-void fb_sysmove_buf_aligned(struct fb_info *info, struct fb_pixmap *buf,
- u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch,
- u32 height)
-{
- int i, j;
-
- for (i = height; i--; ) {
- for (j = 0; j < s_pitch; j++)
- dst[j] = src[j];
- src += s_pitch;
- dst += d_pitch;
- }
-}
-
-void fb_iomove_buf_unaligned(struct fb_info *info, struct fb_pixmap *buf,
- u8 *dst, u32 d_pitch, u8 *src, u32 idx,
- u32 height, u32 shift_high, u32 shift_low,
- u32 mod)
-{
- u8 mask = (u8) (0xfff << shift_high), tmp;
- int i, j;
-
- for (i = height; i--; ) {
- for (j = 0; j < idx; j++) {
- tmp = buf->inbuf(info, dst+j);
- tmp &= mask;
- tmp |= *src >> shift_low;
- buf->outbuf(info, dst+j, &tmp, 1);
- tmp = *src << shift_high;
- buf->outbuf(info, dst+j+1, &tmp, 1);
- src++;
- }
- tmp = buf->inbuf(info, dst+idx);
- tmp &= mask;
- tmp |= *src >> shift_low;
- buf->outbuf(info, dst+idx, &tmp, 1);
- if (shift_high < mod) {
- tmp = *src << shift_high;
- buf->outbuf(info, dst+idx+1, &tmp, 1);
- }
- src++;
- dst += d_pitch;
- }
-}
-
-void fb_sysmove_buf_unaligned(struct fb_info *info, struct fb_pixmap *buf,
- u8 *dst, u32 d_pitch, u8 *src, u32 idx,
- u32 height, u32 shift_high, u32 shift_low,
- u32 mod)
-{
- u8 mask = (u8) (0xfff << shift_high), tmp;
- int i, j;
-
- for (i = height; i--; ) {
- for (j = 0; j < idx; j++) {
- tmp = dst[j];
- tmp &= mask;
- tmp |= *src >> shift_low;
- dst[j] = tmp;
- tmp = *src << shift_high;
- dst[j+1] = tmp;
- src++;
- }
- tmp = dst[idx];
- tmp &= mask;
- tmp |= *src >> shift_low;
- dst[idx] = tmp;
- if (shift_high < mod) {
- tmp = *src << shift_high;
- dst[idx+1] = tmp;
- }
- src++;
- dst += d_pitch;
- }
-}
-
-/*
- * we need to lock this section since fb_cursor
- * may use fb_imageblit()
- */
-char* fb_get_buffer_offset(struct fb_info *info, struct fb_pixmap *buf, u32 size)
-{
- u32 align = buf->buf_align - 1, offset;
- char *addr = buf->addr;
-
- /* If IO mapped, we need to sync before access, no sharing of
- * the pixmap is done
- */
- if (buf->flags & FB_PIXMAP_IO) {
- if (info->fbops->fb_sync && (buf->flags & FB_PIXMAP_SYNC))
- info->fbops->fb_sync(info);
- return addr;
- }
-
- /* See if we fit in the remaining pixmap space */
- offset = buf->offset + align;
- offset &= ~align;
- if (offset + size > buf->size) {
- /* We do not fit. In order to be able to re-use the buffer,
- * we must ensure no asynchronous DMA'ing or whatever operation
- * is in progress, we sync for that.
- */
- if (info->fbops->fb_sync && (buf->flags & FB_PIXMAP_SYNC))
- info->fbops->fb_sync(info);
- offset = 0;
- }
- buf->offset = offset + size;
- addr += offset;
-
- return addr;
-}
-
#ifdef CONFIG_LOGO
#include <linux/linux_logo.h>
@@ -1075,18 +945,8 @@
/* Not fatal */
printk(KERN_WARNING "Unable to create class_device for framebuffer %d; errno = %ld\n", i, PTR_ERR(c));
}
-
- if (fb_info->pixmap.addr == NULL) {
- fb_info->pixmap.addr = kmalloc(FBPIXMAPSIZE, GFP_KERNEL);
- if (fb_info->pixmap.addr) {
- fb_info->pixmap.size = FBPIXMAPSIZE;
- fb_info->pixmap.buf_align = 1;
- fb_info->pixmap.scan_align = 1;
- fb_info->pixmap.access_align = 4;
- fb_info->pixmap.flags = FB_PIXMAP_DEFAULT;
- }
- }
- fb_info->pixmap.offset = 0;
+
+ fb_init_resources(fb_info);
if (!fb_info->modelist.prev ||
!fb_info->modelist.next ||
@@ -1128,9 +988,7 @@
if (!registered_fb[i])
return -EINVAL;
devfs_remove("fb/%d", i);
-
- if (fb_info->pixmap.addr && (fb_info->pixmap.flags & FB_PIXMAP_DEFAULT))
- kfree(fb_info->pixmap.addr);
+ fb_release_resources(&fb_info->resources);
fb_destroy_modelist(&fb_info->modelist);
registered_fb[i]=NULL;
num_registered_fb--;
@@ -1308,11 +1166,6 @@
EXPORT_SYMBOL(fb_set_var);
EXPORT_SYMBOL(fb_blank);
EXPORT_SYMBOL(fb_pan_display);
-EXPORT_SYMBOL(fb_get_buffer_offset);
-EXPORT_SYMBOL(fb_iomove_buf_unaligned);
-EXPORT_SYMBOL(fb_iomove_buf_aligned);
-EXPORT_SYMBOL(fb_sysmove_buf_unaligned);
-EXPORT_SYMBOL(fb_sysmove_buf_aligned);
EXPORT_SYMBOL(fb_set_suspend);
EXPORT_SYMBOL(fb_register_client);
EXPORT_SYMBOL(fb_unregister_client);
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/i810/i810_accel.c fbdev-2.6/drivers/video/i810/i810_accel.c
--- linus-2.6/drivers/video/i810/i810_accel.c 2005-02-24 10:39:36.000000000 -0800
+++ fbdev-2.6/drivers/video/i810/i810_accel.c 2005-02-24 09:07:12.000000000 -0800
@@ -74,7 +74,7 @@
printk("ringbuffer lockup!!!\n");
i810_report_error(mmio);
par->dev_flags |= LOCKUP;
- info->pixmap.scan_align = 1;
+ info->pad->scan_align = 1;
return 1;
}
@@ -102,7 +102,7 @@
printk("INSTDONE: 0x%04x\n", i810_readl(INSTDONE, mmio));
i810_report_error(mmio);
par->dev_flags |= LOCKUP;
- info->pixmap.scan_align = 1;
+ info->pad->scan_align = 1;
return 1;
}
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/i810/i810_main.c fbdev-2.6/drivers/video/i810/i810_main.c
--- linus-2.6/drivers/video/i810/i810_main.c 2005-02-24 10:39:37.000000000 -0800
+++ fbdev-2.6/drivers/video/i810/i810_main.c 2005-02-24 09:06:25.000000000 -0800
@@ -1374,9 +1374,9 @@
info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN |
FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT |
FBINFO_HWACCEL_IMAGEBLIT;
- info->pixmap.scan_align = 2;
+ info->pad->scan_align = 2;
} else {
- info->pixmap.scan_align = 1;
+ info->pad->scan_align = 1;
info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
}
return 0;
@@ -1867,15 +1867,6 @@
par = (struct i810fb_par *) info->par;
par->dev = dev;
- if (!(info->pixmap.addr = kmalloc(8*1024, GFP_KERNEL))) {
- i810fb_release_resource(info, par);
- return -ENOMEM;
- }
- memset(info->pixmap.addr, 0, 8*1024);
- info->pixmap.size = 8*1024;
- info->pixmap.buf_align = 8;
- info->pixmap.flags = FB_PIXMAP_SYSTEM;
-
if ((err = i810_allocate_pci_resource(par, entry))) {
i810fb_release_resource(info, par);
return err;
@@ -1909,6 +1900,9 @@
return err;
}
+ info->pad->buf_align = 8;
+ info->pad->flags = FB_PIXMAP_SYSTEM;
+
pci_set_drvdata(dev, info);
pixclock = 1000000000/(info->var.pixclock);
pixclock *= 1000;
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/intelfb/intelfbdrv.c fbdev-2.6/drivers/video/intelfb/intelfbdrv.c
--- linus-2.6/drivers/video/intelfb/intelfbdrv.c 2005-02-24 10:39:37.000000000 -0800
+++ fbdev-2.6/drivers/video/intelfb/intelfbdrv.c 2005-02-24 09:14:51.000000000 -0800
@@ -419,7 +419,6 @@
return;
fb_dealloc_cmap(&dinfo->info->cmap);
- kfree(dinfo->info->pixmap.addr);
if (dinfo->registered)
unregister_framebuffer(dinfo->info);
@@ -496,14 +495,6 @@
dinfo->fbops = &intel_fb_ops;
dinfo->pdev = pdev;
- /* Reserve pixmap space. */
- info->pixmap.addr = kmalloc(64 * 1024, GFP_KERNEL);
- if (info->pixmap.addr == NULL) {
- ERR_MSG("Cannot reserve pixmap memory.\n");
- goto err_out_pixmap;
- }
- memset(info->pixmap.addr, 0, 64 * 1024);
-
/* set early this option because it could be changed by tv encoder
driver */
dinfo->fixed_mode = fixed;
@@ -843,12 +834,12 @@
return -ENODEV;
}
+ info->pad->buf_align = 8;
+ info->pad->scan_align = 1;
+ info->pad->flags = FB_PIXMAP_SYSTEM;
dinfo->registered = 1;
-
return 0;
-err_out_pixmap:
- fb_dealloc_cmap(&info->cmap);
err_out_cmap:
framebuffer_release(info);
return -ENODEV;
@@ -1039,17 +1030,10 @@
info->fbops = &intel_fb_ops;
info->pseudo_palette = dinfo->pseudo_palette;
- info->pixmap.size = 64*1024;
- info->pixmap.buf_align = 8;
- info->pixmap.flags = FB_PIXMAP_SYSTEM;
-
if (intelfb_init_var(dinfo))
return 1;
- info->pixmap.scan_align = 1;
-
update_dinfo(dinfo, &info->var);
-
return 0;
}
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/neofb.c fbdev-2.6/drivers/video/neofb.c
--- linus-2.6/drivers/video/neofb.c 2005-02-24 10:39:33.000000000 -0800
+++ fbdev-2.6/drivers/video/neofb.c 2005-02-23 15:47:45.000000000 -0800
@@ -1474,8 +1474,9 @@
{
struct neofb_par *par = (struct neofb_par *) info->par;
int s_pitch = (image->width * image->depth + 7) >> 3;
- int scan_align = info->pixmap.scan_align - 1;
- int buf_align = info->pixmap.buf_align - 1;
+ struct fb_pixmap *pad = info->pad;
+ int scan_align = pad->scan_align - 1;
+ int buf_align = pad->buf_align - 1;
int bltCntl_flags, d_pitch, data_len;
// The data is padded for the hardware
@@ -1728,8 +1729,6 @@
static int __devinit neo_map_video(struct fb_info *info,
struct pci_dev *dev, int video_len)
{
- //unsigned long addr;
-
DBG("neo_map_video");
info->fix.smem_start = pci_resource_start(dev, 0);
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/resmgt.c fbdev-2.6/drivers/video/resmgt.c
--- linus-2.6/drivers/video/resmgt.c 1969-12-31 16:00:00.000000000 -0800
+++ fbdev-2.6/drivers/video/resmgt.c 2005-02-24 09:56:53.000000000 -0800
@@ -0,0 +1,213 @@
+/*
+ * linux/drivers/video/resmgt.c -- Manages the resources of a graphics card.
+ *
+ * Copyright (C) 2005 James Simmons <jsimmons@www.infradead.org>
+ *
+ * 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/module.h>
+#include <linux/fb.h>
+
+#undef DEBUG
+
+#ifdef DEBUG
+#define DPRINTK(fmt, args...) printk("modedb %s: " fmt, __FUNCTION__ , ## args)
+#else
+#define DPRINTK(fmt, args...)
+#endif
+
+#define FBPIXMAPSIZE (1024 * 8)
+
+/*
+ * Data padding functions.
+ */
+void fb_pad_aligned_buffer(struct fb_info *info, u8 *dst, u32 d_pitch,
+ u8 *src, u32 s_pitch, u32 height)
+{
+ int i, j;
+
+ for (i = height; i--; ) {
+ for (j = 0; j < s_pitch; j++)
+ dst[j] = src[j];
+ src += s_pitch;
+ dst += d_pitch;
+ }
+}
+EXPORT_SYMBOL(fb_pad_aligned_buffer);
+
+void fb_pad_unaligned_buffer(struct fb_info *info, u8 *dst, u32 d_pitch,
+ u8 *src, u32 idx, u32 height,
+ u32 shift_high, u32 shift_low, u32 mod)
+{
+ u8 mask = (u8) (0xfff << shift_high), tmp;
+ int i, j;
+
+ for (i = height; i--; ) {
+ for (j = 0; j < idx; j++) {
+ tmp = dst[j];
+ tmp &= mask;
+ tmp |= *src >> shift_low;
+ dst[j] = tmp;
+ tmp = *src << shift_high;
+ dst[j+1] = tmp;
+ src++;
+ }
+ tmp = dst[idx];
+ tmp &= mask;
+ tmp |= *src >> shift_low;
+ dst[idx] = tmp;
+ if (shift_high < mod) {
+ tmp = *src << shift_high;
+ dst[idx+1] = tmp;
+ }
+ src++;
+ dst += d_pitch;
+ }
+}
+EXPORT_SYMBOL(fb_pad_unaligned_buffer);
+
+/*
+ * we need to lock this section since fb_cursor
+ * may use fb_imageblit()
+ */
+char* fb_get_buffer_offset(struct fb_info *info, struct fb_pixmap *buf, u32 size)
+{
+ u32 align = buf->buf_align - 1, offset;
+ char *addr = buf->addr;
+
+ /* If IO mapped, we need to sync before access, no sharing of
+ * the pixmap is done
+ */
+ if (buf->flags & FB_PIXMAP_IO) {
+ if (info->fbops->fb_sync && (buf->flags & FB_PIXMAP_SYNC))
+ info->fbops->fb_sync(info);
+ return addr;
+ }
+
+ /* See if we fit in the remaining pixmap space */
+ offset = buf->offset + align;
+ offset &= ~align;
+ if (offset + size > buf->size) {
+ /* We do not fit. In order to be able to re-use the buffer,
+ * we must ensure no asynchronous DMA'ing or whatever operation
+ * is in progress, we sync for that.
+ */
+ if (info->fbops->fb_sync && (buf->flags & FB_PIXMAP_SYNC))
+ info->fbops->fb_sync(info);
+ offset = 0;
+ }
+ buf->offset = offset + size;
+ addr += offset;
+ return addr;
+}
+EXPORT_SYMBOL(fb_get_buffer_offset);
+
+struct graphics_resource {
+ struct fb_pixmap *resource;
+ struct list_head list;
+};
+
+struct fb_pixmap * fb_find_resource(const char *name, struct list_head *head)
+{
+ struct graphics_resource *rlist = NULL;
+ struct fb_pixmap *resource;
+ struct list_head *pos;
+
+ list_for_each(pos, head) {
+ rlist = list_entry(pos, struct graphics_resource, list);
+ resource = rlist->resource;
+ if (!strncmp(resource->name, name, strlen(name)))
+ return rlist->resource;
+ }
+ return NULL;
+}
+
+int fb_add_resource(struct fb_pixmap *res, struct list_head *head)
+{
+ struct fb_pixmap *resource = fb_find_resource(res->name, head);
+ struct graphics_resource *rlist = NULL;
+
+ if (resource)
+ return 1;
+ rlist = kmalloc(sizeof(struct graphics_resource), GFP_KERNEL);
+ if (!rlist)
+ return -ENOMEM;
+ rlist->resource = res;
+ list_add(&rlist->list, head);
+ return 0;
+}
+
+int fb_remove_resource(struct fb_pixmap *resource, struct list_head *head)
+{
+ struct graphics_resource *rlist;
+ struct list_head *pos, *n;
+
+ if (!resource)
+ return 0;
+
+ list_for_each_safe(pos, n, head) {
+ rlist = list_entry(pos, struct graphics_resource, list);
+ if (!strncmp(resource->name, rlist->resource->name, strlen(rlist->resource->name))) {
+ if (rlist->resource->addr && (rlist->resource->flags & FB_PIXMAP_DEFAULT))
+ kfree(rlist->resource->addr);
+ kfree(rlist->resource);
+ list_del(pos);
+ kfree(pos);
+ }
+ }
+ return 0;
+}
+
+int fb_init_resources(struct fb_info *info)
+{
+ struct fb_pixmap *pad;
+ char *p;
+
+ if (!info->resources.prev || !info->resources.next ||
+ list_empty(&info->resources))
+ INIT_LIST_HEAD(&info->resources);
+
+ // First we create our drawing pad
+ pad = fb_find_resource("drawable", &info->resources);
+ if (!pad) {
+ // Next we create our drawing pad.
+ p = kmalloc(sizeof(struct fb_pixmap), GFP_KERNEL);
+ if (!p)
+ return -ENOMEM;
+ memset(p, 0, sizeof(struct fb_pixmap));
+
+ pad = (struct fb_pixmap *) p;
+ strcpy(pad->name, "drawable");
+ pad->addr = info->screen_base;
+ if (info->screen_size)
+ pad->size = info->screen_size;
+ else
+ pad->size = info->fix.smem_len;
+ pad->buf_align = 1;
+ pad->scan_align = 1;
+ pad->access_align = 4;
+ pad->flags = FB_PIXMAP_IO;
+ pad->offset = 0;
+ fb_add_resource(pad, &info->resources);
+ }
+ info->pad = pad;
+ return 0;
+}
+
+void fb_release_resources(struct list_head *head)
+{
+ struct graphics_resource *rlist;
+ struct list_head *pos, *n;
+
+ list_for_each_safe(pos, n, head) {
+ rlist = list_entry(pos, struct graphics_resource, list);
+ if (rlist->resource->addr && (rlist->resource->flags & FB_PIXMAP_DEFAULT))
+ kfree(rlist->resource->addr);
+ kfree(rlist->resource);
+ list_del(pos);
+ kfree(pos);
+ }
+}
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/riva/fbdev.c fbdev-2.6/drivers/video/riva/fbdev.c
--- linus-2.6/drivers/video/riva/fbdev.c 2005-02-24 10:39:38.000000000 -0800
+++ fbdev-2.6/drivers/video/riva/fbdev.c 2005-02-24 08:36:43.000000000 -0800
@@ -1167,6 +1167,7 @@
static int rivafb_set_par(struct fb_info *info)
{
struct riva_par *par = (struct riva_par *) info->par;
+ struct fb_pixmap *pad = info->pad;
NVTRACE_ENTER();
/* vgaHWunlock() + riva unlock (0x7F) */
@@ -1182,9 +1183,9 @@
FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
if (info->flags & FBINFO_HWACCEL_DISABLED)
- info->pixmap.scan_align = 1;
+ pad->scan_align = 1;
else
- info->pixmap.scan_align = 4;
+ pad->scan_align = 4;
NVTRACE_LEAVE();
return 0;
}
@@ -1581,12 +1582,12 @@
static int rivafb_cursor(struct fb_info *info, struct fb_cursor *cursor)
{
struct riva_par *par = (struct riva_par *) info->par;
+ struct fb_pixmap *pad = info->pad;
u8 data[MAX_CURS * MAX_CURS/8];
- u16 fg, bg;
int i, set = cursor->set;
+ u16 fg, bg;
- if (cursor->image.width > MAX_CURS ||
- cursor->image.height > MAX_CURS)
+ if (cursor->image.width > MAX_CURS || cursor->image.height > MAX_CURS)
return soft_cursor(info, cursor);
par->riva.ShowHideCursor(&par->riva, 0);
@@ -1637,9 +1638,8 @@
break;
}
- fb_sysmove_buf_aligned(info, &info->pixmap, data,
- d_pitch, src, s_pitch,
- cursor->image.height);
+ fb_sysmove_buf_aligned(info, pad, data, d_pitch,
+ src, s_pitch, cursor->image.height);
bg = ((info->cmap.red[bg_idx] & 0xf8) << 7) |
((info->cmap.green[bg_idx] & 0xf8) << 2) |
@@ -1725,10 +1725,6 @@
cmap_len = riva_get_cmap_len(&info->var);
fb_alloc_cmap(&info->cmap, cmap_len, 0);
-
- info->pixmap.size = 8 * 1024;
- info->pixmap.buf_align = 4;
- info->pixmap.flags = FB_PIXMAP_SYSTEM;
info->var.yres_virtual = -1;
NVTRACE_LEAVE();
return (rivafb_check_var(&info->var, info));
@@ -1916,17 +1912,10 @@
default_par = (struct riva_par *) info->par;
default_par->pdev = pd;
- info->pixmap.addr = kmalloc(8 * 1024, GFP_KERNEL);
- if (info->pixmap.addr == NULL) {
- ret = -ENOMEM;
- goto err_framebuffer_release;
- }
- memset(info->pixmap.addr, 0, 8 * 1024);
-
ret = pci_enable_device(pd);
if (ret < 0) {
printk(KERN_ERR PFX "cannot enable PCI device\n");
- goto err_free_pixmap;
+ goto err_framebuffer_release;
}
ret = pci_request_regions(pd, "rivafb");
@@ -2062,6 +2051,15 @@
pci_set_drvdata(pd, info);
+ /*
+ * We have special needs for writing to the framebuffer.
+ * register_framebuffer already created this structure so
+ * we can the default values.
+ */
+ info->pad->buf_align = 4;
+ info->pad->scan_align = 4;
+ info->pad->access_align = 4;
+
printk(KERN_INFO PFX
"PCI nVidia %s framebuffer ver %s (%dMB @ 0x%lX)\n",
info->fix.id,
@@ -2090,8 +2088,6 @@
pci_release_regions(pd);
err_disable_device:
pci_disable_device(pd);
-err_free_pixmap:
- kfree(info->pixmap.addr);
err_framebuffer_release:
framebuffer_release(info);
err_ret:
@@ -2126,7 +2122,7 @@
iounmap(par->riva.PRAMIN);
pci_release_regions(pd);
pci_disable_device(pd);
- kfree(info->pixmap.addr);
+ fb_release_resources(&info->resources);
framebuffer_release(info);
pci_set_drvdata(pd, NULL);
NVTRACE_LEAVE();
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/savage/savagefb.c fbdev-2.6/drivers/video/savage/savagefb.c
--- linus-2.6/drivers/video/savage/savagefb.c 2005-02-24 10:39:39.000000000 -0800
+++ fbdev-2.6/drivers/video/savage/savagefb.c 2005-02-24 08:48:19.000000000 -0800
@@ -687,6 +687,18 @@
DBG("savagefb_check_var");
+#if defined(CONFIG_FB_SAVAGE_ACCEL)
+ /*
+ * The clipping coordinates are masked with 0xFFF, so limit our
+ * virtual resolutions to these sizes.
+ */
+ if (info->var.yres_virtual > 0x1000)
+ info->var.yres_virtual = 0x1000;
+
+ if (info->var.xres_virtual > 0x1000)
+ info->var.xres_virtual = 0x1000;
+#endif
+
var->transp.offset = 0;
var->transp.length = 0;
switch (var->bits_per_pixel) {
@@ -1779,7 +1791,7 @@
return videoRambytes;
}
-static int __devinit savage_init_fb_info (struct fb_info *info,
+static void __devinit savage_init_fb_info (struct fb_info *info,
struct pci_dev *dev,
const struct pci_device_id *id)
{
@@ -1883,27 +1895,7 @@
FBINFO_MISC_MODESWITCHLATE;
info->pseudo_palette = par->pseudo_palette;
-
-#if defined(CONFIG_FB_SAVAGE_ACCEL)
- /* FIFO size + padding for commands */
- info->pixmap.addr = kmalloc(8*1024, GFP_KERNEL);
-
- err = -ENOMEM;
- if (info->pixmap.addr) {
- memset(info->pixmap.addr, 0, 8*1024);
- info->pixmap.size = 8*1024;
- info->pixmap.scan_align = 4;
- info->pixmap.buf_align = 4;
- info->pixmap.access_align = 4;
-
- fb_alloc_cmap (&info->cmap, NR_PALETTE, 0);
- info->flags |= FBINFO_HWACCEL_COPYAREA |
- FBINFO_HWACCEL_FILLRECT |
- FBINFO_HWACCEL_IMAGEBLIT;
-
- err = 0;
- }
-#endif
+ fb_alloc_cmap (&info->cmap, NR_PALETTE, 0);
return err;
}
@@ -1936,8 +1928,7 @@
err = -ENOMEM;
- if (savage_init_fb_info(info, dev, id))
- goto failed_init;
+ savage_init_fb_info(info, dev, id);
err = savage_map_mmio(info);
if (err)
@@ -1996,17 +1987,6 @@
if (info->var.yres_virtual < info->var.yres)
goto failed;
-#if defined(CONFIG_FB_SAVAGE_ACCEL)
- /*
- * The clipping coordinates are masked with 0xFFF, so limit our
- * virtual resolutions to these sizes.
- */
- if (info->var.yres_virtual > 0x1000)
- info->var.yres_virtual = 0x1000;
-
- if (info->var.xres_virtual > 0x1000)
- info->var.xres_virtual = 0x1000;
-#endif
savagefb_check_var(&info->var, info);
savagefb_set_fix(info);
@@ -2037,6 +2017,16 @@
if (err < 0)
goto failed;
+#if defined(CONFIG_FB_SAVAGE_ACCEL)
+ /* FIFO size + padding for commands */
+ info->pad->scan_align = 4;
+ info->pad->buf_align = 4;
+ info->pad->access_align = 4;
+
+ info->flags |= FBINFO_HWACCEL_COPYAREA |
+ FBINFO_HWACCEL_FILLRECT |
+ FBINFO_HWACCEL_IMAGEBLIT;
+#endif
printk (KERN_INFO "fb: S3 %s frame buffer device\n",
info->fix.id);
@@ -2051,17 +2041,14 @@
#ifdef CONFIG_FB_SAVAGE_I2C
savagefb_delete_i2c_busses(info);
#endif
- fb_alloc_cmap (&info->cmap, 0, 0);
+ fb_dealloc_cmap(&info->cmap);
savage_unmap_video(info);
failed_video:
savage_unmap_mmio (info);
failed_mmio:
- kfree(info->pixmap.addr);
- failed_init:
pci_release_regions(dev);
failed_enable:
framebuffer_release(info);
-
return err;
}
@@ -2085,10 +2072,9 @@
#ifdef CONFIG_FB_SAVAGE_I2C
savagefb_delete_i2c_busses(info);
#endif
- fb_alloc_cmap (&info->cmap, 0, 0);
+ fb_dealloc_cmap(&info->cmap);
savage_unmap_video (info);
savage_unmap_mmio (info);
- kfree(info->pixmap.addr);
pci_release_regions(dev);
framebuffer_release(info);
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/softcursor.c fbdev-2.6/drivers/video/softcursor.c
--- linus-2.6/drivers/video/softcursor.c 2005-02-24 10:39:34.000000000 -0800
+++ fbdev-2.6/drivers/video/softcursor.c 2005-02-24 09:58:43.000000000 -0800
@@ -19,8 +19,9 @@
int soft_cursor(struct fb_info *info, struct fb_cursor *cursor)
{
- unsigned int scan_align = info->pixmap.scan_align - 1;
- unsigned int buf_align = info->pixmap.buf_align - 1;
+ struct fb_pixmap *pad = info->pad;
+ unsigned int scan_align = pad->scan_align - 1;
+ unsigned int buf_align = pad->buf_align - 1;
unsigned int i, size, dsize, s_pitch, d_pitch;
struct fb_image *image;
u8 *dst, *src;
@@ -41,7 +42,7 @@
size = d_pitch * image->height + buf_align;
size &= ~buf_align;
- dst = fb_get_buffer_offset(info, &info->pixmap, size);
+ dst = fb_get_buffer_offset(info, pad, size);
if (cursor->enable) {
switch (cursor->rop) {
@@ -57,18 +58,11 @@
}
} else
memcpy(src, image->data, dsize);
-
- if (info->pixmap.outbuf)
- fb_iomove_buf_aligned(info, &info->pixmap, dst, d_pitch, src,
- s_pitch, image->height);
- else
- fb_sysmove_buf_aligned(info, &info->pixmap, dst, d_pitch, src,
- s_pitch, image->height);
+ fb_pad_aligned_buffer(info, dst, d_pitch, src, s_pitch, image->height);
image->data = dst;
info->fbops->fb_imageblit(info, image);
kfree(src);
-
return 0;
}
diff -urN -X /home/jsimmons/dontdiff linus-2.6/include/linux/fb.h fbdev-2.6/include/linux/fb.h
--- linus-2.6/include/linux/fb.h 2005-02-24 10:41:22.000000000 -0800
+++ fbdev-2.6/include/linux/fb.h 2005-02-24 09:58:13.000000000 -0800
@@ -514,6 +514,7 @@
#define FB_PIXMAP_SYNC 256 /* set if GPU can DMA */
struct fb_pixmap {
+ char name[16]; /* Name of the resource */
u8 *addr; /* pointer to memory */
u32 size; /* size of buffer in bytes */
u32 offset; /* current offset to buffer */
@@ -523,7 +524,7 @@
u32 flags; /* see FB_PIXMAP_* */
/* access methods */
void (*outbuf)(struct fb_info *info, u8 *addr, u8 *src, unsigned int size);
- u8 (*inbuf) (struct fb_info *info, u8 *addr);
+ u8* (*inbuf) (struct fb_info *info, u8 *addr, unsigned int size);
};
@@ -707,11 +708,12 @@
struct fb_var_screeninfo var; /* Current var */
struct fb_fix_screeninfo fix; /* Current fix */
struct fb_monspecs monspecs; /* Current Monitor specs */
+ struct list_head resources; /* Graphics resources */
+ struct list_head modelist; /* mode list */
struct work_struct queue; /* Framebuffer event queue */
- struct fb_pixmap pixmap; /* Image hardware mapper */
- struct fb_pixmap sprite; /* Cursor hardware mapper */
+ struct fb_pixmap *sprite; /* Cursor hardware mapper */
+ struct fb_pixmap *pad; /* Image hardware mapper */
struct fb_cmap cmap; /* Current cmap */
- struct list_head modelist; /* mode list */
struct fb_ops *fbops;
struct device *device;
#ifdef CONFIG_FB_TILEBLITTING
@@ -807,19 +809,6 @@
extern int unregister_framebuffer(struct fb_info *fb_info);
extern int fb_prepare_logo(struct fb_info *fb_info);
extern int fb_show_logo(struct fb_info *fb_info);
-extern char* fb_get_buffer_offset(struct fb_info *info, struct fb_pixmap *buf, u32 size);
-extern void fb_iomove_buf_unaligned(struct fb_info *info, struct fb_pixmap *buf,
- u8 *dst, u32 d_pitch, u8 *src, u32 idx,
- u32 height, u32 shift_high, u32 shift_low, u32 mod);
-extern void fb_iomove_buf_aligned(struct fb_info *info, struct fb_pixmap *buf,
- u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch,
- u32 height);
-extern void fb_sysmove_buf_unaligned(struct fb_info *info, struct fb_pixmap *buf,
- u8 *dst, u32 d_pitch, u8 *src, u32 idx,
- u32 height, u32 shift_high, u32 shift_low, u32 mod);
-extern void fb_sysmove_buf_aligned(struct fb_info *info, struct fb_pixmap *buf,
- u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch,
- u32 height);
extern void fb_set_suspend(struct fb_info *info, int state);
extern int fb_get_color_depth(struct fb_info *info);
extern int fb_get_options(char *name, char **option);
@@ -827,6 +816,19 @@
extern struct fb_info *registered_fb[FB_MAX];
extern int num_registered_fb;
+/* drivers/video/resmgt.c */
+extern char* fb_get_buffer_offset(struct fb_info *info, struct fb_pixmap *buf, u32 size);
+extern void fb_pad_unaligned_buffer(struct fb_info *info, u8 *dst, u32 d_pitch,
+ u8 *src, u32 idx, u32 height, u32 shift_high,
+ u32 shift_low, u32 mod);
+extern void fb_pad_aligned_buffer(struct fb_info *info, u8 *dst, u32 d_pitch,
+ u8 *src, u32 s_pitch, u32 height);
+void fb_release_resources(struct list_head *head);
+int fb_remove_resource(struct fb_pixmap *resource, struct list_head *head);
+int fb_add_resource(struct fb_pixmap *resource, struct list_head *head);
+struct fb_pixmap* fb_find_resource(const char *name, struct list_head *head);
+int fb_init_resources(struct fb_info *info);
+
/* drivers/video/fbsysfs.c */
extern struct fb_info *framebuffer_alloc(size_t size, struct device *dev);
extern void framebuffer_release(struct fb_info *info);
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Resource management.
2005-02-24 19:57 ` James Simmons
@ 2005-02-24 23:05 ` Antonino A. Daplas
2005-02-28 20:01 ` Resource management II James Simmons
0 siblings, 1 reply; 16+ messages in thread
From: Antonino A. Daplas @ 2005-02-24 23:05 UTC (permalink / raw)
To: James Simmons, adaplas
Cc: Linux Fbdev development list, James Simmons, Geert Uytterhoeven
On Friday 25 February 2005 03:57, James Simmons wrote:
> > If you intend to insist on doing this, this is my proposal:
> >
> > The linked list of resources per fb_info can be kept. However, instead
> > of doing an fb_find_resource() per call to putcs and cursor, this can
> > be done only once, during initialization of fbcon or set_con2fb_map.
> > This resource can then be stored in an fbcon-private area.
>
> I fixed this in my latest work. Alot of cleanups has happened. Still a few
> issues to work out.
Looks much better. And yes, I also see a few issues but is not your fault.
>
> > The advantage of this is that fbcon will only look for the resource that
> > it needs, ie "scratchpad" but not, for example, "overlay". Similarly,
> > a user video application can totally ignore "scratchpad" but will search
> > for "overlay". Secondly, the performance penalty suffered by the your
> > initial patch will be eliminated. We also eliminate one or two more
> > fields in fb_info directly accessed by fbcon.
>
> I removed the scratch pad. We use the data reflecting the "drawable"
> properties.
>
> > Also, instead of storing the resource type as a string, why not use a
> > constant?
>
> We would run out very fast.
With a u32?
> Plus we would need a index field in the case
> we have more than one of the same kind.
Then use a u32 for type, u32 for index.
Tony
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
^ permalink raw reply [flat|nested] 16+ messages in thread
* Resource management II
2005-02-24 23:05 ` Antonino A. Daplas
@ 2005-02-28 20:01 ` James Simmons
0 siblings, 0 replies; 16+ messages in thread
From: James Simmons @ 2005-02-28 20:01 UTC (permalink / raw)
To: adaplas; +Cc: James Simmons, Linux Fbdev development list, Geert Uytterhoeven
Here is a second version of the Resource Manager. Its still not done. I
want to test a few more things. The last issue to tackle is the string in
struct fb_pixmap. I like to keep it for sysfs. Need to ponder the pixmaps
cleanups now with the flags. This patch nukes the kmalloc in softcursor :-)
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/Makefile fbdev-2.6/drivers/video/Makefile
--- linus-2.6/drivers/video/Makefile 2005-02-27 17:56:01.000000000 -0800
+++ fbdev-2.6/drivers/video/Makefile 2005-02-17 14:26:42.000000000 -0800
@@ -8,7 +8,7 @@
obj-$(CONFIG_LOGO) += logo/
obj-$(CONFIG_SYSFS) += backlight/
-obj-$(CONFIG_FB) += fbmem.o fbmon.o fbcmap.o fbsysfs.o modedb.o softcursor.o
+obj-$(CONFIG_FB) += fbmem.o fbmon.o fbcmap.o fbsysfs.o modedb.o resmgt.o softcursor.o
# Only include macmodes.o if we have FB support and are PPC
ifeq ($(CONFIG_FB),y)
obj-$(CONFIG_PPC) += macmodes.o
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/console/bitblit.c fbdev-2.6/drivers/video/console/bitblit.c
--- linus-2.6/drivers/video/console/bitblit.c 2005-02-27 17:56:06.000000000 -0800
+++ fbdev-2.6/drivers/video/console/bitblit.c 2005-02-24 10:00:30.000000000 -0800
@@ -107,25 +107,20 @@
const unsigned short *s, int count, int yy, int xx,
int fg, int bg)
{
- void (*move_unaligned)(struct fb_info *info, struct fb_pixmap *buf,
- u8 *dst, u32 d_pitch, u8 *src, u32 idx,
- u32 height, u32 shift_high, u32 shift_low,
- u32 mod);
- void (*move_aligned)(struct fb_info *info, struct fb_pixmap *buf,
- u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch,
- u32 height);
+ struct fbcon_ops *ops = (struct fbcon_ops *) info->fbcon_par;
unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
unsigned int width = (vc->vc_font.width + 7) >> 3;
unsigned int cellsize = vc->vc_font.height * width;
- unsigned int maxcnt = info->pixmap.size/cellsize;
- unsigned int scan_align = info->pixmap.scan_align - 1;
- unsigned int buf_align = info->pixmap.buf_align - 1;
+ struct fb_pixmap *pad = info->pad;
+ unsigned int maxcnt = pad->size/cellsize;
+ unsigned int scan_align = pad->scan_align - 1;
+ unsigned int buf_align = pad->buf_align - 1;
unsigned int shift_low = 0, mod = vc->vc_font.width % 8;
unsigned int shift_high = 8, pitch, cnt, size, k;
unsigned int idx = vc->vc_font.width >> 3;
unsigned int attribute = get_attribute(info, scr_readw(s));
- struct fb_image image;
u8 *src, *dst, *buf = NULL;
+ struct fb_image image;
if (attribute) {
buf = kmalloc(cellsize, GFP_KERNEL);
@@ -141,13 +136,6 @@
image.height = vc->vc_font.height;
image.depth = 1;
- if (info->pixmap.outbuf && info->pixmap.inbuf) {
- move_aligned = fb_iomove_buf_aligned;
- move_unaligned = fb_iomove_buf_unaligned;
- } else {
- move_aligned = fb_sysmove_buf_aligned;
- move_unaligned = fb_sysmove_buf_unaligned;
- }
while (count) {
if (count > maxcnt)
cnt = k = maxcnt;
@@ -159,7 +147,7 @@
pitch &= ~scan_align;
size = pitch * image.height + buf_align;
size &= ~buf_align;
- dst = fb_get_buffer_offset(info, &info->pixmap, size);
+ dst = ops->scratch_pad;
image.data = dst;
if (mod) {
while (k--) {
@@ -171,9 +159,9 @@
src = buf;
}
- move_unaligned(info, &info->pixmap, dst, pitch,
- src, idx, image.height,
- shift_high, shift_low, mod);
+ fb_pad_unaligned_buffer(info, dst, pitch, src, idx,
+ image.height, shift_high, shift_low,
+ mod);
shift_low += mod;
dst += (shift_low >= 8) ? width : width - 1;
shift_low &= 7;
@@ -189,8 +177,7 @@
src = buf;
}
- move_aligned(info, &info->pixmap, dst, pitch,
- src, idx, image.height);
+ fb_pad_aligned_buffer(info, dst, pitch, src, idx, image.height);
dst += width;
}
}
@@ -238,12 +225,12 @@
static void bit_cursor(struct vc_data *vc, struct fb_info *info,
struct display *p, int mode, int fg, int bg)
{
- struct fb_cursor cursor;
struct fbcon_ops *ops = (struct fbcon_ops *) info->fbcon_par;
unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
int w = (vc->vc_font.width + 7) >> 3, c;
int y = real_y(p, vc->vc_y);
int attribute, use_sw = (vc->vc_cursor_type & 0x10);
+ struct fb_cursor cursor;
char *src;
cursor.set = 0;
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/console/fbcon.c fbdev-2.6/drivers/video/console/fbcon.c
--- linus-2.6/drivers/video/console/fbcon.c 2005-02-27 17:56:07.000000000 -0800
+++ fbdev-2.6/drivers/video/console/fbcon.c 2005-02-24 09:59:37.000000000 -0800
@@ -507,9 +507,10 @@
static int con2fb_acquire_newinfo(struct vc_data *vc, struct fb_info *info,
int unit, int oldidx)
{
+ int size = sizeof(struct fbcon_ops) + FBPIXMAPSIZE, err = 0;
struct fbcon_ops *ops = NULL;
- int err = 0;
-
+ char *p;
+
if (!try_module_get(info->fbops->owner))
err = -ENODEV;
@@ -518,13 +519,15 @@
err = -ENODEV;
if (!err) {
- ops = kmalloc(sizeof(struct fbcon_ops), GFP_KERNEL);
- if (!ops)
+ p = kmalloc(size, GFP_KERNEL);
+ if (!p)
err = -ENOMEM;
}
if (!err) {
- memset(ops, 0, sizeof(struct fbcon_ops));
+ memset(p, 0, size);
+ ops = (struct fbcon_ops *) p;
+ ops->scratch_pad = p + sizeof(struct fbcon_ops);
info->fbcon_par = ops;
set_blitting_type(vc, info, NULL);
}
@@ -533,7 +536,6 @@
con2fb_map[unit] = oldidx;
module_put(info->fbops->owner);
}
-
return err;
}
@@ -720,17 +722,17 @@
static const char *fbcon_startup(void)
{
+ int rows, cols, size = sizeof(struct fbcon_ops) + FBPIXMAPSIZE;
const char *display_desc = "frame buffer device";
struct display *p = &fb_display[fg_console];
struct vc_data *vc = vc_cons[fg_console].d;
struct font_desc *font = NULL;
- struct module *owner;
struct fb_info *info = NULL;
struct fbcon_ops *ops;
- int rows, cols;
- int irqres;
+ struct module *owner;
+ int irqres = 1;
+ char *q;
- irqres = 1;
/*
* If num_registered_fb is zero, this is a call for the dummy part.
* The frame buffer devices weren't initialized yet.
@@ -753,13 +755,15 @@
return NULL;
}
- ops = kmalloc(sizeof(struct fbcon_ops), GFP_KERNEL);
- if (!ops) {
+ q = kmalloc(size, GFP_KERNEL);
+ if (!q) {
module_put(owner);
return NULL;
}
- memset(ops, 0, sizeof(struct fbcon_ops));
+ memset(q, 0, size);
+ ops = (struct fbcon_ops *) q;
+ ops->scratch_pad = q + sizeof(struct fbcon_ops);
ops->currcon = -1;
info->fbcon_par = ops;
set_blitting_type(vc, info, NULL);
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/console/fbcon.h fbdev-2.6/drivers/video/console/fbcon.h
--- linus-2.6/drivers/video/console/fbcon.h 2005-02-27 17:56:07.000000000 -0800
+++ fbdev-2.6/drivers/video/console/fbcon.h 2005-02-23 16:23:26.000000000 -0800
@@ -48,6 +48,8 @@
struct fb_videomode *mode;
};
+#define FBPIXMAPSIZE (1024 * 8)
+
struct fbcon_ops {
void (*bmove)(struct vc_data *vc, struct fb_info *info, int sy,
int sx, int dy, int dx, int height, int width);
@@ -67,7 +69,8 @@
int cursor_flash;
int cursor_reset;
int blank_state;
- char *cursor_data;
+ char *cursor_data;
+ char *scratch_pad;
};
/*
* Attribute Decoding
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/console/tileblit.c fbdev-2.6/drivers/video/console/tileblit.c
--- linus-2.6/drivers/video/console/tileblit.c 2005-02-27 17:56:09.000000000 -0800
+++ fbdev-2.6/drivers/video/console/tileblit.c 2005-02-23 17:44:59.000000000 -0800
@@ -56,9 +56,10 @@
const unsigned short *s, int count, int yy, int xx,
int fg, int bg)
{
- struct fb_tileblit blit;
unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
+ struct fb_pixmap *pad = info->pad;
int size = sizeof(u32) * count, i;
+ struct fb_tileblit blit;
blit.sx = xx;
blit.sy = yy;
@@ -67,7 +68,7 @@
blit.fg = fg;
blit.bg = bg;
blit.length = count;
- blit.indices = (u32 *) fb_get_buffer_offset(info, &info->pixmap, size);
+ blit.indices = (u32 *) fb_get_buffer_offset(info, pad, size);
for (i = 0; i < count; i++)
blit.indices[i] = (u32)(scr_readw(s++) & charmask);
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/fbmem.c fbdev-2.6/drivers/video/fbmem.c
--- linus-2.6/drivers/video/fbmem.c 2005-01-24 09:43:47.000000000 -0800
+++ fbdev-2.6/drivers/video/fbmem.c 2005-02-23 18:53:35.000000000 -0800
@@ -52,8 +52,6 @@
* Frame buffer device initialization and setup routines
*/
-#define FBPIXMAPSIZE (1024 * 8)
-
static struct notifier_block *fb_notifier_list;
struct fb_info *registered_fb[FB_MAX];
int num_registered_fb;
@@ -77,134 +75,6 @@
}
EXPORT_SYMBOL(fb_get_color_depth);
-/*
- * Drawing helpers.
- */
-void fb_iomove_buf_aligned(struct fb_info *info, struct fb_pixmap *buf,
- u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch,
- u32 height)
-{
- int i;
-
- for (i = height; i--; ) {
- buf->outbuf(info, dst, src, s_pitch);
- src += s_pitch;
- dst += d_pitch;
- }
-}
-
-void fb_sysmove_buf_aligned(struct fb_info *info, struct fb_pixmap *buf,
- u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch,
- u32 height)
-{
- int i, j;
-
- for (i = height; i--; ) {
- for (j = 0; j < s_pitch; j++)
- dst[j] = src[j];
- src += s_pitch;
- dst += d_pitch;
- }
-}
-
-void fb_iomove_buf_unaligned(struct fb_info *info, struct fb_pixmap *buf,
- u8 *dst, u32 d_pitch, u8 *src, u32 idx,
- u32 height, u32 shift_high, u32 shift_low,
- u32 mod)
-{
- u8 mask = (u8) (0xfff << shift_high), tmp;
- int i, j;
-
- for (i = height; i--; ) {
- for (j = 0; j < idx; j++) {
- tmp = buf->inbuf(info, dst+j);
- tmp &= mask;
- tmp |= *src >> shift_low;
- buf->outbuf(info, dst+j, &tmp, 1);
- tmp = *src << shift_high;
- buf->outbuf(info, dst+j+1, &tmp, 1);
- src++;
- }
- tmp = buf->inbuf(info, dst+idx);
- tmp &= mask;
- tmp |= *src >> shift_low;
- buf->outbuf(info, dst+idx, &tmp, 1);
- if (shift_high < mod) {
- tmp = *src << shift_high;
- buf->outbuf(info, dst+idx+1, &tmp, 1);
- }
- src++;
- dst += d_pitch;
- }
-}
-
-void fb_sysmove_buf_unaligned(struct fb_info *info, struct fb_pixmap *buf,
- u8 *dst, u32 d_pitch, u8 *src, u32 idx,
- u32 height, u32 shift_high, u32 shift_low,
- u32 mod)
-{
- u8 mask = (u8) (0xfff << shift_high), tmp;
- int i, j;
-
- for (i = height; i--; ) {
- for (j = 0; j < idx; j++) {
- tmp = dst[j];
- tmp &= mask;
- tmp |= *src >> shift_low;
- dst[j] = tmp;
- tmp = *src << shift_high;
- dst[j+1] = tmp;
- src++;
- }
- tmp = dst[idx];
- tmp &= mask;
- tmp |= *src >> shift_low;
- dst[idx] = tmp;
- if (shift_high < mod) {
- tmp = *src << shift_high;
- dst[idx+1] = tmp;
- }
- src++;
- dst += d_pitch;
- }
-}
-
-/*
- * we need to lock this section since fb_cursor
- * may use fb_imageblit()
- */
-char* fb_get_buffer_offset(struct fb_info *info, struct fb_pixmap *buf, u32 size)
-{
- u32 align = buf->buf_align - 1, offset;
- char *addr = buf->addr;
-
- /* If IO mapped, we need to sync before access, no sharing of
- * the pixmap is done
- */
- if (buf->flags & FB_PIXMAP_IO) {
- if (info->fbops->fb_sync && (buf->flags & FB_PIXMAP_SYNC))
- info->fbops->fb_sync(info);
- return addr;
- }
-
- /* See if we fit in the remaining pixmap space */
- offset = buf->offset + align;
- offset &= ~align;
- if (offset + size > buf->size) {
- /* We do not fit. In order to be able to re-use the buffer,
- * we must ensure no asynchronous DMA'ing or whatever operation
- * is in progress, we sync for that.
- */
- if (info->fbops->fb_sync && (buf->flags & FB_PIXMAP_SYNC))
- info->fbops->fb_sync(info);
- offset = 0;
- }
- buf->offset = offset + size;
- addr += offset;
-
- return addr;
-}
-
#ifdef CONFIG_LOGO
#include <linux/linux_logo.h>
@@ -1075,18 +945,8 @@
/* Not fatal */
printk(KERN_WARNING "Unable to create class_device for framebuffer %d; errno = %ld\n", i, PTR_ERR(c));
}
-
- if (fb_info->pixmap.addr == NULL) {
- fb_info->pixmap.addr = kmalloc(FBPIXMAPSIZE, GFP_KERNEL);
- if (fb_info->pixmap.addr) {
- fb_info->pixmap.size = FBPIXMAPSIZE;
- fb_info->pixmap.buf_align = 1;
- fb_info->pixmap.scan_align = 1;
- fb_info->pixmap.access_align = 4;
- fb_info->pixmap.flags = FB_PIXMAP_DEFAULT;
- }
- }
- fb_info->pixmap.offset = 0;
+
+ fb_init_resources(fb_info);
if (!fb_info->modelist.prev ||
!fb_info->modelist.next ||
@@ -1128,9 +988,7 @@
if (!registered_fb[i])
return -EINVAL;
devfs_remove("fb/%d", i);
-
- if (fb_info->pixmap.addr && (fb_info->pixmap.flags & FB_PIXMAP_DEFAULT))
- kfree(fb_info->pixmap.addr);
+ fb_release_resources(&fb_info->resources);
fb_destroy_modelist(&fb_info->modelist);
registered_fb[i]=NULL;
num_registered_fb--;
@@ -1308,11 +1166,6 @@
EXPORT_SYMBOL(fb_set_var);
EXPORT_SYMBOL(fb_blank);
EXPORT_SYMBOL(fb_pan_display);
-EXPORT_SYMBOL(fb_get_buffer_offset);
-EXPORT_SYMBOL(fb_iomove_buf_unaligned);
-EXPORT_SYMBOL(fb_iomove_buf_aligned);
-EXPORT_SYMBOL(fb_sysmove_buf_unaligned);
-EXPORT_SYMBOL(fb_sysmove_buf_aligned);
EXPORT_SYMBOL(fb_set_suspend);
EXPORT_SYMBOL(fb_register_client);
EXPORT_SYMBOL(fb_unregister_client);
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/i810/i810_accel.c fbdev-2.6/drivers/video/i810/i810_accel.c
--- linus-2.6/drivers/video/i810/i810_accel.c 2005-02-27 17:56:10.000000000 -0800
+++ fbdev-2.6/drivers/video/i810/i810_accel.c 2005-02-24 09:07:12.000000000 -0800
@@ -74,7 +74,7 @@
printk("ringbuffer lockup!!!\n");
i810_report_error(mmio);
par->dev_flags |= LOCKUP;
- info->pixmap.scan_align = 1;
+ info->pad->scan_align = 1;
return 1;
}
@@ -102,7 +102,7 @@
printk("INSTDONE: 0x%04x\n", i810_readl(INSTDONE, mmio));
i810_report_error(mmio);
par->dev_flags |= LOCKUP;
- info->pixmap.scan_align = 1;
+ info->pad->scan_align = 1;
return 1;
}
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/i810/i810_main.c fbdev-2.6/drivers/video/i810/i810_main.c
--- linus-2.6/drivers/video/i810/i810_main.c 2005-02-27 17:56:10.000000000 -0800
+++ fbdev-2.6/drivers/video/i810/i810_main.c 2005-02-24 09:06:25.000000000 -0800
@@ -1374,9 +1374,9 @@
info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN |
FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT |
FBINFO_HWACCEL_IMAGEBLIT;
- info->pixmap.scan_align = 2;
+ info->pad->scan_align = 2;
} else {
- info->pixmap.scan_align = 1;
+ info->pad->scan_align = 1;
info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
}
return 0;
@@ -1867,15 +1867,6 @@
par = (struct i810fb_par *) info->par;
par->dev = dev;
- if (!(info->pixmap.addr = kmalloc(8*1024, GFP_KERNEL))) {
- i810fb_release_resource(info, par);
- return -ENOMEM;
- }
- memset(info->pixmap.addr, 0, 8*1024);
- info->pixmap.size = 8*1024;
- info->pixmap.buf_align = 8;
- info->pixmap.flags = FB_PIXMAP_SYSTEM;
-
if ((err = i810_allocate_pci_resource(par, entry))) {
i810fb_release_resource(info, par);
return err;
@@ -1909,6 +1900,9 @@
return err;
}
+ info->pad->buf_align = 8;
+ info->pad->flags = FB_PIXMAP_SYSTEM;
+
pci_set_drvdata(dev, info);
pixclock = 1000000000/(info->var.pixclock);
pixclock *= 1000;
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/intelfb/intelfbdrv.c fbdev-2.6/drivers/video/intelfb/intelfbdrv.c
--- linus-2.6/drivers/video/intelfb/intelfbdrv.c 2005-02-27 17:56:10.000000000 -0800
+++ fbdev-2.6/drivers/video/intelfb/intelfbdrv.c 2005-02-24 09:14:51.000000000 -0800
@@ -419,7 +419,6 @@
return;
fb_dealloc_cmap(&dinfo->info->cmap);
- kfree(dinfo->info->pixmap.addr);
if (dinfo->registered)
unregister_framebuffer(dinfo->info);
@@ -496,14 +495,6 @@
dinfo->fbops = &intel_fb_ops;
dinfo->pdev = pdev;
- /* Reserve pixmap space. */
- info->pixmap.addr = kmalloc(64 * 1024, GFP_KERNEL);
- if (info->pixmap.addr == NULL) {
- ERR_MSG("Cannot reserve pixmap memory.\n");
- goto err_out_pixmap;
- }
- memset(info->pixmap.addr, 0, 64 * 1024);
-
/* set early this option because it could be changed by tv encoder
driver */
dinfo->fixed_mode = fixed;
@@ -843,12 +834,12 @@
return -ENODEV;
}
+ info->pad->buf_align = 8;
+ info->pad->scan_align = 1;
+ info->pad->flags = FB_PIXMAP_SYSTEM;
dinfo->registered = 1;
-
return 0;
-err_out_pixmap:
- fb_dealloc_cmap(&info->cmap);
err_out_cmap:
framebuffer_release(info);
return -ENODEV;
@@ -1039,17 +1030,10 @@
info->fbops = &intel_fb_ops;
info->pseudo_palette = dinfo->pseudo_palette;
- info->pixmap.size = 64*1024;
- info->pixmap.buf_align = 8;
- info->pixmap.flags = FB_PIXMAP_SYSTEM;
-
if (intelfb_init_var(dinfo))
return 1;
- info->pixmap.scan_align = 1;
-
update_dinfo(dinfo, &info->var);
-
return 0;
}
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/neofb.c fbdev-2.6/drivers/video/neofb.c
--- linus-2.6/drivers/video/neofb.c 2005-02-27 17:56:02.000000000 -0800
+++ fbdev-2.6/drivers/video/neofb.c 2005-02-23 15:47:45.000000000 -0800
@@ -1474,8 +1474,9 @@
{
struct neofb_par *par = (struct neofb_par *) info->par;
int s_pitch = (image->width * image->depth + 7) >> 3;
- int scan_align = info->pixmap.scan_align - 1;
- int buf_align = info->pixmap.buf_align - 1;
+ struct fb_pixmap *pad = info->pad;
+ int scan_align = pad->scan_align - 1;
+ int buf_align = pad->buf_align - 1;
int bltCntl_flags, d_pitch, data_len;
// The data is padded for the hardware
@@ -1728,8 +1729,6 @@
static int __devinit neo_map_video(struct fb_info *info,
struct pci_dev *dev, int video_len)
{
- //unsigned long addr;
-
DBG("neo_map_video");
info->fix.smem_start = pci_resource_start(dev, 0);
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/resmgt.c fbdev-2.6/drivers/video/resmgt.c
--- linus-2.6/drivers/video/resmgt.c 1969-12-31 16:00:00.000000000 -0800
+++ fbdev-2.6/drivers/video/resmgt.c 2005-02-28 11:12:38.000000000 -0800
@@ -0,0 +1,246 @@
+/*
+ * linux/drivers/video/resmgt.c -- Manages the resources of a graphics card.
+ *
+ * Copyright (C) 2005 James Simmons <jsimmons@www.infradead.org>
+ *
+ * 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/module.h>
+#include <linux/fb.h>
+
+#undef DEBUG
+
+#ifdef DEBUG
+#define DPRINTK(fmt, args...) printk("modedb %s: " fmt, __FUNCTION__ , ## args)
+#else
+#define DPRINTK(fmt, args...)
+#endif
+
+#define FBPIXMAPSIZE (1024 * 8)
+
+/*
+ * Generic IO access methods for graphics buffers.
+ */
+void fb_writeio(struct fb_info *info, void __iomem *addr, void *src, unsigned int size)
+{
+ memcpy_toio(addr, src, size);
+}
+
+void fb_readio(struct fb_info *info, void *dst, void __iomem *addr, unsigned int size)
+{
+ memcpy_fromio(dst, addr, size);
+}
+
+/*
+ * Data padding functions.
+ */
+void fb_pad_aligned_buffer(struct fb_info *info, u8 *dst, u32 d_pitch,
+ u8 *src, u32 s_pitch, u32 height)
+{
+ int i;
+
+ for (i = height; i--; ) {
+ memcpy(dst, src, s_pitch);
+ src += s_pitch;
+ dst += d_pitch;
+ }
+}
+EXPORT_SYMBOL(fb_pad_aligned_buffer);
+
+void fb_pad_unaligned_buffer(struct fb_info *info, u8 *dst, u32 d_pitch,
+ u8 *src, u32 idx, u32 height,
+ u32 shift_high, u32 shift_low, u32 mod)
+{
+ u8 mask = (u8) (0xfff << shift_high), tmp;
+ int i, j;
+
+ for (i = height; i--; ) {
+ for (j = 0; j < idx; j++) {
+ tmp = dst[j];
+ tmp &= mask;
+ tmp |= *src >> shift_low;
+ dst[j] = tmp;
+ tmp = *src << shift_high;
+ dst[j+1] = tmp;
+ src++;
+ }
+ tmp = dst[idx];
+ tmp &= mask;
+ tmp |= *src >> shift_low;
+ dst[idx] = tmp;
+ if (shift_high < mod) {
+ tmp = *src << shift_high;
+ dst[idx+1] = tmp;
+ }
+ src++;
+ dst += d_pitch;
+ }
+}
+EXPORT_SYMBOL(fb_pad_unaligned_buffer);
+
+/*
+ * we need to lock this section since fb_cursor
+ * may use fb_imageblit()
+ */
+char* fb_get_buffer_offset(struct fb_info *info, struct fb_pixmap *buf, u32 size)
+{
+ u32 align = buf->buf_align - 1, offset;
+ char *addr = buf->addr;
+
+ /* If IO mapped, we need to sync before access, no sharing of
+ * the pixmap is done
+ */
+ if (buf->flags & FB_PIXMAP_IO) {
+ if (info->fbops->fb_sync && (buf->flags & FB_PIXMAP_SYNC))
+ info->fbops->fb_sync(info);
+ return addr;
+ }
+
+ /* See if we fit in the remaining pixmap space */
+ offset = buf->offset + align;
+ offset &= ~align;
+ if (offset + size > buf->size) {
+ /* We do not fit. In order to be able to re-use the buffer,
+ * we must ensure no asynchronous DMA'ing or whatever operation
+ * is in progress, we sync for that.
+ */
+ if (info->fbops->fb_sync && (buf->flags & FB_PIXMAP_SYNC))
+ info->fbops->fb_sync(info);
+ offset = 0;
+ }
+ buf->offset = offset + size;
+ addr += offset;
+ return addr;
+}
+EXPORT_SYMBOL(fb_get_buffer_offset);
+
+struct graphics_resource {
+ struct fb_pixmap *resource;
+ struct list_head list;
+};
+
+struct fb_pixmap * fb_find_resource(const char *name, struct list_head *head)
+{
+ struct graphics_resource *rlist = NULL;
+ struct fb_pixmap *resource;
+ struct list_head *pos;
+
+ list_for_each(pos, head) {
+ rlist = list_entry(pos, struct graphics_resource, list);
+ resource = rlist->resource;
+ if (!strncmp(resource->name, name, strlen(name)))
+ return rlist->resource;
+ }
+ return NULL;
+}
+
+int fb_add_resource(struct fb_pixmap *res, struct list_head *head)
+{
+ struct fb_pixmap *resource = fb_find_resource(res->name, head);
+ struct graphics_resource *rlist = NULL;
+
+ if (resource)
+ return 1;
+ rlist = kmalloc(sizeof(struct graphics_resource), GFP_KERNEL);
+ if (!rlist)
+ return -ENOMEM;
+ rlist->resource = res;
+ list_add(&rlist->list, head);
+ return 0;
+}
+
+int fb_remove_resource(struct fb_pixmap *resource, struct list_head *head)
+{
+ struct graphics_resource *rlist;
+ struct list_head *pos, *n;
+
+ if (!resource)
+ return 0;
+
+ list_for_each_safe(pos, n, head) {
+ rlist = list_entry(pos, struct graphics_resource, list);
+ if (!strncmp(resource->name, rlist->resource->name, strlen(rlist->resource->name))) {
+ if (rlist->resource->addr && (rlist->resource->flags & FB_PIXMAP_DEFAULT))
+ kfree(rlist->resource->addr);
+ kfree(rlist->resource);
+ list_del(pos);
+ kfree(pos);
+ }
+ }
+ return 0;
+}
+
+int fb_init_resources(struct fb_info *info)
+{
+ int size = sizeof(struct fb_pixmap) + FBPIXMAPSIZE;
+ struct fb_pixmap *tmp;
+ char *p;
+
+ if (!info->resources.prev || !info->resources.next ||
+ list_empty(&info->resources))
+ INIT_LIST_HEAD(&info->resources);
+
+ // First we create our drawing pad
+ tmp = fb_find_resource("drawable", &info->resources);
+ if (!tmp) {
+ // Next we create our drawing pad.
+ p = kmalloc(sizeof(struct fb_pixmap), GFP_KERNEL);
+ if (!p)
+ return -ENOMEM;
+ memset(p, 0, sizeof(struct fb_pixmap));
+
+ info->pad = (struct fb_pixmap *) p;
+ strcpy(info->pad->name, "drawable");
+ info->pad->addr = info->screen_base;
+ if (info->screen_size)
+ info->pad->size = info->screen_size;
+ else
+ info->pad->size = info->fix.smem_len;
+ info->pad->buf_align = 1;
+ info->pad->scan_align = 1;
+ info->pad->access_align = 4;
+ info->pad->flags = FB_PIXMAP_IO;
+ info->pad->offset = 0;
+ info->pad->writeio = fb_writeio;
+ info->pad->readio = fb_readio;
+ fb_add_resource(info->pad, &info->resources);
+ }
+ // Now the cursor handling
+ tmp = fb_find_resource("cursor", &info->resources);
+ if (!tmp) {
+ p = kmalloc(size, GFP_KERNEL);
+ if (!p)
+ return -ENOMEM;
+ memset(p, 0, size);
+ info->sprite = (struct fb_pixmap *) p;
+ strcpy(info->sprite->name, "cursor");
+ info->sprite->addr = p + sizeof(struct fb_pixmap);
+ info->sprite->size = FBPIXMAPSIZE;
+ info->sprite->buf_align = info->pad->buf_align;
+ info->sprite->scan_align = info->pad->scan_align;
+ info->sprite->access_align = info->pad->access_align;
+ info->sprite->flags = FB_PIXMAP_SYSTEM;
+ info->sprite->offset = 0;
+ fb_add_resource(info->sprite, &info->resources);
+ }
+ return 0;
+}
+
+void fb_release_resources(struct list_head *head)
+{
+ struct graphics_resource *rlist;
+ struct list_head *pos, *n;
+
+ list_for_each_safe(pos, n, head) {
+ rlist = list_entry(pos, struct graphics_resource, list);
+ if (rlist->resource->addr && (rlist->resource->flags & FB_PIXMAP_DEFAULT))
+ kfree(rlist->resource->addr);
+ kfree(rlist->resource);
+ list_del(pos);
+ kfree(pos);
+ }
+}
+EXPORT_SYMBOL(fb_release_resources);
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/riva/fbdev.c fbdev-2.6/drivers/video/riva/fbdev.c
--- linus-2.6/drivers/video/riva/fbdev.c 2005-02-27 17:56:12.000000000 -0800
+++ fbdev-2.6/drivers/video/riva/fbdev.c 2005-02-24 08:36:43.000000000 -0800
@@ -1167,6 +1167,7 @@
static int rivafb_set_par(struct fb_info *info)
{
struct riva_par *par = (struct riva_par *) info->par;
+ struct fb_pixmap *pad = info->pad;
NVTRACE_ENTER();
/* vgaHWunlock() + riva unlock (0x7F) */
@@ -1182,9 +1183,9 @@
FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
if (info->flags & FBINFO_HWACCEL_DISABLED)
- info->pixmap.scan_align = 1;
+ pad->scan_align = 1;
else
- info->pixmap.scan_align = 4;
+ pad->scan_align = 4;
NVTRACE_LEAVE();
return 0;
}
@@ -1581,12 +1582,12 @@
static int rivafb_cursor(struct fb_info *info, struct fb_cursor *cursor)
{
struct riva_par *par = (struct riva_par *) info->par;
+ struct fb_pixmap *pad = info->pad;
u8 data[MAX_CURS * MAX_CURS/8];
- u16 fg, bg;
int i, set = cursor->set;
+ u16 fg, bg;
- if (cursor->image.width > MAX_CURS ||
- cursor->image.height > MAX_CURS)
+ if (cursor->image.width > MAX_CURS || cursor->image.height > MAX_CURS)
return soft_cursor(info, cursor);
par->riva.ShowHideCursor(&par->riva, 0);
@@ -1637,9 +1638,8 @@
break;
}
- fb_sysmove_buf_aligned(info, &info->pixmap, data,
- d_pitch, src, s_pitch,
- cursor->image.height);
+ fb_sysmove_buf_aligned(info, pad, data, d_pitch,
+ src, s_pitch, cursor->image.height);
bg = ((info->cmap.red[bg_idx] & 0xf8) << 7) |
((info->cmap.green[bg_idx] & 0xf8) << 2) |
@@ -1725,10 +1725,6 @@
cmap_len = riva_get_cmap_len(&info->var);
fb_alloc_cmap(&info->cmap, cmap_len, 0);
-
- info->pixmap.size = 8 * 1024;
- info->pixmap.buf_align = 4;
- info->pixmap.flags = FB_PIXMAP_SYSTEM;
info->var.yres_virtual = -1;
NVTRACE_LEAVE();
return (rivafb_check_var(&info->var, info));
@@ -1916,17 +1912,10 @@
default_par = (struct riva_par *) info->par;
default_par->pdev = pd;
- info->pixmap.addr = kmalloc(8 * 1024, GFP_KERNEL);
- if (info->pixmap.addr == NULL) {
- ret = -ENOMEM;
- goto err_framebuffer_release;
- }
- memset(info->pixmap.addr, 0, 8 * 1024);
-
ret = pci_enable_device(pd);
if (ret < 0) {
printk(KERN_ERR PFX "cannot enable PCI device\n");
- goto err_free_pixmap;
+ goto err_framebuffer_release;
}
ret = pci_request_regions(pd, "rivafb");
@@ -2062,6 +2051,15 @@
pci_set_drvdata(pd, info);
+ /*
+ * We have special needs for writing to the framebuffer.
+ * register_framebuffer already created this structure so
+ * we can the default values.
+ */
+ info->pad->buf_align = 4;
+ info->pad->scan_align = 4;
+ info->pad->access_align = 4;
+
printk(KERN_INFO PFX
"PCI nVidia %s framebuffer ver %s (%dMB @ 0x%lX)\n",
info->fix.id,
@@ -2090,8 +2088,6 @@
pci_release_regions(pd);
err_disable_device:
pci_disable_device(pd);
-err_free_pixmap:
- kfree(info->pixmap.addr);
err_framebuffer_release:
framebuffer_release(info);
err_ret:
@@ -2126,7 +2122,7 @@
iounmap(par->riva.PRAMIN);
pci_release_regions(pd);
pci_disable_device(pd);
- kfree(info->pixmap.addr);
+ fb_release_resources(&info->resources);
framebuffer_release(info);
pci_set_drvdata(pd, NULL);
NVTRACE_LEAVE();
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/savage/savagefb.c fbdev-2.6/drivers/video/savage/savagefb.c
--- linus-2.6/drivers/video/savage/savagefb.c 2005-02-27 17:56:12.000000000 -0800
+++ fbdev-2.6/drivers/video/savage/savagefb.c 2005-02-24 08:48:19.000000000 -0800
@@ -687,6 +687,18 @@
DBG("savagefb_check_var");
+#if defined(CONFIG_FB_SAVAGE_ACCEL)
+ /*
+ * The clipping coordinates are masked with 0xFFF, so limit our
+ * virtual resolutions to these sizes.
+ */
+ if (info->var.yres_virtual > 0x1000)
+ info->var.yres_virtual = 0x1000;
+
+ if (info->var.xres_virtual > 0x1000)
+ info->var.xres_virtual = 0x1000;
+#endif
+
var->transp.offset = 0;
var->transp.length = 0;
switch (var->bits_per_pixel) {
@@ -1779,7 +1791,7 @@
return videoRambytes;
}
-static int __devinit savage_init_fb_info (struct fb_info *info,
+static void __devinit savage_init_fb_info (struct fb_info *info,
struct pci_dev *dev,
const struct pci_device_id *id)
{
@@ -1883,27 +1895,7 @@
FBINFO_MISC_MODESWITCHLATE;
info->pseudo_palette = par->pseudo_palette;
-
-#if defined(CONFIG_FB_SAVAGE_ACCEL)
- /* FIFO size + padding for commands */
- info->pixmap.addr = kmalloc(8*1024, GFP_KERNEL);
-
- err = -ENOMEM;
- if (info->pixmap.addr) {
- memset(info->pixmap.addr, 0, 8*1024);
- info->pixmap.size = 8*1024;
- info->pixmap.scan_align = 4;
- info->pixmap.buf_align = 4;
- info->pixmap.access_align = 4;
-
- fb_alloc_cmap (&info->cmap, NR_PALETTE, 0);
- info->flags |= FBINFO_HWACCEL_COPYAREA |
- FBINFO_HWACCEL_FILLRECT |
- FBINFO_HWACCEL_IMAGEBLIT;
-
- err = 0;
- }
-#endif
+ fb_alloc_cmap (&info->cmap, NR_PALETTE, 0);
return err;
}
@@ -1936,8 +1928,7 @@
err = -ENOMEM;
- if (savage_init_fb_info(info, dev, id))
- goto failed_init;
+ savage_init_fb_info(info, dev, id);
err = savage_map_mmio(info);
if (err)
@@ -1996,17 +1987,6 @@
if (info->var.yres_virtual < info->var.yres)
goto failed;
-#if defined(CONFIG_FB_SAVAGE_ACCEL)
- /*
- * The clipping coordinates are masked with 0xFFF, so limit our
- * virtual resolutions to these sizes.
- */
- if (info->var.yres_virtual > 0x1000)
- info->var.yres_virtual = 0x1000;
-
- if (info->var.xres_virtual > 0x1000)
- info->var.xres_virtual = 0x1000;
-#endif
savagefb_check_var(&info->var, info);
savagefb_set_fix(info);
@@ -2037,6 +2017,16 @@
if (err < 0)
goto failed;
+#if defined(CONFIG_FB_SAVAGE_ACCEL)
+ /* FIFO size + padding for commands */
+ info->pad->scan_align = 4;
+ info->pad->buf_align = 4;
+ info->pad->access_align = 4;
+
+ info->flags |= FBINFO_HWACCEL_COPYAREA |
+ FBINFO_HWACCEL_FILLRECT |
+ FBINFO_HWACCEL_IMAGEBLIT;
+#endif
printk (KERN_INFO "fb: S3 %s frame buffer device\n",
info->fix.id);
@@ -2051,17 +2041,14 @@
#ifdef CONFIG_FB_SAVAGE_I2C
savagefb_delete_i2c_busses(info);
#endif
- fb_alloc_cmap (&info->cmap, 0, 0);
+ fb_dealloc_cmap(&info->cmap);
savage_unmap_video(info);
failed_video:
savage_unmap_mmio (info);
failed_mmio:
- kfree(info->pixmap.addr);
- failed_init:
pci_release_regions(dev);
failed_enable:
framebuffer_release(info);
-
return err;
}
@@ -2085,10 +2072,9 @@
#ifdef CONFIG_FB_SAVAGE_I2C
savagefb_delete_i2c_busses(info);
#endif
- fb_alloc_cmap (&info->cmap, 0, 0);
+ fb_dealloc_cmap(&info->cmap);
savage_unmap_video (info);
savage_unmap_mmio (info);
- kfree(info->pixmap.addr);
pci_release_regions(dev);
framebuffer_release(info);
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/softcursor.c fbdev-2.6/drivers/video/softcursor.c
--- linus-2.6/drivers/video/softcursor.c 2005-02-27 17:56:03.000000000 -0800
+++ fbdev-2.6/drivers/video/softcursor.c 2005-02-28 10:25:34.000000000 -0800
@@ -19,56 +19,45 @@
int soft_cursor(struct fb_info *info, struct fb_cursor *cursor)
{
- unsigned int scan_align = info->pixmap.scan_align - 1;
- unsigned int buf_align = info->pixmap.buf_align - 1;
+ struct fb_pixmap *sprite = info->sprite;
+ unsigned int scan_align = sprite->scan_align - 1;
+ unsigned int buf_align = sprite->buf_align - 1;
unsigned int i, size, dsize, s_pitch, d_pitch;
- struct fb_image *image;
+ struct fb_image image;
u8 *dst, *src;
if (info->state != FBINFO_STATE_RUNNING)
return 0;
s_pitch = (cursor->image.width + 7) >> 3;
- dsize = s_pitch * cursor->image.height;
+ size = s_pitch * cursor->image.height;
+ src = fb_get_buffer_offset(info, sprite, size);
- src = kmalloc(dsize + sizeof(struct fb_image), GFP_ATOMIC);
- if (!src)
- return -ENOMEM;
-
- image = (struct fb_image *) (src + dsize);
- *image = cursor->image;
d_pitch = (s_pitch + scan_align) & ~scan_align;
+ dsize = d_pitch * cursor->image.height + buf_align;
+ dsize &= ~buf_align;
+ dst = fb_get_buffer_offset(info, sprite, dsize);
- size = d_pitch * image->height + buf_align;
- size &= ~buf_align;
- dst = fb_get_buffer_offset(info, &info->pixmap, size);
+ memcpy(&image, &cursor->image, sizeof(struct fb_image));
if (cursor->enable) {
switch (cursor->rop) {
case ROP_XOR:
- for (i = 0; i < dsize; i++)
- src[i] = image->data[i] ^ cursor->mask[i];
+ for (i = 0; i < size; i++)
+ src[i] = cursor->image.data[i] ^ cursor->mask[i];
break;
case ROP_COPY:
default:
- for (i = 0; i < dsize; i++)
- src[i] = image->data[i] & cursor->mask[i];
+ for (i = 0; i < size; i++)
+ src[i] = cursor->image.data[i] & cursor->mask[i];
break;
}
} else
- memcpy(src, image->data, dsize);
-
- if (info->pixmap.outbuf)
- fb_iomove_buf_aligned(info, &info->pixmap, dst, d_pitch, src,
- s_pitch, image->height);
- else
- fb_sysmove_buf_aligned(info, &info->pixmap, dst, d_pitch, src,
- s_pitch, image->height);
-
- image->data = dst;
- info->fbops->fb_imageblit(info, image);
- kfree(src);
+ memcpy(src, cursor->image.data, size);
+ fb_pad_aligned_buffer(info, dst, d_pitch, src, s_pitch, image.height);
+ image.data = dst;
+ info->fbops->fb_imageblit(info, &image);
return 0;
}
diff -urN -X /home/jsimmons/dontdiff linus-2.6/include/linux/fb.h fbdev-2.6/include/linux/fb.h
--- linus-2.6/include/linux/fb.h 2005-02-27 17:57:54.000000000 -0800
+++ fbdev-2.6/include/linux/fb.h 2005-02-28 11:04:37.000000000 -0800
@@ -514,6 +514,7 @@
#define FB_PIXMAP_SYNC 256 /* set if GPU can DMA */
struct fb_pixmap {
+ char name[16]; /* Name of the resource */
u8 *addr; /* pointer to memory */
u32 size; /* size of buffer in bytes */
u32 offset; /* current offset to buffer */
@@ -522,8 +523,8 @@
u32 access_align; /* alignment per read/write */
u32 flags; /* see FB_PIXMAP_* */
/* access methods */
- void (*outbuf)(struct fb_info *info, u8 *addr, u8 *src, unsigned int size);
- u8 (*inbuf) (struct fb_info *info, u8 *addr);
+ void (*writeio)(struct fb_info *info, void __iomem *addr, void *src, unsigned int size);
+ void (*readio) (struct fb_info *info, void *dst, void __iomem *addr, unsigned int size);
};
@@ -707,11 +708,12 @@
struct fb_var_screeninfo var; /* Current var */
struct fb_fix_screeninfo fix; /* Current fix */
struct fb_monspecs monspecs; /* Current Monitor specs */
+ struct list_head resources; /* Graphics resources */
+ struct list_head modelist; /* mode list */
struct work_struct queue; /* Framebuffer event queue */
- struct fb_pixmap pixmap; /* Image hardware mapper */
- struct fb_pixmap sprite; /* Cursor hardware mapper */
+ struct fb_pixmap *sprite; /* Cursor hardware mapper */
+ struct fb_pixmap *pad; /* Image hardware mapper */
struct fb_cmap cmap; /* Current cmap */
- struct list_head modelist; /* mode list */
struct fb_ops *fbops;
struct device *device;
#ifdef CONFIG_FB_TILEBLITTING
@@ -807,19 +809,6 @@
extern int unregister_framebuffer(struct fb_info *fb_info);
extern int fb_prepare_logo(struct fb_info *fb_info);
extern int fb_show_logo(struct fb_info *fb_info);
-extern char* fb_get_buffer_offset(struct fb_info *info, struct fb_pixmap *buf, u32 size);
-extern void fb_iomove_buf_unaligned(struct fb_info *info, struct fb_pixmap *buf,
- u8 *dst, u32 d_pitch, u8 *src, u32 idx,
- u32 height, u32 shift_high, u32 shift_low, u32 mod);
-extern void fb_iomove_buf_aligned(struct fb_info *info, struct fb_pixmap *buf,
- u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch,
- u32 height);
-extern void fb_sysmove_buf_unaligned(struct fb_info *info, struct fb_pixmap *buf,
- u8 *dst, u32 d_pitch, u8 *src, u32 idx,
- u32 height, u32 shift_high, u32 shift_low, u32 mod);
-extern void fb_sysmove_buf_aligned(struct fb_info *info, struct fb_pixmap *buf,
- u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch,
- u32 height);
extern void fb_set_suspend(struct fb_info *info, int state);
extern int fb_get_color_depth(struct fb_info *info);
extern int fb_get_options(char *name, char **option);
@@ -827,6 +816,19 @@
extern struct fb_info *registered_fb[FB_MAX];
extern int num_registered_fb;
+/* drivers/video/resmgt.c */
+extern char* fb_get_buffer_offset(struct fb_info *info, struct fb_pixmap *buf, u32 size);
+extern void fb_pad_unaligned_buffer(struct fb_info *info, u8 *dst, u32 d_pitch,
+ u8 *src, u32 idx, u32 height, u32 shift_high,
+ u32 shift_low, u32 mod);
+extern void fb_pad_aligned_buffer(struct fb_info *info, u8 *dst, u32 d_pitch,
+ u8 *src, u32 s_pitch, u32 height);
+void fb_release_resources(struct list_head *head);
+int fb_remove_resource(struct fb_pixmap *resource, struct list_head *head);
+int fb_add_resource(struct fb_pixmap *resource, struct list_head *head);
+struct fb_pixmap* fb_find_resource(const char *name, struct list_head *head);
+int fb_init_resources(struct fb_info *info);
+
/* drivers/video/fbsysfs.c */
extern struct fb_info *framebuffer_alloc(size_t size, struct device *dev);
extern void framebuffer_release(struct fb_info *info);
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2005-02-28 20:01 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-02-21 19:11 Resource management James Simmons
2005-02-21 22:53 ` Antonino A. Daplas
2005-02-21 23:25 ` James Simmons
2005-02-22 1:01 ` Jon Smirl
2005-02-22 3:53 ` James Simmons
2005-02-22 4:46 ` [Linux-fbdev-devel] " Dave Airlie
2005-02-22 5:13 ` James Simmons
2005-02-22 5:59 ` [Linux-fbdev-devel] " Jon Smirl
2005-02-22 5:23 ` Jon Smirl
2005-02-22 17:23 ` James Simmons
2005-02-22 18:59 ` [Linux-fbdev-devel] " Alex Deucher
2005-02-22 13:25 ` Antonino A. Daplas
2005-02-22 14:06 ` Antonino A. Daplas
2005-02-24 19:57 ` James Simmons
2005-02-24 23:05 ` Antonino A. Daplas
2005-02-28 20:01 ` Resource management II 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).