Ati Radeon 7200 3D feature is buggy (kernel 2.6.34-rc6, ATI driver 6.13) (Answer TWO: more precise)

Uwe Bugla uwe.bugla at gmx.de
Mon May 3 08:01:38 PDT 2010


Am Montag, den 03.05.2010, 15:27 +0200 schrieb Michel Dänzer:
> On Sam, 2010-05-01 at 09:33 +0200, Uwe Bugla wrote: 
> > Hi,
> > 
> > I am working with an ATI Radeon 7200 QD (R100) on a Pentium 4 machine
> > with Intel AGP chipset.
> > The card driver is 6.13 (latest snapshot from April 30).
> > 
> > To savely exclude other side effects I did the following:
> > Recompile mesa library 7.9 devel and libdrm 2.4.20 from snapshot of
> > April 30.
> >  
> > What is the symptom?
> > Via config manager of Gnome 2.30 I make metacity a composite manager for
> > a reduced
> > amount of 3D effects.
> > What happens with the ATI driver (NOT with the self-built nouveau driver
> > running
> > with my Nvidia cards - this one works fantastic!) is the following:
> > 
> > If I go to the Linux Kernel archives via iceweasel 3.59 and push the
> > right mouse
> > button over some "View Patch" entry I get a window throwing shadows, as
> > intended.
> > 
> > BUT: The window does not contain any text!
> > I wonder if the 6.13 driver can deal with the fact that the card only
> > has 32 MB RAM.
> > But this is wild guessing, as I do not have any idea.
> > Maybe this hint / symptom is helpful for the developers.
> > 
> > When publishing driver 6.13 you were promising a driver being able of 3D
> > and 2D
> > effects plus KMS.
> > Except the 3D effects everything is working fine.
> > When will you finally fulfil that promise?
> 
> Did you test the kernel patch I asked you to?


Hello everybody,

SIGH! I got Compiz running together with my ATI Radeon QD 7200 (=R100).

Just to make it clear for every one:

Needed are:

1. Kernel 2.6.34-rc6
2. a self built Debian package containing the latest snapshot from
driver xf86-video-ati, version 6.13.
3. one AGP patch
4. one Radeon patch
5. most important (and this one cost me hours to find out!):

NOT the latest master from here:
http://cgit.freedesktop.org/mesa/mesa/
This master contains hunks which make the whole thing incompatible!



Instead you can use this one:
http://cgit.freedesktop.org/mesa/mesa/snapshot/mesa-nvfx-next-6b.tar.gz

This is Luca Barbieri's experimental tree, which not only works
excellent with my Nvidia nv34 cards, but furthermore seems to be the
only one to work with my ATI driver......

This is the AGP patch needed:

--- a/drivers/char/agp/ali-agp.c
+++ b/drivers/char/agp/ali-agp.c
@@ -204,6 +204,7 @@ static const struct agp_bridge_driver
ali_generic_bridge = {
        .aperture_sizes         = ali_generic_sizes,
        .size_type              = U32_APER_SIZE,
        .num_aperture_sizes     = 7,
+       .needs_scratch_page     = true,
        .configure              = ali_configure,
        .fetch_size             = ali_fetch_size,
        .cleanup                = ali_cleanup,
--- a/drivers/char/agp/amd-k7-agp.c
+++ b/drivers/char/agp/amd-k7-agp.c
@@ -142,6 +142,7 @@ static int amd_create_gatt_table(struct
agp_bridge_data *bridge)
 {
        struct aper_size_info_lvl2 *value;
        struct amd_page_map page_dir;
+       unsigned long __iomem *cur_gatt;
        unsigned long addr;
        int retval;
        u32 temp;
@@ -178,6 +179,13 @@ static int amd_create_gatt_table(struct
agp_bridge_data *bridge)
                readl(page_dir.remapped
+GET_PAGE_DIR_OFF(addr));        /* PCI Posting. */
        }
 
+       for (i = 0; i < value->num_entries; i++) {
+               addr = (i * PAGE_SIZE) + agp_bridge->gart_bus_addr;
+               cur_gatt = GET_GATT(addr);
+               writel(agp_bridge->scratch_page, cur_gatt
+GET_GATT_OFF(addr));
+               readl(cur_gatt+GET_GATT_OFF(addr));     /* PCI Posting.
*/
+       }
+
        return 0;
 }
 
@@ -375,6 +383,7 @@ static const struct agp_bridge_driver
amd_irongate_driver = {
        .aperture_sizes         = amd_irongate_sizes,
        .size_type              = LVL2_APER_SIZE,
        .num_aperture_sizes     = 7,
+       .needs_scratch_page     = true,
        .configure              = amd_irongate_configure,
        .fetch_size             = amd_irongate_fetch_size,
        .cleanup                = amd_irongate_cleanup,
--- a/drivers/char/agp/amd64-agp.c
+++ b/drivers/char/agp/amd64-agp.c
@@ -210,6 +210,7 @@ static const struct agp_bridge_driver
amd_8151_driver = {
        .aperture_sizes         = amd_8151_sizes,
        .size_type              = U32_APER_SIZE,
        .num_aperture_sizes     = 7,
+       .needs_scratch_page     = true,
        .configure              = amd_8151_configure,
        .fetch_size             = amd64_fetch_size,
        .cleanup                = amd64_cleanup,
--- a/drivers/char/agp/ati-agp.c
+++ b/drivers/char/agp/ati-agp.c
@@ -341,6 +341,7 @@ static int ati_create_gatt_table(struct
agp_bridge_data *bridge)
 {
        struct aper_size_info_lvl2 *value;
        struct ati_page_map page_dir;
+       unsigned long __iomem *cur_gatt;
        unsigned long addr;
        int retval;
        u32 temp;
@@ -395,6 +396,12 @@ static int ati_create_gatt_table(struct
agp_bridge_data *bridge)
                readl(page_dir.remapped
+GET_PAGE_DIR_OFF(addr));        /* PCI Posting. */
        }
 
+       for (i = 0; i < value->num_entries; i++) {
+               addr = (i * PAGE_SIZE) + agp_bridge->gart_bus_addr;
+               cur_gatt = GET_GATT(addr);
+               writel(agp_bridge->scratch_page, cur_gatt
+GET_GATT_OFF(addr));
+       }
+
        return 0;
 }
 
@@ -415,6 +422,7 @@ static const struct agp_bridge_driver
ati_generic_bridge = {
        .aperture_sizes         = ati_generic_sizes,
        .size_type              = LVL2_APER_SIZE,
        .num_aperture_sizes     = 7,
+       .needs_scratch_page     = true,
        .configure              = ati_configure,
        .fetch_size             = ati_fetch_size,
        .cleanup                = ati_cleanup,
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -1982,6 +1982,7 @@ static const struct agp_bridge_driver
intel_generic_driver = {
        .aperture_sizes         = intel_generic_sizes,
        .size_type              = U16_APER_SIZE,
        .num_aperture_sizes     = 7,
+       .needs_scratch_page     = true,
        .configure              = intel_configure,
        .fetch_size             = intel_fetch_size,
        .cleanup                = intel_cleanup,
@@ -2035,6 +2036,7 @@ static const struct agp_bridge_driver
intel_815_driver = {
        .aperture_sizes         = intel_815_sizes,
        .size_type              = U8_APER_SIZE,
        .num_aperture_sizes     = 2,
+       .needs_scratch_page     = true,
        .configure              = intel_815_configure,
        .fetch_size             = intel_815_fetch_size,
        .cleanup                = intel_8xx_cleanup,
@@ -2089,6 +2091,7 @@ static const struct agp_bridge_driver
intel_820_driver = {
        .aperture_sizes         = intel_8xx_sizes,
        .size_type              = U8_APER_SIZE,
        .num_aperture_sizes     = 7,
+       .needs_scratch_page     = true,
        .configure              = intel_820_configure,
        .fetch_size             = intel_8xx_fetch_size,
        .cleanup                = intel_820_cleanup,
@@ -2115,6 +2118,7 @@ static const struct agp_bridge_driver
intel_830mp_driver = {
        .aperture_sizes         = intel_830mp_sizes,
        .size_type              = U8_APER_SIZE,
        .num_aperture_sizes     = 4,
+       .needs_scratch_page     = true,
        .configure              = intel_830mp_configure,
        .fetch_size             = intel_8xx_fetch_size,
        .cleanup                = intel_8xx_cleanup,
@@ -2141,6 +2145,7 @@ static const struct agp_bridge_driver
intel_840_driver = {
        .aperture_sizes         = intel_8xx_sizes,
        .size_type              = U8_APER_SIZE,
        .num_aperture_sizes     = 7,
+       .needs_scratch_page     = true,
        .configure              = intel_840_configure,
        .fetch_size             = intel_8xx_fetch_size,
        .cleanup                = intel_8xx_cleanup,
@@ -2167,6 +2172,7 @@ static const struct agp_bridge_driver
intel_845_driver = {
        .aperture_sizes         = intel_8xx_sizes,
        .size_type              = U8_APER_SIZE,
        .num_aperture_sizes     = 7,
+       .needs_scratch_page     = true,
        .configure              = intel_845_configure,
        .fetch_size             = intel_8xx_fetch_size,
        .cleanup                = intel_8xx_cleanup,
@@ -2193,6 +2199,7 @@ static const struct agp_bridge_driver
intel_850_driver = {
        .aperture_sizes         = intel_8xx_sizes,
        .size_type              = U8_APER_SIZE,
        .num_aperture_sizes     = 7,
+       .needs_scratch_page     = true,
        .configure              = intel_850_configure,
        .fetch_size             = intel_8xx_fetch_size,
        .cleanup                = intel_8xx_cleanup,
@@ -2219,6 +2226,7 @@ static const struct agp_bridge_driver
intel_860_driver = {
        .aperture_sizes         = intel_8xx_sizes,
        .size_type              = U8_APER_SIZE,
        .num_aperture_sizes     = 7,
+       .needs_scratch_page     = true,
        .configure              = intel_860_configure,
        .fetch_size             = intel_8xx_fetch_size,
        .cleanup                = intel_8xx_cleanup,
@@ -2313,6 +2321,7 @@ static const struct agp_bridge_driver
intel_7505_driver = {
        .aperture_sizes         = intel_8xx_sizes,
        .size_type              = U8_APER_SIZE,
        .num_aperture_sizes     = 7,
+       .needs_scratch_page     = true,
        .configure              = intel_7505_configure,
        .fetch_size             = intel_8xx_fetch_size,
        .cleanup                = intel_8xx_cleanup,
--- a/drivers/char/agp/nvidia-agp.c
+++ b/drivers/char/agp/nvidia-agp.c
@@ -310,6 +310,7 @@ static const struct agp_bridge_driver nvidia_driver
= {
        .aperture_sizes         = nvidia_generic_sizes,
        .size_type              = U8_APER_SIZE,
        .num_aperture_sizes     = 5,
+       .needs_scratch_page     = true,
        .configure              = nvidia_configure,
        .fetch_size             = nvidia_fetch_size,
        .cleanup                = nvidia_cleanup,
--- a/drivers/char/agp/sis-agp.c
+++ b/drivers/char/agp/sis-agp.c
@@ -125,6 +125,7 @@ static struct agp_bridge_driver sis_driver = {
        .aperture_sizes         = sis_generic_sizes,
        .size_type              = U8_APER_SIZE,
        .num_aperture_sizes     = 7,
+       .needs_scratch_page     = true,
        .configure              = sis_configure,
        .fetch_size             = sis_fetch_size,
        .cleanup                = sis_cleanup,
--- a/drivers/char/agp/uninorth-agp.c
+++ b/drivers/char/agp/uninorth-agp.c
@@ -28,6 +28,7 @@
  */
 static int uninorth_rev;
 static int is_u3;
+static u32 scratch_value;
 
 #define DEFAULT_APERTURE_SIZE 256
 #define DEFAULT_APERTURE_STRING "256"
@@ -172,7 +173,7 @@ static int uninorth_insert_memory(struct agp_memory
*mem, off_t pg_start, int ty
 
        gp = (u32 *) &agp_bridge->gatt_table[pg_start];
        for (i = 0; i < mem->page_count; ++i) {
-               if (gp[i]) {
+               if (gp[i] != scratch_value) {
                        dev_info(&agp_bridge->dev->dev,
                                 "uninorth_insert_memory: entry 0x%x
occupied (%x)\n",
                                 i, gp[i]);
@@ -214,8 +215,9 @@ int uninorth_remove_memory(struct agp_memory *mem,
off_t pg_start, int type)
                return 0;
 
        gp = (u32 *) &agp_bridge->gatt_table[pg_start];
-       for (i = 0; i < mem->page_count; ++i)
-               gp[i] = 0;
+       for (i = 0; i < mem->page_count; ++i) {
+               gp[i] = scratch_value;
+       }
        mb();
        uninorth_tlbflush(mem);
 
@@ -421,8 +423,13 @@ static int uninorth_create_gatt_table(struct
agp_bridge_data *bridge)
 
        bridge->gatt_bus_addr = virt_to_phys(table);
 
+       if (is_u3)
+               scratch_value =
(page_to_phys(agp_bridge->scratch_page_page) >>
PAGE_SHIFT) | 0x80000000UL;
+       else
+               scratch_value =
cpu_to_le32((page_to_phys(agp_bridge->scratch_page_page) & 0xFFFFF000UL)
|
+                               0x1UL);
        for (i = 0; i < num_entries; i++)
-               bridge->gatt_table[i] = 0;
+               bridge->gatt_table[i] = scratch_value;
 
        return 0;
 
@@ -519,6 +526,7 @@ const struct agp_bridge_driver uninorth_agp_driver =
{
        .agp_destroy_pages      = agp_generic_destroy_pages,
        .agp_type_to_mask_type  = agp_generic_type_to_mask_type,
        .cant_use_aperture      = true,
+       .needs_scratch_page     = true,
 };
 
 const struct agp_bridge_driver u3_agp_driver = {
--- a/drivers/char/agp/via-agp.c
+++ b/drivers/char/agp/via-agp.c
@@ -175,6 +175,7 @@ static const struct agp_bridge_driver
via_agp3_driver = {
        .aperture_sizes         = agp3_generic_sizes,
        .size_type              = U8_APER_SIZE,
        .num_aperture_sizes     = 10,
+       .needs_scratch_page     = true,
        .configure              = via_configure_agp3,
        .fetch_size             = via_fetch_size_agp3,
        .cleanup                = via_cleanup_agp3,
@@ -201,6 +202,7 @@ static const struct agp_bridge_driver via_driver = {
        .aperture_sizes         = via_generic_sizes,
        .size_type              = U8_APER_SIZE,
        .num_aperture_sizes     = 9,
+       .needs_scratch_page     = true,
        .configure              = via_configure,
        .fetch_size             = via_fetch_size,
        .cleanup                = via_cleanup,



And this is the Radeon patch that you need:


--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -239,7 +239,9 @@ struct radeon_bo {
        struct list_head                list;
        /* Protected by tbo.reserved */
        u32                             placements[3];
+       u32                             busy_placements[3];
        struct ttm_placement            placement;
+       struct ttm_placement            busy_placement;
        struct ttm_buffer_object        tbo;
        struct ttm_bo_kmap_obj          kmap;
        unsigned                        pin_count;
--- a/drivers/gpu/drm/radeon/radeon_object.c
+++ b/drivers/gpu/drm/radeon/radeon_object.c
@@ -66,15 +66,19 @@ bool radeon_ttm_bo_is_radeon_bo(struct
ttm_buffer_object *bo)
 
 void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32
domain)
 {
-       u32 c = 0;
+       u32 c = 0, b = 0;
 
        rbo->placement.fpfn = 0;
        rbo->placement.lpfn = 0;
        rbo->placement.placement = rbo->placements;
-       rbo->placement.busy_placement = rbo->placements;
+       rbo->placement.busy_placement = rbo->busy_placements;
        if (domain & RADEON_GEM_DOMAIN_VRAM)
                rbo->placements[c++] = TTM_PL_FLAG_WC |
TTM_PL_FLAG_UNCACHED |
                                        TTM_PL_FLAG_VRAM;
+       /* add busy placement to TTM if VRAM is only option */
+       if (domain == RADEON_GEM_DOMAIN_VRAM) {
+               rbo->busy_placements[b++] = TTM_PL_MASK_CACHING |
TTM_PL_FLAG_TT;
+       }
        if (domain & RADEON_GEM_DOMAIN_GTT)
                rbo->placements[c++] = TTM_PL_MASK_CACHING |
TTM_PL_FLAG_TT;
        if (domain & RADEON_GEM_DOMAIN_CPU)
@@ -82,7 +86,7 @@ void radeon_ttm_placement_from_domain(struct radeon_bo
*rbo, u32 domain)
        if (!c)
                rbo->placements[c++] = TTM_PL_MASK_CACHING |
TTM_PL_FLAG_SYSTEM;
        rbo->placement.num_placement = c;
-       rbo->placement.num_busy_placement = c;
+       rbo->placement.num_busy_placement = b;
 }
 
 int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object
*gobj,



Michel Dänzer does not like the Radeon patch, and Dave Airlie promised
to write a better one.
Unfortunately I haven't seen any patch from Dave yet, so the empty
promise stays to at least try to find a better solution......

Cheers

Uwe























More information about the xorg mailing list