[patch] VRAM detection in controlfb
Geert Uytterhoeven
Geert.Uytterhoeven at sonycom.com
Thu Jun 8 01:10:39 EST 2000
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 at 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/
More information about the Linuxppc-dev
mailing list