drm/radeon/kms: add HDP flushing for all GPUs.
authorDave Airlie <airlied@redhat.com>
Mon, 23 Nov 2009 02:01:09 +0000 (12:01 +1000)
committerDave Airlie <airlied@redhat.com>
Wed, 2 Dec 2009 01:37:11 +0000 (11:37 +1000)
rendercheck under kms on r600s was failing due to HDP flushing not happening.

This adds HDP flushing to the object wait function for r100->r700 families.

rendercheck passes basic tests on r600 with this change.

Acked-by: Alex Deucher <alexdeucher@gmail.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
drivers/gpu/drm/radeon/r100.c
drivers/gpu/drm/radeon/r600.c
drivers/gpu/drm/radeon/r600d.h
drivers/gpu/drm/radeon/radeon.h
drivers/gpu/drm/radeon/radeon_asic.h
drivers/gpu/drm/radeon/radeon_object.c

index 4e0a804..772bcd8 100644 (file)
@@ -1589,6 +1589,14 @@ void r100_gpu_init(struct radeon_device *rdev)
        r100_hdp_reset(rdev);
 }
 
+void r100_hdp_flush(struct radeon_device *rdev)
+{
+       u32 tmp;
+       tmp = RREG32(RADEON_HOST_PATH_CNTL);
+       tmp |= RADEON_HDP_READ_BUFFER_INVALIDATE;
+       WREG32(RADEON_HOST_PATH_CNTL, tmp);
+}
+
 void r100_hdp_reset(struct radeon_device *rdev)
 {
        uint32_t tmp;
index 278f646..797a36f 100644 (file)
@@ -1101,6 +1101,10 @@ void r600_pciep_wreg(struct radeon_device *rdev, u32 reg, u32 v)
        (void)RREG32(PCIE_PORT_DATA);
 }
 
+void r600_hdp_flush(struct radeon_device *rdev)
+{
+       WREG32(R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1);
+}
 
 /*
  * CP & Ring
index 27ab428..b7f4ce2 100644 (file)
 #define                S_000E60_SOFT_RESET_TSC(x)              (((x) & 1) << 16)
 #define                S_000E60_SOFT_RESET_VMC(x)              (((x) & 1) << 17)
 
+#define R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL          0x5480
 #endif
index 9cb81a8..c32fe1c 100644 (file)
@@ -639,6 +639,7 @@ struct radeon_asic {
                               uint32_t offset, uint32_t obj_size);
        int (*clear_surface_reg)(struct radeon_device *rdev, int reg);
        void (*bandwidth_update)(struct radeon_device *rdev);
+       void (*hdp_flush)(struct radeon_device *rdev);
 };
 
 /*
@@ -971,6 +972,7 @@ static inline void radeon_ring_write(struct radeon_device *rdev, uint32_t v)
 #define radeon_set_surface_reg(rdev, r, f, p, o, s) ((rdev)->asic->set_surface_reg((rdev), (r), (f), (p), (o), (s)))
 #define radeon_clear_surface_reg(rdev, r) ((rdev)->asic->clear_surface_reg((rdev), (r)))
 #define radeon_bandwidth_update(rdev) (rdev)->asic->bandwidth_update((rdev))
+#define radeon_hdp_flush(rdev) (rdev)->asic->hdp_flush((rdev))
 
 /* Common functions */
 extern int radeon_gart_table_vram_pin(struct radeon_device *rdev);
index c18fbee..c7a7f84 100644 (file)
@@ -76,6 +76,7 @@ int r100_clear_surface_reg(struct radeon_device *rdev, int reg);
 void r100_bandwidth_update(struct radeon_device *rdev);
 void r100_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib);
 int r100_ring_test(struct radeon_device *rdev);
+void r100_hdp_flush(struct radeon_device *rdev);
 
 static struct radeon_asic r100_asic = {
        .init = &r100_init,
@@ -107,6 +108,7 @@ static struct radeon_asic r100_asic = {
        .set_surface_reg = r100_set_surface_reg,
        .clear_surface_reg = r100_clear_surface_reg,
        .bandwidth_update = &r100_bandwidth_update,
+       .hdp_flush = &r100_hdp_flush,
 };
 
 
@@ -162,6 +164,7 @@ static struct radeon_asic r300_asic = {
        .set_surface_reg = r100_set_surface_reg,
        .clear_surface_reg = r100_clear_surface_reg,
        .bandwidth_update = &r100_bandwidth_update,
+       .hdp_flush = &r100_hdp_flush,
 };
 
 /*
@@ -201,6 +204,7 @@ static struct radeon_asic r420_asic = {
        .set_surface_reg = r100_set_surface_reg,
        .clear_surface_reg = r100_clear_surface_reg,
        .bandwidth_update = &r100_bandwidth_update,
+       .hdp_flush = &r100_hdp_flush,
 };
 
 
@@ -245,6 +249,7 @@ static struct radeon_asic rs400_asic = {
        .set_surface_reg = r100_set_surface_reg,
        .clear_surface_reg = r100_clear_surface_reg,
        .bandwidth_update = &r100_bandwidth_update,
+       .hdp_flush = &r100_hdp_flush,
 };
 
 
@@ -291,6 +296,7 @@ static struct radeon_asic rs600_asic = {
        .set_pcie_lanes = NULL,
        .set_clock_gating = &radeon_atom_set_clock_gating,
        .bandwidth_update = &rs600_bandwidth_update,
+       .hdp_flush = &r100_hdp_flush,
 };
 
 
@@ -334,6 +340,7 @@ static struct radeon_asic rs690_asic = {
        .set_surface_reg = r100_set_surface_reg,
        .clear_surface_reg = r100_clear_surface_reg,
        .bandwidth_update = &rs690_bandwidth_update,
+       .hdp_flush = &r100_hdp_flush,
 };
 
 
@@ -381,6 +388,7 @@ static struct radeon_asic rv515_asic = {
        .set_surface_reg = r100_set_surface_reg,
        .clear_surface_reg = r100_clear_surface_reg,
        .bandwidth_update = &rv515_bandwidth_update,
+       .hdp_flush = &r100_hdp_flush,
 };
 
 
@@ -419,6 +427,7 @@ static struct radeon_asic r520_asic = {
        .set_surface_reg = r100_set_surface_reg,
        .clear_surface_reg = r100_clear_surface_reg,
        .bandwidth_update = &rv515_bandwidth_update,
+       .hdp_flush = &r100_hdp_flush,
 };
 
 /*
@@ -455,6 +464,7 @@ int r600_ring_test(struct radeon_device *rdev);
 int r600_copy_blit(struct radeon_device *rdev,
                   uint64_t src_offset, uint64_t dst_offset,
                   unsigned num_pages, struct radeon_fence *fence);
+void r600_hdp_flush(struct radeon_device *rdev);
 
 static struct radeon_asic r600_asic = {
        .init = &r600_init,
@@ -484,6 +494,7 @@ static struct radeon_asic r600_asic = {
        .set_surface_reg = r600_set_surface_reg,
        .clear_surface_reg = r600_clear_surface_reg,
        .bandwidth_update = &rv515_bandwidth_update,
+       .hdp_flush = &r600_hdp_flush,
 };
 
 /*
@@ -523,6 +534,7 @@ static struct radeon_asic rv770_asic = {
        .set_surface_reg = r600_set_surface_reg,
        .clear_surface_reg = r600_clear_surface_reg,
        .bandwidth_update = &rv515_bandwidth_update,
+       .hdp_flush = &r600_hdp_flush,
 };
 
 #endif
index 1f056da..98835f5 100644 (file)
@@ -315,6 +315,7 @@ int radeon_object_wait(struct radeon_object *robj)
        }
        spin_unlock(&robj->tobj.lock);
        radeon_object_unreserve(robj);
+       radeon_hdp_flush(robj->rdev);
        return r;
 }