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);