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

Commit 52d07331 authored by Ben Skeggs's avatar Ben Skeggs
Browse files

drm/nv31/mpeg: support for a single class3174 user



Uncertain if/how the hw does multiple PMPEG channels, supporting one is
better than none however.

Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 323dcac5
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -633,7 +633,10 @@ nouveau_card_init(struct drm_device *dev)
			break;
		}

		if (dev_priv->card_type == NV_40)
		if (dev_priv->card_type == NV_40 ||
		    dev_priv->chipset == 0x31 ||
		    dev_priv->chipset == 0x34 ||
		    dev_priv->chipset == 0x36)
			nv31_mpeg_create(dev);
		else
		if (dev_priv->card_type == NV_50 &&
+36 −3
Original line number Diff line number Diff line
@@ -28,8 +28,30 @@

struct nv31_mpeg_engine {
	struct nouveau_exec_engine base;
	atomic_t refcount;
};


static int
nv31_mpeg_context_new(struct nouveau_channel *chan, int engine)
{
	struct nv31_mpeg_engine *pmpeg = nv_engine(chan->dev, engine);

	if (!atomic_add_unless(&pmpeg->refcount, 1, 1))
		return -EBUSY;

	chan->engctx[engine] = (void *)0xdeadcafe;
	return 0;
}

static void
nv31_mpeg_context_del(struct nouveau_channel *chan, int engine)
{
	struct nv31_mpeg_engine *pmpeg = nv_engine(chan->dev, engine);
	atomic_dec(&pmpeg->refcount);
	chan->engctx[engine] = NULL;
}

static int
nv40_mpeg_context_new(struct nouveau_channel *chan, int engine)
{
@@ -121,7 +143,7 @@ nv31_mpeg_init(struct drm_device *dev, int engine)
	/* PMPEG init */
	nv_wr32(dev, 0x00b32c, 0x00000000);
	nv_wr32(dev, 0x00b314, 0x00000100);
	nv_wr32(dev, 0x00b220, 0x00000044);
	nv_wr32(dev, 0x00b220, nv44_graph_class(dev) ? 0x00000044 : 0x00000031);
	nv_wr32(dev, 0x00b300, 0x02001ec1);
	nv_mask(dev, 0x00b32c, 0x00000001, 0x00000001);

@@ -191,6 +213,10 @@ nv31_mpeg_isr_chid(struct drm_device *dev, u32 inst)
	unsigned long flags;
	int i;

	/* hardcode drm channel id on nv3x, so swmthd lookup works */
	if (dev_priv->card_type < NV_40)
		return 0;

	spin_lock_irqsave(&dev_priv->channels.lock, flags);
	for (i = 0; i < dev_priv->engine.fifo.channels; i++) {
		if (!dev_priv->channels.ptr[i])
@@ -275,17 +301,24 @@ nv31_mpeg_destroy(struct drm_device *dev, int engine)
int
nv31_mpeg_create(struct drm_device *dev)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct nv31_mpeg_engine *pmpeg;

	pmpeg = kzalloc(sizeof(*pmpeg), GFP_KERNEL);
	if (!pmpeg)
		return -ENOMEM;
	atomic_set(&pmpeg->refcount, 0);

	pmpeg->base.destroy = nv31_mpeg_destroy;
	pmpeg->base.init = nv31_mpeg_init;
	pmpeg->base.fini = nv31_mpeg_fini;
	if (dev_priv->card_type < NV_40) {
		pmpeg->base.context_new = nv31_mpeg_context_new;
		pmpeg->base.context_del = nv31_mpeg_context_del;
	} else {
		pmpeg->base.context_new = nv40_mpeg_context_new;
		pmpeg->base.context_del = nv40_mpeg_context_del;
	}
	pmpeg->base.object_new = nv31_mpeg_object_new;

	/* ISR vector, PMC_ENABLE bit,  and TILE regs are shared between