2004-11-28 18:46:29

by jurriaan

[permalink] [raw]
Subject: why does radeonfb work fine in 2.6, but not in 2.4.29-pre1?

The same radeonfb-setup works fine in every 2.6 kernel I can remember
(last tested with 2.6.10-rc2-mm3) but give the dreaded 'cannot map FB'
in 2.4.29-pre1.

The card has 128 Mb of ram, and my system has 3 Mb of RAM.

Is there any reason the ioremap() call works on 2.6, but doesn't on 2.4?

I've tried searching google for hints, but nothing has turned up.

Is there any way to test 2.4 with my radeonfb and all of my memory?

Thanks,
Jurriaan
--
proof by exhaustion:
An issue or two of a journal devoted to your proof is useful.
Debian (Unstable) GNU/Linux 2.6.10-rc2-mm3 2x6078 bogomips load 1.67


2004-11-29 20:28:02

by jurriaan

[permalink] [raw]
Subject: Re: [Linux-fbdev-devel] why does radeonfb work fine in 2.6, but not in 2.4.29-pre1?

From: Jurriaan <[email protected]>
Date: Sun, Nov 28, 2004 at 07:46:06PM +0100
> The same radeonfb-setup works fine in every 2.6 kernel I can remember
> (last tested with 2.6.10-rc2-mm3) but give the dreaded 'cannot map FB'
> in 2.4.29-pre1.
>
> The card has 128 Mb of ram, and my system has 3 Mb of RAM.

I mean 3 Gb, of course. Sorry about that. This means I got high memory.

I'd love to know what difference 2.4 and 2.6 have in this regard.

Jurriaan
--
The memory management on the PowerPC can be used to frighten small children.
Linus Torvalds
Debian (Unstable) GNU/Linux 2.6.10-rc2-mm3 2x6078 bogomips load load 0.31

2004-11-29 21:36:38

by Luca Tettamanti

[permalink] [raw]
Subject: Re: [Linux-fbdev-devel] why does radeonfb work fine in 2.6, but not in 2.4.29-pre1?

Il Sun, Nov 28, 2004 at 07:46:06PM +0100, Jurriaan ha scritto:
> The same radeonfb-setup works fine in every 2.6 kernel I can remember
> (last tested with 2.6.10-rc2-mm3) but give the dreaded 'cannot map FB'
> in 2.4.29-pre1.
>
> The card has 128 Mb of ram, and my system has 3 Mb of RAM.
>
> Is there any reason the ioremap() call works on 2.6, but doesn't on 2.4?

Driver in 2.6 only ioremap()s the memory needed for the framebuffer,
while the one in 2.4 ioremap()s all the VRAM (and fails).

> Is there any way to test 2.4 with my radeonfb and all of my memory?

I proposed the following patch some time ago (for 2.4.28-pre2 IIRC) as a
quick fix:

--- a/drivers/video/radeonfb.c 2004-06-27 22:26:56.000000000 +0200
+++ b/drivers/video/radeonfb.c 2004-06-29 19:13:24.000000000 +0200
@@ -176,7 +176,8 @@
#define RTRACE if(0) printk
#endif

-
+#define MAX_MAPPED_VRAM (2048*2048*4)
+#define MIN_MAPPED_VRAM (1024*768*1)

enum radeon_chips {
RADEON_QD,
@@ -499,7 +500,8 @@

short chipset;
unsigned char arch;
- int video_ram;
+ unsigned int video_ram;
+ unsigned int mapped_vram;
u8 rev;
int pitch, bpp, depth;
int xres, yres, pixclock;
@@ -1823,8 +1825,19 @@
}
}

- rinfo->fb_base = (unsigned long) ioremap (rinfo->fb_base_phys,
- rinfo->video_ram);
+ if (rinfo->video_ram < rinfo->mapped_vram)
+ rinfo->mapped_vram = rinfo->video_ram;
+ else
+ rinfo->mapped_vram = MAX_MAPPED_VRAM;
+ do {
+ rinfo->fb_base = (unsigned long) ioremap (rinfo->fb_base_phys,
+ rinfo->mapped_vram);
+ if (rinfo->fb_base)
+ break;
+
+ rinfo->mapped_vram /= 2;
+ } while(rinfo->mapped_vram > MIN_MAPPED_VRAM);
+
if (!rinfo->fb_base) {
printk ("radeonfb: cannot map FB\n");
iounmap ((void*)rinfo->mmio_base);
@@ -1835,6 +1848,7 @@
kfree (rinfo);
return -ENODEV;
}
+ RTRACE(KERN_INFO "radeonfb: mapped %dk videoram\n", rinfo->mapped_vram/1024);

/* currcon not yet configured, will be set by first switch */
rinfo->currcon = -1;
@@ -2204,7 +2218,7 @@
printk("radeonfb: using max available virtual resolution\n");
for (i=0; modes[i].xres != -1; i++) {
if (modes[i].xres * nom / den * modes[i].yres <
- rinfo->video_ram / 2)
+ rinfo->mapped_vram / 2)
break;
}
if (modes[i].xres == -1) {
@@ -2217,15 +2231,15 @@
printk("radeonfb: virtual resolution set to max of %dx%d\n",
v->xres_virtual, v->yres_virtual);
} else if (v->xres_virtual == -1) {
- v->xres_virtual = (rinfo->video_ram * den /
+ v->xres_virtual = (rinfo->mapped_vram * den /
(nom * v->yres_virtual * 2)) & ~15;
} else if (v->yres_virtual == -1) {
v->xres_virtual = (v->xres_virtual + 15) & ~15;
- v->yres_virtual = rinfo->video_ram * den /
+ v->yres_virtual = rinfo->mapped_vram * den /
(nom * v->xres_virtual *2);
} else {
if (v->xres_virtual * nom / den * v->yres_virtual >
- rinfo->video_ram) {
+ rinfo->mapped_vram) {
return -EINVAL;
}
}
@@ -2261,7 +2275,7 @@
sprintf (fix->id, "ATI Radeon %s", rinfo->name);

fix->smem_start = rinfo->fb_base_phys;
- fix->smem_len = rinfo->video_ram;
+ fix->smem_len = rinfo->mapped_vram;

fix->type = disp->type;
fix->type_aux = disp->type_aux;
@@ -2429,6 +2443,9 @@
return -EINVAL;
}

+ if (((v.xres_virtual * v.yres_virtual * nom) / den) > rinfo->mapped_vram)
+ return -EINVAL;
+
if (radeonfb_do_maximize(rinfo, var, &v, nom, den) < 0)
return -EINVAL;


Problem is that fix->smem_len is used both by FBIOGET_FSCREENINFO to
report the amount of VRAM to userspace and by read/write/mmap on fb
for bounds checking. So with my patch FBIOGET_FSCREENINFO reports mapped
VRAM instead of physical VRAM.

smem_len should be splitted in (say) smem_mapped (for read/write/mmap)
and smem_total_vram (for FBIOGET_FSCREENINFO). I'll code something
tomorrow... -ENEEDSLEEP ;)

Luca
--
Home: http://kronoz.cjb.net
E' stato a causa di una donna che ho cominciato a bere e non ho mai
avuto la cortesia di ringraziarla.

2004-11-30 06:56:01

by jurriaan

[permalink] [raw]
Subject: Re: [Linux-fbdev-devel] why does radeonfb work fine in 2.6, but not in 2.4.29-pre1?

From: Kronos <[email protected]>
Date: Mon, Nov 29, 2004 at 10:35:10PM +0100
> Il Sun, Nov 28, 2004 at 07:46:06PM +0100, Jurriaan ha scritto:
> > The same radeonfb-setup works fine in every 2.6 kernel I can remember
> > (last tested with 2.6.10-rc2-mm3) but give the dreaded 'cannot map FB'
> > in 2.4.29-pre1.
> >
> > The card has 128 Mb of ram, and my system has 3 Mb of RAM.
> >
> > Is there any reason the ioremap() call works on 2.6, but doesn't on 2.4?
>
> Driver in 2.6 only ioremap()s the memory needed for the framebuffer,
> while the one in 2.4 ioremap()s all the VRAM (and fails).
>
> > Is there any way to test 2.4 with my radeonfb and all of my memory?
>
> I proposed the following patch some time ago (for 2.4.28-pre2 IIRC) as a
> quick fix:
>
Thanks. I found that patch on google. Problem is: when I look through
the radeonfb in 2.6, I don't see any assignments to rinfo->video_ram
that indicate it maps less than the full amount.

>
> Problem is that fix->smem_len is used both by FBIOGET_FSCREENINFO to
> report the amount of VRAM to userspace and by read/write/mmap on fb
> for bounds checking. So with my patch FBIOGET_FSCREENINFO reports mapped
> VRAM instead of physical VRAM.
>
> smem_len should be splitted in (say) smem_mapped (for read/write/mmap)
> and smem_total_vram (for FBIOGET_FSCREENINFO). I'll code something
> tomorrow... -ENEEDSLEEP ;)
>
Thanks,
Jurriaan
--
All wiyht. Rho sritched mg kegtops awound?
Debian (Unstable) GNU/Linux 2.6.10-rc2-mm3 2x6078 bogomips load load 0.24

2004-11-30 18:02:01

by Luca Tettamanti

[permalink] [raw]
Subject: Re: [Linux-fbdev-devel] why does radeonfb work fine in 2.6, but not in 2.4.29-pre1?

Il Tue, Nov 30, 2004 at 07:55:55AM +0100, Jurriaan ha scritto:
> From: Kronos <[email protected]>
> Date: Mon, Nov 29, 2004 at 10:35:10PM +0100
> > Il Sun, Nov 28, 2004 at 07:46:06PM +0100, Jurriaan ha scritto:
> > > The same radeonfb-setup works fine in every 2.6 kernel I can remember
> > > (last tested with 2.6.10-rc2-mm3) but give the dreaded 'cannot map FB'
> > > in 2.4.29-pre1.
> > >
> > > The card has 128 Mb of ram, and my system has 3 Mb of RAM.
> > >
> > > Is there any reason the ioremap() call works on 2.6, but doesn't on 2.4?
> >
> > Driver in 2.6 only ioremap()s the memory needed for the framebuffer,
> > while the one in 2.4 ioremap()s all the VRAM (and fails).
> >
> > > Is there any way to test 2.4 with my radeonfb and all of my memory?
> >
> > I proposed the following patch some time ago (for 2.4.28-pre2 IIRC) as a
> > quick fix:
> >
> Thanks. I found that patch on google. Problem is: when I look through
> the radeonfb in 2.6, I don't see any assignments to rinfo->video_ram
> that indicate it maps less than the full amount.

rinfo->video_ram is the physical ram. Look at drivers/video/aty/radeon_base.c:2200

rinfo->mapped_vram = min_t(unsigned long, MAX_MAPPED_VRAM, rinfo->video_ram);

and the following loop tries to shrink the mapped area in case of
ioremap() failure.

Can you test the following patch (against 2.2.29-pre1)? If everything is
ok I'll push to Marcelo.

--- a/include/linux/fb.h 2004-11-30 18:30:08.000000000 +0100
+++ b/include/linux/fb.h 2004-11-30 18:33:00.000000000 +0100
@@ -126,7 +126,8 @@
/* (physical address) */
__u32 mmio_len; /* Length of Memory Mapped I/O */
__u32 accel; /* Type of acceleration available */
- __u16 reserved[3]; /* Reserved for future compatibility */
+ __u32 mapped_vram; /* Amount of ioremap()'ed VRAM */
+ __u16 reserved[1]; /* Reserved for future compatibility */
};

/* Interpretation of offset for color fields: All offsets are from the right,
--- a/drivers/video/fbmem.c 2004-11-30 18:30:00.000000000 +0100
+++ b/drivers/video/fbmem.c 2004-11-30 18:43:06.000000000 +0100
@@ -410,6 +410,7 @@
struct fb_info *info = registered_fb[fbidx];
struct fb_ops *fb = info->fbops;
struct fb_fix_screeninfo fix;
+ unsigned int size;

if (! fb || ! info->disp)
return -ENODEV;
@@ -418,10 +419,12 @@
return -EINVAL;

fb->fb_get_fix(&fix,PROC_CONSOLE(info), info);
- if (p >= fix.smem_len)
+ size = fix.mapped_vram ? fix.mapped_vram : fix.smem_len;
+
+ if (p >= size)
return 0;
- if (count > fix.smem_len - p)
- count = fix.smem_len - p;
+ if (count > size - p)
+ count = size - p;
if (count) {
char *base_addr;

@@ -444,6 +447,7 @@
struct fb_ops *fb = info->fbops;
struct fb_fix_screeninfo fix;
int err;
+ unsigned int size;

if (! fb || ! info->disp)
return -ENODEV;
@@ -452,11 +456,13 @@
return -EINVAL;

fb->fb_get_fix(&fix, PROC_CONSOLE(info), info);
- if (p > fix.smem_len)
+ size = fix.mapped_vram ? fix.mapped_vram : fix.smem_len;
+
+ if (p > size)
return -ENOSPC;
err = 0;
- if (count > fix.smem_len - p) {
- count = fix.smem_len - p;
+ if (count > size - p) {
+ count = size - p;
err = -ENOSPC;
}
if (count) {
@@ -619,7 +625,10 @@

/* frame buffer memory */
start = fix.smem_start;
- len = PAGE_ALIGN((start & ~PAGE_MASK)+fix.smem_len);
+ if (fix.mapped_vram)
+ len = PAGE_ALIGN((start & ~PAGE_MASK) + fix.mapped_vram);
+ else
+ len = PAGE_ALIGN((start & ~PAGE_MASK) + fix.smem_len);
if (off >= len) {
/* memory mapped io */
off -= len;
--- a/drivers/video/radeonfb.c 2004-11-30 18:06:45.000000000 +0100
+++ b/drivers/video/radeonfb.c 2004-11-30 18:50:25.000000000 +0100
@@ -176,7 +176,8 @@
#define RTRACE if(0) printk
#endif

-
+#define MAX_MAPPED_VRAM (2048*2048*4)
+#define MIN_MAPPED_VRAM (1024*768*1)

enum radeon_chips {
RADEON_QD,
@@ -499,7 +500,8 @@

short chipset;
unsigned char arch;
- int video_ram;
+ unsigned int video_ram;
+ unsigned int mapped_vram;
u8 rev;
int pitch, bpp, depth;
int xres, yres, pixclock;
@@ -1824,8 +1826,16 @@
}
}

- rinfo->fb_base = (unsigned long) ioremap (rinfo->fb_base_phys,
- rinfo->video_ram);
+ rinfo->mapped_vram = min_t(unsigned int, MAX_MAPPED_VRAM, rinfo->video_ram);
+ do {
+ rinfo->fb_base = (unsigned long) ioremap (rinfo->fb_base_phys,
+ rinfo->mapped_vram);
+ if (rinfo->fb_base)
+ break;
+
+ rinfo->mapped_vram /= 2;
+ } while(rinfo->mapped_vram > MIN_MAPPED_VRAM);
+
if (!rinfo->fb_base) {
printk ("radeonfb: cannot map FB\n");
iounmap ((void*)rinfo->mmio_base);
@@ -1836,6 +1846,7 @@
kfree (rinfo);
return -ENODEV;
}
+ RTRACE(KERN_INFO "radeonfb: mapped %dk videoram\n", rinfo->mapped_vram/1024);

/* currcon not yet configured, will be set by first switch */
rinfo->currcon = -1;
@@ -2205,7 +2216,7 @@
printk("radeonfb: using max available virtual resolution\n");
for (i=0; modes[i].xres != -1; i++) {
if (modes[i].xres * nom / den * modes[i].yres <
- rinfo->video_ram / 2)
+ rinfo->mapped_vram / 2)
break;
}
if (modes[i].xres == -1) {
@@ -2218,15 +2229,15 @@
printk("radeonfb: virtual resolution set to max of %dx%d\n",
v->xres_virtual, v->yres_virtual);
} else if (v->xres_virtual == -1) {
- v->xres_virtual = (rinfo->video_ram * den /
+ v->xres_virtual = (rinfo->mapped_vram * den /
(nom * v->yres_virtual * 2)) & ~15;
} else if (v->yres_virtual == -1) {
v->xres_virtual = (v->xres_virtual + 15) & ~15;
- v->yres_virtual = rinfo->video_ram * den /
+ v->yres_virtual = rinfo->mapped_vram * den /
(nom * v->xres_virtual *2);
} else {
if (v->xres_virtual * nom / den * v->yres_virtual >
- rinfo->video_ram) {
+ rinfo->mapped_vram) {
return -EINVAL;
}
}
@@ -2263,6 +2274,7 @@

fix->smem_start = rinfo->fb_base_phys;
fix->smem_len = rinfo->video_ram;
+ fix->mapped_vram = rinfo->mapped_vram;

fix->type = disp->type;
fix->type_aux = disp->type_aux;
@@ -2430,6 +2442,9 @@
return -EINVAL;
}

+ if (((v.xres_virtual * v.yres_virtual * nom) / den) > rinfo->mapped_vram)
+ return -EINVAL;
+
if (radeonfb_do_maximize(rinfo, var, &v, nom, den) < 0)
return -EINVAL;



Luca
--
Home: http://kronoz.cjb.net
Non sempre quello che viene dopo e` progresso.
Alessandro Manzoni