Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

drm/nouveau/pageflip: kick flip handling out of engsw and into fence



This is all very much a policy thing, and hence will not belong in SW
after the rework.

engsw now only handles receiving the event to say "can flip now" and makes
a callback to perform the actual work.

Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent bc9e7b9a
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -132,7 +132,7 @@ nouveau-y += nouveau_drm.o nouveau_compat.o \
	     nouveau_mxm.o nouveau_agp.o \
	     nouveau_abi16.o \
	     nouveau_bios.o \
             nv04_fence.o nv10_fence.o nv84_fence.o nvc0_fence.o \
             nv04_fence.o nv10_fence.o nv50_fence.o nv84_fence.o nvc0_fence.o \
             nv04_software.o nv50_software.o nvc0_software.o \
             nv04_dac.o nv04_dfp.o nv04_tv.o nv17_tv.o nv17_tv_modes.o \
             nv04_crtc.o nv04_display.o nv04_cursor.o \
+6 −2
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@
#include "nouveau_drv.h"
#include <core/mm.h>
#include <engine/fifo.h>
#include "nouveau_software.h"

static void nvc0_fifo_isr(struct drm_device *);

@@ -323,8 +324,11 @@ nvc0_fifo_page_flip(struct drm_device *dev, u32 chid)
	spin_lock_irqsave(&dev_priv->channels.lock, flags);
	if (likely(chid >= 0 && chid < priv->base.channels)) {
		chan = dev_priv->channels.ptr[chid];
		if (likely(chan))
			ret = nouveau_finish_page_flip(chan, NULL);
		if (likely(chan)) {
			struct nouveau_software_chan *swch =
				chan->engctx[NVOBJ_ENGINE_SW];
			ret = swch->flip(swch->flip_data);
		}
	}
	spin_unlock_irqrestore(&dev_priv->channels.lock, flags);
	return ret;
+7 −3
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@
#include "nouveau_drv.h"
#include <core/mm.h>
#include <engine/fifo.h>
#include "nouveau_software.h"

#define NVE0_FIFO_ENGINE_NUM 32

@@ -302,8 +303,11 @@ nve0_fifo_page_flip(struct drm_device *dev, u32 chid)
	spin_lock_irqsave(&dev_priv->channels.lock, flags);
	if (likely(chid >= 0 && chid < priv->base.channels)) {
		chan = dev_priv->channels.ptr[chid];
		if (likely(chan))
			ret = nouveau_finish_page_flip(chan, NULL);
		if (likely(chan)) {
			struct nouveau_software_chan *swch =
				chan->engctx[NVOBJ_ENGINE_SW];
			ret = swch->flip(swch->flip_data);
		}
	}
	spin_unlock_irqrestore(&dev_priv->channels.lock, flags);
	return ret;
@@ -315,7 +319,7 @@ nve0_fifo_isr_subfifo_intr(struct drm_device *dev, int unit)
	u32 stat = nv_rd32(dev, 0x040108 + (unit * 0x2000));
	u32 addr = nv_rd32(dev, 0x0400c0 + (unit * 0x2000));
	u32 data = nv_rd32(dev, 0x0400c4 + (unit * 0x2000));
	u32 chid = nv_rd32(dev, 0x040120 + (unit * 0x2000)) & 0x7f;
	u32 chid = nv_rd32(dev, 0x040120 + (unit * 0x2000)) & 0xfff;
	u32 subc = (addr & 0x00070000);
	u32 mthd = (addr & 0x00003ffc);
	u32 show = stat;
+24 −5
Original line number Diff line number Diff line
@@ -435,7 +435,7 @@ nouveau_page_flip_emit(struct nouveau_channel *chan,
		       struct nouveau_page_flip_state *s,
		       struct nouveau_fence **pfence)
{
	struct nouveau_software_chan *swch = chan->engctx[NVOBJ_ENGINE_SW];
	struct nouveau_fence_chan *fctx = chan->fence;
	struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
	struct drm_device *dev = chan->dev;
	unsigned long flags;
@@ -443,7 +443,7 @@ nouveau_page_flip_emit(struct nouveau_channel *chan,

	/* Queue it to the pending list */
	spin_lock_irqsave(&dev->event_lock, flags);
	list_add_tail(&s->head, &swch->flip);
	list_add_tail(&s->head, &fctx->flip);
	spin_unlock_irqrestore(&dev->event_lock, flags);

	/* Synchronize with the old framebuffer */
@@ -553,20 +553,20 @@ int
nouveau_finish_page_flip(struct nouveau_channel *chan,
			 struct nouveau_page_flip_state *ps)
{
	struct nouveau_software_chan *swch = chan->engctx[NVOBJ_ENGINE_SW];
	struct nouveau_fence_chan *fctx = chan->fence;
	struct drm_device *dev = chan->dev;
	struct nouveau_page_flip_state *s;
	unsigned long flags;

	spin_lock_irqsave(&dev->event_lock, flags);

	if (list_empty(&swch->flip)) {
	if (list_empty(&fctx->flip)) {
		NV_ERROR(dev, "Unexpected pageflip in channel %d.\n", chan->id);
		spin_unlock_irqrestore(&dev->event_lock, flags);
		return -EINVAL;
	}

	s = list_first_entry(&swch->flip, struct nouveau_page_flip_state, head);
	s = list_first_entry(&fctx->flip, struct nouveau_page_flip_state, head);
	if (s->event) {
		struct drm_pending_vblank_event *e = s->event;
		struct timeval now;
@@ -588,6 +588,25 @@ nouveau_finish_page_flip(struct nouveau_channel *chan,
	return 0;
}

int
nouveau_flip_complete(void *data)
{
	struct nouveau_channel *chan = data;
	struct drm_device *dev = chan->dev;
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct nouveau_page_flip_state state;

	if (!nouveau_finish_page_flip(chan, &state)) {
		if (dev_priv->card_type < NV_50) {
			nv_set_crtc_base(dev, state.crtc, state.offset +
					 state.y * state.pitch +
					 state.x * state.bpp / 8);
		}
	}

	return 0;
}

int
nouveau_display_dumb_create(struct drm_file *file_priv, struct drm_device *dev,
			    struct drm_mode_create_dumb *args)
+1 −0
Original line number Diff line number Diff line
@@ -54,6 +54,7 @@ nouveau_fence_context_del(struct nouveau_fence_chan *fctx)
void
nouveau_fence_context_new(struct nouveau_fence_chan *fctx)
{
	INIT_LIST_HEAD(&fctx->flip);
	INIT_LIST_HEAD(&fctx->pending);
	spin_lock_init(&fctx->lock);
}
Loading