On Tue, 2003-07-22 at 07:06, Leigh Dyer wrote:
> 
> I've just been lucky enough to get a 1Ghz Powerbook G4 with 64Mb Radeon
> Mobility 9000 to work on, 

Great machine, isn't it? :)

> and I've been having a little trouble getting X and DRI working 
> nicely. The process so far has been:
> 
> 1. Installed debian sid (following the branden's ibook page)
> 2. Installed Daniel Stone's XFree86 4.3.0 packages
> 3. Built and installed 2.4.21-ben2 kernel from source
> 4. Built and installed DRI trunk from CVS

BTW, are you not using my dri-trunk-sid packages intentionally?


> [drm] AGP 0.99 aperture @ 0x00000000 16MB
> [drm] Initialized radeon 1.9.0 20020828 on minor 0
> __ioremap(): phys addr 0 is RAM lr c0011be8
> __ioremap(): phys addr 101000 is RAM lr c0011be8
> __ioremap(): phys addr 102000 is RAM lr c0011be8
> [drm:radeon_do_init_cp] *ERROR* could not find ioremap agp regions!

Your kernel lacks a vmap() implementation taking four arguments, which
the DRM requires for using agpgart with AGP bridges that don't provide
direct CPU access to the AGP aperture. The attached vmap-2.4.diff is
what I'm using for this; alternatively, you can try merging
http://penguinppc.org/~daenzer/DRI/drm-ioremapagp.diff to the current
DRM.

Anyway, you exposed a couple of bugs:

      * RADEONDRIFinishScreenInit() fails, so the DRI gets disabled, but
        XAA has already been set up to use the CP for 2D acceleration.
        This causes the CP errors you're seeing. The attached
        radeon-accel-init.diff moves the RADEONAccelInit() call after
        the RADEONDRIFinishScreenInit() call.
      * AGP initialization in the DRM should really fail as early as
        possible in this case, such that the DRI may be enabled using
        PCI GART. The attached drm-agp-acquire.diff tries to achieve
        this.

So, please try only the first patch first and verify that the X server
works correctly (the DRI will be disabled). Then, try the second patch
and verify that the DRI is enabled, but AGP is disabled.


-- 
Earthling Michel Dänzer   \  Debian (powerpc), XFree86 and DRI developer
Software libre enthusiast  \     http://svcs.affero.net/rm.php?r=daenzer
Index: programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c
===================================================================
RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c,v
retrieving revision 1.57
diff -p -u -r1.57 radeon_driver.c
--- programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c	25 Mar 2003 11:19:52 -0000	1.57
+++ programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c	22 Jul 2003 15:38:03 -0000
@@ -3969,29 +4525,6 @@ Bool RADEONScreenInit(int scrnIndex, Scr
 	}
     }
 
-				/* Acceleration setup */
-    if (!xf86ReturnOptValBool(info->Options, OPTION_NOACCEL, FALSE)) {
-	if (RADEONAccelInit(pScreen)) {
-	    xf86DrvMsg(scrnIndex, X_INFO, "Acceleration enabled\n");
-	    info->accelOn = TRUE;
-
-	    /* FIXME: Figure out why this was added because it shouldn't be! */
-	    /* This is needed by the DRI and XAA code for shared entities */
-	    pScrn->pScreen = pScreen;
-	} else {
-	    xf86DrvMsg(scrnIndex, X_ERROR,
-		       "Acceleration initialization failed\n");
-	    xf86DrvMsg(scrnIndex, X_INFO, "Acceleration disabled\n");
-	    info->accelOn = FALSE;
-	}
-    } else {
-	xf86DrvMsg(scrnIndex, X_INFO, "Acceleration disabled\n");
-	info->accelOn = FALSE;
-    }
-
-				/* DGA setup */
-    RADEONDGAInit(pScreen);
-
 				/* Backing store setup */
     miInitializeBackingStore(pScreen);
     xf86SetBackingStore(pScreen);
@@ -4042,8 +4575,6 @@ Bool RADEONScreenInit(int scrnIndex, Scr
     xf86DPMSInit(pScreen, RADEONDisplayPowerManagementSet, 0);
 #endif
 
-    RADEONInitVideo(pScreen);
-
 				/* Provide SaveScreen */
     pScreen->SaveScreen  = RADEONSaveScreen;
 
@@ -4068,8 +4599,33 @@ Bool RADEONScreenInit(int scrnIndex, Scr
     } else {
 	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct rendering disabled\n");
     }
 #endif
 
+				/* Acceleration setup */
+    if (!xf86ReturnOptValBool(info->Options, OPTION_NOACCEL, FALSE)) {
+	if (RADEONAccelInit(pScreen)) {
+	    xf86DrvMsg(scrnIndex, X_INFO, "Acceleration enabled\n");
+	    info->accelOn = TRUE;
+
+	    /* This is needed by the XAA code for shared entities */
+	    pScrn->pScreen = pScreen;
+	} else {
+	    xf86DrvMsg(scrnIndex, X_ERROR,
+		       "Acceleration initialization failed\n");
+	    xf86DrvMsg(scrnIndex, X_INFO, "Acceleration disabled\n");
+	    info->accelOn = FALSE;
+	}
+    } else {
+	xf86DrvMsg(scrnIndex, X_INFO, "Acceleration disabled\n");
+	info->accelOn = FALSE;
+    }
+
+				/* DGA setup */
+    RADEONDGAInit(pScreen);
+
+				/* XVideo setup */
+    RADEONInitVideo(pScreen);
+
     info->BlockHandler = pScreen->BlockHandler;
     pScreen->BlockHandler = RADEONBlockHandler;
 
Index: programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_agpsupport.h
===================================================================
RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_agpsupport.h,v
retrieving revision 1.16
diff -p -u -r1.16 drm_agpsupport.h
--- programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_agpsupport.h	9 Jul 2003 23:21:15 -0000	1.16
+++ programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_agpsupport.h	22 Jul 2003 15:46:56 -0000
@@ -106,6 +106,10 @@ int DRM(agp_acquire)(struct inode *inode
 
 	if (!dev->agp || dev->agp->acquired || !drm_agp->acquire)
 		return -EINVAL;
+#ifndef VMAP_4_ARGS
+	if ( dev->agp->cant_use_aperture )
+		return -EINVAL;
+#endif
 	if ((retcode = drm_agp->acquire())) return retcode;
 	dev->agp->acquired = 1;
 	return 0;
--- linux-2.4.20-ben8/mm/vmalloc.c      2002-11-23 10:52:31.000000000 +0100
+++ linux-2.4.20-ben8-xfs-lolat/mm/vmalloc.c    2003-05-15 15:48:39.000000000 +0200
@@ -93,7 +93,8 @@ void vmfree_area_pages(unsigned long add
 }
 
 static inline int alloc_area_pte (pte_t * pte, unsigned long address,
-                       unsigned long size, int gfp_mask, pgprot_t prot)
+                       unsigned long size, int gfp_mask,
+                       pgprot_t prot, struct page ***pages)
 {
        unsigned long end;
 
@@ -103,9 +104,17 @@ static inline int alloc_area_pte (pte_t 
                end = PMD_SIZE;
        do {
                struct page * page;
-               spin_unlock(&init_mm.page_table_lock);
-               page = alloc_page(gfp_mask);
-               spin_lock(&init_mm.page_table_lock);
+               if (!pages) {
+                 spin_unlock(&init_mm.page_table_lock);
+                 page = alloc_page(gfp_mask);
+                 spin_lock(&init_mm.page_table_lock);
+               } else {
+                       page = (*pages)[0];
+                       (*pages)++;
+                       /* Add a reference to the page so we can free later */
+                       if (page) atomic_inc(&page->count);
+
+               }
                if (!pte_none(*pte))
                        printk(KERN_ERR "alloc_area_pte: page already exists\n");
                if (!page)
@@ -117,7 +126,9 @@ static inline int alloc_area_pte (pte_t 
        return 0;
 }
 
-static inline int alloc_area_pmd(pmd_t * pmd, unsigned long address, unsigned long 
size, int gfp_mask, pgprot_t prot)
+static inline int alloc_area_pmd(pmd_t * pmd, unsigned long address,
+                       unsigned long size, int gfp_mask,
+                       pgprot_t prot, struct page ***pages)
 {
        unsigned long end;
 
@@ -129,7 +140,8 @@ static inline int alloc_area_pmd(pmd_t *
                pte_t * pte = pte_alloc(&init_mm, pmd, address);
                if (!pte)
                        return -ENOMEM;
-               if (alloc_area_pte(pte, address, end - address, gfp_mask, prot))
+               if (alloc_area_pte(pte, address, end - address,
+                                       gfp_mask, prot, pages))
                        return -ENOMEM;
                address = (address + PMD_SIZE) & PMD_MASK;
                pmd++;
@@ -137,8 +149,10 @@ static inline int alloc_area_pmd(pmd_t *
        return 0;
 }
 
-inline int vmalloc_area_pages (unsigned long address, unsigned long size,
-                               int gfp_mask, pgprot_t prot)
+static inline int _vmalloc_area_pages (unsigned long address,
+                               unsigned long size,
+                                int gfp_mask, pgprot_t prot,
+                               struct page ***pages)
 {
        pgd_t * dir;
        unsigned long end = address + size;
@@ -155,7 +169,7 @@ inline int vmalloc_area_pages (unsigned 
                        break;
 
                ret = -ENOMEM;
-               if (alloc_area_pmd(pmd, address, end - address, gfp_mask, prot))
+               if (alloc_area_pmd(pmd, address, end - address, gfp_mask, prot, pages))
                        break;
 
                address = (address + PGDIR_SIZE) & PGDIR_MASK;
@@ -168,6 +182,13 @@ inline int vmalloc_area_pages (unsigned 
        return ret;
 }
 
+inline int vmalloc_area_pages (unsigned long address,
+                               unsigned long size,
+                               int gfp_mask, pgprot_t prot)
+{
+       return _vmalloc_area_pages(address, size, gfp_mask, prot, NULL);
+}
+
 struct vm_struct * get_vm_area(unsigned long size, unsigned long flags)
 {
        unsigned long addr;
@@ -253,6 +274,49 @@ void * __vmalloc (unsigned long size, in
        return addr;
 }
 
+void * vmap(struct page **pages, int count,
+           unsigned long flags, pgprot_t prot)
+{
+       void * addr;
+       struct vm_struct *area;
+       unsigned long size = count << PAGE_SHIFT;
+
+       if (!size || size > (max_mapnr << PAGE_SHIFT))
+               return NULL;
+       area = get_vm_area(size, flags);
+       if (!area) {
+               return NULL;
+       }
+       addr = area->addr;
+       if (_vmalloc_area_pages(VMALLOC_VMADDR(addr), size, 0,
+                                prot, &pages)) {
+               vfree(addr);
+               return NULL;
+       }
+       return addr;
+}
+
+void * remap_page_array(struct page **page_array, int count, int gfp_mask)
+{
+       void * addr;
+       struct vm_struct *area;
+       unsigned long size = count << PAGE_SHIFT;
+
+       if (!size || size > (max_mapnr << PAGE_SHIFT))
+               return NULL;
+       area = get_vm_area(size, VM_ALLOC);
+       if (!area) {
+               return NULL;
+       }
+       addr = area->addr;
+       if (_vmalloc_area_pages(VMALLOC_VMADDR(addr), size,
+               gfp_mask, PAGE_KERNEL, &page_array)) {
+               vfree(addr);
+               return NULL;
+       }
+       return addr;
+}
+
 long vread(char *buf, char *addr, unsigned long count)
 {
        struct vm_struct *tmp;
--- linux-2.4.20-ben8/include/linux/vmalloc.h   2003-03-14 19:32:28.000000000 +0100
+++ linux-2.4.20-ben8-xfs-lolat/include/linux/vmalloc.h 2003-05-15 16:35:42.000000000 
+0200
@@ -21,12 +21,16 @@ struct vm_struct {
 
 extern struct vm_struct * get_vm_area (unsigned long size, unsigned long flags);
 extern void vfree(void * addr);
+#define vunmap(addr)   vfree(addr)
+extern void * vmap(struct page **pages, int count,
+                  unsigned long flags, pgprot_t prot);
 extern void * __vmalloc (unsigned long size, int gfp_mask, pgprot_t prot);
 extern long vread(char *buf, char *addr, unsigned long count);
 extern void vmfree_area_pages(unsigned long address, unsigned long size);
 extern int vmalloc_area_pages(unsigned long address, unsigned long size,
                               int gfp_mask, pgprot_t prot);
 
+void * remap_page_array(struct page **, int, int);
 /*
  *     Allocate any pages
  */
--- linux-2.4.20-ben8/kernel/ksyms.c    2003-03-05 20:32:53.000000000 +0100
+++ linux-2.4.20-ben8-xfs-lolat/kernel/ksyms.c  2003-05-15 16:29:41.000000000 +0200
@@ -110,9 +110,11 @@ EXPORT_SYMBOL(kmem_cache_create);
 EXPORT_SYMBOL(kfree);
 EXPORT_SYMBOL(vfree);
 EXPORT_SYMBOL(__vmalloc);
+EXPORT_SYMBOL(vmap);
 EXPORT_SYMBOL(vmalloc_to_page);
 EXPORT_SYMBOL(mem_map);
 EXPORT_SYMBOL(remap_page_range);
+EXPORT_SYMBOL(remap_page_array);
 EXPORT_SYMBOL(max_mapnr);
 EXPORT_SYMBOL(high_memory);
 EXPORT_SYMBOL(vmtruncate);
--- linux-2.4.20-ben8/arch/ppc/kernel/ppc_ksyms.c       2002-11-23 10:52:30.000000000 
+0100
+++ linux-2.4.20-ben8-xfs-lolat/arch/ppc/kernel/ppc_ksyms.c     2003-05-15 
17:12:38.000000000 +0200
@@ -163,6 +163,7 @@ EXPORT_SYMBOL(_outsw_ns);
 EXPORT_SYMBOL(_insl_ns);
 EXPORT_SYMBOL(_outsl_ns);
 EXPORT_SYMBOL(ioremap);
+EXPORT_SYMBOL(ioremap_bot);
 EXPORT_SYMBOL(__ioremap);
 EXPORT_SYMBOL(iounmap);
 EXPORT_SYMBOL(iopa);
@@ -196,6 +197,7 @@ EXPORT_SYMBOL(flush_dcache_range);
 EXPORT_SYMBOL(flush_icache_user_range);
 EXPORT_SYMBOL(flush_icache_page);
 EXPORT_SYMBOL(flush_dcache_page);
+EXPORT_SYMBOL(local_flush_tlb_all);
 EXPORT_SYMBOL(xchg_u32);
 #ifdef CONFIG_ALTIVEC
 EXPORT_SYMBOL(last_task_used_altivec);

Reply via email to