drm/nouveau: add delayed switch complete callback.
[deliverable/linux.git] / drivers / gpu / drm / nouveau / nouveau_state.c
index e779e93204538129ca10656909ef3f165fd501ad..db4b410f4a8cbd19d90f4a5bab308e5244dc9943 100644 (file)
@@ -100,6 +100,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->pm.clock_set            = nv04_pm_clock_set;
                engine->crypt.init              = nouveau_stub_init;
                engine->crypt.takedown          = nouveau_stub_takedown;
+               engine->vram.init               = nouveau_mem_detect;
+               engine->vram.flags_valid        = nouveau_mem_flags_valid;
                break;
        case 0x10:
                engine->instmem.init            = nv04_instmem_init;
@@ -157,6 +159,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->pm.clock_set            = nv04_pm_clock_set;
                engine->crypt.init              = nouveau_stub_init;
                engine->crypt.takedown          = nouveau_stub_takedown;
+               engine->vram.init               = nouveau_mem_detect;
+               engine->vram.flags_valid        = nouveau_mem_flags_valid;
                break;
        case 0x20:
                engine->instmem.init            = nv04_instmem_init;
@@ -214,6 +218,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->pm.clock_set            = nv04_pm_clock_set;
                engine->crypt.init              = nouveau_stub_init;
                engine->crypt.takedown          = nouveau_stub_takedown;
+               engine->vram.init               = nouveau_mem_detect;
+               engine->vram.flags_valid        = nouveau_mem_flags_valid;
                break;
        case 0x30:
                engine->instmem.init            = nv04_instmem_init;
@@ -273,6 +279,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->pm.voltage_set          = nouveau_voltage_gpio_set;
                engine->crypt.init              = nouveau_stub_init;
                engine->crypt.takedown          = nouveau_stub_takedown;
+               engine->vram.init               = nouveau_mem_detect;
+               engine->vram.flags_valid        = nouveau_mem_flags_valid;
                break;
        case 0x40:
        case 0x60:
@@ -334,6 +342,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->pm.temp_get             = nv40_temp_get;
                engine->crypt.init              = nouveau_stub_init;
                engine->crypt.takedown          = nouveau_stub_takedown;
+               engine->vram.init               = nouveau_mem_detect;
+               engine->vram.flags_valid        = nouveau_mem_flags_valid;
                break;
        case 0x50:
        case 0x80: /* gotta love NVIDIA's consistency.. */
@@ -444,17 +454,21 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                        engine->crypt.takedown  = nouveau_stub_takedown;
                        break;
                }
+               engine->vram.init               = nv50_vram_init;
+               engine->vram.get                = nv50_vram_new;
+               engine->vram.put                = nv50_vram_del;
+               engine->vram.flags_valid        = nv50_vram_flags_valid;
                break;
        case 0xC0:
                engine->instmem.init            = nvc0_instmem_init;
                engine->instmem.takedown        = nvc0_instmem_takedown;
                engine->instmem.suspend         = nvc0_instmem_suspend;
                engine->instmem.resume          = nvc0_instmem_resume;
-               engine->instmem.get             = nvc0_instmem_get;
-               engine->instmem.put             = nvc0_instmem_put;
-               engine->instmem.map             = nvc0_instmem_map;
-               engine->instmem.unmap           = nvc0_instmem_unmap;
-               engine->instmem.flush           = nvc0_instmem_flush;
+               engine->instmem.get             = nv50_instmem_get;
+               engine->instmem.put             = nv50_instmem_put;
+               engine->instmem.map             = nv50_instmem_map;
+               engine->instmem.unmap           = nv50_instmem_unmap;
+               engine->instmem.flush           = nv84_instmem_flush;
                engine->mc.init                 = nv50_mc_init;
                engine->mc.takedown             = nv50_mc_takedown;
                engine->timer.init              = nv04_timer_init;
@@ -495,6 +509,10 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->gpio.irq_enable         = nv50_gpio_irq_enable;
                engine->crypt.init              = nouveau_stub_init;
                engine->crypt.takedown          = nouveau_stub_takedown;
+               engine->vram.init               = nvc0_vram_init;
+               engine->vram.get                = nvc0_vram_new;
+               engine->vram.put                = nv50_vram_del;
+               engine->vram.flags_valid        = nvc0_vram_flags_valid;
                break;
        default:
                NV_ERROR(dev, "NV%02x unsupported\n", dev_priv->chipset);
@@ -534,6 +552,10 @@ nouveau_card_init_channel(struct drm_device *dev)
        if (ret)
                return ret;
 
+       /* no dma objects on fermi... */
+       if (dev_priv->card_type >= NV_C0)
+               goto out_done;
+
        ret = nouveau_gpuobj_dma_new(dev_priv->channel, NV_CLASS_DMA_IN_MEMORY,
                                     0, dev_priv->vram_size,
                                     NV_MEM_ACCESS_RW, NV_MEM_TARGET_VRAM,
@@ -558,6 +580,7 @@ nouveau_card_init_channel(struct drm_device *dev)
        if (ret)
                goto out_err;
 
+out_done:
        mutex_unlock(&dev_priv->channel->mutex);
        return 0;
 
@@ -1031,6 +1054,7 @@ err_out:
 
 void nouveau_lastclose(struct drm_device *dev)
 {
+       vga_switcheroo_process_delayed_switch();
 }
 
 int nouveau_unload(struct drm_device *dev)
@@ -1126,8 +1150,9 @@ nouveau_ioctl_setparam(struct drm_device *dev, void *data,
 }
 
 /* Wait until (value(reg) & mask) == val, up until timeout has hit */
-bool nouveau_wait_until(struct drm_device *dev, uint64_t timeout,
-                       uint32_t reg, uint32_t mask, uint32_t val)
+bool
+nouveau_wait_eq(struct drm_device *dev, uint64_t timeout,
+               uint32_t reg, uint32_t mask, uint32_t val)
 {
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer;
@@ -1141,6 +1166,23 @@ bool nouveau_wait_until(struct drm_device *dev, uint64_t timeout,
        return false;
 }
 
+/* Wait until (value(reg) & mask) != val, up until timeout has hit */
+bool
+nouveau_wait_ne(struct drm_device *dev, uint64_t timeout,
+               uint32_t reg, uint32_t mask, uint32_t val)
+{
+       struct drm_nouveau_private *dev_priv = dev->dev_private;
+       struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer;
+       uint64_t start = ptimer->read(dev);
+
+       do {
+               if ((nv_rd32(dev, reg) & mask) != val)
+                       return true;
+       } while (ptimer->read(dev) - start < timeout);
+
+       return false;
+}
+
 /* Waits for PGRAPH to go completely idle */
 bool nouveau_wait_for_idle(struct drm_device *dev)
 {
This page took 0.028078 seconds and 5 git commands to generate.