1 /* 2 * Copyright 2012 Red Hat Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 * OTHER DEALINGS IN THE SOFTWARE. 21 * 22 * Authors: Ben Skeggs 23 */ 24 #include "nouveau_drv.h" 25 #include "nouveau_dma.h" 26 #include "nouveau_fence.h" 27 28 #include "nv50_display.h" 29 30 #include <nvif/push906f.h> 31 32 #include <nvhw/class/cl906f.h> 33 34 static int 35 nvc0_fence_emit32(struct nouveau_channel *chan, u64 virtual, u32 sequence) 36 { 37 struct nvif_push *push = &chan->chan.push; 38 int ret = PUSH_WAIT(push, 6); 39 if (ret == 0) { 40 PUSH_MTHD(push, NV906F, SEMAPHOREA, 41 NVVAL(NV906F, SEMAPHOREA, OFFSET_UPPER, upper_32_bits(virtual)), 42 43 SEMAPHOREB, lower_32_bits(virtual), 44 SEMAPHOREC, sequence, 45 46 SEMAPHORED, 47 NVDEF(NV906F, SEMAPHORED, OPERATION, RELEASE) | 48 NVDEF(NV906F, SEMAPHORED, RELEASE_WFI, EN) | 49 NVDEF(NV906F, SEMAPHORED, RELEASE_SIZE, 16BYTE), 50 51 NON_STALL_INTERRUPT, 0); 52 PUSH_KICK(push); 53 } 54 return ret; 55 } 56 57 static int 58 nvc0_fence_sync32(struct nouveau_channel *chan, u64 virtual, u32 sequence) 59 { 60 struct nvif_push *push = &chan->chan.push; 61 int ret = PUSH_WAIT(push, 5); 62 if (ret == 0) { 63 PUSH_MTHD(push, NV906F, SEMAPHOREA, 64 NVVAL(NV906F, SEMAPHOREA, OFFSET_UPPER, upper_32_bits(virtual)), 65 66 SEMAPHOREB, lower_32_bits(virtual), 67 SEMAPHOREC, sequence, 68 69 SEMAPHORED, 70 NVDEF(NV906F, SEMAPHORED, OPERATION, ACQ_GEQ) | 71 NVDEF(NV906F, SEMAPHORED, ACQUIRE_SWITCH, ENABLED)); 72 PUSH_KICK(push); 73 } 74 return ret; 75 } 76 77 static int 78 nvc0_fence_context_new(struct nouveau_channel *chan) 79 { 80 int ret = nv84_fence_context_new(chan); 81 if (ret == 0) { 82 struct nv84_fence_chan *fctx = chan->fence; 83 fctx->base.emit32 = nvc0_fence_emit32; 84 fctx->base.sync32 = nvc0_fence_sync32; 85 } 86 return ret; 87 } 88 89 int 90 nvc0_fence_create(struct nouveau_drm *drm) 91 { 92 int ret = nv84_fence_create(drm); 93 if (ret == 0) { 94 struct nv84_fence_priv *priv = drm->fence; 95 priv->base.context_new = nvc0_fence_context_new; 96 } 97 return ret; 98 } 99