summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/core/engine/mpeg
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-11-15 14:19:54 +0900
committerLinus Torvalds <torvalds@linux-foundation.org>2013-11-15 14:19:54 +0900
commit049ffa8ab33a63b3bff672d1a0ee6a35ad253fe8 (patch)
tree70f4c684818b1c9871fa800088427e40d260592e /drivers/gpu/drm/nouveau/core/engine/mpeg
parentc681427e5ca22925fcc1be76a2e260a11e0a8498 (diff)
parent0846c728e20a0cd1e43fb75a3015f3b176a26466 (diff)
Merge branch 'drm-next' of git://people.freedesktop.org/~airlied/linux
Pull drm updates from Dave Airlie: "This is a combo of -next and some -fixes that came in in the intervening time. Highlights: New drivers: ARM Armada driver for Marvell Armada 510 SOCs Intel: Broadwell initial support under a default off switch, Stereo/3D HDMI mode support Valleyview improvements Displayport improvements Haswell fixes initial mipi dsi panel support CRC support for debugging build with CONFIG_FB=n Radeon: enable DPM on a number of GPUs by default secondary GPU powerdown support enable HDMI audio by default Hawaii support Nouveau: dynamic pm code infrastructure reworked, does nothing major yet GK208 modesetting support MSI fixes, on by default again PMPEG improvements pageflipping fixes GMA500: minnowboard SDVO support VMware: misc fixes MSM: prime, plane and rendernodes support Tegra: rearchitected to put the drm driver into the drm subsystem. HDMI and gr2d support for tegra 114 SoC QXL: oops fix, and multi-head fixes DRM core: sysfs lifetime fixes client capability ioctl further cleanups to device midlayer more vblank timestamp fixes" * 'drm-next' of git://people.freedesktop.org/~airlied/linux: (789 commits) drm/nouveau: do not map evicted vram buffers in nouveau_bo_vma_add drm/nvc0-/gr: shift wrapping bug in nvc0_grctx_generate_r406800 drm/nouveau/pwr: fix missing mutex unlock in a failure path drm/nv40/therm: fix slowing down fan when pstate undefined drm/nv11-: synchronise flips to vblank, unless async flip requested drm/nvc0-: remove nasty fifo swmthd hack for flip completion method drm/nv10-: we no longer need to create nvsw object on user channels drm/nouveau: always queue flips relative to kernel channel activity drm/nouveau: there is no need to reserve/fence the new fb when flipping drm/nouveau: when bailing out of a pushbuf ioctl, do not remove previous fence drm/nouveau: allow nouveau_fence_ref() to be a noop drm/nvc8/mc: msi rearm is via the nvc0 method drm/ttm: Fix vma page_prot bit manipulation drm/vmwgfx: Fix a couple of compile / sparse warnings and errors drm/vmwgfx: Resource evict fixes drm/edid: compare actual vrefresh for all modes for quirks drm: shmob_drm: Convert to clk_prepare/unprepare drm/nouveau: fix 32-bit build drm/i915/opregion: fix build error on CONFIG_ACPI=n Revert "drm/radeon/audio: don't set speaker allocation on DCE4+" ...
Diffstat (limited to 'drivers/gpu/drm/nouveau/core/engine/mpeg')
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c68
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.h15
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c103
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/mpeg/nv44.c194
4 files changed, 291 insertions, 89 deletions
diff --git a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c
index c1900430130..7eb6d94c84e 100644
--- a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c
+++ b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c
@@ -34,16 +34,7 @@
#include <engine/fifo.h>
#include <engine/mpeg.h>
-#include <engine/graph/nv40.h>
-
-struct nv31_mpeg_priv {
- struct nouveau_mpeg base;
- atomic_t refcount;
-};
-
-struct nv31_mpeg_chan {
- struct nouveau_object base;
-};
+#include <engine/mpeg/nv31.h>
/*******************************************************************************
* MPEG object classes
@@ -89,18 +80,18 @@ nv31_mpeg_mthd_dma(struct nouveau_object *object, u32 mthd, void *arg, u32 len)
if (mthd == 0x0190) {
/* DMA_CMD */
- nv_mask(priv, 0x00b300, 0x00030000, (dma0 & 0x00030000));
+ nv_mask(priv, 0x00b300, 0x00010000, (dma0 & 0x00030000) ? 0x00010000 : 0);
nv_wr32(priv, 0x00b334, base);
nv_wr32(priv, 0x00b324, size);
} else
if (mthd == 0x01a0) {
/* DMA_DATA */
- nv_mask(priv, 0x00b300, 0x000c0000, (dma0 & 0x00030000) << 2);
+ nv_mask(priv, 0x00b300, 0x00020000, (dma0 & 0x00030000) ? 0x00020000 : 0);
nv_wr32(priv, 0x00b360, base);
nv_wr32(priv, 0x00b364, size);
} else {
/* DMA_IMAGE, VRAM only */
- if (dma0 & 0x000c0000)
+ if (dma0 & 0x00030000)
return -EINVAL;
nv_wr32(priv, 0x00b370, base);
@@ -110,7 +101,7 @@ nv31_mpeg_mthd_dma(struct nouveau_object *object, u32 mthd, void *arg, u32 len)
return 0;
}
-static struct nouveau_ofuncs
+struct nouveau_ofuncs
nv31_mpeg_ofuncs = {
.ctor = nv31_mpeg_object_ctor,
.dtor = _nouveau_gpuobj_dtor,
@@ -146,16 +137,23 @@ nv31_mpeg_context_ctor(struct nouveau_object *parent,
{
struct nv31_mpeg_priv *priv = (void *)engine;
struct nv31_mpeg_chan *chan;
+ unsigned long flags;
int ret;
- if (!atomic_add_unless(&priv->refcount, 1, 1))
- return -EBUSY;
-
ret = nouveau_object_create(parent, engine, oclass, 0, &chan);
*pobject = nv_object(chan);
if (ret)
return ret;
+ spin_lock_irqsave(&nv_engine(priv)->lock, flags);
+ if (priv->chan) {
+ spin_unlock_irqrestore(&nv_engine(priv)->lock, flags);
+ nouveau_object_destroy(&chan->base);
+ *pobject = NULL;
+ return -EBUSY;
+ }
+ priv->chan = chan;
+ spin_unlock_irqrestore(&nv_engine(priv)->lock, flags);
return 0;
}
@@ -164,11 +162,15 @@ nv31_mpeg_context_dtor(struct nouveau_object *object)
{
struct nv31_mpeg_priv *priv = (void *)object->engine;
struct nv31_mpeg_chan *chan = (void *)object;
- atomic_dec(&priv->refcount);
+ unsigned long flags;
+
+ spin_lock_irqsave(&nv_engine(priv)->lock, flags);
+ priv->chan = NULL;
+ spin_unlock_irqrestore(&nv_engine(priv)->lock, flags);
nouveau_object_destroy(&chan->base);
}
-static struct nouveau_oclass
+struct nouveau_oclass
nv31_mpeg_cclass = {
.handle = NV_ENGCTX(MPEG, 0x31),
.ofuncs = &(struct nouveau_ofuncs) {
@@ -197,21 +199,19 @@ nv31_mpeg_tile_prog(struct nouveau_engine *engine, int i)
void
nv31_mpeg_intr(struct nouveau_subdev *subdev)
{
+ struct nv31_mpeg_priv *priv = (void *)subdev;
struct nouveau_fifo *pfifo = nouveau_fifo(subdev);
- struct nouveau_engine *engine = nv_engine(subdev);
- struct nouveau_object *engctx;
struct nouveau_handle *handle;
- struct nv31_mpeg_priv *priv = (void *)subdev;
- u32 inst = nv_rd32(priv, 0x00b318) & 0x000fffff;
+ struct nouveau_object *engctx;
u32 stat = nv_rd32(priv, 0x00b100);
u32 type = nv_rd32(priv, 0x00b230);
u32 mthd = nv_rd32(priv, 0x00b234);
u32 data = nv_rd32(priv, 0x00b238);
u32 show = stat;
- int chid;
+ unsigned long flags;
- engctx = nouveau_engctx_get(engine, inst);
- chid = pfifo->chid(pfifo, engctx);
+ spin_lock_irqsave(&nv_engine(priv)->lock, flags);
+ engctx = nv_object(priv->chan);
if (stat & 0x01000000) {
/* happens on initial binding of the object */
@@ -220,7 +220,7 @@ nv31_mpeg_intr(struct nouveau_subdev *subdev)
show &= ~0x01000000;
}
- if (type == 0x00000010) {
+ if (type == 0x00000010 && engctx) {
handle = nouveau_handle_get_class(engctx, 0x3174);
if (handle && !nv_call(handle->object, mthd, data))
show &= ~0x01000000;
@@ -232,13 +232,12 @@ nv31_mpeg_intr(struct nouveau_subdev *subdev)
nv_wr32(priv, 0x00b230, 0x00000001);
if (show) {
- nv_error(priv,
- "ch %d [0x%08x %s] 0x%08x 0x%08x 0x%08x 0x%08x\n",
- chid, inst << 4, nouveau_client_name(engctx), stat,
- type, mthd, data);
+ nv_error(priv, "ch %d [%s] 0x%08x 0x%08x 0x%08x 0x%08x\n",
+ pfifo->chid(pfifo, engctx),
+ nouveau_client_name(engctx), stat, type, mthd, data);
}
- nouveau_engctx_put(engctx);
+ spin_unlock_irqrestore(&nv_engine(priv)->lock, flags);
}
static int
@@ -284,10 +283,7 @@ nv31_mpeg_init(struct nouveau_object *object)
/* PMPEG init */
nv_wr32(priv, 0x00b32c, 0x00000000);
nv_wr32(priv, 0x00b314, 0x00000100);
- if (nv_device(priv)->chipset >= 0x40 && nv44_graph_class(priv))
- nv_wr32(priv, 0x00b220, 0x00000044);
- else
- nv_wr32(priv, 0x00b220, 0x00000031);
+ nv_wr32(priv, 0x00b220, 0x00000031);
nv_wr32(priv, 0x00b300, 0x02001ec1);
nv_mask(priv, 0x00b32c, 0x00000001, 0x00000001);
diff --git a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.h b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.h
new file mode 100644
index 00000000000..d08629d0b6a
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.h
@@ -0,0 +1,15 @@
+#ifndef __NV31_MPEG_H__
+#define __NV31_MPEG_H__
+
+#include <engine/mpeg.h>
+
+struct nv31_mpeg_chan {
+ struct nouveau_object base;
+};
+
+struct nv31_mpeg_priv {
+ struct nouveau_mpeg base;
+ struct nv31_mpeg_chan *chan;
+};
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c
index dd6196072e9..d4e7ec0ba68 100644
--- a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c
+++ b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c
@@ -31,66 +31,63 @@
#include <subdev/instmem.h>
#include <engine/mpeg.h>
-#include <engine/graph/nv40.h>
-
-struct nv40_mpeg_priv {
- struct nouveau_mpeg base;
-};
-
-struct nv40_mpeg_chan {
- struct nouveau_mpeg_chan base;
-};
+#include <engine/mpeg/nv31.h>
/*******************************************************************************
- * PMPEG context
+ * MPEG object classes
******************************************************************************/
static int
-nv40_mpeg_context_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv40_mpeg_mthd_dma(struct nouveau_object *object, u32 mthd, void *arg, u32 len)
{
- struct nv40_mpeg_chan *chan;
- int ret;
-
- ret = nouveau_mpeg_context_create(parent, engine, oclass, NULL,
- 264 * 4, 16,
- NVOBJ_FLAG_ZERO_ALLOC, &chan);
- *pobject = nv_object(chan);
- if (ret)
- return ret;
+ struct nouveau_instmem *imem = nouveau_instmem(object);
+ struct nv31_mpeg_priv *priv = (void *)object->engine;
+ u32 inst = *(u32 *)arg << 4;
+ u32 dma0 = nv_ro32(imem, inst + 0);
+ u32 dma1 = nv_ro32(imem, inst + 4);
+ u32 dma2 = nv_ro32(imem, inst + 8);
+ u32 base = (dma2 & 0xfffff000) | (dma0 >> 20);
+ u32 size = dma1 + 1;
+
+ /* only allow linear DMA objects */
+ if (!(dma0 & 0x00002000))
+ return -EINVAL;
+
+ if (mthd == 0x0190) {
+ /* DMA_CMD */
+ nv_mask(priv, 0x00b300, 0x00030000, (dma0 & 0x00030000));
+ nv_wr32(priv, 0x00b334, base);
+ nv_wr32(priv, 0x00b324, size);
+ } else
+ if (mthd == 0x01a0) {
+ /* DMA_DATA */
+ nv_mask(priv, 0x00b300, 0x000c0000, (dma0 & 0x00030000) << 2);
+ nv_wr32(priv, 0x00b360, base);
+ nv_wr32(priv, 0x00b364, size);
+ } else {
+ /* DMA_IMAGE, VRAM only */
+ if (dma0 & 0x00030000)
+ return -EINVAL;
+
+ nv_wr32(priv, 0x00b370, base);
+ nv_wr32(priv, 0x00b374, size);
+ }
- nv_wo32(&chan->base.base, 0x78, 0x02001ec1);
return 0;
}
-static int
-nv40_mpeg_context_fini(struct nouveau_object *object, bool suspend)
-{
-
- struct nv40_mpeg_priv *priv = (void *)object->engine;
- struct nv40_mpeg_chan *chan = (void *)object;
- u32 inst = 0x80000000 | nv_gpuobj(chan)->addr >> 4;
-
- nv_mask(priv, 0x00b32c, 0x00000001, 0x00000000);
- if (nv_rd32(priv, 0x00b318) == inst)
- nv_mask(priv, 0x00b318, 0x80000000, 0x00000000);
- nv_mask(priv, 0x00b32c, 0x00000001, 0x00000001);
- return 0;
-}
+static struct nouveau_omthds
+nv40_mpeg_omthds[] = {
+ { 0x0190, 0x0190, nv40_mpeg_mthd_dma },
+ { 0x01a0, 0x01a0, nv40_mpeg_mthd_dma },
+ { 0x01b0, 0x01b0, nv40_mpeg_mthd_dma },
+ {}
+};
-static struct nouveau_oclass
-nv40_mpeg_cclass = {
- .handle = NV_ENGCTX(MPEG, 0x40),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv40_mpeg_context_ctor,
- .dtor = _nouveau_mpeg_context_dtor,
- .init = _nouveau_mpeg_context_init,
- .fini = nv40_mpeg_context_fini,
- .rd32 = _nouveau_mpeg_context_rd32,
- .wr32 = _nouveau_mpeg_context_wr32,
- },
+struct nouveau_oclass
+nv40_mpeg_sclass[] = {
+ { 0x3174, &nv31_mpeg_ofuncs, nv40_mpeg_omthds },
+ {}
};
/*******************************************************************************
@@ -100,7 +97,7 @@ nv40_mpeg_cclass = {
static void
nv40_mpeg_intr(struct nouveau_subdev *subdev)
{
- struct nv40_mpeg_priv *priv = (void *)subdev;
+ struct nv31_mpeg_priv *priv = (void *)subdev;
u32 stat;
if ((stat = nv_rd32(priv, 0x00b100)))
@@ -117,7 +114,7 @@ nv40_mpeg_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
- struct nv40_mpeg_priv *priv;
+ struct nv31_mpeg_priv *priv;
int ret;
ret = nouveau_mpeg_create(parent, engine, oclass, &priv);
@@ -127,8 +124,8 @@ nv40_mpeg_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
nv_subdev(priv)->unit = 0x00000002;
nv_subdev(priv)->intr = nv40_mpeg_intr;
- nv_engine(priv)->cclass = &nv40_mpeg_cclass;
- nv_engine(priv)->sclass = nv31_mpeg_sclass;
+ nv_engine(priv)->cclass = &nv31_mpeg_cclass;
+ nv_engine(priv)->sclass = nv40_mpeg_sclass;
nv_engine(priv)->tile_prog = nv31_mpeg_tile_prog;
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv44.c b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv44.c
new file mode 100644
index 00000000000..3d8c2133e0e
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv44.c
@@ -0,0 +1,194 @@
+/*
+ * Copyright 2012 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <core/os.h>
+#include <core/class.h>
+#include <core/client.h>
+#include <core/engctx.h>
+#include <core/handle.h>
+
+#include <subdev/fb.h>
+#include <subdev/timer.h>
+#include <subdev/instmem.h>
+
+#include <engine/fifo.h>
+#include <engine/mpeg.h>
+
+struct nv44_mpeg_priv {
+ struct nouveau_mpeg base;
+};
+
+struct nv44_mpeg_chan {
+ struct nouveau_mpeg_chan base;
+};
+
+/*******************************************************************************
+ * PMPEG context
+ ******************************************************************************/
+
+static int
+nv44_mpeg_context_ctor(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv44_mpeg_chan *chan;
+ int ret;
+
+ ret = nouveau_mpeg_context_create(parent, engine, oclass, NULL,
+ 264 * 4, 16,
+ NVOBJ_FLAG_ZERO_ALLOC, &chan);
+ *pobject = nv_object(chan);
+ if (ret)
+ return ret;
+
+ nv_wo32(&chan->base.base, 0x78, 0x02001ec1);
+ return 0;
+}
+
+static int
+nv44_mpeg_context_fini(struct nouveau_object *object, bool suspend)
+{
+
+ struct nv44_mpeg_priv *priv = (void *)object->engine;
+ struct nv44_mpeg_chan *chan = (void *)object;
+ u32 inst = 0x80000000 | nv_gpuobj(chan)->addr >> 4;
+
+ nv_mask(priv, 0x00b32c, 0x00000001, 0x00000000);
+ if (nv_rd32(priv, 0x00b318) == inst)
+ nv_mask(priv, 0x00b318, 0x80000000, 0x00000000);
+ nv_mask(priv, 0x00b32c, 0x00000001, 0x00000001);
+ return 0;
+}
+
+static struct nouveau_oclass
+nv44_mpeg_cclass = {
+ .handle = NV_ENGCTX(MPEG, 0x44),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv44_mpeg_context_ctor,
+ .dtor = _nouveau_mpeg_context_dtor,
+ .init = _nouveau_mpeg_context_init,
+ .fini = nv44_mpeg_context_fini,
+ .rd32 = _nouveau_mpeg_context_rd32,
+ .wr32 = _nouveau_mpeg_context_wr32,
+ },
+};
+
+/*******************************************************************************
+ * PMPEG engine/subdev functions
+ ******************************************************************************/
+
+static void
+nv44_mpeg_intr(struct nouveau_subdev *subdev)
+{
+ struct nouveau_fifo *pfifo = nouveau_fifo(subdev);
+ struct nouveau_engine *engine = nv_engine(subdev);
+ struct nouveau_object *engctx;
+ struct nouveau_handle *handle;
+ struct nv44_mpeg_priv *priv = (void *)subdev;
+ u32 inst = nv_rd32(priv, 0x00b318) & 0x000fffff;
+ u32 stat = nv_rd32(priv, 0x00b100);
+ u32 type = nv_rd32(priv, 0x00b230);
+ u32 mthd = nv_rd32(priv, 0x00b234);
+ u32 data = nv_rd32(priv, 0x00b238);
+ u32 show = stat;
+ int chid;
+
+ engctx = nouveau_engctx_get(engine, inst);
+ chid = pfifo->chid(pfifo, engctx);
+
+ if (stat & 0x01000000) {
+ /* happens on initial binding of the object */
+ if (type == 0x00000020 && mthd == 0x0000) {
+ nv_mask(priv, 0x00b308, 0x00000000, 0x00000000);
+ show &= ~0x01000000;
+ }
+
+ if (type == 0x00000010) {
+ handle = nouveau_handle_get_class(engctx, 0x3174);
+ if (handle && !nv_call(handle->object, mthd, data))
+ show &= ~0x01000000;
+ nouveau_handle_put(handle);
+ }
+ }
+
+ nv_wr32(priv, 0x00b100, stat);
+ nv_wr32(priv, 0x00b230, 0x00000001);
+
+ if (show) {
+ nv_error(priv,
+ "ch %d [0x%08x %s] 0x%08x 0x%08x 0x%08x 0x%08x\n",
+ chid, inst << 4, nouveau_client_name(engctx), stat,
+ type, mthd, data);
+ }
+
+ nouveau_engctx_put(engctx);
+}
+
+static void
+nv44_mpeg_me_intr(struct nouveau_subdev *subdev)
+{
+ struct nv44_mpeg_priv *priv = (void *)subdev;
+ u32 stat;
+
+ if ((stat = nv_rd32(priv, 0x00b100)))
+ nv44_mpeg_intr(subdev);
+
+ if ((stat = nv_rd32(priv, 0x00b800))) {
+ nv_error(priv, "PMSRCH 0x%08x\n", stat);
+ nv_wr32(priv, 0x00b800, stat);
+ }
+}
+
+static int
+nv44_mpeg_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv44_mpeg_priv *priv;
+ int ret;
+
+ ret = nouveau_mpeg_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ nv_subdev(priv)->unit = 0x00000002;
+ nv_subdev(priv)->intr = nv44_mpeg_me_intr;
+ nv_engine(priv)->cclass = &nv44_mpeg_cclass;
+ nv_engine(priv)->sclass = nv40_mpeg_sclass;
+ nv_engine(priv)->tile_prog = nv31_mpeg_tile_prog;
+ return 0;
+}
+
+struct nouveau_oclass
+nv44_mpeg_oclass = {
+ .handle = NV_ENGINE(MPEG, 0x44),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv44_mpeg_ctor,
+ .dtor = _nouveau_mpeg_dtor,
+ .init = nv31_mpeg_init,
+ .fini = _nouveau_mpeg_fini,
+ },
+};