1 /* $NetBSD: nouveau_nvkm_engine_sw_chan.c,v 1.3 2021/12/18 23:45:37 riastradh Exp $ */ 2 3 /* 4 * Copyright 2015 Red Hat Inc. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the "Software"), 8 * to deal in the Software without restriction, including without limitation 9 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 * and/or sell copies of the Software, and to permit persons to whom the 11 * Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 * OTHER DEALINGS IN THE SOFTWARE. 23 * 24 * Authors: Ben Skeggs <bskeggs (at) redhat.com> 25 */ 26 #include <sys/cdefs.h> 27 __KERNEL_RCSID(0, "$NetBSD: nouveau_nvkm_engine_sw_chan.c,v 1.3 2021/12/18 23:45:37 riastradh Exp $"); 28 29 #include "chan.h" 30 31 #include <core/notify.h> 32 #include <engine/fifo.h> 33 34 #include <nvif/event.h> 35 #include <nvif/unpack.h> 36 37 bool 38 nvkm_sw_chan_mthd(struct nvkm_sw_chan *chan, int subc, u32 mthd, u32 data) 39 { 40 switch (mthd) { 41 case 0x0000: 42 return true; 43 case 0x0500: 44 nvkm_event_send(&chan->event, 1, 0, NULL, 0); 45 return true; 46 default: 47 if (chan->func->mthd) 48 return chan->func->mthd(chan, subc, mthd, data); 49 break; 50 } 51 return false; 52 } 53 54 static int 55 nvkm_sw_chan_event_ctor(struct nvkm_object *object, void *data, u32 size, 56 struct nvkm_notify *notify) 57 { 58 union { 59 struct nvif_notify_uevent_req none; 60 } *req = data; 61 int ret = -ENOSYS; 62 63 if (!(ret = nvif_unvers(ret, &data, &size, req->none))) { 64 notify->size = sizeof(struct nvif_notify_uevent_rep); 65 notify->types = 1; 66 notify->index = 0; 67 } 68 69 return ret; 70 } 71 72 static const struct nvkm_event_func 73 nvkm_sw_chan_event = { 74 .ctor = nvkm_sw_chan_event_ctor, 75 }; 76 77 static void * 78 nvkm_sw_chan_dtor(struct nvkm_object *object) 79 { 80 struct nvkm_sw_chan *chan = nvkm_sw_chan(object); 81 struct nvkm_sw *sw = chan->sw; 82 unsigned long flags; 83 void *data = chan; 84 85 if (chan->func->dtor) 86 data = chan->func->dtor(chan); 87 nvkm_event_fini(&chan->event); 88 89 spin_lock_irqsave(&sw->engine.lock, flags); 90 list_del(&chan->head); 91 spin_unlock_irqrestore(&sw->engine.lock, flags); 92 return data; 93 } 94 95 static const struct nvkm_object_func 96 nvkm_sw_chan = { 97 .dtor = nvkm_sw_chan_dtor, 98 }; 99 100 int 101 nvkm_sw_chan_ctor(const struct nvkm_sw_chan_func *func, struct nvkm_sw *sw, 102 struct nvkm_fifo_chan *fifo, const struct nvkm_oclass *oclass, 103 struct nvkm_sw_chan *chan) 104 { 105 unsigned long flags; 106 107 nvkm_object_ctor(&nvkm_sw_chan, oclass, &chan->object); 108 chan->func = func; 109 chan->sw = sw; 110 chan->fifo = fifo; 111 spin_lock_irqsave(&sw->engine.lock, flags); 112 list_add(&chan->head, &sw->chan); 113 spin_unlock_irqrestore(&sw->engine.lock, flags); 114 115 return nvkm_event_init(&nvkm_sw_chan_event, 1, 1, &chan->event); 116 } 117