drm/nv50: implement global channel address space on new VM code
[cascardo/linux.git] / drivers / gpu / drm / nouveau / nouveau_state.c
index c5f29f0..e0811f9 100644 (file)
@@ -53,10 +53,10 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->instmem.takedown        = nv04_instmem_takedown;
                engine->instmem.suspend         = nv04_instmem_suspend;
                engine->instmem.resume          = nv04_instmem_resume;
-               engine->instmem.populate        = nv04_instmem_populate;
-               engine->instmem.clear           = nv04_instmem_clear;
-               engine->instmem.bind            = nv04_instmem_bind;
-               engine->instmem.unbind          = nv04_instmem_unbind;
+               engine->instmem.get             = nv04_instmem_get;
+               engine->instmem.put             = nv04_instmem_put;
+               engine->instmem.map             = nv04_instmem_map;
+               engine->instmem.unmap           = nv04_instmem_unmap;
                engine->instmem.flush           = nv04_instmem_flush;
                engine->mc.init                 = nv04_mc_init;
                engine->mc.takedown             = nv04_mc_takedown;
@@ -75,7 +75,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->graph.unload_context    = nv04_graph_unload_context;
                engine->fifo.channels           = 16;
                engine->fifo.init               = nv04_fifo_init;
-               engine->fifo.takedown           = nouveau_stub_takedown;
+               engine->fifo.takedown           = nv04_fifo_fini;
                engine->fifo.disable            = nv04_fifo_disable;
                engine->fifo.enable             = nv04_fifo_enable;
                engine->fifo.reassign           = nv04_fifo_reassign;
@@ -106,10 +106,10 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->instmem.takedown        = nv04_instmem_takedown;
                engine->instmem.suspend         = nv04_instmem_suspend;
                engine->instmem.resume          = nv04_instmem_resume;
-               engine->instmem.populate        = nv04_instmem_populate;
-               engine->instmem.clear           = nv04_instmem_clear;
-               engine->instmem.bind            = nv04_instmem_bind;
-               engine->instmem.unbind          = nv04_instmem_unbind;
+               engine->instmem.get             = nv04_instmem_get;
+               engine->instmem.put             = nv04_instmem_put;
+               engine->instmem.map             = nv04_instmem_map;
+               engine->instmem.unmap           = nv04_instmem_unmap;
                engine->instmem.flush           = nv04_instmem_flush;
                engine->mc.init                 = nv04_mc_init;
                engine->mc.takedown             = nv04_mc_takedown;
@@ -118,7 +118,9 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->timer.takedown          = nv04_timer_takedown;
                engine->fb.init                 = nv10_fb_init;
                engine->fb.takedown             = nv10_fb_takedown;
-               engine->fb.set_region_tiling    = nv10_fb_set_region_tiling;
+               engine->fb.init_tile_region     = nv10_fb_init_tile_region;
+               engine->fb.set_tile_region      = nv10_fb_set_tile_region;
+               engine->fb.free_tile_region     = nv10_fb_free_tile_region;
                engine->graph.init              = nv10_graph_init;
                engine->graph.takedown          = nv10_graph_takedown;
                engine->graph.channel           = nv10_graph_channel;
@@ -127,10 +129,10 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->graph.fifo_access       = nv04_graph_fifo_access;
                engine->graph.load_context      = nv10_graph_load_context;
                engine->graph.unload_context    = nv10_graph_unload_context;
-               engine->graph.set_region_tiling = nv10_graph_set_region_tiling;
+               engine->graph.set_tile_region   = nv10_graph_set_tile_region;
                engine->fifo.channels           = 32;
                engine->fifo.init               = nv10_fifo_init;
-               engine->fifo.takedown           = nouveau_stub_takedown;
+               engine->fifo.takedown           = nv04_fifo_fini;
                engine->fifo.disable            = nv04_fifo_disable;
                engine->fifo.enable             = nv04_fifo_enable;
                engine->fifo.reassign           = nv04_fifo_reassign;
@@ -161,10 +163,10 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->instmem.takedown        = nv04_instmem_takedown;
                engine->instmem.suspend         = nv04_instmem_suspend;
                engine->instmem.resume          = nv04_instmem_resume;
-               engine->instmem.populate        = nv04_instmem_populate;
-               engine->instmem.clear           = nv04_instmem_clear;
-               engine->instmem.bind            = nv04_instmem_bind;
-               engine->instmem.unbind          = nv04_instmem_unbind;
+               engine->instmem.get             = nv04_instmem_get;
+               engine->instmem.put             = nv04_instmem_put;
+               engine->instmem.map             = nv04_instmem_map;
+               engine->instmem.unmap           = nv04_instmem_unmap;
                engine->instmem.flush           = nv04_instmem_flush;
                engine->mc.init                 = nv04_mc_init;
                engine->mc.takedown             = nv04_mc_takedown;
@@ -173,7 +175,9 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->timer.takedown          = nv04_timer_takedown;
                engine->fb.init                 = nv10_fb_init;
                engine->fb.takedown             = nv10_fb_takedown;
-               engine->fb.set_region_tiling    = nv10_fb_set_region_tiling;
+               engine->fb.init_tile_region     = nv10_fb_init_tile_region;
+               engine->fb.set_tile_region      = nv10_fb_set_tile_region;
+               engine->fb.free_tile_region     = nv10_fb_free_tile_region;
                engine->graph.init              = nv20_graph_init;
                engine->graph.takedown          = nv20_graph_takedown;
                engine->graph.channel           = nv10_graph_channel;
@@ -182,10 +186,10 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->graph.fifo_access       = nv04_graph_fifo_access;
                engine->graph.load_context      = nv20_graph_load_context;
                engine->graph.unload_context    = nv20_graph_unload_context;
-               engine->graph.set_region_tiling = nv20_graph_set_region_tiling;
+               engine->graph.set_tile_region   = nv20_graph_set_tile_region;
                engine->fifo.channels           = 32;
                engine->fifo.init               = nv10_fifo_init;
-               engine->fifo.takedown           = nouveau_stub_takedown;
+               engine->fifo.takedown           = nv04_fifo_fini;
                engine->fifo.disable            = nv04_fifo_disable;
                engine->fifo.enable             = nv04_fifo_enable;
                engine->fifo.reassign           = nv04_fifo_reassign;
@@ -216,10 +220,10 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->instmem.takedown        = nv04_instmem_takedown;
                engine->instmem.suspend         = nv04_instmem_suspend;
                engine->instmem.resume          = nv04_instmem_resume;
-               engine->instmem.populate        = nv04_instmem_populate;
-               engine->instmem.clear           = nv04_instmem_clear;
-               engine->instmem.bind            = nv04_instmem_bind;
-               engine->instmem.unbind          = nv04_instmem_unbind;
+               engine->instmem.get             = nv04_instmem_get;
+               engine->instmem.put             = nv04_instmem_put;
+               engine->instmem.map             = nv04_instmem_map;
+               engine->instmem.unmap           = nv04_instmem_unmap;
                engine->instmem.flush           = nv04_instmem_flush;
                engine->mc.init                 = nv04_mc_init;
                engine->mc.takedown             = nv04_mc_takedown;
@@ -228,7 +232,9 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->timer.takedown          = nv04_timer_takedown;
                engine->fb.init                 = nv30_fb_init;
                engine->fb.takedown             = nv30_fb_takedown;
-               engine->fb.set_region_tiling    = nv10_fb_set_region_tiling;
+               engine->fb.init_tile_region     = nv30_fb_init_tile_region;
+               engine->fb.set_tile_region      = nv10_fb_set_tile_region;
+               engine->fb.free_tile_region     = nv30_fb_free_tile_region;
                engine->graph.init              = nv30_graph_init;
                engine->graph.takedown          = nv20_graph_takedown;
                engine->graph.fifo_access       = nv04_graph_fifo_access;
@@ -237,10 +243,10 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->graph.destroy_context   = nv20_graph_destroy_context;
                engine->graph.load_context      = nv20_graph_load_context;
                engine->graph.unload_context    = nv20_graph_unload_context;
-               engine->graph.set_region_tiling = nv20_graph_set_region_tiling;
+               engine->graph.set_tile_region   = nv20_graph_set_tile_region;
                engine->fifo.channels           = 32;
                engine->fifo.init               = nv10_fifo_init;
-               engine->fifo.takedown           = nouveau_stub_takedown;
+               engine->fifo.takedown           = nv04_fifo_fini;
                engine->fifo.disable            = nv04_fifo_disable;
                engine->fifo.enable             = nv04_fifo_enable;
                engine->fifo.reassign           = nv04_fifo_reassign;
@@ -274,10 +280,10 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->instmem.takedown        = nv04_instmem_takedown;
                engine->instmem.suspend         = nv04_instmem_suspend;
                engine->instmem.resume          = nv04_instmem_resume;
-               engine->instmem.populate        = nv04_instmem_populate;
-               engine->instmem.clear           = nv04_instmem_clear;
-               engine->instmem.bind            = nv04_instmem_bind;
-               engine->instmem.unbind          = nv04_instmem_unbind;
+               engine->instmem.get             = nv04_instmem_get;
+               engine->instmem.put             = nv04_instmem_put;
+               engine->instmem.map             = nv04_instmem_map;
+               engine->instmem.unmap           = nv04_instmem_unmap;
                engine->instmem.flush           = nv04_instmem_flush;
                engine->mc.init                 = nv40_mc_init;
                engine->mc.takedown             = nv40_mc_takedown;
@@ -286,7 +292,9 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->timer.takedown          = nv04_timer_takedown;
                engine->fb.init                 = nv40_fb_init;
                engine->fb.takedown             = nv40_fb_takedown;
-               engine->fb.set_region_tiling    = nv40_fb_set_region_tiling;
+               engine->fb.init_tile_region     = nv30_fb_init_tile_region;
+               engine->fb.set_tile_region      = nv40_fb_set_tile_region;
+               engine->fb.free_tile_region     = nv30_fb_free_tile_region;
                engine->graph.init              = nv40_graph_init;
                engine->graph.takedown          = nv40_graph_takedown;
                engine->graph.fifo_access       = nv04_graph_fifo_access;
@@ -295,10 +303,10 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->graph.destroy_context   = nv40_graph_destroy_context;
                engine->graph.load_context      = nv40_graph_load_context;
                engine->graph.unload_context    = nv40_graph_unload_context;
-               engine->graph.set_region_tiling = nv40_graph_set_region_tiling;
+               engine->graph.set_tile_region   = nv40_graph_set_tile_region;
                engine->fifo.channels           = 32;
                engine->fifo.init               = nv40_fifo_init;
-               engine->fifo.takedown           = nouveau_stub_takedown;
+               engine->fifo.takedown           = nv04_fifo_fini;
                engine->fifo.disable            = nv04_fifo_disable;
                engine->fifo.enable             = nv04_fifo_enable;
                engine->fifo.reassign           = nv04_fifo_reassign;
@@ -335,10 +343,10 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->instmem.takedown        = nv50_instmem_takedown;
                engine->instmem.suspend         = nv50_instmem_suspend;
                engine->instmem.resume          = nv50_instmem_resume;
-               engine->instmem.populate        = nv50_instmem_populate;
-               engine->instmem.clear           = nv50_instmem_clear;
-               engine->instmem.bind            = nv50_instmem_bind;
-               engine->instmem.unbind          = nv50_instmem_unbind;
+               engine->instmem.get             = nv50_instmem_get;
+               engine->instmem.put             = nv50_instmem_put;
+               engine->instmem.map             = nv50_instmem_map;
+               engine->instmem.unmap           = nv50_instmem_unmap;
                if (dev_priv->chipset == 0x50)
                        engine->instmem.flush   = nv50_instmem_flush;
                else
@@ -385,9 +393,11 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->display.init            = nv50_display_init;
                engine->display.destroy         = nv50_display_destroy;
                engine->gpio.init               = nv50_gpio_init;
-               engine->gpio.takedown           = nouveau_stub_takedown;
+               engine->gpio.takedown           = nv50_gpio_fini;
                engine->gpio.get                = nv50_gpio_get;
                engine->gpio.set                = nv50_gpio_set;
+               engine->gpio.irq_register       = nv50_gpio_irq_register;
+               engine->gpio.irq_unregister     = nv50_gpio_irq_unregister;
                engine->gpio.irq_enable         = nv50_gpio_irq_enable;
                switch (dev_priv->chipset) {
                case 0x84:
@@ -427,6 +437,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                        engine->crypt.takedown  = nv84_crypt_fini;
                        engine->crypt.create_context = nv84_crypt_create_context;
                        engine->crypt.destroy_context = nv84_crypt_destroy_context;
+                       engine->crypt.tlb_flush = nv84_crypt_tlb_flush;
                        break;
                default:
                        engine->crypt.init      = nouveau_stub_init;
@@ -439,10 +450,10 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->instmem.takedown        = nvc0_instmem_takedown;
                engine->instmem.suspend         = nvc0_instmem_suspend;
                engine->instmem.resume          = nvc0_instmem_resume;
-               engine->instmem.populate        = nvc0_instmem_populate;
-               engine->instmem.clear           = nvc0_instmem_clear;
-               engine->instmem.bind            = nvc0_instmem_bind;
-               engine->instmem.unbind          = nvc0_instmem_unbind;
+               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->mc.init                 = nv50_mc_init;
                engine->mc.takedown             = nv50_mc_takedown;
@@ -479,6 +490,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->gpio.takedown           = nouveau_stub_takedown;
                engine->gpio.get                = nv50_gpio_get;
                engine->gpio.set                = nv50_gpio_set;
+               engine->gpio.irq_register       = nv50_gpio_irq_register;
+               engine->gpio.irq_unregister     = nv50_gpio_irq_unregister;
                engine->gpio.irq_enable         = nv50_gpio_irq_enable;
                engine->crypt.init              = nouveau_stub_init;
                engine->crypt.takedown          = nouveau_stub_takedown;
@@ -523,7 +536,7 @@ nouveau_card_init_channel(struct drm_device *dev)
 
        ret = nouveau_gpuobj_dma_new(dev_priv->channel, NV_CLASS_DMA_IN_MEMORY,
                                     0, dev_priv->vram_size,
-                                    NV_DMA_ACCESS_RW, NV_DMA_TARGET_VIDMEM,
+                                    NV_MEM_ACCESS_RW, NV_MEM_TARGET_VRAM,
                                     &gpuobj);
        if (ret)
                goto out_err;
@@ -533,9 +546,10 @@ nouveau_card_init_channel(struct drm_device *dev)
        if (ret)
                goto out_err;
 
-       ret = nouveau_gpuobj_gart_dma_new(dev_priv->channel, 0,
-                                         dev_priv->gart_info.aper_size,
-                                         NV_DMA_ACCESS_RW, &gpuobj, NULL);
+       ret = nouveau_gpuobj_dma_new(dev_priv->channel, NV_CLASS_DMA_IN_MEMORY,
+                                    0, dev_priv->gart_info.aper_size,
+                                    NV_MEM_ACCESS_RW, NV_MEM_TARGET_GART,
+                                    &gpuobj);
        if (ret)
                goto out_err;
 
@@ -596,6 +610,7 @@ nouveau_card_init(struct drm_device *dev)
                goto out;
        engine = &dev_priv->engine;
        spin_lock_init(&dev_priv->channels.lock);
+       spin_lock_init(&dev_priv->tile.lock);
        spin_lock_init(&dev_priv->context_switch_lock);
 
        /* Make the CRTCs and I2C buses accessible */
@@ -669,13 +684,13 @@ nouveau_card_init(struct drm_device *dev)
        if (ret)
                goto out_fifo;
 
-       ret = nouveau_irq_init(dev);
+       ret = drm_vblank_init(dev, nv_two_heads(dev) ? 2 : 1);
        if (ret)
-               goto out_display;
+               goto out_vblank;
 
-       ret = drm_vblank_init(dev, 0);
+       ret = nouveau_irq_init(dev);
        if (ret)
-               goto out_irq;
+               goto out_vblank;
 
        /* what about PVIDEO/PCRTC/PRAMDAC etc? */
 
@@ -701,7 +716,8 @@ out_fence:
        nouveau_fence_fini(dev);
 out_irq:
        nouveau_irq_fini(dev);
-out_display:
+out_vblank:
+       drm_vblank_cleanup(dev);
        engine->display.destroy(dev);
 out_fifo:
        if (!nouveau_noaccel)
@@ -772,6 +788,7 @@ static void nouveau_card_takedown(struct drm_device *dev)
        nouveau_mem_vram_fini(dev);
 
        nouveau_irq_fini(dev);
+       drm_vblank_cleanup(dev);
 
        nouveau_pm_fini(dev);
        nouveau_bios_takedown(dev);
@@ -1058,21 +1075,6 @@ int nouveau_ioctl_getparam(struct drm_device *dev, void *data,
                else
                        getparam->value = NV_PCI;
                break;
-       case NOUVEAU_GETPARAM_FB_PHYSICAL:
-               getparam->value = dev_priv->fb_phys;
-               break;
-       case NOUVEAU_GETPARAM_AGP_PHYSICAL:
-               getparam->value = dev_priv->gart_info.aper_base;
-               break;
-       case NOUVEAU_GETPARAM_PCI_PHYSICAL:
-               if (dev->sg) {
-                       getparam->value = (unsigned long)dev->sg->virtual;
-               } else {
-                       NV_ERROR(dev, "Requested PCIGART address, "
-                                       "while no PCIGART was created\n");
-                       return -EINVAL;
-               }
-               break;
        case NOUVEAU_GETPARAM_FB_SIZE:
                getparam->value = dev_priv->fb_available_size;
                break;
@@ -1080,7 +1082,7 @@ int nouveau_ioctl_getparam(struct drm_device *dev, void *data,
                getparam->value = dev_priv->gart_info.aper_size;
                break;
        case NOUVEAU_GETPARAM_VM_VRAM_BASE:
-               getparam->value = dev_priv->vm_vram_base;
+               getparam->value = 0; /* deprecated */
                break;
        case NOUVEAU_GETPARAM_PTIMER_TIME:
                getparam->value = dev_priv->engine.timer.read(dev);
@@ -1088,6 +1090,9 @@ int nouveau_ioctl_getparam(struct drm_device *dev, void *data,
        case NOUVEAU_GETPARAM_HAS_BO_USAGE:
                getparam->value = 1;
                break;
+       case NOUVEAU_GETPARAM_HAS_PAGEFLIP:
+               getparam->value = (dev_priv->card_type < NV_50);
+               break;
        case NOUVEAU_GETPARAM_GRAPH_UNITS:
                /* NV40 and NV50 versions are quite different, but register
                 * address is the same. User is supposed to know the card
@@ -1121,8 +1126,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;
@@ -1136,6 +1142,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)
 {