Merge branch 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik...
[powerpc.git] / drivers / char / drm / sis_mm.c
index 0eb1dca..d26f5db 100644 (file)
@@ -40,8 +40,6 @@
 #define VIDEO_TYPE 0
 #define AGP_TYPE 1
 
-#define SIS_MM_ALIGN_SHIFT 4
-#define SIS_MM_ALIGN_MASK ( (1 << SIS_MM_ALIGN_SHIFT) - 1)
 
 #if defined(CONFIG_FB_SIS)
 /* fb management via fb device */
@@ -72,12 +70,17 @@ static void sis_sman_mm_destroy(void *private)
        ;
 }
 
-unsigned long sis_sman_mm_offset(void *private, void *ref)
+static unsigned long sis_sman_mm_offset(void *private, void *ref)
 {
        return ~((unsigned long)ref);
 }
 
-#endif
+#else /* CONFIG_FB_SIS */
+
+#define SIS_MM_ALIGN_SHIFT 4
+#define SIS_MM_ALIGN_MASK ( (1 << SIS_MM_ALIGN_SHIFT) - 1)
+
+#endif /* CONFIG_FB_SIS */
 
 static int sis_fb_init(DRM_IOCTL_ARGS)
 {
@@ -111,7 +114,7 @@ static int sis_fb_init(DRM_IOCTL_ARGS)
                return ret;
        }
 
-       dev_priv->vram_initialized = TRUE;
+       dev_priv->vram_initialized = 1;
        dev_priv->vram_offset = fb.offset;
 
        mutex_unlock(&dev->struct_mutex);
@@ -133,7 +136,7 @@ static int sis_drm_alloc(drm_device_t * dev, drm_file_t * priv,
 
        mutex_lock(&dev->struct_mutex);
 
-       if (FALSE == ((pool == 0) ? dev_priv->vram_initialized :
+       if (0 == ((pool == 0) ? dev_priv->vram_initialized :
                      dev_priv->agp_initialized)) {
                DRM_ERROR
                    ("Attempt to allocate from uninitialized memory manager.\n");
@@ -211,7 +214,7 @@ static int sis_ioctl_agp_init(DRM_IOCTL_ARGS)
                return ret;
        }
 
-       dev_priv->agp_initialized = TRUE;
+       dev_priv->agp_initialized = 1;
        dev_priv->agp_offset = agp.offset;
        mutex_unlock(&dev->struct_mutex);
 
@@ -226,6 +229,76 @@ static int sis_ioctl_agp_alloc(DRM_IOCTL_ARGS)
        return sis_drm_alloc(dev, priv, data, AGP_TYPE);
 }
 
+static drm_local_map_t *sis_reg_init(drm_device_t *dev)
+{
+       drm_map_list_t *entry;
+       drm_local_map_t *map;
+
+       list_for_each_entry(entry, &dev->maplist->head, head) {
+               map = entry->map;
+               if (!map)
+                       continue;
+               if (map->type == _DRM_REGISTERS) {
+                       return map;
+               }
+       }
+       return NULL;
+}
+
+int sis_idle(drm_device_t *dev)
+{
+       drm_sis_private_t *dev_priv = dev->dev_private;
+       uint32_t idle_reg;
+       unsigned long end;
+       int i;
+
+       if (dev_priv->idle_fault)
+               return 0;
+
+       if (dev_priv->mmio == NULL) {
+               dev_priv->mmio = sis_reg_init(dev);
+               if (dev_priv->mmio == NULL) {
+                       DRM_ERROR("Could not find register map.\n");
+                       return 0;
+               }
+       }
+       
+       /*
+        * Implement a device switch here if needed
+        */
+
+       if (dev_priv->chipset != SIS_CHIP_315)
+               return 0;
+
+       /*
+        * Timeout after 3 seconds. We cannot use DRM_WAIT_ON here
+        * because its polling frequency is too low.
+        */
+
+       end = jiffies + (DRM_HZ * 3);
+
+       for (i=0; i<4; ++i) {
+               do {
+                       idle_reg = SIS_READ(0x85cc);
+               } while ( !time_after_eq(jiffies, end) &&
+                         ((idle_reg & 0x80000000) != 0x80000000));
+       }
+
+       if (time_after_eq(jiffies, end)) {
+               DRM_ERROR("Graphics engine idle timeout. "
+                         "Disabling idle check\n");
+               dev_priv->idle_fault = 1;
+       }
+
+       /*
+        * The caller never sees an error code. It gets trapped
+        * in libdrm.
+        */
+
+       return 0;
+}
+
+
 void sis_lastclose(struct drm_device *dev)
 {
        drm_sis_private_t *dev_priv = dev->dev_private;
@@ -235,8 +308,9 @@ void sis_lastclose(struct drm_device *dev)
 
        mutex_lock(&dev->struct_mutex);
        drm_sman_cleanup(&dev_priv->sman);
-       dev_priv->vram_initialized = FALSE;
-       dev_priv->agp_initialized = FALSE;
+       dev_priv->vram_initialized = 0;
+       dev_priv->agp_initialized = 0;
+       dev_priv->mmio = NULL;
        mutex_unlock(&dev->struct_mutex);
 }