drm/radeon/kms: fence cleanup + more reliable GPU lockup detection V4
[safe/jmp/linux-2.6] / drivers / gpu / drm / radeon / r300.c
index 63fe275..9825fb1 100644 (file)
@@ -26,8 +26,9 @@
  *          Jerome Glisse
  */
 #include <linux/seq_file.h>
-#include "drmP.h"
-#include "drm.h"
+#include <drm/drmP.h>
+#include <drm/drm.h>
+#include <drm/drm_crtc_helper.h>
 #include "radeon_reg.h"
 #include "radeon.h"
 #include "radeon_asic.h"
@@ -165,9 +166,9 @@ void rv370_pcie_gart_disable(struct radeon_device *rdev)
 
 void rv370_pcie_gart_fini(struct radeon_device *rdev)
 {
+       radeon_gart_fini(rdev);
        rv370_pcie_gart_disable(rdev);
        radeon_gart_table_vram_free(rdev);
-       radeon_gart_fini(rdev);
 }
 
 void r300_fence_ring_emit(struct radeon_device *rdev,
@@ -324,11 +325,12 @@ void r300_gpu_init(struct radeon_device *rdev)
 
        r100_hdp_reset(rdev);
        /* FIXME: rv380 one pipes ? */
-       if ((rdev->family == CHIP_R300) || (rdev->family == CHIP_R350)) {
+       if ((rdev->family == CHIP_R300 && rdev->pdev->device != 0x4144) ||
+           (rdev->family == CHIP_R350)) {
                /* r300,r350 */
                rdev->num_gb_pipes = 2;
        } else {
-               /* rv350,rv370,rv380 */
+               /* rv350,rv370,rv380,r300 AD */
                rdev->num_gb_pipes = 1;
        }
        rdev->num_z_pipes = 1;
@@ -425,12 +427,35 @@ int r300_ga_reset(struct radeon_device *rdev)
        return -1;
 }
 
+bool r300_gpu_is_lockup(struct radeon_device *rdev)
+{
+       u32 rbbm_status;
+       int r;
+
+       rbbm_status = RREG32(R_000E40_RBBM_STATUS);
+       if (!G_000E40_GUI_ACTIVE(rbbm_status)) {
+               r100_gpu_lockup_update(&rdev->config.r300.lockup, &rdev->cp);
+               return false;
+       }
+       /* force CP activities */
+       r = radeon_ring_lock(rdev, 2);
+       if (!r) {
+               /* PACKET2 NOP */
+               radeon_ring_write(rdev, 0x80000000);
+               radeon_ring_write(rdev, 0x80000000);
+               radeon_ring_unlock_commit(rdev);
+       }
+       rdev->cp.rptr = RREG32(RADEON_CP_RB_RPTR);
+       return r100_gpu_cp_is_lockup(rdev, &rdev->config.r300.lockup, &rdev->cp);
+}
+
 int r300_gpu_reset(struct radeon_device *rdev)
 {
        uint32_t status;
 
        /* reset order likely matter */
        status = RREG32(RADEON_RBBM_STATUS);
+       dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status);
        /* reset HDP */
        r100_hdp_reset(rdev);
        /* reset rb2d */