drm/nouveau: port all engines to new engine module format
[deliverable/linux.git] / drivers / gpu / drm / nouveau / core / engine / crypt / nv98.c
index c9adc1b8a7db2f2645ce8498949a3861d17222bb..559a1b1d7082ddb431ef4c74655a57b293976169 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2011 Red Hat Inc.
+ * 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"),
  * Authors: Ben Skeggs
  */
 
-#include "drmP.h"
+#include <core/os.h>
+#include <core/enum.h>
+#include <core/class.h>
+#include <core/engctx.h>
 
-#include "nouveau_drv.h"
-#include "nouveau_util.h"
-#include <core/ramht.h>
+#include <subdev/timer.h>
+#include <subdev/fb.h>
+
+#include <engine/crypt.h>
 
 #include "fuc/nv98.fuc.h"
 
 struct nv98_crypt_priv {
-       struct nouveau_exec_engine base;
+       struct nouveau_crypt base;
 };
 
 struct nv98_crypt_chan {
-       struct nouveau_gpuobj *mem;
+       struct nouveau_crypt_chan base;
 };
 
-static int
-nv98_crypt_context_new(struct nouveau_channel *chan, int engine)
-{
-       struct drm_device *dev = chan->dev;
-       struct nv98_crypt_priv *priv = nv_engine(dev, engine);
-       struct nv98_crypt_chan *cctx;
-       int ret;
-
-       cctx = chan->engctx[engine] = kzalloc(sizeof(*cctx), GFP_KERNEL);
-       if (!cctx)
-               return -ENOMEM;
-
-       nvvm_engref(chan->vm, engine, 1);
-
-       ret = nouveau_gpuobj_new(dev, chan, 256, 0, NVOBJ_FLAG_ZERO_ALLOC |
-                                NVOBJ_FLAG_ZERO_FREE, &cctx->mem);
-       if (ret)
-               goto error;
-
-       nv_wo32(chan->ramin, 0xa0, 0x00190000);
-       nv_wo32(chan->ramin, 0xa4, cctx->mem->addr + cctx->mem->size - 1);
-       nv_wo32(chan->ramin, 0xa8, cctx->mem->addr);
-       nv_wo32(chan->ramin, 0xac, 0x00000000);
-       nv_wo32(chan->ramin, 0xb0, 0x00000000);
-       nv_wo32(chan->ramin, 0xb4, 0x00000000);
-       nvimem_flush(dev);
-
-error:
-       if (ret)
-               priv->base.context_del(chan, engine);
-       return ret;
-}
-
-static void
-nv98_crypt_context_del(struct nouveau_channel *chan, int engine)
-{
-       struct nv98_crypt_chan *cctx = chan->engctx[engine];
-       int i;
-
-       for (i = 0xa0; i < 0xb4; i += 4)
-               nv_wo32(chan->ramin, i, 0x00000000);
+/*******************************************************************************
+ * Crypt object classes
+ ******************************************************************************/
 
-       nouveau_gpuobj_ref(NULL, &cctx->mem);
+static struct nouveau_oclass
+nv98_crypt_sclass[] = {
+       { 0x88b4, &nouveau_object_ofuncs },
+       {},
+};
 
-       nvvm_engref(chan->vm, engine, -1);
-       chan->engctx[engine] = NULL;
-       kfree(cctx);
-}
+/*******************************************************************************
+ * PCRYPT context
+ ******************************************************************************/
 
 static int
-nv98_crypt_object_new(struct nouveau_channel *chan, int engine,
-                    u32 handle, u16 class)
+nv98_crypt_context_ctor(struct nouveau_object *parent,
+                       struct nouveau_object *engine,
+                       struct nouveau_oclass *oclass, void *data, u32 size,
+                       struct nouveau_object **pobject)
 {
-       struct nv98_crypt_chan *cctx = chan->engctx[engine];
-
-       /* fuc engine doesn't need an object, our ramht code does.. */
-       cctx->mem->engine = 5;
-       cctx->mem->class  = class;
-       return nouveau_ramht_insert(chan, handle, cctx->mem);
-}
+       struct nv98_crypt_chan *priv;
+       int ret;
 
-static void
-nv98_crypt_tlb_flush(struct drm_device *dev, int engine)
-{
-       nv50_vm_flush_engine(dev, 0x0a);
-}
+       ret = nouveau_crypt_context_create(parent, engine, oclass, NULL, 256,
+                                          256, NVOBJ_FLAG_ZERO_ALLOC, &priv);
+       *pobject = nv_object(priv);
+       if (ret)
+               return ret;
 
-static int
-nv98_crypt_fini(struct drm_device *dev, int engine, bool suspend)
-{
-       nv_mask(dev, 0x000200, 0x00004000, 0x00000000);
        return 0;
 }
 
-static int
-nv98_crypt_init(struct drm_device *dev, int engine)
-{
-       int i;
-
-       /* reset! */
-       nv_mask(dev, 0x000200, 0x00004000, 0x00000000);
-       nv_mask(dev, 0x000200, 0x00004000, 0x00004000);
-
-       /* wait for exit interrupt to signal */
-       nv_wait(dev, 0x087008, 0x00000010, 0x00000010);
-       nv_wr32(dev, 0x087004, 0x00000010);
-
-       /* upload microcode code and data segments */
-       nv_wr32(dev, 0x087ff8, 0x00100000);
-       for (i = 0; i < ARRAY_SIZE(nv98_pcrypt_code); i++)
-               nv_wr32(dev, 0x087ff4, nv98_pcrypt_code[i]);
-
-       nv_wr32(dev, 0x087ff8, 0x00000000);
-       for (i = 0; i < ARRAY_SIZE(nv98_pcrypt_data); i++)
-               nv_wr32(dev, 0x087ff4, nv98_pcrypt_data[i]);
+static struct nouveau_oclass
+nv98_crypt_cclass = {
+       .handle = NV_ENGCTX(CRYPT, 0x98),
+       .ofuncs = &(struct nouveau_ofuncs) {
+               .ctor = nv98_crypt_context_ctor,
+               .dtor = _nouveau_crypt_context_dtor,
+               .init = _nouveau_crypt_context_init,
+               .fini = _nouveau_crypt_context_fini,
+               .rd32 = _nouveau_crypt_context_rd32,
+               .wr32 = _nouveau_crypt_context_wr32,
+       },
+};
 
-       /* start it running */
-       nv_wr32(dev, 0x08710c, 0x00000000);
-       nv_wr32(dev, 0x087104, 0x00000000); /* ENTRY */
-       nv_wr32(dev, 0x087100, 0x00000002); /* TRIGGER */
-       return 0;
-}
+/*******************************************************************************
+ * PCRYPT engine/subdev functions
+ ******************************************************************************/
 
 static struct nouveau_enum nv98_crypt_isr_error_name[] = {
        { 0x0000, "ILLEGAL_MTHD" },
@@ -150,65 +100,100 @@ static struct nouveau_enum nv98_crypt_isr_error_name[] = {
 };
 
 static void
-nv98_crypt_isr(struct drm_device *dev)
+nv98_crypt_intr(struct nouveau_subdev *subdev)
 {
-       u32 disp = nv_rd32(dev, 0x08701c);
-       u32 stat = nv_rd32(dev, 0x087008) & disp & ~(disp >> 16);
-       u32 inst = nv_rd32(dev, 0x087050) & 0x3fffffff;
-       u32 ssta = nv_rd32(dev, 0x087040) & 0x0000ffff;
-       u32 addr = nv_rd32(dev, 0x087040) >> 16;
+       struct nv98_crypt_priv *priv = (void *)subdev;
+       u32 disp = nv_rd32(priv, 0x08701c);
+       u32 stat = nv_rd32(priv, 0x087008) & disp & ~(disp >> 16);
+       u32 inst = nv_rd32(priv, 0x087050) & 0x3fffffff;
+       u32 ssta = nv_rd32(priv, 0x087040) & 0x0000ffff;
+       u32 addr = nv_rd32(priv, 0x087040) >> 16;
        u32 mthd = (addr & 0x07ff) << 2;
        u32 subc = (addr & 0x3800) >> 11;
-       u32 data = nv_rd32(dev, 0x087044);
-       int chid = nv50_graph_isr_chid(dev, inst);
+       u32 data = nv_rd32(priv, 0x087044);
 
        if (stat & 0x00000040) {
-               NV_INFO(dev, "PCRYPT: DISPATCH_ERROR [");
+               nv_error(priv, "DISPATCH_ERROR [");
                nouveau_enum_print(nv98_crypt_isr_error_name, ssta);
-               printk("] ch %d [0x%08x] subc %d mthd 0x%04x data 0x%08x\n",
-                       chid, inst, subc, mthd, data);
-               nv_wr32(dev, 0x087004, 0x00000040);
+               printk("] ch 0x%08x subc %d mthd 0x%04x data 0x%08x\n",
+                      inst, subc, mthd, data);
+               nv_wr32(priv, 0x087004, 0x00000040);
                stat &= ~0x00000040;
        }
 
        if (stat) {
-               NV_INFO(dev, "PCRYPT: unhandled intr 0x%08x\n", stat);
-               nv_wr32(dev, 0x087004, stat);
+               nv_error(priv, "unhandled intr 0x%08x\n", stat);
+               nv_wr32(priv, 0x087004, stat);
        }
 
-       nv50_fb_vm_trap(dev, 1);
+       nv50_fb_trap(nouveau_fb(priv), 1);
 }
 
-static void
-nv98_crypt_destroy(struct drm_device *dev, int engine)
+static int
+nv98_crypt_tlb_flush(struct nouveau_engine *engine)
 {
-       struct nv98_crypt_priv *priv = nv_engine(dev, engine);
-
-       nouveau_irq_unregister(dev, 14);
-       NVOBJ_ENGINE_DEL(dev, CRYPT);
-       kfree(priv);
+       nv50_vm_flush_engine(&engine->base, 0x0a);
+       return 0;
 }
 
-int
-nv98_crypt_create(struct drm_device *dev)
+static int
+nv98_crypt_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+              struct nouveau_oclass *oclass, void *data, u32 size,
+              struct nouveau_object **pobject)
 {
        struct nv98_crypt_priv *priv;
+       int ret;
+
+       ret = nouveau_crypt_create(parent, engine, oclass, &priv);
+       *pobject = nv_object(priv);
+       if (ret)
+               return ret;
+
+       nv_subdev(priv)->unit = 0x00004000;
+       nv_subdev(priv)->intr = nv98_crypt_intr;
+       nv_engine(priv)->cclass = &nv98_crypt_cclass;
+       nv_engine(priv)->sclass = nv98_crypt_sclass;
+       nv_engine(priv)->tlb_flush = nv98_crypt_tlb_flush;
+       return 0;
+}
+
+static int
+nv98_crypt_init(struct nouveau_object *object)
+{
+       struct nv98_crypt_priv *priv = (void *)object;
+       int ret, i;
+
+       ret = nouveau_crypt_init(&priv->base);
+       if (ret)
+               return ret;
 
-       priv = kzalloc(sizeof(*priv), GFP_KERNEL);
-       if (!priv)
-               return -ENOMEM;
+       /* wait for exit interrupt to signal */
+       nv_wait(priv, 0x087008, 0x00000010, 0x00000010);
+       nv_wr32(priv, 0x087004, 0x00000010);
 
-       priv->base.destroy = nv98_crypt_destroy;
-       priv->base.init = nv98_crypt_init;
-       priv->base.fini = nv98_crypt_fini;
-       priv->base.context_new = nv98_crypt_context_new;
-       priv->base.context_del = nv98_crypt_context_del;
-       priv->base.object_new = nv98_crypt_object_new;
-       priv->base.tlb_flush = nv98_crypt_tlb_flush;
+       /* upload microcode code and data segments */
+       nv_wr32(priv, 0x087ff8, 0x00100000);
+       for (i = 0; i < ARRAY_SIZE(nv98_pcrypt_code); i++)
+               nv_wr32(priv, 0x087ff4, nv98_pcrypt_code[i]);
 
-       nouveau_irq_register(dev, 14, nv98_crypt_isr);
+       nv_wr32(priv, 0x087ff8, 0x00000000);
+       for (i = 0; i < ARRAY_SIZE(nv98_pcrypt_data); i++)
+               nv_wr32(priv, 0x087ff4, nv98_pcrypt_data[i]);
 
-       NVOBJ_ENGINE_ADD(dev, CRYPT, &priv->base);
-       NVOBJ_CLASS(dev, 0x88b4, CRYPT);
+       /* start it running */
+       nv_wr32(priv, 0x08710c, 0x00000000);
+       nv_wr32(priv, 0x087104, 0x00000000); /* ENTRY */
+       nv_wr32(priv, 0x087100, 0x00000002); /* TRIGGER */
        return 0;
 }
+
+struct nouveau_oclass
+nv98_crypt_oclass = {
+       .handle = NV_ENGINE(CRYPT, 0x98),
+       .ofuncs = &(struct nouveau_ofuncs) {
+               .ctor = nv98_crypt_ctor,
+               .dtor = _nouveau_crypt_dtor,
+               .init = nv98_crypt_init,
+               .fini = _nouveau_crypt_fini,
+       },
+};
This page took 0.037861 seconds and 5 git commands to generate.