15e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs/* 25e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs * Copyright 2012 Red Hat Inc. 35e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs * 45e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs * Permission is hereby granted, free of charge, to any person obtaining a 55e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs * copy of this software and associated documentation files (the "Software"), 65e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs * to deal in the Software without restriction, including without limitation 75e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs * the rights to use, copy, modify, merge, publish, distribute, sublicense, 85e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs * and/or sell copies of the Software, and to permit persons to whom the 95e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs * Software is furnished to do so, subject to the following conditions: 105e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs * 115e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs * The above copyright notice and this permission notice shall be included in 125e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs * all copies or substantial portions of the Software. 135e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs * 145e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 155e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 165e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 175e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 185e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 195e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 205e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs * OTHER DEALINGS IN THE SOFTWARE. 215e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs * 225e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs * Authors: Ben Skeggs 235e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs */ 245e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs 25ebb945a94bba2ce8dff7b0942ff2b3f2a52a0a69Ben Skeggs#include "nouveau_drm.h" 26ebb945a94bba2ce8dff7b0942ff2b3f2a52a0a69Ben Skeggs#include "nouveau_dma.h" 275e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs#include "nouveau_fence.h" 285e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs 2977145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs#include "nv50_display.h" 3077145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 31a34caf78f26bda63869471cb3f46f354f4658758Ben Skeggsu64 32a34caf78f26bda63869471cb3f46f354f4658758Ben Skeggsnv84_fence_crtc(struct nouveau_channel *chan, int crtc) 33a34caf78f26bda63869471cb3f46f354f4658758Ben Skeggs{ 34a34caf78f26bda63869471cb3f46f354f4658758Ben Skeggs struct nv84_fence_chan *fctx = chan->fence; 35a34caf78f26bda63869471cb3f46f354f4658758Ben Skeggs return fctx->dispc_vma[crtc].offset; 36a34caf78f26bda63869471cb3f46f354f4658758Ben Skeggs} 375e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs 385e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggsstatic int 39bba9852feedf3d38f963278e07bdd3db622090b9Ben Skeggsnv84_fence_emit32(struct nouveau_channel *chan, u64 virtual, u32 sequence) 405e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs{ 41bba9852feedf3d38f963278e07bdd3db622090b9Ben Skeggs int ret = RING_SPACE(chan, 8); 425e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs if (ret == 0) { 435e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs BEGIN_NV04(chan, 0, NV11_SUBCHAN_DMA_SEMAPHORE, 1); 440ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs OUT_RING (chan, chan->vram.handle); 45e18c080fb8695d038f69c26c248f5ecbd9e8aa77Ben Skeggs BEGIN_NV04(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 5); 46bba9852feedf3d38f963278e07bdd3db622090b9Ben Skeggs OUT_RING (chan, upper_32_bits(virtual)); 47bba9852feedf3d38f963278e07bdd3db622090b9Ben Skeggs OUT_RING (chan, lower_32_bits(virtual)); 48bba9852feedf3d38f963278e07bdd3db622090b9Ben Skeggs OUT_RING (chan, sequence); 495e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs OUT_RING (chan, NV84_SUBCHAN_SEMAPHORE_TRIGGER_WRITE_LONG); 50e18c080fb8695d038f69c26c248f5ecbd9e8aa77Ben Skeggs OUT_RING (chan, 0x00000000); 515e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs FIRE_RING (chan); 525e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs } 535e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs return ret; 545e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs} 555e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs 565e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggsstatic int 57bba9852feedf3d38f963278e07bdd3db622090b9Ben Skeggsnv84_fence_sync32(struct nouveau_channel *chan, u64 virtual, u32 sequence) 585e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs{ 59bba9852feedf3d38f963278e07bdd3db622090b9Ben Skeggs int ret = RING_SPACE(chan, 7); 605e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs if (ret == 0) { 615e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs BEGIN_NV04(chan, 0, NV11_SUBCHAN_DMA_SEMAPHORE, 1); 620ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs OUT_RING (chan, chan->vram.handle); 635e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs BEGIN_NV04(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4); 64bba9852feedf3d38f963278e07bdd3db622090b9Ben Skeggs OUT_RING (chan, upper_32_bits(virtual)); 65bba9852feedf3d38f963278e07bdd3db622090b9Ben Skeggs OUT_RING (chan, lower_32_bits(virtual)); 66bba9852feedf3d38f963278e07bdd3db622090b9Ben Skeggs OUT_RING (chan, sequence); 675e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs OUT_RING (chan, NV84_SUBCHAN_SEMAPHORE_TRIGGER_ACQUIRE_GEQUAL); 685e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs FIRE_RING (chan); 695e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs } 705e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs return ret; 715e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs} 725e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs 73264ce192b3e7f45d0adb37bfbab2b01a3fbe6c30Ben Skeggsstatic int 74bba9852feedf3d38f963278e07bdd3db622090b9Ben Skeggsnv84_fence_emit(struct nouveau_fence *fence) 75bba9852feedf3d38f963278e07bdd3db622090b9Ben Skeggs{ 76bba9852feedf3d38f963278e07bdd3db622090b9Ben Skeggs struct nouveau_channel *chan = fence->channel; 77bba9852feedf3d38f963278e07bdd3db622090b9Ben Skeggs struct nv84_fence_chan *fctx = chan->fence; 78bbf8906b2cad17cf9530b06db7509d0e39b02d16Ben Skeggs u64 addr = chan->chid * 16; 79264ce192b3e7f45d0adb37bfbab2b01a3fbe6c30Ben Skeggs 80264ce192b3e7f45d0adb37bfbab2b01a3fbe6c30Ben Skeggs if (fence->sysmem) 81264ce192b3e7f45d0adb37bfbab2b01a3fbe6c30Ben Skeggs addr += fctx->vma_gart.offset; 82264ce192b3e7f45d0adb37bfbab2b01a3fbe6c30Ben Skeggs else 83264ce192b3e7f45d0adb37bfbab2b01a3fbe6c30Ben Skeggs addr += fctx->vma.offset; 84264ce192b3e7f45d0adb37bfbab2b01a3fbe6c30Ben Skeggs 8529ba89b2371d466ca68973525816cf10debc2655Maarten Lankhorst return fctx->base.emit32(chan, addr, fence->base.seqno); 86bba9852feedf3d38f963278e07bdd3db622090b9Ben Skeggs} 87bba9852feedf3d38f963278e07bdd3db622090b9Ben Skeggs 88264ce192b3e7f45d0adb37bfbab2b01a3fbe6c30Ben Skeggsstatic int 89bba9852feedf3d38f963278e07bdd3db622090b9Ben Skeggsnv84_fence_sync(struct nouveau_fence *fence, 90bba9852feedf3d38f963278e07bdd3db622090b9Ben Skeggs struct nouveau_channel *prev, struct nouveau_channel *chan) 91bba9852feedf3d38f963278e07bdd3db622090b9Ben Skeggs{ 92bba9852feedf3d38f963278e07bdd3db622090b9Ben Skeggs struct nv84_fence_chan *fctx = chan->fence; 93bbf8906b2cad17cf9530b06db7509d0e39b02d16Ben Skeggs u64 addr = prev->chid * 16; 94264ce192b3e7f45d0adb37bfbab2b01a3fbe6c30Ben Skeggs 95264ce192b3e7f45d0adb37bfbab2b01a3fbe6c30Ben Skeggs if (fence->sysmem) 96264ce192b3e7f45d0adb37bfbab2b01a3fbe6c30Ben Skeggs addr += fctx->vma_gart.offset; 97264ce192b3e7f45d0adb37bfbab2b01a3fbe6c30Ben Skeggs else 98264ce192b3e7f45d0adb37bfbab2b01a3fbe6c30Ben Skeggs addr += fctx->vma.offset; 99264ce192b3e7f45d0adb37bfbab2b01a3fbe6c30Ben Skeggs 10029ba89b2371d466ca68973525816cf10debc2655Maarten Lankhorst return fctx->base.sync32(chan, addr, fence->base.seqno); 101bba9852feedf3d38f963278e07bdd3db622090b9Ben Skeggs} 102bba9852feedf3d38f963278e07bdd3db622090b9Ben Skeggs 103264ce192b3e7f45d0adb37bfbab2b01a3fbe6c30Ben Skeggsstatic u32 1045e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggsnv84_fence_read(struct nouveau_channel *chan) 1055e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs{ 106ebb945a94bba2ce8dff7b0942ff2b3f2a52a0a69Ben Skeggs struct nv84_fence_priv *priv = chan->drm->fence; 107bbf8906b2cad17cf9530b06db7509d0e39b02d16Ben Skeggs return nouveau_bo_rd32(priv->bo, chan->chid * 16/4); 1085e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs} 1095e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs 110264ce192b3e7f45d0adb37bfbab2b01a3fbe6c30Ben Skeggsstatic void 111e193b1d42c390bf1bff7fa02a5a1202b98e75601Ben Skeggsnv84_fence_context_del(struct nouveau_channel *chan) 1125e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs{ 113a34caf78f26bda63869471cb3f46f354f4658758Ben Skeggs struct drm_device *dev = chan->drm->dev; 114a34caf78f26bda63869471cb3f46f354f4658758Ben Skeggs struct nv84_fence_priv *priv = chan->drm->fence; 115e193b1d42c390bf1bff7fa02a5a1202b98e75601Ben Skeggs struct nv84_fence_chan *fctx = chan->fence; 116a34caf78f26bda63869471cb3f46f354f4658758Ben Skeggs int i; 117a34caf78f26bda63869471cb3f46f354f4658758Ben Skeggs 118a34caf78f26bda63869471cb3f46f354f4658758Ben Skeggs for (i = 0; i < dev->mode_config.num_crtc; i++) { 119a34caf78f26bda63869471cb3f46f354f4658758Ben Skeggs struct nouveau_bo *bo = nv50_display_crtc_sema(dev, i); 120a34caf78f26bda63869471cb3f46f354f4658758Ben Skeggs nouveau_bo_vma_del(bo, &fctx->dispc_vma[i]); 121a34caf78f26bda63869471cb3f46f354f4658758Ben Skeggs } 122a34caf78f26bda63869471cb3f46f354f4658758Ben Skeggs 1231dadba87cba20989c5a5a56f2a86fe6672e37c30Maarten Lankhorst nouveau_bo_wr32(priv->bo, chan->chid * 16 / 4, fctx->base.sequence); 124264ce192b3e7f45d0adb37bfbab2b01a3fbe6c30Ben Skeggs nouveau_bo_vma_del(priv->bo, &fctx->vma_gart); 125a34caf78f26bda63869471cb3f46f354f4658758Ben Skeggs nouveau_bo_vma_del(priv->bo, &fctx->vma); 1265e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs nouveau_fence_context_del(&fctx->base); 127e193b1d42c390bf1bff7fa02a5a1202b98e75601Ben Skeggs chan->fence = NULL; 12815a996bbb6978ae21c497aeadfe20deca6ddd07aMaarten Lankhorst nouveau_fence_context_free(&fctx->base); 1295e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs} 1305e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs 131a34caf78f26bda63869471cb3f46f354f4658758Ben Skeggsint 132e193b1d42c390bf1bff7fa02a5a1202b98e75601Ben Skeggsnv84_fence_context_new(struct nouveau_channel *chan) 1335e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs{ 1340ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs struct nouveau_cli *cli = (void *)nvif_client(&chan->device->base); 135ebb945a94bba2ce8dff7b0942ff2b3f2a52a0a69Ben Skeggs struct nv84_fence_priv *priv = chan->drm->fence; 1365e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs struct nv84_fence_chan *fctx; 137f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggs int ret, i; 1385e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs 139e193b1d42c390bf1bff7fa02a5a1202b98e75601Ben Skeggs fctx = chan->fence = kzalloc(sizeof(*fctx), GFP_KERNEL); 1405e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs if (!fctx) 1415e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs return -ENOMEM; 1425e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs 14329ba89b2371d466ca68973525816cf10debc2655Maarten Lankhorst nouveau_fence_context_new(chan, &fctx->base); 144827520ce06568f699dad275dcca61647cce08757Ben Skeggs fctx->base.emit = nv84_fence_emit; 145827520ce06568f699dad275dcca61647cce08757Ben Skeggs fctx->base.sync = nv84_fence_sync; 146827520ce06568f699dad275dcca61647cce08757Ben Skeggs fctx->base.read = nv84_fence_read; 147827520ce06568f699dad275dcca61647cce08757Ben Skeggs fctx->base.emit32 = nv84_fence_emit32; 148827520ce06568f699dad275dcca61647cce08757Ben Skeggs fctx->base.sync32 = nv84_fence_sync32; 14929ba89b2371d466ca68973525816cf10debc2655Maarten Lankhorst fctx->base.sequence = nv84_fence_read(chan); 1505e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs 1513ee6f5b5036be4fd4e64be4233f29ee1c552c005Ben Skeggs ret = nouveau_bo_vma_add(priv->bo, cli->vm, &fctx->vma); 152264ce192b3e7f45d0adb37bfbab2b01a3fbe6c30Ben Skeggs if (ret == 0) { 1533ee6f5b5036be4fd4e64be4233f29ee1c552c005Ben Skeggs ret = nouveau_bo_vma_add(priv->bo_gart, cli->vm, 154264ce192b3e7f45d0adb37bfbab2b01a3fbe6c30Ben Skeggs &fctx->vma_gart); 155264ce192b3e7f45d0adb37bfbab2b01a3fbe6c30Ben Skeggs } 156ebb945a94bba2ce8dff7b0942ff2b3f2a52a0a69Ben Skeggs 157a34caf78f26bda63869471cb3f46f354f4658758Ben Skeggs /* map display semaphore buffers into channel's vm */ 158a34caf78f26bda63869471cb3f46f354f4658758Ben Skeggs for (i = 0; !ret && i < chan->drm->dev->mode_config.num_crtc; i++) { 159a34caf78f26bda63869471cb3f46f354f4658758Ben Skeggs struct nouveau_bo *bo = nv50_display_crtc_sema(chan->drm->dev, i); 1603ee6f5b5036be4fd4e64be4233f29ee1c552c005Ben Skeggs ret = nouveau_bo_vma_add(bo, cli->vm, &fctx->dispc_vma[i]); 161f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggs } 162f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggs 163264ce192b3e7f45d0adb37bfbab2b01a3fbe6c30Ben Skeggs if (ret) 164264ce192b3e7f45d0adb37bfbab2b01a3fbe6c30Ben Skeggs nv84_fence_context_del(chan); 1655e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs return ret; 1665e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs} 1675e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs 168264ce192b3e7f45d0adb37bfbab2b01a3fbe6c30Ben Skeggsstatic bool 169a34caf78f26bda63869471cb3f46f354f4658758Ben Skeggsnv84_fence_suspend(struct nouveau_drm *drm) 170a34caf78f26bda63869471cb3f46f354f4658758Ben Skeggs{ 171a34caf78f26bda63869471cb3f46f354f4658758Ben Skeggs struct nv84_fence_priv *priv = drm->fence; 172a34caf78f26bda63869471cb3f46f354f4658758Ben Skeggs int i; 173a34caf78f26bda63869471cb3f46f354f4658758Ben Skeggs 17429ba89b2371d466ca68973525816cf10debc2655Maarten Lankhorst priv->suspend = vmalloc(priv->base.contexts * sizeof(u32)); 175a34caf78f26bda63869471cb3f46f354f4658758Ben Skeggs if (priv->suspend) { 17629ba89b2371d466ca68973525816cf10debc2655Maarten Lankhorst for (i = 0; i < priv->base.contexts; i++) 177a34caf78f26bda63869471cb3f46f354f4658758Ben Skeggs priv->suspend[i] = nouveau_bo_rd32(priv->bo, i*4); 178a34caf78f26bda63869471cb3f46f354f4658758Ben Skeggs } 179a34caf78f26bda63869471cb3f46f354f4658758Ben Skeggs 180a34caf78f26bda63869471cb3f46f354f4658758Ben Skeggs return priv->suspend != NULL; 181a34caf78f26bda63869471cb3f46f354f4658758Ben Skeggs} 182a34caf78f26bda63869471cb3f46f354f4658758Ben Skeggs 183264ce192b3e7f45d0adb37bfbab2b01a3fbe6c30Ben Skeggsstatic void 184a34caf78f26bda63869471cb3f46f354f4658758Ben Skeggsnv84_fence_resume(struct nouveau_drm *drm) 185a34caf78f26bda63869471cb3f46f354f4658758Ben Skeggs{ 186a34caf78f26bda63869471cb3f46f354f4658758Ben Skeggs struct nv84_fence_priv *priv = drm->fence; 187a34caf78f26bda63869471cb3f46f354f4658758Ben Skeggs int i; 188a34caf78f26bda63869471cb3f46f354f4658758Ben Skeggs 189a34caf78f26bda63869471cb3f46f354f4658758Ben Skeggs if (priv->suspend) { 19029ba89b2371d466ca68973525816cf10debc2655Maarten Lankhorst for (i = 0; i < priv->base.contexts; i++) 191a34caf78f26bda63869471cb3f46f354f4658758Ben Skeggs nouveau_bo_wr32(priv->bo, i*4, priv->suspend[i]); 192a34caf78f26bda63869471cb3f46f354f4658758Ben Skeggs vfree(priv->suspend); 193a34caf78f26bda63869471cb3f46f354f4658758Ben Skeggs priv->suspend = NULL; 194a34caf78f26bda63869471cb3f46f354f4658758Ben Skeggs } 195a34caf78f26bda63869471cb3f46f354f4658758Ben Skeggs} 196a34caf78f26bda63869471cb3f46f354f4658758Ben Skeggs 197264ce192b3e7f45d0adb37bfbab2b01a3fbe6c30Ben Skeggsstatic void 198ebb945a94bba2ce8dff7b0942ff2b3f2a52a0a69Ben Skeggsnv84_fence_destroy(struct nouveau_drm *drm) 1995e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs{ 200ebb945a94bba2ce8dff7b0942ff2b3f2a52a0a69Ben Skeggs struct nv84_fence_priv *priv = drm->fence; 201264ce192b3e7f45d0adb37bfbab2b01a3fbe6c30Ben Skeggs nouveau_bo_unmap(priv->bo_gart); 202264ce192b3e7f45d0adb37bfbab2b01a3fbe6c30Ben Skeggs if (priv->bo_gart) 203264ce192b3e7f45d0adb37bfbab2b01a3fbe6c30Ben Skeggs nouveau_bo_unpin(priv->bo_gart); 204264ce192b3e7f45d0adb37bfbab2b01a3fbe6c30Ben Skeggs nouveau_bo_ref(NULL, &priv->bo_gart); 205a34caf78f26bda63869471cb3f46f354f4658758Ben Skeggs nouveau_bo_unmap(priv->bo); 206a34caf78f26bda63869471cb3f46f354f4658758Ben Skeggs if (priv->bo) 207a34caf78f26bda63869471cb3f46f354f4658758Ben Skeggs nouveau_bo_unpin(priv->bo); 208a34caf78f26bda63869471cb3f46f354f4658758Ben Skeggs nouveau_bo_ref(NULL, &priv->bo); 209ebb945a94bba2ce8dff7b0942ff2b3f2a52a0a69Ben Skeggs drm->fence = NULL; 2105e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs kfree(priv); 2115e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs} 2125e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs 2135e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggsint 214ebb945a94bba2ce8dff7b0942ff2b3f2a52a0a69Ben Skeggsnv84_fence_create(struct nouveau_drm *drm) 2155e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs{ 216967e7bde8739fe3b215f7537e8f1f39c044902afBen Skeggs struct nouveau_fifo *pfifo = nvkm_fifo(&drm->device); 2175e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs struct nv84_fence_priv *priv; 2185e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs int ret; 2195e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs 220ebb945a94bba2ce8dff7b0942ff2b3f2a52a0a69Ben Skeggs priv = drm->fence = kzalloc(sizeof(*priv), GFP_KERNEL); 2215e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs if (!priv) 2225e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs return -ENOMEM; 2235e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs 224e193b1d42c390bf1bff7fa02a5a1202b98e75601Ben Skeggs priv->base.dtor = nv84_fence_destroy; 225a34caf78f26bda63869471cb3f46f354f4658758Ben Skeggs priv->base.suspend = nv84_fence_suspend; 226a34caf78f26bda63869471cb3f46f354f4658758Ben Skeggs priv->base.resume = nv84_fence_resume; 227e193b1d42c390bf1bff7fa02a5a1202b98e75601Ben Skeggs priv->base.context_new = nv84_fence_context_new; 228e193b1d42c390bf1bff7fa02a5a1202b98e75601Ben Skeggs priv->base.context_del = nv84_fence_context_del; 2295e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs 23029ba89b2371d466ca68973525816cf10debc2655Maarten Lankhorst priv->base.contexts = pfifo->max + 1; 23129ba89b2371d466ca68973525816cf10debc2655Maarten Lankhorst priv->base.context_base = fence_context_alloc(priv->base.contexts); 232e18c080fb8695d038f69c26c248f5ecbd9e8aa77Ben Skeggs priv->base.uevent = true; 233e18c080fb8695d038f69c26c248f5ecbd9e8aa77Ben Skeggs 23429ba89b2371d466ca68973525816cf10debc2655Maarten Lankhorst ret = nouveau_bo_new(drm->dev, 16 * priv->base.contexts, 0, 235bb6178b04f5ef6f62990306713fb6afdf5d8bc56Maarten Lankhorst TTM_PL_FLAG_VRAM, 0, 0, NULL, NULL, &priv->bo); 236a34caf78f26bda63869471cb3f46f354f4658758Ben Skeggs if (ret == 0) { 237a34caf78f26bda63869471cb3f46f354f4658758Ben Skeggs ret = nouveau_bo_pin(priv->bo, TTM_PL_FLAG_VRAM); 238a34caf78f26bda63869471cb3f46f354f4658758Ben Skeggs if (ret == 0) { 239a34caf78f26bda63869471cb3f46f354f4658758Ben Skeggs ret = nouveau_bo_map(priv->bo); 240a34caf78f26bda63869471cb3f46f354f4658758Ben Skeggs if (ret) 241a34caf78f26bda63869471cb3f46f354f4658758Ben Skeggs nouveau_bo_unpin(priv->bo); 242a34caf78f26bda63869471cb3f46f354f4658758Ben Skeggs } 243a34caf78f26bda63869471cb3f46f354f4658758Ben Skeggs if (ret) 244a34caf78f26bda63869471cb3f46f354f4658758Ben Skeggs nouveau_bo_ref(NULL, &priv->bo); 245a34caf78f26bda63869471cb3f46f354f4658758Ben Skeggs } 246a34caf78f26bda63869471cb3f46f354f4658758Ben Skeggs 247264ce192b3e7f45d0adb37bfbab2b01a3fbe6c30Ben Skeggs if (ret == 0) 24829ba89b2371d466ca68973525816cf10debc2655Maarten Lankhorst ret = nouveau_bo_new(drm->dev, 16 * priv->base.contexts, 0, 249bb6178b04f5ef6f62990306713fb6afdf5d8bc56Maarten Lankhorst TTM_PL_FLAG_TT, 0, 0, NULL, NULL, 250264ce192b3e7f45d0adb37bfbab2b01a3fbe6c30Ben Skeggs &priv->bo_gart); 251264ce192b3e7f45d0adb37bfbab2b01a3fbe6c30Ben Skeggs if (ret == 0) { 252264ce192b3e7f45d0adb37bfbab2b01a3fbe6c30Ben Skeggs ret = nouveau_bo_pin(priv->bo_gart, TTM_PL_FLAG_TT); 253264ce192b3e7f45d0adb37bfbab2b01a3fbe6c30Ben Skeggs if (ret == 0) { 254264ce192b3e7f45d0adb37bfbab2b01a3fbe6c30Ben Skeggs ret = nouveau_bo_map(priv->bo_gart); 255264ce192b3e7f45d0adb37bfbab2b01a3fbe6c30Ben Skeggs if (ret) 256264ce192b3e7f45d0adb37bfbab2b01a3fbe6c30Ben Skeggs nouveau_bo_unpin(priv->bo_gart); 257264ce192b3e7f45d0adb37bfbab2b01a3fbe6c30Ben Skeggs } 258264ce192b3e7f45d0adb37bfbab2b01a3fbe6c30Ben Skeggs if (ret) 259264ce192b3e7f45d0adb37bfbab2b01a3fbe6c30Ben Skeggs nouveau_bo_ref(NULL, &priv->bo_gart); 260264ce192b3e7f45d0adb37bfbab2b01a3fbe6c30Ben Skeggs } 261264ce192b3e7f45d0adb37bfbab2b01a3fbe6c30Ben Skeggs 2625e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs if (ret) 263ebb945a94bba2ce8dff7b0942ff2b3f2a52a0a69Ben Skeggs nv84_fence_destroy(drm); 2645e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs return ret; 2655e120f6e4b3f35b741c5445dfc755f50128c3c44Ben Skeggs} 266