drm/radeon: fixes for r6xx/r7xx gfx init
[safe/jmp/linux-2.6] / drivers / gpu / drm / radeon / radeon_kms.c
index 937a2f1..3c5002e 100644 (file)
 #include "radeon.h"
 #include "radeon_drm.h"
 
+int radeon_driver_unload_kms(struct drm_device *dev)
+{
+       struct radeon_device *rdev = dev->dev_private;
+
+       if (rdev == NULL)
+               return 0;
+       radeon_modeset_fini(rdev);
+       radeon_device_fini(rdev);
+       kfree(rdev);
+       dev->dev_private = NULL;
+       return 0;
+}
 
-/*
- * Driver load/unload
- */
 int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags)
 {
        struct radeon_device *rdev;
@@ -54,23 +63,28 @@ int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags)
                flags |= RADEON_IS_PCI;
        }
 
+       /* radeon_device_init should report only fatal error
+        * like memory allocation failure or iomapping failure,
+        * or memory manager initialization failure, it must
+        * properly initialize the GPU MC controller and permit
+        * VRAM allocation
+        */
        r = radeon_device_init(rdev, dev, dev->pdev, flags);
        if (r) {
-               DRM_ERROR("Failed to initialize radeon, disabling IOCTL\n");
-               radeon_device_fini(rdev);
-               return r;
+               dev_err(&dev->pdev->dev, "Fatal error during GPU init\n");
+               goto out;
        }
-       return 0;
-}
-
-int radeon_driver_unload_kms(struct drm_device *dev)
-{
-       struct radeon_device *rdev = dev->dev_private;
-
-       radeon_device_fini(rdev);
-       kfree(rdev);
-       dev->dev_private = NULL;
-       return 0;
+       /* Again modeset_init should fail only on fatal error
+        * otherwise it should provide enough functionalities
+        * for shadowfb to run
+        */
+       r = radeon_modeset_init(rdev);
+       if (r)
+               dev_err(&dev->pdev->dev, "Fatal error during modeset init\n");
+out:
+       if (r)
+               radeon_driver_unload_kms(dev);
+       return r;
 }
 
 
@@ -93,6 +107,12 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
        case RADEON_INFO_NUM_GB_PIPES:
                value = rdev->num_gb_pipes;
                break;
+       case RADEON_INFO_NUM_Z_PIPES:
+               value = rdev->num_z_pipes;
+               break;
+       case RADEON_INFO_ACCEL_WORKING:
+               value = rdev->accel_working;
+               break;
        default:
                DRM_DEBUG("Invalid request %d\n", info->request);
                return -EINVAL;
@@ -139,68 +159,42 @@ void radeon_driver_preclose_kms(struct drm_device *dev,
  */
 u32 radeon_get_vblank_counter_kms(struct drm_device *dev, int crtc)
 {
-       /* FIXME: implement */
-       return 0;
-}
+       struct radeon_device *rdev = dev->dev_private;
 
-int radeon_enable_vblank_kms(struct drm_device *dev, int crtc)
-{
-       /* FIXME: implement */
-       return 0;
-}
+       if (crtc < 0 || crtc > 1) {
+               DRM_ERROR("Invalid crtc %d\n", crtc);
+               return -EINVAL;
+       }
 
-void radeon_disable_vblank_kms(struct drm_device *dev, int crtc)
-{
-       /* FIXME: implement */
+       return radeon_get_vblank_counter(rdev, crtc);
 }
 
-
-/*
- * For multiple master (like multiple X).
- */
-struct drm_radeon_master_private {
-       drm_local_map_t *sarea;
-       drm_radeon_sarea_t *sarea_priv;
-};
-
-int radeon_master_create_kms(struct drm_device *dev, struct drm_master *master)
+int radeon_enable_vblank_kms(struct drm_device *dev, int crtc)
 {
-       struct drm_radeon_master_private *master_priv;
-       unsigned long sareapage;
-       int ret;
+       struct radeon_device *rdev = dev->dev_private;
 
-       master_priv = kzalloc(sizeof(*master_priv), GFP_KERNEL);
-       if (master_priv == NULL) {
-               return -ENOMEM;
-       }
-       /* prebuild the SAREA */
-       sareapage = max_t(unsigned long, SAREA_MAX, PAGE_SIZE);
-       ret = drm_addmap(dev, 0, sareapage, _DRM_SHM,
-                        _DRM_CONTAINS_LOCK,
-                        &master_priv->sarea);
-       if (ret) {
-               DRM_ERROR("SAREA setup failed\n");
-               return ret;
+       if (crtc < 0 || crtc > 1) {
+               DRM_ERROR("Invalid crtc %d\n", crtc);
+               return -EINVAL;
        }
-       master_priv->sarea_priv = master_priv->sarea->handle + sizeof(struct drm_sarea);
-       master_priv->sarea_priv->pfCurrentPage = 0;
-       master->driver_priv = master_priv;
-       return 0;
+
+       rdev->irq.crtc_vblank_int[crtc] = true;
+
+       return radeon_irq_set(rdev);
 }
 
-void radeon_master_destroy_kms(struct drm_device *dev,
-                              struct drm_master *master)
+void radeon_disable_vblank_kms(struct drm_device *dev, int crtc)
 {
-       struct drm_radeon_master_private *master_priv = master->driver_priv;
+       struct radeon_device *rdev = dev->dev_private;
 
-       if (master_priv == NULL) {
+       if (crtc < 0 || crtc > 1) {
+               DRM_ERROR("Invalid crtc %d\n", crtc);
                return;
        }
-       if (master_priv->sarea) {
-               drm_rmmap_locked(dev, master_priv->sarea);
-       }
-       kfree(master_priv);
-       master->driver_priv = NULL;
+
+       rdev->irq.crtc_vblank_int[crtc] = false;
+
+       radeon_irq_set(rdev);
 }
 
 
@@ -282,16 +276,17 @@ struct drm_ioctl_desc radeon_ioctls_kms[] = {
        DRM_IOCTL_DEF(DRM_RADEON_SURF_ALLOC, radeon_surface_alloc_kms, DRM_AUTH),
        DRM_IOCTL_DEF(DRM_RADEON_SURF_FREE, radeon_surface_free_kms, DRM_AUTH),
        /* KMS */
-       DRM_IOCTL_DEF(DRM_RADEON_GEM_INFO, radeon_gem_info_ioctl, DRM_AUTH),
-       DRM_IOCTL_DEF(DRM_RADEON_GEM_CREATE, radeon_gem_create_ioctl, DRM_AUTH),
-       DRM_IOCTL_DEF(DRM_RADEON_GEM_MMAP, radeon_gem_mmap_ioctl, DRM_AUTH),
-       DRM_IOCTL_DEF(DRM_RADEON_GEM_SET_DOMAIN, radeon_gem_set_domain_ioctl, DRM_AUTH),
-       DRM_IOCTL_DEF(DRM_RADEON_GEM_PREAD, radeon_gem_pread_ioctl, DRM_AUTH),
-       DRM_IOCTL_DEF(DRM_RADEON_GEM_PWRITE, radeon_gem_pwrite_ioctl, DRM_AUTH),
-       DRM_IOCTL_DEF(DRM_RADEON_GEM_WAIT_IDLE, radeon_gem_wait_idle_ioctl, DRM_AUTH),
-       DRM_IOCTL_DEF(DRM_RADEON_CS, radeon_cs_ioctl, DRM_AUTH),
-       DRM_IOCTL_DEF(DRM_RADEON_INFO, radeon_info_ioctl, DRM_AUTH),
-       DRM_IOCTL_DEF(DRM_RADEON_GEM_SET_TILING, radeon_gem_set_tiling_ioctl, DRM_AUTH),
-       DRM_IOCTL_DEF(DRM_RADEON_GEM_GET_TILING, radeon_gem_get_tiling_ioctl, DRM_AUTH),
+       DRM_IOCTL_DEF(DRM_RADEON_GEM_INFO, radeon_gem_info_ioctl, DRM_AUTH|DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_RADEON_GEM_CREATE, radeon_gem_create_ioctl, DRM_AUTH|DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_RADEON_GEM_MMAP, radeon_gem_mmap_ioctl, DRM_AUTH|DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_RADEON_GEM_SET_DOMAIN, radeon_gem_set_domain_ioctl, DRM_AUTH|DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_RADEON_GEM_PREAD, radeon_gem_pread_ioctl, DRM_AUTH|DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_RADEON_GEM_PWRITE, radeon_gem_pwrite_ioctl, DRM_AUTH|DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_RADEON_GEM_WAIT_IDLE, radeon_gem_wait_idle_ioctl, DRM_AUTH|DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_RADEON_CS, radeon_cs_ioctl, DRM_AUTH|DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_RADEON_INFO, radeon_info_ioctl, DRM_AUTH|DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_RADEON_GEM_SET_TILING, radeon_gem_set_tiling_ioctl, DRM_AUTH|DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_RADEON_GEM_GET_TILING, radeon_gem_get_tiling_ioctl, DRM_AUTH|DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_RADEON_GEM_BUSY, radeon_gem_busy_ioctl, DRM_AUTH|DRM_UNLOCKED),
 };
 int radeon_max_kms_ioctl = DRM_ARRAY_SIZE(radeon_ioctls_kms);