drm/nvd0/dmaobj: initial bind() method implementation
authorBen Skeggs <bskeggs@redhat.com>
Mon, 8 Oct 2012 04:44:00 +0000 (14:44 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Wed, 28 Nov 2012 23:56:40 +0000 (09:56 +1000)
Currently unused, and rudimentary.  Lots to figure out here still, but
this is sufficient for what disp will need.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/core/engine/dmaobj/nvd0.c
drivers/gpu/drm/nouveau/core/include/core/class.h

index 7211cd83c0ee5f5e1fd97a44888d2757a60fbbce..8cefccf4cb56b3e871b9eaf986db79bd4cfb00f7 100644 (file)
@@ -39,7 +39,8 @@ nvd0_dmaobj_bind(struct nouveau_dmaeng *dmaeng,
                 struct nouveau_dmaobj *dmaobj,
                 struct nouveau_gpuobj **pgpuobj)
 {
-       int ret = 0;
+       u32 flags0 = 0x00000000;
+       int ret;
 
        if (!nv_iclass(parent, NV_ENGCTX_CLASS)) {
                switch (nv_mclass(parent->parent)) {
@@ -50,6 +51,38 @@ nvd0_dmaobj_bind(struct nouveau_dmaeng *dmaeng,
        } else
                return 0;
 
+       if (!(dmaobj->conf0 & NVD0_DMA_CONF0_ENABLE)) {
+               if (dmaobj->target == NV_MEM_TARGET_VM) {
+                       dmaobj->conf0 |= NVD0_DMA_CONF0_TYPE_VM;
+                       dmaobj->conf0 |= NVD0_DMA_CONF0_PAGE_LP;
+               } else {
+                       dmaobj->conf0 |= NVD0_DMA_CONF0_TYPE_LINEAR;
+                       dmaobj->conf0 |= NVD0_DMA_CONF0_PAGE_SP;
+               }
+       }
+
+       flags0 |= (dmaobj->conf0 & NVD0_DMA_CONF0_TYPE) << 20;
+       flags0 |= (dmaobj->conf0 & NVD0_DMA_CONF0_PAGE) >> 4;
+
+       switch (dmaobj->target) {
+       case NV_MEM_TARGET_VRAM:
+               flags0 |= 0x00000009;
+               break;
+       default:
+               return -EINVAL;
+               break;
+       }
+
+       ret = nouveau_gpuobj_new(parent, parent, 24, 32, 0, pgpuobj);
+       if (ret == 0) {
+               nv_wo32(*pgpuobj, 0x00, flags0);
+               nv_wo32(*pgpuobj, 0x04, dmaobj->start >> 8);
+               nv_wo32(*pgpuobj, 0x08, dmaobj->limit >> 8);
+               nv_wo32(*pgpuobj, 0x0c, 0x00000000);
+               nv_wo32(*pgpuobj, 0x10, 0x00000000);
+               nv_wo32(*pgpuobj, 0x14, 0x00000000);
+       }
+
        return ret;
 }
 
index ab4ab662a8ba095795bbcfe92e536b7c564c7900..b8520334935e1a3eda42f47cfeefa9c8662035c0 100644 (file)
@@ -80,6 +80,15 @@ struct nv_device_class {
 #define NVC0_DMA_CONF0_TYPE_LINEAR                                   0x00000000
 #define NVC0_DMA_CONF0_TYPE_VM                                       0x000000ff
 
+/* NVD9- */
+#define NVD0_DMA_CONF0_ENABLE                                        0x80000000
+#define NVD0_DMA_CONF0_PAGE                                          0x00000400
+#define NVD0_DMA_CONF0_PAGE_LP                                       0x00000000
+#define NVD0_DMA_CONF0_PAGE_SP                                       0x00000400
+#define NVD0_DMA_CONF0_TYPE                                          0x000000ff
+#define NVD0_DMA_CONF0_TYPE_LINEAR                                   0x00000000
+#define NVD0_DMA_CONF0_TYPE_VM                                       0x000000ff
+
 struct nv_dma_class {
        u32 flags;
        u32 pad0;