xf 4.0.1 + ati driver with rage II/rage pro

Geert Uytterhoeven geert at linux-m68k.org
Thu Sep 28 22:18:19 EST 2000


On Wed, 27 Sep 2000, Michael Schmitz wrote:
> So here we have three fb devices in the kernel (you could check with
> fbset that each is in fact accessible via /dev/fb[0-2]), and XFree unable
> to cope. You specify the PCI bus ID but not the corresponding framebuffer
> device node - I heard someone mention this was possible when I was
> fighting the Lombard crashes, could anyone point out the syntax to use
> there?
>
> If we can't specify the fb node XFree will have to probe for it (Geert
> mentioned an easy way to do that: open the device and compare
> pScrn->memPhysBase or fPtr->fix.smem_start to the PCI base address).

Besides, the current fbdev_open_pci() can't cope with multiple cards of the
same type, and doesn't recognize ATI Mach64.

> BTW Geert: why is fPtr->fboff calculated from fix.smem_len not
> fix.smem_start while pScrn->fbOffset is calculated from fix.smem_start?

That's indeed incorrect. But it's not the only bug in that part of the code
:-)

Hmmm... I just noticed I kept that bug in my version...

For reference, these are my (untested) patches...
Michel, I'll send you a diff relative to my previous version.

diff -urN michel/fbdevhw.c geert-3/fbdevhw.c
--- michel/fbdevhw.c	Mon Aug 28 16:36:59 2000
+++ geert-3/fbdevhw.c	Thu Sep 28 13:15:54 2000
@@ -86,8 +86,10 @@
 	char*				device;
 	int				fd;
 	void*				fbmem;
-	int				fboff;
+	unsigned int			fbmem_len;
+	unsigned int			fboff;
 	void*				mmio;
+	unsigned int			mmio_len;

 	/* current hardware state */
 	struct fb_fix_screeninfo	fix;
@@ -95,6 +97,8 @@

 	/* saved video mode */
 	struct fb_var_screeninfo	saved_var;
+
+	/* FIXME: unused??? [geert] */
 	struct fb_cmap			saved_cmap;
 	unsigned short			*saved_red;
 	unsigned short			*saved_green;
@@ -194,7 +198,7 @@
 		var->sync |= FB_SYNC_VERT_HIGH_ACT;
 	if (mode->Flags & V_PCSYNC)
 		var->sync |= FB_SYNC_COMP_HIGH_ACT;
-#if 0
+#if 1 /* Badly needed for PAL/NTSC on Amiga (amifb)!! [geert] */
 	if (mode->Flags & V_BCAST)
 		var->sync |= FB_SYNC_BROADCAST;
 #endif
@@ -222,7 +226,7 @@
 	mode->Flags |= var->sync & FB_SYNC_HOR_HIGH_ACT ? V_PHSYNC : V_NHSYNC;
 	mode->Flags |= var->sync & FB_SYNC_VERT_HIGH_ACT ? V_PVSYNC : V_NVSYNC;
 	mode->Flags |= var->sync & FB_SYNC_COMP_HIGH_ACT ? V_PCSYNC : V_NCSYNC;
-#if 0
+#if 1 /* Badly needed for PAL/NTSC on Amiga (amifb)!! [geert] */
 	if (var->sync & FB_SYNC_BROADCAST)
 		mode->Flags |= V_BCAST;
 #endif
@@ -247,28 +251,6 @@
 /* -------------------------------------------------------------------- */
 /* open correct framebuffer device                                      */

-static struct fb2pci_entry {
-	CARD32 id;
-	CARD32 vendor;
-	CARD32 chip;
-} fb2pci_map[] = {
-	{ FB_ACCEL_MATROX_MGA2064W,     PCI_VENDOR_MATROX, PCI_CHIP_MGA2064      },
-	{ FB_ACCEL_MATROX_MGA1064SG,    PCI_VENDOR_MATROX, PCI_CHIP_MGA1064      },
-	{ FB_ACCEL_MATROX_MGA2164W,     PCI_VENDOR_MATROX, PCI_CHIP_MGA2164      },
-	{ FB_ACCEL_MATROX_MGA2164W_AGP, PCI_VENDOR_MATROX, PCI_CHIP_MGA2164_AGP  },
-	{ FB_ACCEL_MATROX_MGAG100,      PCI_VENDOR_MATROX, PCI_CHIP_MGAG100      },
-	{ FB_ACCEL_MATROX_MGAG200,      PCI_VENDOR_MATROX, PCI_CHIP_MGAG200      },
-	{ FB_ACCEL_ATI_RAGE128,         PCI_VENDOR_ATI,    PCI_CHIP_RAGE128RE    },
-	{ FB_ACCEL_ATI_RAGE128,         PCI_VENDOR_ATI,    PCI_CHIP_RAGE128RF    },
-	{ FB_ACCEL_ATI_RAGE128,         PCI_VENDOR_ATI,    PCI_CHIP_RAGE128RK    },
-	{ FB_ACCEL_ATI_RAGE128,         PCI_VENDOR_ATI,    PCI_CHIP_RAGE128RL    },
-	{ FB_ACCEL_ATI_RAGE128,         PCI_VENDOR_ATI,    PCI_CHIP_RAGE128PF    },
-	{ FB_ACCEL_ATI_RAGE128,         PCI_VENDOR_ATI,    PCI_CHIP_RAGE128LE    },
-	{ FB_ACCEL_ATI_RAGE128,         PCI_VENDOR_ATI,    PCI_CHIP_RAGE128LF    },
-	{ FB_ACCEL_3DFX_BANSHEE,        PCI_VENDOR_3DFX,   PCI_CHIP_VOODOO3      },
-};
-#define FB2PCICOUNT (sizeof(fb2pci_map)/sizeof(struct fb2pci_entry))
-
 /* try to find the framebuffer device for a given PCI device */
 static int
 fbdev_open_pci(pciVideoPtr pPci, char **namep)
@@ -276,8 +258,9 @@
 	struct	fb_fix_screeninfo fix;
 	char	filename[16];
 	int	fd,i,j;
+	memType res_start, res_end;

-	for (i = 0; i < 4; i++) {
+	for (i = 0; i < 8; i++) {
 		sprintf(filename,"/dev/fb%d",i);
 		if (-1 == (fd = open(filename,O_RDWR,0))) {
 			continue;
@@ -286,15 +269,20 @@
 			close(fd);
 			continue;
 		}
-		/* FIXME: better ask the fbdev driver for bus/device/func,
-                          but there is no way to to this yet. */
-		for (j = 0; j < FB2PCICOUNT; j++) {
-			if (pPci->vendor   == fb2pci_map[j].vendor &&
-			    pPci->chipType == fb2pci_map[j].chip   &&
-			    fix.accel      == fb2pci_map[j].id)
+		for (j = 0; j < 6; j++) {
+			if ((pPci->type[i] & ResPhysMask) != ResMem)
+				continue;
+			res_start = pPci->memBase[j];
+			res_end = res_start+pPci->size[j];
+			if ((0 != fix.smem_len &&
+			     fix.smem_start >= res_start &&
+			     fix.smem_start < res_end) ||
+			    (0 != fix.mmio_len &&
+			     fix.mmio_start >= res_start &&
+			     fix.mmio_start < res_end))
 				break;
 		}
-		if (j == FB2PCICOUNT) {
+		if (j == 6) {
 			close(fd);
 			continue;
 		}
@@ -541,12 +529,19 @@

 	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,
+		fPtr->fboff = fPtr->fix.smem_start & ~PAGE_MASK;
+		fPtr->fbmem_len = (fPtr->fboff+fPtr->fix.smem_len+~PAGE_MASK) &
+				  PAGE_MASK;
+		fPtr->fbmem = mmap(NULL, fPtr->fbmem_len, PROT_READ | PROT_WRITE,
 				   MAP_SHARED, fPtr->fd, 0);
 		if (-1 == (int)fPtr->fbmem) {
 			perror("mmap fbmem");
 			fPtr->fbmem = NULL;
+		} else {
+		    /* Perhaps we'd better add fboff to fbmem and return 0 in
+		       fbdevHWLinearOffset()? Of course we then need to mask
+		       fPtr->fbmem with PAGE_MASK in fbdevHWUnmapVidmem() as
+		       well. [geert] */
 		}
 	}
 	pScrn->memPhysBase = (unsigned long)fPtr->fix.smem_start & (unsigned long)(PAGE_MASK);
@@ -570,7 +565,7 @@

 	TRACE_ENTER("UnmapVidmem");
 	if (NULL != fPtr->fbmem) {
-		if (-1 == munmap(fPtr->fbmem, fPtr->fix.smem_len))
+		if (-1 == munmap(fPtr->fbmem, fPtr->fbmem_len))
 			perror("munmap fbmem");
 		fPtr->fbmem = NULL;
 	}
@@ -580,6 +575,8 @@
 void*
 fbdevHWMapMMIO(ScrnInfoPtr pScrn)
 {
+	unsigned int mmio_off;
+
 	fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);

 	TRACE_ENTER("MapMMIO");
@@ -590,12 +587,17 @@
 			perror("FBIOPUT_VSCREENINFO");
 			return FALSE;
 		}
-		fPtr->mmio = mmap(NULL, fPtr->fix.mmio_len, PROT_READ | PROT_WRITE,
-				  MAP_SHARED, fPtr->fd, fPtr->fix.smem_len);
+		mmio_off = fPtr->fix.mmio_start & ~PAGE_MASK;
+		fPtr->mmio_len = (mmio_off+fPtr->fix.mmio_len+~PAGE_MASK) &
+				  PAGE_MASK;
+		fPtr->mmio = mmap(NULL, fPtr->mmio_len, PROT_READ | PROT_WRITE,
+				  MAP_SHARED, fPtr->fd, fPtr->fbmem_len);
 		if (-1 == (int)fPtr->mmio) {
 			perror("mmap mmio");
 			fPtr->mmio = NULL;
-		}
+		} else
+			fPtr->mmio = (void *)((unsigned long)fPtr->mmio+
+							     mmio_off);
 	}
 	return fPtr->mmio;
 }
@@ -607,9 +609,11 @@

 	TRACE_ENTER("UnmapMMIO");
 	if (NULL != fPtr->mmio) {
-		if (-1 == munmap(fPtr->mmio, fPtr->fix.mmio_len))
+		if (-1 == munmap((void *)((unsigned long)fPtr->mmio & PAGE_MASK),
+				 fPtr->mmio_len))
 			perror("munmap mmio");
 		fPtr->mmio = NULL;
+		/* FIXME: restore var.accel_flags [geert] */
 	}
 	return TRUE;
 }
@@ -691,9 +695,12 @@
 	cmap.transp = NULL;
 	for (i = 0; i < numColors; i++) {
 		cmap.start = indices[i];
-		red   = colors[indices[i]].red   << 8;
-		green = colors[indices[i]].green << 8;
-		blue  = colors[indices[i]].blue  << 8;
+		red   = (colors[indices[i]].red   << 8) |
+			colors[indices[i]].red;
+		green = (colors[indices[i]].green << 8) |
+			colors[indices[i]].green;
+		blue  = (colors[indices[i]].blue  << 8) |
+			colors[indices[i]].blue;
 		if (-1 == ioctl(fPtr->fd,FBIOPUTCMAP,(void*)&cmap))
 			perror("ioctl FBIOPUTCMAP");
 	}

Gr{oetje,eeting}s,

						Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
							    -- Linus Torvalds


** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/





More information about the Linuxppc-dev mailing list