xref: /openbmc/linux/drivers/gpu/drm/nouveau/nvkm/engine/sw/chan.c (revision c900529f3d9161bfde5cca0754f83b4d3c3e0220)
1898a2b32SBen Skeggs /*
2898a2b32SBen Skeggs  * Copyright 2015 Red Hat Inc.
3898a2b32SBen Skeggs  *
4898a2b32SBen Skeggs  * Permission is hereby granted, free of charge, to any person obtaining a
5898a2b32SBen Skeggs  * copy of this software and associated documentation files (the "Software"),
6898a2b32SBen Skeggs  * to deal in the Software without restriction, including without limitation
7898a2b32SBen Skeggs  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8898a2b32SBen Skeggs  * and/or sell copies of the Software, and to permit persons to whom the
9898a2b32SBen Skeggs  * Software is furnished to do so, subject to the following conditions:
10898a2b32SBen Skeggs  *
11898a2b32SBen Skeggs  * The above copyright notice and this permission notice shall be included in
12898a2b32SBen Skeggs  * all copies or substantial portions of the Software.
13898a2b32SBen Skeggs  *
14898a2b32SBen Skeggs  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15898a2b32SBen Skeggs  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16898a2b32SBen Skeggs  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17898a2b32SBen Skeggs  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18898a2b32SBen Skeggs  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19898a2b32SBen Skeggs  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20898a2b32SBen Skeggs  * OTHER DEALINGS IN THE SOFTWARE.
21898a2b32SBen Skeggs  *
22898a2b32SBen Skeggs  * Authors: Ben Skeggs <bskeggs@redhat.com>
23898a2b32SBen Skeggs  */
24898a2b32SBen Skeggs #include "chan.h"
25898a2b32SBen Skeggs 
2661570911SBen Skeggs #include <engine/fifo.h>
27898a2b32SBen Skeggs 
28898a2b32SBen Skeggs #include <nvif/event.h>
29898a2b32SBen Skeggs #include <nvif/unpack.h>
30898a2b32SBen Skeggs 
3161570911SBen Skeggs bool
nvkm_sw_chan_mthd(struct nvkm_sw_chan * chan,int subc,u32 mthd,u32 data)3261570911SBen Skeggs nvkm_sw_chan_mthd(struct nvkm_sw_chan *chan, int subc, u32 mthd, u32 data)
3361570911SBen Skeggs {
3461570911SBen Skeggs 	switch (mthd) {
3561570911SBen Skeggs 	case 0x0000:
3661570911SBen Skeggs 		return true;
3761570911SBen Skeggs 	case 0x0500:
3899d0701aSBen Skeggs 		nvkm_event_ntfy(&chan->event, 0, NVKM_SW_CHAN_EVENT_PAGE_FLIP);
3961570911SBen Skeggs 		return true;
4061570911SBen Skeggs 	default:
4161570911SBen Skeggs 		if (chan->func->mthd)
4261570911SBen Skeggs 			return chan->func->mthd(chan, subc, mthd, data);
4361570911SBen Skeggs 		break;
4461570911SBen Skeggs 	}
4561570911SBen Skeggs 	return false;
4661570911SBen Skeggs }
4761570911SBen Skeggs 
48898a2b32SBen Skeggs static const struct nvkm_event_func
49898a2b32SBen Skeggs nvkm_sw_chan_event = {
50898a2b32SBen Skeggs };
51898a2b32SBen Skeggs 
5207b9e6ccSBen Skeggs static void *
nvkm_sw_chan_dtor(struct nvkm_object * object)5307b9e6ccSBen Skeggs nvkm_sw_chan_dtor(struct nvkm_object *object)
54898a2b32SBen Skeggs {
5507b9e6ccSBen Skeggs 	struct nvkm_sw_chan *chan = nvkm_sw_chan(object);
5607b9e6ccSBen Skeggs 	struct nvkm_sw *sw = chan->sw;
5707b9e6ccSBen Skeggs 	unsigned long flags;
5807b9e6ccSBen Skeggs 	void *data = chan;
5907b9e6ccSBen Skeggs 
6007b9e6ccSBen Skeggs 	if (chan->func->dtor)
6107b9e6ccSBen Skeggs 		data = chan->func->dtor(chan);
62898a2b32SBen Skeggs 	nvkm_event_fini(&chan->event);
6307b9e6ccSBen Skeggs 
6407b9e6ccSBen Skeggs 	spin_lock_irqsave(&sw->engine.lock, flags);
6507b9e6ccSBen Skeggs 	list_del(&chan->head);
6607b9e6ccSBen Skeggs 	spin_unlock_irqrestore(&sw->engine.lock, flags);
6707b9e6ccSBen Skeggs 	return data;
68898a2b32SBen Skeggs }
69898a2b32SBen Skeggs 
7007b9e6ccSBen Skeggs static const struct nvkm_object_func
7107b9e6ccSBen Skeggs nvkm_sw_chan = {
7207b9e6ccSBen Skeggs 	.dtor = nvkm_sw_chan_dtor,
7307b9e6ccSBen Skeggs };
7407b9e6ccSBen Skeggs 
75898a2b32SBen Skeggs int
nvkm_sw_chan_ctor(const struct nvkm_sw_chan_func * func,struct nvkm_sw * sw,struct nvkm_chan * fifo,const struct nvkm_oclass * oclass,struct nvkm_sw_chan * chan)7607b9e6ccSBen Skeggs nvkm_sw_chan_ctor(const struct nvkm_sw_chan_func *func, struct nvkm_sw *sw,
77*c546656fSBen Skeggs 		  struct nvkm_chan *fifo, const struct nvkm_oclass *oclass,
7807b9e6ccSBen Skeggs 		  struct nvkm_sw_chan *chan)
79898a2b32SBen Skeggs {
8007b9e6ccSBen Skeggs 	unsigned long flags;
81898a2b32SBen Skeggs 
8207b9e6ccSBen Skeggs 	nvkm_object_ctor(&nvkm_sw_chan, oclass, &chan->object);
8361570911SBen Skeggs 	chan->func = func;
8407b9e6ccSBen Skeggs 	chan->sw = sw;
8507b9e6ccSBen Skeggs 	chan->fifo = fifo;
8607b9e6ccSBen Skeggs 	spin_lock_irqsave(&sw->engine.lock, flags);
8761570911SBen Skeggs 	list_add(&chan->head, &sw->chan);
8807b9e6ccSBen Skeggs 	spin_unlock_irqrestore(&sw->engine.lock, flags);
8961570911SBen Skeggs 
90f43e47c0SBen Skeggs 	return nvkm_event_init(&nvkm_sw_chan_event, &sw->engine.subdev, 1, 1, &chan->event);
91898a2b32SBen Skeggs }
92