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