These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / drivers / gpu / drm / nouveau / nvkm / engine / mpeg / nv50.c
index b3463f3..c3a85df 100644 (file)
  *
  * Authors: Ben Skeggs
  */
-#include <engine/mpeg.h>
+#include "priv.h"
 
-#include <subdev/bar.h>
+#include <core/gpuobj.h>
 #include <subdev/timer.h>
 
-struct nv50_mpeg_priv {
-       struct nvkm_mpeg base;
-};
-
-struct nv50_mpeg_chan {
-       struct nvkm_mpeg_chan base;
-};
-
-/*******************************************************************************
- * MPEG object classes
- ******************************************************************************/
-
-static int
-nv50_mpeg_object_ctor(struct nvkm_object *parent,
-                     struct nvkm_object *engine,
-                     struct nvkm_oclass *oclass, void *data, u32 size,
-                     struct nvkm_object **pobject)
-{
-       struct nvkm_gpuobj *obj;
-       int ret;
-
-       ret = nvkm_gpuobj_create(parent, engine, oclass, 0, parent,
-                                16, 16, 0, &obj);
-       *pobject = nv_object(obj);
-       if (ret)
-               return ret;
-
-       nv_wo32(obj, 0x00, nv_mclass(obj));
-       nv_wo32(obj, 0x04, 0x00000000);
-       nv_wo32(obj, 0x08, 0x00000000);
-       nv_wo32(obj, 0x0c, 0x00000000);
-       return 0;
-}
-
-struct nvkm_ofuncs
-nv50_mpeg_ofuncs = {
-       .ctor = nv50_mpeg_object_ctor,
-       .dtor = _nvkm_gpuobj_dtor,
-       .init = _nvkm_gpuobj_init,
-       .fini = _nvkm_gpuobj_fini,
-       .rd32 = _nvkm_gpuobj_rd32,
-       .wr32 = _nvkm_gpuobj_wr32,
-};
-
-static struct nvkm_oclass
-nv50_mpeg_sclass[] = {
-       { 0x3174, &nv50_mpeg_ofuncs },
-       {}
-};
+#include <nvif/class.h>
 
 /*******************************************************************************
  * PMPEG context
  ******************************************************************************/
 
-int
-nv50_mpeg_context_ctor(struct nvkm_object *parent,
-                      struct nvkm_object *engine,
-                      struct nvkm_oclass *oclass, void *data, u32 size,
-                      struct nvkm_object **pobject)
+static int
+nv50_mpeg_cclass_bind(struct nvkm_object *object, struct nvkm_gpuobj *parent,
+                     int align, struct nvkm_gpuobj **pgpuobj)
 {
-       struct nvkm_bar *bar = nvkm_bar(parent);
-       struct nv50_mpeg_chan *chan;
-       int ret;
-
-       ret = nvkm_mpeg_context_create(parent, engine, oclass, NULL, 128 * 4,
-                                      0, NVOBJ_FLAG_ZERO_ALLOC, &chan);
-       *pobject = nv_object(chan);
-       if (ret)
-               return ret;
-
-       nv_wo32(chan, 0x0070, 0x00801ec1);
-       nv_wo32(chan, 0x007c, 0x0000037c);
-       bar->flush(bar);
-       return 0;
+       int ret = nvkm_gpuobj_new(object->engine->subdev.device, 128 * 4,
+                                 align, true, parent, pgpuobj);
+       if (ret == 0) {
+               nvkm_kmap(*pgpuobj);
+               nvkm_wo32(*pgpuobj, 0x70, 0x00801ec1);
+               nvkm_wo32(*pgpuobj, 0x7c, 0x0000037c);
+               nvkm_done(*pgpuobj);
+       }
+       return ret;
 }
 
-static struct nvkm_oclass
+const struct nvkm_object_func
 nv50_mpeg_cclass = {
-       .handle = NV_ENGCTX(MPEG, 0x50),
-       .ofuncs = &(struct nvkm_ofuncs) {
-               .ctor = nv50_mpeg_context_ctor,
-               .dtor = _nvkm_mpeg_context_dtor,
-               .init = _nvkm_mpeg_context_init,
-               .fini = _nvkm_mpeg_context_fini,
-               .rd32 = _nvkm_mpeg_context_rd32,
-               .wr32 = _nvkm_mpeg_context_wr32,
-       },
+       .bind = nv50_mpeg_cclass_bind,
 };
 
 /*******************************************************************************
@@ -120,106 +57,79 @@ nv50_mpeg_cclass = {
  ******************************************************************************/
 
 void
-nv50_mpeg_intr(struct nvkm_subdev *subdev)
+nv50_mpeg_intr(struct nvkm_engine *mpeg)
 {
-       struct nv50_mpeg_priv *priv = (void *)subdev;
-       u32 stat = nv_rd32(priv, 0x00b100);
-       u32 type = nv_rd32(priv, 0x00b230);
-       u32 mthd = nv_rd32(priv, 0x00b234);
-       u32 data = nv_rd32(priv, 0x00b238);
+       struct nvkm_subdev *subdev = &mpeg->subdev;
+       struct nvkm_device *device = subdev->device;
+       u32 stat = nvkm_rd32(device, 0x00b100);
+       u32 type = nvkm_rd32(device, 0x00b230);
+       u32 mthd = nvkm_rd32(device, 0x00b234);
+       u32 data = nvkm_rd32(device, 0x00b238);
        u32 show = stat;
 
        if (stat & 0x01000000) {
                /* happens on initial binding of the object */
                if (type == 0x00000020 && mthd == 0x0000) {
-                       nv_wr32(priv, 0x00b308, 0x00000100);
+                       nvkm_wr32(device, 0x00b308, 0x00000100);
                        show &= ~0x01000000;
                }
        }
 
        if (show) {
-               nv_info(priv, "0x%08x 0x%08x 0x%08x 0x%08x\n",
-                       stat, type, mthd, data);
-       }
-
-       nv_wr32(priv, 0x00b100, stat);
-       nv_wr32(priv, 0x00b230, 0x00000001);
-}
-
-static void
-nv50_vpe_intr(struct nvkm_subdev *subdev)
-{
-       struct nv50_mpeg_priv *priv = (void *)subdev;
-
-       if (nv_rd32(priv, 0x00b100))
-               nv50_mpeg_intr(subdev);
-
-       if (nv_rd32(priv, 0x00b800)) {
-               u32 stat = nv_rd32(priv, 0x00b800);
-               nv_info(priv, "PMSRCH: 0x%08x\n", stat);
-               nv_wr32(priv, 0xb800, stat);
+               nvkm_info(subdev, "%08x %08x %08x %08x\n",
+                         stat, type, mthd, data);
        }
-}
 
-static int
-nv50_mpeg_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
-              struct nvkm_oclass *oclass, void *data, u32 size,
-              struct nvkm_object **pobject)
-{
-       struct nv50_mpeg_priv *priv;
-       int ret;
-
-       ret = nvkm_mpeg_create(parent, engine, oclass, &priv);
-       *pobject = nv_object(priv);
-       if (ret)
-               return ret;
-
-       nv_subdev(priv)->unit = 0x00400002;
-       nv_subdev(priv)->intr = nv50_vpe_intr;
-       nv_engine(priv)->cclass = &nv50_mpeg_cclass;
-       nv_engine(priv)->sclass = nv50_mpeg_sclass;
-       return 0;
+       nvkm_wr32(device, 0x00b100, stat);
+       nvkm_wr32(device, 0x00b230, 0x00000001);
 }
 
 int
-nv50_mpeg_init(struct nvkm_object *object)
+nv50_mpeg_init(struct nvkm_engine *mpeg)
 {
-       struct nv50_mpeg_priv *priv = (void *)object;
-       int ret;
-
-       ret = nvkm_mpeg_init(&priv->base);
-       if (ret)
-               return ret;
-
-       nv_wr32(priv, 0x00b32c, 0x00000000);
-       nv_wr32(priv, 0x00b314, 0x00000100);
-       nv_wr32(priv, 0x00b0e0, 0x0000001a);
-
-       nv_wr32(priv, 0x00b220, 0x00000044);
-       nv_wr32(priv, 0x00b300, 0x00801ec1);
-       nv_wr32(priv, 0x00b390, 0x00000000);
-       nv_wr32(priv, 0x00b394, 0x00000000);
-       nv_wr32(priv, 0x00b398, 0x00000000);
-       nv_mask(priv, 0x00b32c, 0x00000001, 0x00000001);
-
-       nv_wr32(priv, 0x00b100, 0xffffffff);
-       nv_wr32(priv, 0x00b140, 0xffffffff);
-
-       if (!nv_wait(priv, 0x00b200, 0x00000001, 0x00000000)) {
-               nv_error(priv, "timeout 0x%08x\n", nv_rd32(priv, 0x00b200));
+       struct nvkm_subdev *subdev = &mpeg->subdev;
+       struct nvkm_device *device = subdev->device;
+
+       nvkm_wr32(device, 0x00b32c, 0x00000000);
+       nvkm_wr32(device, 0x00b314, 0x00000100);
+       nvkm_wr32(device, 0x00b0e0, 0x0000001a);
+
+       nvkm_wr32(device, 0x00b220, 0x00000044);
+       nvkm_wr32(device, 0x00b300, 0x00801ec1);
+       nvkm_wr32(device, 0x00b390, 0x00000000);
+       nvkm_wr32(device, 0x00b394, 0x00000000);
+       nvkm_wr32(device, 0x00b398, 0x00000000);
+       nvkm_mask(device, 0x00b32c, 0x00000001, 0x00000001);
+
+       nvkm_wr32(device, 0x00b100, 0xffffffff);
+       nvkm_wr32(device, 0x00b140, 0xffffffff);
+
+       if (nvkm_msec(device, 2000,
+               if (!(nvkm_rd32(device, 0x00b200) & 0x00000001))
+                       break;
+       ) < 0) {
+               nvkm_error(subdev, "timeout %08x\n",
+                          nvkm_rd32(device, 0x00b200));
                return -EBUSY;
        }
 
        return 0;
 }
 
-struct nvkm_oclass
-nv50_mpeg_oclass = {
-       .handle = NV_ENGINE(MPEG, 0x50),
-       .ofuncs = &(struct nvkm_ofuncs) {
-               .ctor = nv50_mpeg_ctor,
-               .dtor = _nvkm_mpeg_dtor,
-               .init = nv50_mpeg_init,
-               .fini = _nvkm_mpeg_fini,
-       },
+static const struct nvkm_engine_func
+nv50_mpeg = {
+       .init = nv50_mpeg_init,
+       .intr = nv50_mpeg_intr,
+       .cclass = &nv50_mpeg_cclass,
+       .sclass = {
+               { -1, -1, NV31_MPEG, &nv31_mpeg_object },
+               {}
+       }
 };
+
+int
+nv50_mpeg_new(struct nvkm_device *device, int index, struct nvkm_engine **pmpeg)
+{
+       return nvkm_engine_new_(&nv50_mpeg, device, index, 0x00400002,
+                               true, pmpeg);
+}