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

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

drm/nouveau/fifo: turn all fifo modules into engine modules



Been tested on each major revision that's relevant here, but I'm sure there
are still bugs waiting to be ironed out.

This is a *very* invasive change.

There's a couple of pieces left that I don't like much (eg. other engines
using fifo_priv for the channel count), but that's an artefact of there
being a master channel list still.  This is changing, slowly.

Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent a226c32a
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -16,8 +16,8 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \
             nv04_mc.o nv40_mc.o nv50_mc.o \
             nv04_fb.o nv10_fb.o nv20_fb.o nv30_fb.o nv40_fb.o \
             nv50_fb.o nvc0_fb.o \
             nv04_fifo.o nv10_fifo.o nv40_fifo.o nv50_fifo.o nvc0_fifo.o \
             nve0_fifo.o \
             nv04_fifo.o nv10_fifo.o nv17_fifo.o nv40_fifo.o nv50_fifo.o \
             nv84_fifo.o nvc0_fifo.o nve0_fifo.o \
             nv04_fence.o nv10_fence.o nv84_fence.o nvc0_fence.o \
             nv04_software.o nv50_software.o nvc0_software.o \
             nv04_graph.o nv10_graph.o nv20_graph.o \
+9 −24
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@
#include "nouveau_drv.h"
#include "nouveau_drm.h"
#include "nouveau_dma.h"
#include "nouveau_fifo.h"
#include "nouveau_ramht.h"
#include "nouveau_fence.h"
#include "nouveau_software.h"
@@ -120,8 +121,8 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret,
		      uint32_t vram_handle, uint32_t gart_handle)
{
	struct nouveau_exec_engine *fence = nv_engine(dev, NVOBJ_ENGINE_FENCE);
	struct nouveau_fifo_priv *pfifo = nv_engine(dev, NVOBJ_ENGINE_FIFO);
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
	struct nouveau_fpriv *fpriv = nouveau_fpriv(file_priv);
	struct nouveau_channel *chan;
	unsigned long flags;
@@ -189,20 +190,13 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret,
	if (dev_priv->card_type >= NV_50)
		chan->user_get_hi = 0x60;

	/* disable the fifo caches */
	if (dev_priv->card_type < NV_50)
		nv_wr32(dev, NV03_PFIFO_CACHES, 0);

	/* Construct initial RAMFC for new channel */
	ret = pfifo->create_context(chan);
	/* create fifo context */
	ret = pfifo->base.context_new(chan, NVOBJ_ENGINE_FIFO);
	if (ret) {
		nouveau_channel_put(&chan);
		return ret;
	}

	if (dev_priv->card_type < NV_50)
		nv_wr32(dev, NV03_PFIFO_CACHES, 1);

	/* Insert NOPs for NOUVEAU_DMA_SKIPS */
	ret = RING_SPACE(chan, NOUVEAU_DMA_SKIPS);
	if (ret) {
@@ -288,7 +282,6 @@ nouveau_channel_put_unlocked(struct nouveau_channel **pchan)
	struct nouveau_channel *chan = *pchan;
	struct drm_device *dev = chan->dev;
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
	unsigned long flags;
	int i;

@@ -305,22 +298,12 @@ nouveau_channel_put_unlocked(struct nouveau_channel **pchan)
	/* give it chance to idle */
	nouveau_channel_idle(chan);

	/* boot it off the hardware */
	if (dev_priv->card_type < NV_50)
		nv_wr32(dev, NV03_PFIFO_CACHES, 0);

	/* destroy the engine specific contexts */
	for (i = NVOBJ_ENGINE_NR - 1; i >= 0; i--) {
		if (chan->engctx[i])
			dev_priv->eng[i]->context_del(chan, i);
		/*XXX: clean this up later, order is important */
		if (i == NVOBJ_ENGINE_FENCE)
			pfifo->destroy_context(chan);
	}

	if (dev_priv->card_type < NV_50)
		nv_wr32(dev, NV03_PFIFO_CACHES, 1);

	/* aside from its resources, the channel should now be dead,
	 * remove it from the channel list
	 */
@@ -393,13 +376,15 @@ nouveau_channel_idle(struct nouveau_channel *chan)
void
nouveau_channel_cleanup(struct drm_device *dev, struct drm_file *file_priv)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct nouveau_engine *engine = &dev_priv->engine;
	struct nouveau_fifo_priv *pfifo = nv_engine(dev, NVOBJ_ENGINE_FIFO);
	struct nouveau_channel *chan;
	int i;

	if (!pfifo)
		return;

	NV_DEBUG(dev, "clearing FIFO enables from file_priv\n");
	for (i = 0; i < engine->fifo.channels; i++) {
	for (i = 0; i < pfifo->channels; i++) {
		chan = nouveau_channel_get(file_priv, i);
		if (IS_ERR(chan))
			continue;
+5 −17
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@
#include "nouveau_fb.h"
#include "nouveau_fbcon.h"
#include "nouveau_pm.h"
#include "nouveau_fifo.h"
#include "nv50_display.h"

#include "drm_pciids.h"
@@ -175,7 +176,7 @@ nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state)
	struct drm_device *dev = pci_get_drvdata(pdev);
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem;
	struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
	struct nouveau_fifo_priv *pfifo = nv_engine(dev, NVOBJ_ENGINE_FIFO);
	struct nouveau_channel *chan;
	struct drm_crtc *crtc;
	int ret, i, e;
@@ -214,21 +215,13 @@ nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state)
	ttm_bo_evict_mm(&dev_priv->ttm.bdev, TTM_PL_VRAM);

	NV_INFO(dev, "Idling channels...\n");
	for (i = 0; i < pfifo->channels; i++) {
	for (i = 0; i < (pfifo ? pfifo->channels : 0); i++) {
		chan = dev_priv->channels.ptr[i];

		if (chan && chan->pushbuf_bo)
			nouveau_channel_idle(chan);
	}

	if (dev_priv->card_type < NV_50) {
		nv_wr32(dev, NV03_PFIFO_CACHES, 0);
		nv_mask(dev, NV04_PFIFO_CACHE1_DMA_PUSH, 0x00000001, 0);
		nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH0, 0);
		nv_mask(dev, NV04_PFIFO_CACHE1_PULL0, 0x00000001, 0);
	}
	pfifo->unload_context(dev);

	for (e = NVOBJ_ENGINE_NR - 1; e >= 0; e--) {
		if (!dev_priv->eng[e])
			continue;
@@ -269,11 +262,6 @@ nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state)
		if (dev_priv->eng[e])
			dev_priv->eng[e]->init(dev, e);
	}
	if (dev_priv->card_type < NV_50) {
		nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH0, 1);
		nv_wr32(dev, NV04_PFIFO_CACHE1_PULL0, 1);
		nv_wr32(dev, NV03_PFIFO_CACHES, 1);
	}
	return ret;
}

@@ -281,6 +269,7 @@ int
nouveau_pci_resume(struct pci_dev *pdev)
{
	struct drm_device *dev = pci_get_drvdata(pdev);
	struct nouveau_fifo_priv *pfifo = nv_engine(dev, NVOBJ_ENGINE_FIFO);
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct nouveau_engine *engine = &dev_priv->engine;
	struct drm_crtc *crtc;
@@ -328,7 +317,6 @@ nouveau_pci_resume(struct pci_dev *pdev)
		if (dev_priv->eng[i])
			dev_priv->eng[i]->init(dev, i);
	}
	engine->fifo.init(dev);

	nouveau_irq_postinstall(dev);

@@ -337,7 +325,7 @@ nouveau_pci_resume(struct pci_dev *pdev)
		struct nouveau_channel *chan;
		int j;

		for (i = 0; i < dev_priv->engine.fifo.channels; i++) {
		for (i = 0; i < (pfifo ? pfifo->channels : 0); i++) {
			chan = dev_priv->channels.ptr[i];
			if (!chan || !chan->pushbuf_bo)
				continue;
+3 −70
Original line number Diff line number Diff line
@@ -165,9 +165,10 @@ enum nouveau_flags {
#define NVOBJ_ENGINE_PPP	NVOBJ_ENGINE_MPEG
#define NVOBJ_ENGINE_BSP	6
#define NVOBJ_ENGINE_VP		7
#define NVOBJ_ENGINE_FENCE	14
#define NVOBJ_ENGINE_DISPLAY	15
#define NVOBJ_ENGINE_FIFO	14
#define NVOBJ_ENGINE_FENCE	15
#define NVOBJ_ENGINE_NR		16
#define NVOBJ_ENGINE_DISPLAY	(NVOBJ_ENGINE_NR + 0) /*XXX*/

#define NVOBJ_FLAG_DONT_MAP             (1 << 0)
#define NVOBJ_FLAG_ZERO_ALLOC		(1 << 1)
@@ -248,8 +249,6 @@ struct nouveau_channel {

	/* PFIFO context */
	struct nouveau_gpuobj *ramfc;
	struct nouveau_gpuobj *cache;
	void *fifo_priv;

	/* Execution engine contexts */
	void *engctx[NVOBJ_ENGINE_NR];
@@ -283,8 +282,6 @@ struct nouveau_channel {
		int ib_put;
	} dma;

	uint32_t sw_subchannel[8];

	struct {
		bool active;
		char name[32];
@@ -347,23 +344,6 @@ struct nouveau_fb_engine {
	void (*free_tile_region)(struct drm_device *dev, int i);
};

struct nouveau_fifo_engine {
	void *priv;
	int  channels;

	struct nouveau_gpuobj *playlist[2];
	int cur_playlist;

	int  (*init)(struct drm_device *);
	void (*takedown)(struct drm_device *);

	int  (*create_context)(struct nouveau_channel *);
	void (*destroy_context)(struct nouveau_channel *);
	int  (*load_context)(struct nouveau_channel *);
	int  (*unload_context)(struct drm_device *);
	void (*tlb_flush)(struct drm_device *dev);
};

struct nouveau_display_engine {
	void *priv;
	int (*early_init)(struct drm_device *);
@@ -571,7 +551,6 @@ struct nouveau_engine {
	struct nouveau_mc_engine      mc;
	struct nouveau_timer_engine   timer;
	struct nouveau_fb_engine      fb;
	struct nouveau_fifo_engine    fifo;
	struct nouveau_display_engine display;
	struct nouveau_gpio_engine    gpio;
	struct nouveau_pm_engine      pm;
@@ -1183,52 +1162,6 @@ extern void nv50_fb_vm_trap(struct drm_device *, int display);
extern int  nvc0_fb_init(struct drm_device *);
extern void nvc0_fb_takedown(struct drm_device *);

/* nv04_fifo.c */
extern int  nv04_fifo_init(struct drm_device *);
extern void nv04_fifo_fini(struct drm_device *);
extern int  nv04_fifo_create_context(struct nouveau_channel *);
extern void nv04_fifo_destroy_context(struct nouveau_channel *);
extern int  nv04_fifo_load_context(struct nouveau_channel *);
extern int  nv04_fifo_unload_context(struct drm_device *);
extern void nv04_fifo_isr(struct drm_device *);
bool nv04_fifo_cache_pull(struct drm_device *, bool enable);

/* nv10_fifo.c */
extern int  nv10_fifo_init(struct drm_device *);
extern int  nv10_fifo_create_context(struct nouveau_channel *);
extern int  nv10_fifo_load_context(struct nouveau_channel *);
extern int  nv10_fifo_unload_context(struct drm_device *);

/* nv40_fifo.c */
extern int  nv40_fifo_init(struct drm_device *);
extern int  nv40_fifo_create_context(struct nouveau_channel *);
extern int  nv40_fifo_load_context(struct nouveau_channel *);
extern int  nv40_fifo_unload_context(struct drm_device *);

/* nv50_fifo.c */
extern int  nv50_fifo_init(struct drm_device *);
extern void nv50_fifo_takedown(struct drm_device *);
extern int  nv50_fifo_create_context(struct nouveau_channel *);
extern void nv50_fifo_destroy_context(struct nouveau_channel *);
extern int  nv50_fifo_load_context(struct nouveau_channel *);
extern int  nv50_fifo_unload_context(struct drm_device *);
extern void nv50_fifo_tlb_flush(struct drm_device *dev);

/* nvc0_fifo.c */
extern int  nvc0_fifo_init(struct drm_device *);
extern void nvc0_fifo_takedown(struct drm_device *);
extern int  nvc0_fifo_create_context(struct nouveau_channel *);
extern void nvc0_fifo_destroy_context(struct nouveau_channel *);
extern int  nvc0_fifo_load_context(struct nouveau_channel *);
extern int  nvc0_fifo_unload_context(struct drm_device *);

/* nve0_fifo.c */
extern int  nve0_fifo_init(struct drm_device *);
extern void nve0_fifo_takedown(struct drm_device *);
extern int  nve0_fifo_create_context(struct nouveau_channel *);
extern void nve0_fifo_destroy_context(struct nouveau_channel *);
extern int  nve0_fifo_unload_context(struct drm_device *);

/* nv04_graph.c */
extern int  nv04_graph_create(struct drm_device *);
extern int  nv04_graph_object_new(struct nouveau_channel *, int, u32, u16);
+32 −0
Original line number Diff line number Diff line
#ifndef __NOUVEAU_FIFO_H__
#define __NOUVEAU_FIFO_H__

struct nouveau_fifo_priv {
	struct nouveau_exec_engine base;
	u32 channels;
};

struct nouveau_fifo_chan {
};

bool nv04_fifo_cache_pull(struct drm_device *, bool);
void nv04_fifo_context_del(struct nouveau_channel *, int);
int  nv04_fifo_fini(struct drm_device *, int, bool);
int  nv04_fifo_init(struct drm_device *, int);
void nv04_fifo_isr(struct drm_device *);
void nv04_fifo_destroy(struct drm_device *, int);

void nv50_fifo_playlist_update(struct drm_device *);
void nv50_fifo_destroy(struct drm_device *, int);
void nv50_fifo_tlb_flush(struct drm_device *, int);

int  nv04_fifo_create(struct drm_device *);
int  nv10_fifo_create(struct drm_device *);
int  nv17_fifo_create(struct drm_device *);
int  nv40_fifo_create(struct drm_device *);
int  nv50_fifo_create(struct drm_device *);
int  nv84_fifo_create(struct drm_device *);
int  nvc0_fifo_create(struct drm_device *);
int  nve0_fifo_create(struct drm_device *);

#endif
Loading