Re: [patch] VRAM detection in controlfb
From: Geert Uytterhoeven <hidden>
Date: 2000-06-07 15:10:39
On Wed, 7 Jun 2000, Ryuichi Oikawa wrote:
Geert did explain the problem. It is due to incorrect offset estimation.
Let me explain your case in detail. The authur of fbdev module seems to
assume frame buffer size as a multiple of page size:
fbdevhw.c
void* fbdevHWMapVidmem(ScrnInfoPtr pScrn)
{
fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
TRACE_ENTER("MapVidmem");
if (NULL == fPtr->fbmem) {
fPtr->fboff = fPtr->fix.smem_len & (PAGE_SIZE-1);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
fPtr->fbmem = mmap(NULL, fPtr->fix.smem_len, PROT_READ | PROT_WRITE,
MAP_SHARED, fPtr->fd, 0);
but the fact is different from his assumption. As you know very well,
controlfb adjusts fb memory size by subtracting display offset(in your
case 80 = 0x50 bytes) so that
fboff = (4M - 0x50) & 0xfff = 0xfb0
fbmem = smem_start & 0xfffff000 = smem_start - 0x50.
Thus your Xserver's video memory starts at offset
(fbmem + fboff) - smem_start = 0xfb0 - 0x50 = 0xf60 = 3936 bytes.
Now you understand the fix is very simple:
- fPtr->fboff = fPtr->fix.smem_len & (PAGE_SIZE-1);
+ fPtr->fboff = fPtr->fix.smem_start & (PAGE_SIZE-1);That's not sufficient (perhaps it is in this case, though): both fix.smem_start and fix.smem_len may be not page aligned. To catch all cases, you have to use the formula from my previous posting.
But looking through the XF4 fbdev support code I saw two more mistakes causing potential problem. One is a confusion of virtual screen width with screen pitch: fbdev.c pScrn->displayWidth = pScrn->virtualX; /* FIXME: might be wrong */ Yes, this is wrong as the authur noted, but interestingly this code spreads over the all drivers supporting fbdev, though I can't distinguish which is the original :^) Maybe polite solution is to fix each driver, but quick fix will be + pScrn->displayWidth = fPtr->fix.line_width / + (fPtr->var.bits_per_pixel >> 3)
Typo: the field is called `line_length', not `line_width'.
And that formula is valid for chunky displays only, not for interleaved
bitplanes (I suppose pScrn->displayWidth is the width of one line in memory,
counted in pixel units?).
If line_length is 0, you must fallback to xres_virtual / bytes_per_pixel.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven ------------- Sony Software Development Center Europe (SDCE)
Geert.Uytterhoeven@sonycom.com ------------------- Sint-Stevens-Woluwestraat 55
Voice +32-2-7248638 Fax +32-2-7262686 ---------------- B-1130 Brussels, Belgium
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/