drm/radeon: handle vfct with multiple vbios images
[pandora-kernel.git] / drivers / gpu / drm / radeon / r100.c
index 8f8b8fa..dfd1267 100644 (file)
@@ -41,6 +41,7 @@
 
 #include <linux/firmware.h>
 #include <linux/platform_device.h>
+#include <linux/module.h>
 
 #include "r100_reg_safe.h"
 #include "rn50_reg_safe.h"
@@ -186,13 +187,18 @@ u32 r100_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
 {
        struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
        u32 tmp = ((u32)crtc_base) | RADEON_CRTC_OFFSET__OFFSET_LOCK;
+       int i;
 
        /* Lock the graphics update lock */
        /* update the scanout addresses */
        WREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset, tmp);
 
        /* Wait for update_pending to go high. */
-       while (!(RREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset) & RADEON_CRTC_OFFSET__GUI_TRIG_OFFSET));
+       for (i = 0; i < rdev->usec_timeout; i++) {
+               if (RREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset) & RADEON_CRTC_OFFSET__GUI_TRIG_OFFSET)
+                       break;
+               udelay(1);
+       }
        DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n");
 
        /* Unlock the lock, so double-buffering can take place inside vblank */
@@ -536,6 +542,7 @@ void r100_hpd_init(struct radeon_device *rdev)
                default:
                        break;
                }
+               radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd);
        }
        if (rdev->irq.installed)
                r100_irq_set(rdev);
@@ -576,7 +583,7 @@ int r100_pci_gart_init(struct radeon_device *rdev)
 {
        int r;
 
-       if (rdev->gart.table.ram.ptr) {
+       if (rdev->gart.ptr) {
                WARN(1, "R100 PCI GART already initialized\n");
                return 0;
        }
@@ -635,10 +642,12 @@ void r100_pci_gart_disable(struct radeon_device *rdev)
 
 int r100_pci_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr)
 {
+       u32 *gtt = rdev->gart.ptr;
+
        if (i < 0 || i > rdev->gart.num_gpu_pages) {
                return -EINVAL;
        }
-       rdev->gart.table.ram.ptr[i] = cpu_to_le32(lower_32_bits(addr));
+       gtt[i] = cpu_to_le32(lower_32_bits(addr));
        return 0;
 }
 
@@ -679,6 +688,10 @@ int r100_irq_set(struct radeon_device *rdev)
                tmp |= RADEON_FP2_DETECT_MASK;
        }
        WREG32(RADEON_GEN_INT_CNTL, tmp);
+
+       /* read back to post the write */
+       RREG32(RADEON_GEN_INT_CNTL);
+
        return 0;
 }
 
@@ -780,9 +793,7 @@ int r100_irq_process(struct radeon_device *rdev)
                        WREG32(RADEON_AIC_CNTL, msi_rearm | RS400_MSI_REARM);
                        break;
                default:
-                       msi_rearm = RREG32(RADEON_MSI_REARM_EN) & ~RV370_MSI_REARM_EN;
-                       WREG32(RADEON_MSI_REARM_EN, msi_rearm);
-                       WREG32(RADEON_MSI_REARM_EN, msi_rearm | RV370_MSI_REARM_EN);
+                       WREG32(RADEON_MSI_REARM_EN, RV370_MSI_REARM_EN);
                        break;
                }
        }
@@ -2168,6 +2179,7 @@ bool r100_gpu_is_lockup(struct radeon_device *rdev)
 void r100_bm_disable(struct radeon_device *rdev)
 {
        u32 tmp;
+       u16 tmp16;
 
        /* disable bus mastering */
        tmp = RREG32(R_000030_BUS_CNTL);
@@ -2178,8 +2190,8 @@ void r100_bm_disable(struct radeon_device *rdev)
        WREG32(R_000030_BUS_CNTL, (tmp & 0xFFFFFFFF) | 0x00000040);
        tmp = RREG32(RADEON_BUS_CNTL);
        mdelay(1);
-       pci_read_config_word(rdev->pdev, 0x4, (u16*)&tmp);
-       pci_write_config_word(rdev->pdev, 0x4, tmp & 0xFFFB);
+       pci_read_config_word(rdev->pdev, 0x4, &tmp16);
+       pci_write_config_word(rdev->pdev, 0x4, tmp16 & 0xFFFB);
        mdelay(1);
 }
 
@@ -3897,6 +3909,12 @@ static int r100_startup(struct radeon_device *rdev)
                return r;
 
        /* Enable IRQ */
+       if (!rdev->irq.installed) {
+               r = radeon_irq_kms_init(rdev);
+               if (r)
+                       return r;
+       }
+
        r100_irq_set(rdev);
        rdev->config.r100.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL);
        /* 1M ring buffer */
@@ -4040,9 +4058,6 @@ int r100_init(struct radeon_device *rdev)
        r100_mc_init(rdev);
        /* Fence driver */
        r = radeon_fence_driver_init(rdev);
-       if (r)
-               return r;
-       r = radeon_irq_kms_init(rdev);
        if (r)
                return r;
        /* Memory manager */