Commit acff9415 authored by Ben Skeggs's avatar Ben Skeggs
Browse files

drm/nouveau/fifo: add chan/cgrp preempt()



Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
Reviewed-by: default avatarLyude Paul <lyude@redhat.com>
parent 67059b9f
Loading
Loading
Loading
Loading
+0 −11
Original line number Diff line number Diff line
@@ -33,17 +33,6 @@
#include <nvif/cl0080.h>
#include <nvif/unpack.h>

void
nvkm_fifo_recover_chan(struct nvkm_fifo *fifo, int chid)
{
	unsigned long flags;
	if (WARN_ON(!fifo->func->recover_chan))
		return;
	spin_lock_irqsave(&fifo->lock, flags);
	fifo->func->recover_chan(fifo, chid);
	spin_unlock_irqrestore(&fifo->lock, flags);
}

void
nvkm_fifo_pause(struct nvkm_fifo *fifo, unsigned long *flags)
{
+1 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ struct nvkm_ectx {

struct nvkm_cgrp {
	const struct nvkm_cgrp_func {
		void (*preempt)(struct nvkm_cgrp *);
	} *func;
	char name[64];
	struct nvkm_runl *runl;
+30 −0
Original line number Diff line number Diff line
@@ -222,6 +222,7 @@ nvkm_chan_cctx_bind(struct nvkm_chan *chan, struct nvkm_oproxy *oproxy, struct n
		nvkm_runl_block(runl);
	else
		nvkm_chan_block(chan);
	nvkm_chan_preempt(chan, true);

	/* Update context pointer. */
	if (cctx)
@@ -300,6 +301,33 @@ nvkm_chan_cctx_get(struct nvkm_chan *chan, struct nvkm_engn *engn, struct nvkm_c
	return ret;
}

int
nvkm_chan_preempt_locked(struct nvkm_chan *chan, bool wait)
{
	struct nvkm_runl *runl = chan->cgrp->runl;

	CHAN_TRACE(chan, "preempt");
	chan->func->preempt(chan);
	if (!wait)
		return 0;

	return nvkm_runl_preempt_wait(runl);
}

int
nvkm_chan_preempt(struct nvkm_chan *chan, bool wait)
{
	int ret;

	if (!chan->func->preempt)
		return 0;

	mutex_lock(&chan->cgrp->runl->mutex);
	ret = nvkm_chan_preempt_locked(chan, wait);
	mutex_unlock(&chan->cgrp->runl->mutex);
	return ret;
}

static int
nvkm_fifo_chan_map(struct nvkm_object *object, void *argv, u32 argc,
		   enum nvkm_object_map *type, u64 *addr, u64 *size)
@@ -346,6 +374,8 @@ nvkm_chan_error(struct nvkm_chan *chan, bool preempt)
	if (atomic_inc_return(&chan->errored) == 1) {
		CHAN_ERROR(chan, "errored - disabling channel");
		nvkm_chan_block_locked(chan);
		if (preempt)
			chan->func->preempt(chan);
		nvkm_event_ntfy(&chan->cgrp->runl->chid->event, chan->id, NVKM_CHAN_EVENT_ERRORED);
	}
	spin_unlock_irqrestore(&chan->lock, flags);
+3 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ struct nvkm_chan_func {
	void (*unbind)(struct nvkm_chan *);
	void (*start)(struct nvkm_chan *);
	void (*stop)(struct nvkm_chan *);
	void (*preempt)(struct nvkm_chan *);
	u32 (*doorbell_handle)(struct nvkm_chan *);

	void *(*dtor)(struct nvkm_fifo_chan *);
@@ -43,6 +44,8 @@ void nvkm_chan_del(struct nvkm_chan **);
void nvkm_chan_allow(struct nvkm_chan *);
void nvkm_chan_block(struct nvkm_chan *);
void nvkm_chan_error(struct nvkm_chan *, bool preempt);
int nvkm_chan_preempt(struct nvkm_chan *, bool wait);
int nvkm_chan_preempt_locked(struct nvkm_chan *, bool wait);
int nvkm_chan_cctx_get(struct nvkm_chan *, struct nvkm_engn *, struct nvkm_cctx **,
		       struct nvkm_client * /*TODO: remove need for this */);
void nvkm_chan_cctx_put(struct nvkm_chan *, struct nvkm_cctx **);
+0 −2
Original line number Diff line number Diff line
@@ -33,8 +33,6 @@ int gk104_fifo_gpfifo_engine_ctor(struct nvkm_fifo_chan *, struct nvkm_engine *,
				  struct nvkm_object *);
void gk104_fifo_gpfifo_engine_dtor(struct nvkm_fifo_chan *,
				   struct nvkm_engine *);
int gk104_fifo_gpfifo_kick(struct gk104_fifo_chan *);
int gk104_fifo_gpfifo_kick_locked(struct gk104_fifo_chan *);

int gv100_fifo_gpfifo_new(struct gk104_fifo *, const struct nvkm_oclass *,
			  void *data, u32 size, struct nvkm_object **);
Loading