return -ENOSPC;
        }
 
-       /* map fifo control registers */
-       chan->user = ioremap(nv_device_resource_start(device, bar) + addr +
-                            (chan->chid * size), size);
-       if (!chan->user)
-               return -EFAULT;
-
-       nvkm_event_send(&priv->cevent, 1, 0, NULL, 0);
-
+       chan->addr = nv_device_resource_start(device, bar) +
+                    addr + size * chan->chid;
        chan->size = size;
+       nvkm_event_send(&priv->cevent, 1, 0, NULL, 0);
        return 0;
 }
 
        struct nouveau_fifo *priv = (void *)nv_object(chan)->engine;
        unsigned long flags;
 
-       iounmap(chan->user);
+       if (chan->user)
+               iounmap(chan->user);
 
        spin_lock_irqsave(&priv->lock, flags);
        priv->channel[chan->chid] = NULL;
        nouveau_fifo_channel_destroy(chan);
 }
 
+int
+_nouveau_fifo_channel_map(struct nouveau_object *object, u64 *addr, u32 *size)
+{
+       struct nouveau_fifo_chan *chan = (void *)object;
+       *addr = chan->addr;
+       *size = chan->size;
+       return 0;
+}
+
 u32
 _nouveau_fifo_channel_rd32(struct nouveau_object *object, u64 addr)
 {
        struct nouveau_fifo_chan *chan = (void *)object;
+       if (unlikely(!chan->user)) {
+               chan->user = ioremap(chan->addr, chan->size);
+               if (WARN_ON_ONCE(chan->user == NULL))
+                       return 0;
+       }
        return ioread32_native(chan->user + addr);
 }
 
 _nouveau_fifo_channel_wr32(struct nouveau_object *object, u64 addr, u32 data)
 {
        struct nouveau_fifo_chan *chan = (void *)object;
+       if (unlikely(!chan->user)) {
+               chan->user = ioremap(chan->addr, chan->size);
+               if (WARN_ON_ONCE(chan->user == NULL))
+                       return;
+       }
        iowrite32_native(data, chan->user + addr);
 }
 
 
        .dtor = nv04_fifo_chan_dtor,
        .init = nv04_fifo_chan_init,
        .fini = nv04_fifo_chan_fini,
+       .map  = _nouveau_fifo_channel_map,
        .rd32 = _nouveau_fifo_channel_rd32,
        .wr32 = _nouveau_fifo_channel_wr32,
 };
 
        .dtor = nv04_fifo_chan_dtor,
        .init = nv04_fifo_chan_init,
        .fini = nv04_fifo_chan_fini,
+       .map  = _nouveau_fifo_channel_map,
        .rd32 = _nouveau_fifo_channel_rd32,
        .wr32 = _nouveau_fifo_channel_wr32,
 };
 
        .dtor = nv04_fifo_chan_dtor,
        .init = nv04_fifo_chan_init,
        .fini = nv04_fifo_chan_fini,
+       .map  = _nouveau_fifo_channel_map,
        .rd32 = _nouveau_fifo_channel_rd32,
        .wr32 = _nouveau_fifo_channel_wr32,
 };
 
        .dtor = nv04_fifo_chan_dtor,
        .init = nv04_fifo_chan_init,
        .fini = nv04_fifo_chan_fini,
+       .map  = _nouveau_fifo_channel_map,
        .rd32 = _nouveau_fifo_channel_rd32,
        .wr32 = _nouveau_fifo_channel_wr32,
 };
 
        .dtor = nv50_fifo_chan_dtor,
        .init = nv50_fifo_chan_init,
        .fini = nv50_fifo_chan_fini,
+       .map  = _nouveau_fifo_channel_map,
        .rd32 = _nouveau_fifo_channel_rd32,
        .wr32 = _nouveau_fifo_channel_wr32,
 };
        .dtor = nv50_fifo_chan_dtor,
        .init = nv50_fifo_chan_init,
        .fini = nv50_fifo_chan_fini,
+       .map  = _nouveau_fifo_channel_map,
        .rd32 = _nouveau_fifo_channel_rd32,
        .wr32 = _nouveau_fifo_channel_wr32,
 };
 
        .dtor = nv50_fifo_chan_dtor,
        .init = nv84_fifo_chan_init,
        .fini = nv50_fifo_chan_fini,
+       .map  = _nouveau_fifo_channel_map,
        .rd32 = _nouveau_fifo_channel_rd32,
        .wr32 = _nouveau_fifo_channel_wr32,
 };
        .dtor = nv50_fifo_chan_dtor,
        .init = nv84_fifo_chan_init,
        .fini = nv50_fifo_chan_fini,
+       .map  = _nouveau_fifo_channel_map,
        .rd32 = _nouveau_fifo_channel_rd32,
        .wr32 = _nouveau_fifo_channel_wr32,
 };
 
        .dtor = _nouveau_fifo_channel_dtor,
        .init = nvc0_fifo_chan_init,
        .fini = nvc0_fifo_chan_fini,
+       .map  = _nouveau_fifo_channel_map,
        .rd32 = _nouveau_fifo_channel_rd32,
        .wr32 = _nouveau_fifo_channel_wr32,
 };
 
        .dtor = _nouveau_fifo_channel_dtor,
        .init = nve0_fifo_chan_init,
        .fini = nve0_fifo_chan_fini,
+       .map  = _nouveau_fifo_channel_map,
        .rd32 = _nouveau_fifo_channel_rd32,
        .wr32 = _nouveau_fifo_channel_wr32,
 };
 
        struct nouveau_dmaobj *pushdma;
        struct nouveau_gpuobj *pushgpu;
        void __iomem *user;
+       u64 addr;
        u32 size;
        u16 chid;
        atomic_t refcnt; /* NV04_NVSW_SET_REF */
 #define _nouveau_fifo_channel_fini _nouveau_namedb_fini
 
 void _nouveau_fifo_channel_dtor(struct nouveau_object *);
+int  _nouveau_fifo_channel_map(struct nouveau_object *, u64 *, u32 *);
 u32  _nouveau_fifo_channel_rd32(struct nouveau_object *, u64);
 void _nouveau_fifo_channel_wr32(struct nouveau_object *, u64, u32);
 
 
        struct nv_dma_v0 args = {};
        int ret, i;
 
+       nvif_object_map(chan->object);
+
        /* allocate dma objects to cover all allowed vram, and gart */
        if (device->info.family < NV_DEVICE_INFO_V0_FERMI) {
                if (device->info.family >= NV_DEVICE_INFO_V0_TESLA) {