Radeon acceleration with Xfbdev

Michel Dänzer <[email protected]>
Newsgroups gmane.comp.freedesktop.xserver
Message-ID <[email protected]>
Here's a quick'n'dirty patch to get this going, comments appreciated.

I see some corruption with it, is that to be expected Eric?


PS: Has there been a decision on what CVS commit mail scripts to use?

-- 
Earthling Michel Dänzer      |     Debian (powerpc), X and DRI developer
Software libre enthusiast    |   http://svcs.affero.net/rm.php?r=daenzer
xserver-fbdev-radeon.diff (text/x-patch, 7.8 KB)
Index: hw/kdrive/ati/ati.h
===================================================================
RCS file: /cvs/xserver/xserver/hw/kdrive/ati/ati.h,v
retrieving revision 1.2
diff -p -u -r1.2 ati.h
--- hw/kdrive/ati/ati.h	20 Nov 2003 07:49:45 -0000	1.2
+++ hw/kdrive/ati/ati.h	24 Nov 2003 23:59:24 -0000
@@ -25,14 +25,49 @@
 
 #ifndef _ATI_H_
 #define _ATI_H_
+
+#ifdef FBDEV_SERVER
+#include <fbdev.h>
+#else
 #include <vesa.h>
+#endif
 
 #define RADEON_REG_BASE(c)		((c)->attr.address[1])
 #define RADEON_REG_SIZE(c)		(0x10000)
 
+#ifdef __powerpc__
+
+static __inline__ void
+MMIO_OUT32(__volatile__ void *base, const unsigned long offset,
+	   const unsigned int val)
+{
+        __asm__ __volatile__(
+                        "stwbrx %1,%2,%3\n\t"
+			"eieio"
+                        : "=m" (*((volatile unsigned char *)base+offset))
+                        : "r" (val), "b" (base), "r" (offset));
+}
+
+static __inline__ CARD32
+MMIO_IN32(__volatile__ void *base, const unsigned long offset)
+{
+        register unsigned int val;
+        __asm__ __volatile__(
+                        "lwbrx %0,%1,%2\n\t"
+                        "eieio"
+                        : "=r" (val)
+                        : "b" (base), "r" (offset),
+                        "m" (*((volatile unsigned char *)base+offset)));
+        return val;
+}
+
+#else
+
 #define MMIO_OUT32(mmio, a, v)		(*(VOL32 *)((mmio) + (a)) = (v))
 #define MMIO_IN32(mmio, a)		(*(VOL32 *)((mmio) + (a)))
 
+#endif
+
 typedef volatile CARD8	VOL8;
 typedef volatile CARD16	VOL16;
 typedef volatile CARD32	VOL32;
@@ -44,16 +79,24 @@ struct pci_id_list {
 };
 
 typedef struct _ATICardInfo {
+#ifndef FBDEV_SERVER
 	VesaCardPrivRec vesa;
+#endif
 	CARD8 *reg_base;
 	Bool is_radeon;
 } ATICardInfo;
 
+#ifdef FBDEV_SERVER
+#define getATICardInfo(kd)	((ATICardInfo *) (((FbdevPriv *)(kd)->card->driver)->accel))
+#else
 #define getATICardInfo(kd)	((ATICardInfo *) ((kd)->card->driver))
+#endif
 #define ATICardInfo(kd)		ATICardInfo *atic = getATICardInfo(kd)
 
 typedef struct _ATIScreenInfo {
+#ifndef FBDEV_SERVER
 	VesaScreenPrivRec vesa;
+#endif
 	CARD8 *screen;
 	CARD8 *off_screen;
 	int off_screen_size;
@@ -62,7 +105,11 @@ typedef struct _ATIScreenInfo {
 	int dp_gui_master_cntl;
 } ATIScreenInfo;
 
+#ifdef FBDEV_SERVER
+#define getATIScreenInfo(kd)	((ATIScreenInfo *) (((FbdevScrPriv *)(kd)->screen->driver)->accel))
+#else
 #define getATIScreenInfo(kd)	((ATIScreenInfo *) ((kd)->screen->driver))
+#endif
 #define ATIScreenInfo(kd)	ATIScreenInfo *atis = getATIScreenInfo(kd)
 
 Bool
Index: hw/kdrive/ati/ati_draw.c
===================================================================
RCS file: /cvs/xserver/xserver/hw/kdrive/ati/ati_draw.c,v
retrieving revision 1.4
diff -p -u -r1.4 ati_draw.c
--- hw/kdrive/ati/ati_draw.c	23 Nov 2003 10:12:04 -0000	1.4
+++ hw/kdrive/ati/ati_draw.c	24 Nov 2003 23:59:24 -0000
@@ -22,7 +22,6 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 /* $Header: /cvs/xserver/xserver/hw/kdrive/ati/ati_draw.c,v 1.4 2003/11/23 10:12:04 anholt Exp $ */
-#include <sys/io.h>
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
Index: hw/kdrive/fbdev/Makefile.am
===================================================================
RCS file: /cvs/xserver/xserver/hw/kdrive/fbdev/Makefile.am,v
retrieving revision 1.9
diff -p -u -r1.9 Makefile.am
--- hw/kdrive/fbdev/Makefile.am	11 Nov 2003 05:46:09 -0000	1.9
+++ hw/kdrive/fbdev/Makefile.am	24 Nov 2003 23:59:24 -0000
@@ -1,6 +1,6 @@
 INCLUDES = 					\
 	@KDRIVE_INCS@				\
-	@XSERVER_CFLAGS@
+	@XSERVER_CFLAGS@ -DFBDEV_SERVER
 
 noinst_LIBRARIES = libfbdev.a
 
@@ -15,8 +15,16 @@ libfbdev_a_SOURCES =	\
 	fbdev.h
 
 Xfbdev_SOURCES = \
+	ati_reg.h \
+	ati.h \
+	ati_draw.c \
 	fbinit.c
 
+ati_draw.c ati_reg.h ati.h:
+	ln -s ../ati/$@ .
+
+ati_draw.o:	ati_reg.h ati.h
+
 Xfbdev_LDADD = 						\
 	libfbdev.a					\
 	@KDRIVE_LIBS@					\
Index: hw/kdrive/fbdev/fbdev.h
===================================================================
RCS file: /cvs/xserver/xserver/hw/kdrive/fbdev/fbdev.h,v
retrieving revision 1.15
diff -p -u -r1.15 fbdev.h
--- hw/kdrive/fbdev/fbdev.h	2 Nov 2003 19:56:10 -0000	1.15
+++ hw/kdrive/fbdev/fbdev.h	24 Nov 2003 23:59:25 -0000
@@ -44,12 +44,14 @@ typedef struct _fbdevPriv {
     int				fd;
     char			*fb;
     char			*fb_base;
+    void			*accel;
 } FbdevPriv;
     
 typedef struct _fbdevScrPriv {
     Rotation			randr;
     Bool			shadow;
     PixmapPtr			pShadow;
+    void			*accel;
 } FbdevScrPriv;
 
 extern KdCardFuncs  fbdevFuncs;
@@ -124,7 +126,10 @@ fbdevSetShadow (ScreenPtr pScreen);
 
 Bool
 fbdevCreateColormap (ColormapPtr pmap);
-    
+
+Bool
+fbdevDrawInit(ScreenPtr pScreen);
+
 #ifdef RANDR
 Bool
 fbdevRandRGetInfo (ScreenPtr pScreen, Rotation *rotations);
Index: hw/kdrive/fbdev/fbinit.c
===================================================================
RCS file: /cvs/xserver/xserver/hw/kdrive/fbdev/fbinit.c,v
retrieving revision 1.14
diff -p -u -r1.14 fbinit.c
--- hw/kdrive/fbdev/fbinit.c	18 Nov 2003 04:53:15 -0000	1.14
+++ hw/kdrive/fbdev/fbinit.c	24 Nov 2003 23:59:25 -0000
@@ -28,6 +28,8 @@
 #endif
 #include <fbdev.h>
 
+#include "ati.h"
+
 void
 InitCard (char *name)
 {
@@ -51,6 +53,79 @@ InitInput (int argc, char **argv)
 #endif
 }
 
+
+Bool
+fbdevDrawInit(ScreenPtr pScreen)
+{
+    KdScreenPriv(pScreen);
+    KdScreenInfo *screen = pScreenPriv->screen;
+    FbdevScrPriv	*scrpriv = screen->driver;
+    FbdevPriv	*priv = pScreenPriv->card->driver;
+
+    if (priv->fix.mmio_len) {
+	switch (priv->fix.accel) {
+	case FB_ACCEL_ATI_RADEON:
+	    {
+		ATICardInfo *atic = (ATICardInfo *)priv->accel = xalloc(sizeof(ATICardInfo));
+		ATIScreenInfo *atis = (ATIScreenInfo *)scrpriv->accel = xalloc(sizeof(ATIScreenInfo));
+		int screen_size = screen->fb[0].byteStride * screen->height;
+		int memory = priv->fix.smem_len - screen_size;
+
+		if (atic == NULL || atis == NULL)
+		    goto ATIError;
+
+		/* Initialise card info */
+		atic->is_radeon = TRUE;
+		atic->reg_base = (unsigned char *) mmap ((caddr_t) NULL,
+							 priv->fix.mmio_len,
+							 PROT_READ|PROT_WRITE,
+							 MAP_SHARED,
+							 priv->fd, priv->fix.smem_len);
+		if ((long)atic->reg_base == -1)
+		    goto ATIError;
+
+		/* Initialise screen info */
+		memset(atis, '\0', sizeof(ATIScreenInfo));
+		atis->screen = priv->fb_base;
+		if (memory > screen->fb[0].byteStride) {
+		    atis->off_screen = atis->screen + (screen->off_screen_base = screen_size);
+		    atis->off_screen_size = screen->memory_size = memory;
+		    screen->memory_size = priv->fix.smem_len;
+		} else {
+		    atis->off_screen = 0;
+		    atis->off_screen_size = 0;
+		}
+
+		/* Initialise acceleration */
+		if (ATIDrawInit(pScreen)) {
+		    fbdevFuncs.enableAccel = ATIDrawEnable;
+		    fbdevFuncs.syncAccel = ATIDrawSync;
+		    fbdevFuncs.disableAccel = ATIDrawDisable;
+		    fbdevFuncs.finiAccel = ATIDrawFini;
+
+		    fprintf(stderr, "Acceleration for Radeon card successfully initialised\n");
+		    screen->dumb = FALSE;
+		    return TRUE;
+		}
+
+	ATIError:
+		fprintf(stderr, "Failed to initialise acceleration for Radeon card\n");
+		if (atis)
+		    xfree(atis);
+		if (atic) {
+		    if (atic->reg_base)
+			munmap(atic->reg_base, priv->fix.mmio_len);
+		    xfree(atic);
+		}
+		priv->accel = scrpriv->accel = NULL;
+	    }
+	}
+    }
+
+    screen->dumb = TRUE;
+    return FALSE;
+}
+
 void
 ddxUseMsg (void)
 {
@@ -85,7 +160,7 @@ KdCardFuncs	fbdevFuncs = {
     0,			    /* finiCursor */
     0,			    /* recolorCursor */
     
-    0,			    /* initAccel */
+    fbdevDrawInit,	    /* initAccel */
     0,			    /* enableAccel */
     0,			    /* syncAccel */
     0,			    /* disableAccel */
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.