提交 f7d452f4 编写于 作者: D Dave Airlie

Merge branch 'drm-nouveau-next' of...

Merge branch 'drm-nouveau-next' of git://anongit.freedesktop.org/git/nouveau/linux-2.6 into drm-next

- Various fixes that make surviving concurrent piglit more possible.
- Buffer object deletion no longer synchronous
- Context/register initialisation updates that have been reported to
solve some stability issues (particularly on some problematic GF119
chips)
- Kernel side support for VP2 video decoding engines

* 'drm-nouveau-next' of git://anongit.freedesktop.org/git/nouveau/linux-2.6: (44 commits)
  drm/nvd0-/disp: handle case where display engine is missing/disabled
  drm/gr/nvc0-: merge nvc0/nve0 ucode, and use cpp instead of m4
  drm/nouveau/bsp/nv84: initial vp2 engine implementation
  drm/nouveau/vp/nv84: initial vp2 engine implementation
  drm/nouveau/core: xtensa engine base class implementation
  drm/nouveau/vdec: fork vp3 implementations from vp2
  drm/nouveau/core: move falcon class to engine/
  drm/nouveau/kms: don't fail if there's no dcb table entries
  drm/nouveau: remove limit on gart
  drm/nouveau/vm: perform a bar flush when flushing vm
  drm/nvc0/gr: cleanup register lists, and add nvce/nvcf to switches
  drm/nvc8/gr: update initial register/context values
  drm/nvc4/gr: update initial register/context values
  drm/nvc1/gr: update initial register/context values
  drm/nvc3/gr: update initial register/context values
  drm/nvc0/gr: update initial register/context values
  drm/nvd9/gr: update initial register/context values
  drm/nve4/gr: update initial register/context values
  drm/nvc0-/gr: bump maximum gpc/tpc limits
  drm/nvf0/gr: initial register/context setup
  ...
...@@ -12,7 +12,6 @@ nouveau-y += core/core/engctx.o ...@@ -12,7 +12,6 @@ nouveau-y += core/core/engctx.o
nouveau-y += core/core/engine.o nouveau-y += core/core/engine.o
nouveau-y += core/core/enum.o nouveau-y += core/core/enum.o
nouveau-y += core/core/event.o nouveau-y += core/core/event.o
nouveau-y += core/core/falcon.o
nouveau-y += core/core/gpuobj.o nouveau-y += core/core/gpuobj.o
nouveau-y += core/core/handle.o nouveau-y += core/core/handle.o
nouveau-y += core/core/mm.o nouveau-y += core/core/mm.o
...@@ -60,6 +59,8 @@ nouveau-y += core/subdev/devinit/nv10.o ...@@ -60,6 +59,8 @@ nouveau-y += core/subdev/devinit/nv10.o
nouveau-y += core/subdev/devinit/nv1a.o nouveau-y += core/subdev/devinit/nv1a.o
nouveau-y += core/subdev/devinit/nv20.o nouveau-y += core/subdev/devinit/nv20.o
nouveau-y += core/subdev/devinit/nv50.o nouveau-y += core/subdev/devinit/nv50.o
nouveau-y += core/subdev/devinit/nva3.o
nouveau-y += core/subdev/devinit/nvc0.o
nouveau-y += core/subdev/fb/base.o nouveau-y += core/subdev/fb/base.o
nouveau-y += core/subdev/fb/nv04.o nouveau-y += core/subdev/fb/nv04.o
nouveau-y += core/subdev/fb/nv10.o nouveau-y += core/subdev/fb/nv10.o
...@@ -78,6 +79,17 @@ nouveau-y += core/subdev/fb/nv49.o ...@@ -78,6 +79,17 @@ nouveau-y += core/subdev/fb/nv49.o
nouveau-y += core/subdev/fb/nv4e.o nouveau-y += core/subdev/fb/nv4e.o
nouveau-y += core/subdev/fb/nv50.o nouveau-y += core/subdev/fb/nv50.o
nouveau-y += core/subdev/fb/nvc0.o nouveau-y += core/subdev/fb/nvc0.o
nouveau-y += core/subdev/fb/ramnv04.o
nouveau-y += core/subdev/fb/ramnv10.o
nouveau-y += core/subdev/fb/ramnv1a.o
nouveau-y += core/subdev/fb/ramnv20.o
nouveau-y += core/subdev/fb/ramnv40.o
nouveau-y += core/subdev/fb/ramnv41.o
nouveau-y += core/subdev/fb/ramnv44.o
nouveau-y += core/subdev/fb/ramnv49.o
nouveau-y += core/subdev/fb/ramnv4e.o
nouveau-y += core/subdev/fb/ramnv50.o
nouveau-y += core/subdev/fb/ramnvc0.o
nouveau-y += core/subdev/gpio/base.o nouveau-y += core/subdev/gpio/base.o
nouveau-y += core/subdev/gpio/nv10.o nouveau-y += core/subdev/gpio/nv10.o
nouveau-y += core/subdev/gpio/nv50.o nouveau-y += core/subdev/gpio/nv50.o
...@@ -129,12 +141,15 @@ nouveau-y += core/subdev/vm/nv44.o ...@@ -129,12 +141,15 @@ nouveau-y += core/subdev/vm/nv44.o
nouveau-y += core/subdev/vm/nv50.o nouveau-y += core/subdev/vm/nv50.o
nouveau-y += core/subdev/vm/nvc0.o nouveau-y += core/subdev/vm/nvc0.o
nouveau-y += core/engine/falcon.o
nouveau-y += core/engine/xtensa.o
nouveau-y += core/engine/dmaobj/base.o nouveau-y += core/engine/dmaobj/base.o
nouveau-y += core/engine/dmaobj/nv04.o nouveau-y += core/engine/dmaobj/nv04.o
nouveau-y += core/engine/dmaobj/nv50.o nouveau-y += core/engine/dmaobj/nv50.o
nouveau-y += core/engine/dmaobj/nvc0.o nouveau-y += core/engine/dmaobj/nvc0.o
nouveau-y += core/engine/dmaobj/nvd0.o nouveau-y += core/engine/dmaobj/nvd0.o
nouveau-y += core/engine/bsp/nv84.o nouveau-y += core/engine/bsp/nv84.o
nouveau-y += core/engine/bsp/nv98.o
nouveau-y += core/engine/bsp/nvc0.o nouveau-y += core/engine/bsp/nvc0.o
nouveau-y += core/engine/bsp/nve0.o nouveau-y += core/engine/bsp/nve0.o
nouveau-y += core/engine/copy/nva3.o nouveau-y += core/engine/copy/nva3.o
...@@ -209,6 +224,7 @@ nouveau-y += core/engine/software/nv10.o ...@@ -209,6 +224,7 @@ nouveau-y += core/engine/software/nv10.o
nouveau-y += core/engine/software/nv50.o nouveau-y += core/engine/software/nv50.o
nouveau-y += core/engine/software/nvc0.o nouveau-y += core/engine/software/nvc0.o
nouveau-y += core/engine/vp/nv84.o nouveau-y += core/engine/vp/nv84.o
nouveau-y += core/engine/vp/nv98.o
nouveau-y += core/engine/vp/nvc0.o nouveau-y += core/engine/vp/nvc0.o
nouveau-y += core/engine/vp/nve0.o nouveau-y += core/engine/vp/nve0.o
......
...@@ -208,7 +208,6 @@ nouveau_mm_init(struct nouveau_mm *mm, u32 offset, u32 length, u32 block) ...@@ -208,7 +208,6 @@ nouveau_mm_init(struct nouveau_mm *mm, u32 offset, u32 length, u32 block)
struct nouveau_mm_node *node; struct nouveau_mm_node *node;
if (block) { if (block) {
mutex_init(&mm->mutex);
INIT_LIST_HEAD(&mm->nodes); INIT_LIST_HEAD(&mm->nodes);
INIT_LIST_HEAD(&mm->free); INIT_LIST_HEAD(&mm->free);
mm->block_size = block; mm->block_size = block;
......
...@@ -19,24 +19,19 @@ ...@@ -19,24 +19,19 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE. * OTHER DEALINGS IN THE SOFTWARE.
* *
* Authors: Ben Skeggs * Authors: Ben Skeggs, Ilia Mirkin
*/ */
#include <core/engctx.h> #include <engine/xtensa.h>
#include <core/class.h>
#include <engine/bsp.h> #include <engine/bsp.h>
struct nv84_bsp_priv {
struct nouveau_engine base;
};
/******************************************************************************* /*******************************************************************************
* BSP object classes * BSP object classes
******************************************************************************/ ******************************************************************************/
static struct nouveau_oclass static struct nouveau_oclass
nv84_bsp_sclass[] = { nv84_bsp_sclass[] = {
{ 0x74b0, &nouveau_object_ofuncs },
{}, {},
}; };
...@@ -48,7 +43,7 @@ static struct nouveau_oclass ...@@ -48,7 +43,7 @@ static struct nouveau_oclass
nv84_bsp_cclass = { nv84_bsp_cclass = {
.handle = NV_ENGCTX(BSP, 0x84), .handle = NV_ENGCTX(BSP, 0x84),
.ofuncs = &(struct nouveau_ofuncs) { .ofuncs = &(struct nouveau_ofuncs) {
.ctor = _nouveau_engctx_ctor, .ctor = _nouveau_xtensa_engctx_ctor,
.dtor = _nouveau_engctx_dtor, .dtor = _nouveau_engctx_dtor,
.init = _nouveau_engctx_init, .init = _nouveau_engctx_init,
.fini = _nouveau_engctx_fini, .fini = _nouveau_engctx_fini,
...@@ -66,10 +61,10 @@ nv84_bsp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, ...@@ -66,10 +61,10 @@ nv84_bsp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size, struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject) struct nouveau_object **pobject)
{ {
struct nv84_bsp_priv *priv; struct nouveau_xtensa *priv;
int ret; int ret;
ret = nouveau_engine_create(parent, engine, oclass, true, ret = nouveau_xtensa_create(parent, engine, oclass, 0x103000, true,
"PBSP", "bsp", &priv); "PBSP", "bsp", &priv);
*pobject = nv_object(priv); *pobject = nv_object(priv);
if (ret) if (ret)
...@@ -78,6 +73,8 @@ nv84_bsp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, ...@@ -78,6 +73,8 @@ nv84_bsp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
nv_subdev(priv)->unit = 0x04008000; nv_subdev(priv)->unit = 0x04008000;
nv_engine(priv)->cclass = &nv84_bsp_cclass; nv_engine(priv)->cclass = &nv84_bsp_cclass;
nv_engine(priv)->sclass = nv84_bsp_sclass; nv_engine(priv)->sclass = nv84_bsp_sclass;
priv->fifo_val = 0x1111;
priv->unkd28 = 0x90044;
return 0; return 0;
} }
...@@ -86,8 +83,10 @@ nv84_bsp_oclass = { ...@@ -86,8 +83,10 @@ nv84_bsp_oclass = {
.handle = NV_ENGINE(BSP, 0x84), .handle = NV_ENGINE(BSP, 0x84),
.ofuncs = &(struct nouveau_ofuncs) { .ofuncs = &(struct nouveau_ofuncs) {
.ctor = nv84_bsp_ctor, .ctor = nv84_bsp_ctor,
.dtor = _nouveau_engine_dtor, .dtor = _nouveau_xtensa_dtor,
.init = _nouveau_engine_init, .init = _nouveau_xtensa_init,
.fini = _nouveau_engine_fini, .fini = _nouveau_xtensa_fini,
.rd32 = _nouveau_xtensa_rd32,
.wr32 = _nouveau_xtensa_wr32,
}, },
}; };
/*
* 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/engctx.h>
#include <core/class.h>
#include <engine/bsp.h>
struct nv98_bsp_priv {
struct nouveau_engine base;
};
/*******************************************************************************
* BSP object classes
******************************************************************************/
static struct nouveau_oclass
nv98_bsp_sclass[] = {
{},
};
/*******************************************************************************
* BSP context
******************************************************************************/
static struct nouveau_oclass
nv98_bsp_cclass = {
.handle = NV_ENGCTX(BSP, 0x98),
.ofuncs = &(struct nouveau_ofuncs) {
.ctor = _nouveau_engctx_ctor,
.dtor = _nouveau_engctx_dtor,
.init = _nouveau_engctx_init,
.fini = _nouveau_engctx_fini,
.rd32 = _nouveau_engctx_rd32,
.wr32 = _nouveau_engctx_wr32,
},
};
/*******************************************************************************
* BSP engine/subdev functions
******************************************************************************/
static int
nv98_bsp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
struct nv98_bsp_priv *priv;
int ret;
ret = nouveau_engine_create(parent, engine, oclass, true,
"PBSP", "bsp", &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
nv_subdev(priv)->unit = 0x04008000;
nv_engine(priv)->cclass = &nv98_bsp_cclass;
nv_engine(priv)->sclass = nv98_bsp_sclass;
return 0;
}
struct nouveau_oclass
nv98_bsp_oclass = {
.handle = NV_ENGINE(BSP, 0x98),
.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nv98_bsp_ctor,
.dtor = _nouveau_engine_dtor,
.init = _nouveau_engine_init,
.fini = _nouveau_engine_fini,
},
};
...@@ -22,8 +22,7 @@ ...@@ -22,8 +22,7 @@
* Authors: Maarten Lankhorst * Authors: Maarten Lankhorst
*/ */
#include <core/falcon.h> #include <engine/falcon.h>
#include <engine/bsp.h> #include <engine/bsp.h>
struct nvc0_bsp_priv { struct nvc0_bsp_priv {
......
...@@ -22,8 +22,7 @@ ...@@ -22,8 +22,7 @@
* Authors: Ben Skeggs * Authors: Ben Skeggs
*/ */
#include <core/falcon.h> #include <engine/falcon.h>
#include <engine/bsp.h> #include <engine/bsp.h>
struct nve0_bsp_priv { struct nve0_bsp_priv {
......
static u32 nva3_pcopy_data[] = { uint32_t nva3_pcopy_data[] = {
/* 0x0000: ctx_object */ /* 0x0000: ctx_object */
0x00000000, 0x00000000,
/* 0x0004: ctx_dma */ /* 0x0004: ctx_dma */
...@@ -183,7 +183,7 @@ static u32 nva3_pcopy_data[] = { ...@@ -183,7 +183,7 @@ static u32 nva3_pcopy_data[] = {
0x00000800, 0x00000800,
}; };
static u32 nva3_pcopy_code[] = { uint32_t nva3_pcopy_code[] = {
/* 0x0000: main */ /* 0x0000: main */
0x04fe04bd, 0x04fe04bd,
0x3517f000, 0x3517f000,
......
static u32 nvc0_pcopy_data[] = { uint32_t nvc0_pcopy_data[] = {
/* 0x0000: ctx_object */ /* 0x0000: ctx_object */
0x00000000, 0x00000000,
/* 0x0004: ctx_query_address_high */ /* 0x0004: ctx_query_address_high */
...@@ -171,7 +171,7 @@ static u32 nvc0_pcopy_data[] = { ...@@ -171,7 +171,7 @@ static u32 nvc0_pcopy_data[] = {
0x00000800, 0x00000800,
}; };
static u32 nvc0_pcopy_code[] = { uint32_t nvc0_pcopy_code[] = {
/* 0x0000: main */ /* 0x0000: main */
0x04fe04bd, 0x04fe04bd,
0x3517f000, 0x3517f000,
......
...@@ -22,16 +22,17 @@ ...@@ -22,16 +22,17 @@
* Authors: Ben Skeggs * Authors: Ben Skeggs
*/ */
#include <core/client.h> #include <engine/falcon.h>
#include <core/falcon.h> #include <engine/fifo.h>
#include <core/class.h> #include <engine/copy.h>
#include <core/enum.h>
#include <subdev/fb.h> #include <subdev/fb.h>
#include <subdev/vm.h> #include <subdev/vm.h>
#include <engine/fifo.h> #include <core/client.h>
#include <engine/copy.h> #include <core/class.h>
#include <core/enum.h>
#include "fuc/nva3.fuc.h" #include "fuc/nva3.fuc.h"
...@@ -116,13 +117,6 @@ nva3_copy_intr(struct nouveau_subdev *subdev) ...@@ -116,13 +117,6 @@ nva3_copy_intr(struct nouveau_subdev *subdev)
nouveau_engctx_put(engctx); nouveau_engctx_put(engctx);
} }
static int
nva3_copy_tlb_flush(struct nouveau_engine *engine)
{
nv50_vm_flush_engine(&engine->base, 0x0d);
return 0;
}
static int static int
nva3_copy_ctor(struct nouveau_object *parent, struct nouveau_object *engine, nva3_copy_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size, struct nouveau_oclass *oclass, void *data, u32 size,
...@@ -142,7 +136,6 @@ nva3_copy_ctor(struct nouveau_object *parent, struct nouveau_object *engine, ...@@ -142,7 +136,6 @@ nva3_copy_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
nv_subdev(priv)->intr = nva3_copy_intr; nv_subdev(priv)->intr = nva3_copy_intr;
nv_engine(priv)->cclass = &nva3_copy_cclass; nv_engine(priv)->cclass = &nva3_copy_cclass;
nv_engine(priv)->sclass = nva3_copy_sclass; nv_engine(priv)->sclass = nva3_copy_sclass;
nv_engine(priv)->tlb_flush = nva3_copy_tlb_flush;
nv_falcon(priv)->code.data = nva3_pcopy_code; nv_falcon(priv)->code.data = nva3_pcopy_code;
nv_falcon(priv)->code.size = sizeof(nva3_pcopy_code); nv_falcon(priv)->code.size = sizeof(nva3_pcopy_code);
nv_falcon(priv)->data.data = nva3_pcopy_data; nv_falcon(priv)->data.data = nva3_pcopy_data;
......
...@@ -22,13 +22,15 @@ ...@@ -22,13 +22,15 @@
* Authors: Ben Skeggs * Authors: Ben Skeggs
*/ */
#include <core/falcon.h> #include <engine/falcon.h>
#include <core/class.h>
#include <core/enum.h>
#include <engine/fifo.h> #include <engine/fifo.h>
#include <engine/copy.h> #include <engine/copy.h>
#include <core/class.h>
#include <core/enum.h>
#include <core/class.h>
#include <core/enum.h>
#include "fuc/nvc0.fuc.h" #include "fuc/nvc0.fuc.h"
struct nvc0_copy_priv { struct nvc0_copy_priv {
......
...@@ -67,6 +67,19 @@ nve0_copy_cclass = { ...@@ -67,6 +67,19 @@ nve0_copy_cclass = {
* PCOPY engine/subdev functions * PCOPY engine/subdev functions
******************************************************************************/ ******************************************************************************/
static void
nve0_copy_intr(struct nouveau_subdev *subdev)
{
const int ce = nv_subidx(nv_object(subdev)) - NVDEV_ENGINE_COPY0;
struct nve0_copy_priv *priv = (void *)subdev;
u32 stat = nv_rd32(priv, 0x104908 + (ce * 0x1000));
if (stat) {
nv_warn(priv, "unhandled intr 0x%08x\n", stat);
nv_wr32(priv, 0x104908 + (ce * 0x1000), stat);
}
}
static int static int
nve0_copy0_ctor(struct nouveau_object *parent, struct nouveau_object *engine, nve0_copy0_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size, struct nouveau_oclass *oclass, void *data, u32 size,
...@@ -85,6 +98,7 @@ nve0_copy0_ctor(struct nouveau_object *parent, struct nouveau_object *engine, ...@@ -85,6 +98,7 @@ nve0_copy0_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return ret; return ret;
nv_subdev(priv)->unit = 0x00000040; nv_subdev(priv)->unit = 0x00000040;
nv_subdev(priv)->intr = nve0_copy_intr;
nv_engine(priv)->cclass = &nve0_copy_cclass; nv_engine(priv)->cclass = &nve0_copy_cclass;
nv_engine(priv)->sclass = nve0_copy_sclass; nv_engine(priv)->sclass = nve0_copy_sclass;
return 0; return 0;
...@@ -108,6 +122,28 @@ nve0_copy1_ctor(struct nouveau_object *parent, struct nouveau_object *engine, ...@@ -108,6 +122,28 @@ nve0_copy1_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return ret; return ret;
nv_subdev(priv)->unit = 0x00000080; nv_subdev(priv)->unit = 0x00000080;
nv_subdev(priv)->intr = nve0_copy_intr;
nv_engine(priv)->cclass = &nve0_copy_cclass;
nv_engine(priv)->sclass = nve0_copy_sclass;
return 0;
}
static int
nve0_copy2_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
struct nve0_copy_priv *priv;
int ret;
ret = nouveau_engine_create(parent, engine, oclass, true,
"PCE2", "copy2", &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
nv_subdev(priv)->unit = 0x00200000;
nv_subdev(priv)->intr = nve0_copy_intr;
nv_engine(priv)->cclass = &nve0_copy_cclass; nv_engine(priv)->cclass = &nve0_copy_cclass;
nv_engine(priv)->sclass = nve0_copy_sclass; nv_engine(priv)->sclass = nve0_copy_sclass;
return 0; return 0;
...@@ -134,3 +170,14 @@ nve0_copy1_oclass = { ...@@ -134,3 +170,14 @@ nve0_copy1_oclass = {
.fini = _nouveau_engine_fini, .fini = _nouveau_engine_fini,
}, },
}; };
struct nouveau_oclass
nve0_copy2_oclass = {
.handle = NV_ENGINE(COPY2, 0xe0),
.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nve0_copy2_ctor,
.dtor = _nouveau_engine_dtor,
.init = _nouveau_engine_init,
.fini = _nouveau_engine_fini,
},
};
static uint32_t nv98_pcrypt_data[] = { uint32_t nv98_pcrypt_data[] = {
/* 0x0000: ctx_dma */ /* 0x0000: ctx_dma */
/* 0x0000: ctx_dma_query */ /* 0x0000: ctx_dma_query */
0x00000000, 0x00000000,
...@@ -150,7 +150,7 @@ static uint32_t nv98_pcrypt_data[] = { ...@@ -150,7 +150,7 @@ static uint32_t nv98_pcrypt_data[] = {
0x00000000, 0x00000000,
}; };
static uint32_t nv98_pcrypt_code[] = { uint32_t nv98_pcrypt_code[] = {
0x17f004bd, 0x17f004bd,
0x0010fe35, 0x0010fe35,
0xf10004fe, 0xf10004fe,
......
...@@ -140,13 +140,6 @@ nv84_crypt_intr(struct nouveau_subdev *subdev) ...@@ -140,13 +140,6 @@ nv84_crypt_intr(struct nouveau_subdev *subdev)
nouveau_engctx_put(engctx); nouveau_engctx_put(engctx);
} }
static int
nv84_crypt_tlb_flush(struct nouveau_engine *engine)
{
nv50_vm_flush_engine(&engine->base, 0x0a);
return 0;
}
static int static int
nv84_crypt_ctor(struct nouveau_object *parent, struct nouveau_object *engine, nv84_crypt_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size, struct nouveau_oclass *oclass, void *data, u32 size,
...@@ -165,7 +158,6 @@ nv84_crypt_ctor(struct nouveau_object *parent, struct nouveau_object *engine, ...@@ -165,7 +158,6 @@ nv84_crypt_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
nv_subdev(priv)->intr = nv84_crypt_intr; nv_subdev(priv)->intr = nv84_crypt_intr;
nv_engine(priv)->cclass = &nv84_crypt_cclass; nv_engine(priv)->cclass = &nv84_crypt_cclass;
nv_engine(priv)->sclass = nv84_crypt_sclass; nv_engine(priv)->sclass = nv84_crypt_sclass;
nv_engine(priv)->tlb_flush = nv84_crypt_tlb_flush;
return 0; return 0;
} }
......
...@@ -27,11 +27,11 @@ ...@@ -27,11 +27,11 @@
#include <core/enum.h> #include <core/enum.h>
#include <core/class.h> #include <core/class.h>
#include <core/engctx.h> #include <core/engctx.h>
#include <core/falcon.h>
#include <subdev/timer.h> #include <subdev/timer.h>
#include <subdev/fb.h> #include <subdev/fb.h>
#include <engine/falcon.h>
#include <engine/fifo.h> #include <engine/fifo.h>
#include <engine/crypt.h> #include <engine/crypt.h>
...@@ -118,13 +118,6 @@ nv98_crypt_intr(struct nouveau_subdev *subdev) ...@@ -118,13 +118,6 @@ nv98_crypt_intr(struct nouveau_subdev *subdev)
nouveau_engctx_put(engctx); nouveau_engctx_put(engctx);
} }
static int
nv98_crypt_tlb_flush(struct nouveau_engine *engine)
{
nv50_vm_flush_engine(&engine->base, 0x0a);
return 0;
}
static int static int
nv98_crypt_ctor(struct nouveau_object *parent, struct nouveau_object *engine, nv98_crypt_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size, struct nouveau_oclass *oclass, void *data, u32 size,
...@@ -143,7 +136,6 @@ nv98_crypt_ctor(struct nouveau_object *parent, struct nouveau_object *engine, ...@@ -143,7 +136,6 @@ nv98_crypt_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
nv_subdev(priv)->intr = nv98_crypt_intr; nv_subdev(priv)->intr = nv98_crypt_intr;
nv_engine(priv)->cclass = &nv98_crypt_cclass; nv_engine(priv)->cclass = &nv98_crypt_cclass;
nv_engine(priv)->sclass = nv98_crypt_sclass; nv_engine(priv)->sclass = nv98_crypt_sclass;
nv_engine(priv)->tlb_flush = nv98_crypt_tlb_flush;
nv_falcon(priv)->code.data = nv98_pcrypt_code; nv_falcon(priv)->code.data = nv98_pcrypt_code;
nv_falcon(priv)->code.size = sizeof(nv98_pcrypt_code); nv_falcon(priv)->code.size = sizeof(nv98_pcrypt_code);
nv_falcon(priv)->data.data = nv98_pcrypt_data; nv_falcon(priv)->data.data = nv98_pcrypt_data;
......
...@@ -227,9 +227,9 @@ nv50_identify(struct nouveau_device *device) ...@@ -227,9 +227,9 @@ nv50_identify(struct nouveau_device *device)
device->oclass[NVDEV_ENGINE_FIFO ] = &nv84_fifo_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = &nv84_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = &nv50_software_oclass; device->oclass[NVDEV_ENGINE_SW ] = &nv50_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass;
device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass; device->oclass[NVDEV_ENGINE_VP ] = &nv98_vp_oclass;
device->oclass[NVDEV_ENGINE_CRYPT ] = &nv98_crypt_oclass; device->oclass[NVDEV_ENGINE_CRYPT ] = &nv98_crypt_oclass;
device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass; device->oclass[NVDEV_ENGINE_BSP ] = &nv98_bsp_oclass;
device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass; device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nv94_disp_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nv94_disp_oclass;
break; break;
...@@ -279,9 +279,9 @@ nv50_identify(struct nouveau_device *device) ...@@ -279,9 +279,9 @@ nv50_identify(struct nouveau_device *device)
device->oclass[NVDEV_ENGINE_FIFO ] = &nv84_fifo_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = &nv84_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = &nv50_software_oclass; device->oclass[NVDEV_ENGINE_SW ] = &nv50_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass;
device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass; device->oclass[NVDEV_ENGINE_VP ] = &nv98_vp_oclass;
device->oclass[NVDEV_ENGINE_CRYPT ] = &nv98_crypt_oclass; device->oclass[NVDEV_ENGINE_CRYPT ] = &nv98_crypt_oclass;
device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass; device->oclass[NVDEV_ENGINE_BSP ] = &nv98_bsp_oclass;
device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass; device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nv94_disp_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nv94_disp_oclass;
break; break;
...@@ -305,9 +305,9 @@ nv50_identify(struct nouveau_device *device) ...@@ -305,9 +305,9 @@ nv50_identify(struct nouveau_device *device)
device->oclass[NVDEV_ENGINE_FIFO ] = &nv84_fifo_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = &nv84_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = &nv50_software_oclass; device->oclass[NVDEV_ENGINE_SW ] = &nv50_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass;
device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass; device->oclass[NVDEV_ENGINE_VP ] = &nv98_vp_oclass;
device->oclass[NVDEV_ENGINE_CRYPT ] = &nv98_crypt_oclass; device->oclass[NVDEV_ENGINE_CRYPT ] = &nv98_crypt_oclass;
device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass; device->oclass[NVDEV_ENGINE_BSP ] = &nv98_bsp_oclass;
device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass; device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nv94_disp_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nv94_disp_oclass;
break; break;
...@@ -319,7 +319,7 @@ nv50_identify(struct nouveau_device *device) ...@@ -319,7 +319,7 @@ nv50_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nva3_clock_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nva3_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nva3_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = &nv50_bus_oclass; device->oclass[NVDEV_SUBDEV_BUS ] = &nv50_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
...@@ -332,8 +332,8 @@ nv50_identify(struct nouveau_device *device) ...@@ -332,8 +332,8 @@ nv50_identify(struct nouveau_device *device)
device->oclass[NVDEV_ENGINE_SW ] = &nv50_software_oclass; device->oclass[NVDEV_ENGINE_SW ] = &nv50_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv84_mpeg_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &nv84_mpeg_oclass;
device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass; device->oclass[NVDEV_ENGINE_VP ] = &nv98_vp_oclass;
device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass; device->oclass[NVDEV_ENGINE_BSP ] = &nv98_bsp_oclass;
device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass; device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass;
device->oclass[NVDEV_ENGINE_COPY0 ] = &nva3_copy_oclass; device->oclass[NVDEV_ENGINE_COPY0 ] = &nva3_copy_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass;
...@@ -346,7 +346,7 @@ nv50_identify(struct nouveau_device *device) ...@@ -346,7 +346,7 @@ nv50_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nva3_clock_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nva3_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nva3_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = &nv50_bus_oclass; device->oclass[NVDEV_SUBDEV_BUS ] = &nv50_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
...@@ -358,8 +358,8 @@ nv50_identify(struct nouveau_device *device) ...@@ -358,8 +358,8 @@ nv50_identify(struct nouveau_device *device)
device->oclass[NVDEV_ENGINE_FIFO ] = &nv84_fifo_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = &nv84_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = &nv50_software_oclass; device->oclass[NVDEV_ENGINE_SW ] = &nv50_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass;
device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass; device->oclass[NVDEV_ENGINE_VP ] = &nv98_vp_oclass;
device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass; device->oclass[NVDEV_ENGINE_BSP ] = &nv98_bsp_oclass;
device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass; device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass;
device->oclass[NVDEV_ENGINE_COPY0 ] = &nva3_copy_oclass; device->oclass[NVDEV_ENGINE_COPY0 ] = &nva3_copy_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass;
...@@ -372,7 +372,7 @@ nv50_identify(struct nouveau_device *device) ...@@ -372,7 +372,7 @@ nv50_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nva3_clock_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nva3_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nva3_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = &nv50_bus_oclass; device->oclass[NVDEV_SUBDEV_BUS ] = &nv50_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
...@@ -384,8 +384,8 @@ nv50_identify(struct nouveau_device *device) ...@@ -384,8 +384,8 @@ nv50_identify(struct nouveau_device *device)
device->oclass[NVDEV_ENGINE_FIFO ] = &nv84_fifo_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = &nv84_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = &nv50_software_oclass; device->oclass[NVDEV_ENGINE_SW ] = &nv50_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass;
device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass; device->oclass[NVDEV_ENGINE_VP ] = &nv98_vp_oclass;
device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass; device->oclass[NVDEV_ENGINE_BSP ] = &nv98_bsp_oclass;
device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass; device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass;
device->oclass[NVDEV_ENGINE_COPY0 ] = &nva3_copy_oclass; device->oclass[NVDEV_ENGINE_COPY0 ] = &nva3_copy_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass;
...@@ -398,7 +398,7 @@ nv50_identify(struct nouveau_device *device) ...@@ -398,7 +398,7 @@ nv50_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nva3_clock_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nva3_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nva3_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = &nv50_bus_oclass; device->oclass[NVDEV_SUBDEV_BUS ] = &nv50_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
...@@ -410,8 +410,8 @@ nv50_identify(struct nouveau_device *device) ...@@ -410,8 +410,8 @@ nv50_identify(struct nouveau_device *device)
device->oclass[NVDEV_ENGINE_FIFO ] = &nv84_fifo_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = &nv84_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = &nv50_software_oclass; device->oclass[NVDEV_ENGINE_SW ] = &nv50_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass;
device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass; device->oclass[NVDEV_ENGINE_VP ] = &nv98_vp_oclass;
device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass; device->oclass[NVDEV_ENGINE_BSP ] = &nv98_bsp_oclass;
device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass; device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass;
device->oclass[NVDEV_ENGINE_COPY0 ] = &nva3_copy_oclass; device->oclass[NVDEV_ENGINE_COPY0 ] = &nva3_copy_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass;
......
...@@ -62,7 +62,7 @@ nvc0_identify(struct nouveau_device *device) ...@@ -62,7 +62,7 @@ nvc0_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = &nvc0_bus_oclass; device->oclass[NVDEV_SUBDEV_BUS ] = &nvc0_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
...@@ -91,7 +91,7 @@ nvc0_identify(struct nouveau_device *device) ...@@ -91,7 +91,7 @@ nvc0_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = &nvc0_bus_oclass; device->oclass[NVDEV_SUBDEV_BUS ] = &nvc0_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
...@@ -120,7 +120,7 @@ nvc0_identify(struct nouveau_device *device) ...@@ -120,7 +120,7 @@ nvc0_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = &nvc0_bus_oclass; device->oclass[NVDEV_SUBDEV_BUS ] = &nvc0_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
...@@ -148,7 +148,7 @@ nvc0_identify(struct nouveau_device *device) ...@@ -148,7 +148,7 @@ nvc0_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = &nvc0_bus_oclass; device->oclass[NVDEV_SUBDEV_BUS ] = &nvc0_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
...@@ -177,7 +177,7 @@ nvc0_identify(struct nouveau_device *device) ...@@ -177,7 +177,7 @@ nvc0_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = &nvc0_bus_oclass; device->oclass[NVDEV_SUBDEV_BUS ] = &nvc0_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
...@@ -206,7 +206,7 @@ nvc0_identify(struct nouveau_device *device) ...@@ -206,7 +206,7 @@ nvc0_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = &nvc0_bus_oclass; device->oclass[NVDEV_SUBDEV_BUS ] = &nvc0_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
...@@ -234,7 +234,7 @@ nvc0_identify(struct nouveau_device *device) ...@@ -234,7 +234,7 @@ nvc0_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = &nvc0_bus_oclass; device->oclass[NVDEV_SUBDEV_BUS ] = &nvc0_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
...@@ -263,7 +263,7 @@ nvc0_identify(struct nouveau_device *device) ...@@ -263,7 +263,7 @@ nvc0_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = &nvc0_bus_oclass; device->oclass[NVDEV_SUBDEV_BUS ] = &nvc0_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
......
...@@ -62,7 +62,7 @@ nve0_identify(struct nouveau_device *device) ...@@ -62,7 +62,7 @@ nve0_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = &nvc0_bus_oclass; device->oclass[NVDEV_SUBDEV_BUS ] = &nvc0_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
...@@ -79,6 +79,7 @@ nve0_identify(struct nouveau_device *device) ...@@ -79,6 +79,7 @@ nve0_identify(struct nouveau_device *device)
device->oclass[NVDEV_ENGINE_DISP ] = &nve0_disp_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nve0_disp_oclass;
device->oclass[NVDEV_ENGINE_COPY0 ] = &nve0_copy0_oclass; device->oclass[NVDEV_ENGINE_COPY0 ] = &nve0_copy0_oclass;
device->oclass[NVDEV_ENGINE_COPY1 ] = &nve0_copy1_oclass; device->oclass[NVDEV_ENGINE_COPY1 ] = &nve0_copy1_oclass;
device->oclass[NVDEV_ENGINE_COPY2 ] = &nve0_copy2_oclass;
device->oclass[NVDEV_ENGINE_BSP ] = &nve0_bsp_oclass; device->oclass[NVDEV_ENGINE_BSP ] = &nve0_bsp_oclass;
device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass; device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass;
device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
...@@ -91,7 +92,7 @@ nve0_identify(struct nouveau_device *device) ...@@ -91,7 +92,7 @@ nve0_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = &nvc0_bus_oclass; device->oclass[NVDEV_SUBDEV_BUS ] = &nvc0_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
...@@ -108,6 +109,7 @@ nve0_identify(struct nouveau_device *device) ...@@ -108,6 +109,7 @@ nve0_identify(struct nouveau_device *device)
device->oclass[NVDEV_ENGINE_DISP ] = &nve0_disp_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nve0_disp_oclass;
device->oclass[NVDEV_ENGINE_COPY0 ] = &nve0_copy0_oclass; device->oclass[NVDEV_ENGINE_COPY0 ] = &nve0_copy0_oclass;
device->oclass[NVDEV_ENGINE_COPY1 ] = &nve0_copy1_oclass; device->oclass[NVDEV_ENGINE_COPY1 ] = &nve0_copy1_oclass;
device->oclass[NVDEV_ENGINE_COPY2 ] = &nve0_copy2_oclass;
device->oclass[NVDEV_ENGINE_BSP ] = &nve0_bsp_oclass; device->oclass[NVDEV_ENGINE_BSP ] = &nve0_bsp_oclass;
device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass; device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass;
device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
...@@ -120,7 +122,7 @@ nve0_identify(struct nouveau_device *device) ...@@ -120,7 +122,7 @@ nve0_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = &nvc0_bus_oclass; device->oclass[NVDEV_SUBDEV_BUS ] = &nvc0_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
...@@ -137,6 +139,7 @@ nve0_identify(struct nouveau_device *device) ...@@ -137,6 +139,7 @@ nve0_identify(struct nouveau_device *device)
device->oclass[NVDEV_ENGINE_DISP ] = &nve0_disp_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nve0_disp_oclass;
device->oclass[NVDEV_ENGINE_COPY0 ] = &nve0_copy0_oclass; device->oclass[NVDEV_ENGINE_COPY0 ] = &nve0_copy0_oclass;
device->oclass[NVDEV_ENGINE_COPY1 ] = &nve0_copy1_oclass; device->oclass[NVDEV_ENGINE_COPY1 ] = &nve0_copy1_oclass;
device->oclass[NVDEV_ENGINE_COPY2 ] = &nve0_copy2_oclass;
device->oclass[NVDEV_ENGINE_BSP ] = &nve0_bsp_oclass; device->oclass[NVDEV_ENGINE_BSP ] = &nve0_bsp_oclass;
device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass; device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass;
device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
...@@ -149,7 +152,7 @@ nve0_identify(struct nouveau_device *device) ...@@ -149,7 +152,7 @@ nve0_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass; device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = &nvc0_bus_oclass; device->oclass[NVDEV_SUBDEV_BUS ] = &nvc0_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
......
...@@ -34,9 +34,9 @@ ...@@ -34,9 +34,9 @@
#include <subdev/bios/disp.h> #include <subdev/bios/disp.h>
#include <subdev/bios/init.h> #include <subdev/bios/init.h>
#include <subdev/bios/pll.h> #include <subdev/bios/pll.h>
#include <subdev/devinit.h>
#include <subdev/timer.h> #include <subdev/timer.h>
#include <subdev/fb.h> #include <subdev/fb.h>
#include <subdev/clock.h>
#include "nv50.h" #include "nv50.h"
...@@ -987,10 +987,10 @@ nv50_disp_intr_unk20_0(struct nv50_disp_priv *priv, int head) ...@@ -987,10 +987,10 @@ nv50_disp_intr_unk20_0(struct nv50_disp_priv *priv, int head)
static void static void
nv50_disp_intr_unk20_1(struct nv50_disp_priv *priv, int head) nv50_disp_intr_unk20_1(struct nv50_disp_priv *priv, int head)
{ {
struct nouveau_clock *clk = nouveau_clock(priv); struct nouveau_devinit *devinit = nouveau_devinit(priv);
u32 pclk = nv_rd32(priv, 0x610ad0 + (head * 0x540)) & 0x3fffff; u32 pclk = nv_rd32(priv, 0x610ad0 + (head * 0x540)) & 0x3fffff;
if (pclk) if (pclk)
clk->pll_set(clk, PLL_VPLL0 + head, pclk); devinit->pll_set(devinit, PLL_VPLL0 + head, pclk);
} }
static void static void
......
...@@ -29,15 +29,14 @@ ...@@ -29,15 +29,14 @@
#include <engine/disp.h> #include <engine/disp.h>
#include <subdev/timer.h>
#include <subdev/fb.h>
#include <subdev/clock.h>
#include <subdev/bios.h> #include <subdev/bios.h>
#include <subdev/bios/dcb.h> #include <subdev/bios/dcb.h>
#include <subdev/bios/disp.h> #include <subdev/bios/disp.h>
#include <subdev/bios/init.h> #include <subdev/bios/init.h>
#include <subdev/bios/pll.h> #include <subdev/bios/pll.h>
#include <subdev/devinit.h>
#include <subdev/fb.h>
#include <subdev/timer.h>
#include "nv50.h" #include "nv50.h"
...@@ -738,10 +737,10 @@ nvd0_disp_intr_unk2_0(struct nv50_disp_priv *priv, int head) ...@@ -738,10 +737,10 @@ nvd0_disp_intr_unk2_0(struct nv50_disp_priv *priv, int head)
static void static void
nvd0_disp_intr_unk2_1(struct nv50_disp_priv *priv, int head) nvd0_disp_intr_unk2_1(struct nv50_disp_priv *priv, int head)
{ {
struct nouveau_clock *clk = nouveau_clock(priv); struct nouveau_devinit *devinit = nouveau_devinit(priv);
u32 pclk = nv_rd32(priv, 0x660450 + (head * 0x300)) / 1000; u32 pclk = nv_rd32(priv, 0x660450 + (head * 0x300)) / 1000;
if (pclk) if (pclk)
clk->pll_set(clk, PLL_VPLL0 + head, pclk); devinit->pll_set(devinit, PLL_VPLL0 + head, pclk);
nv_wr32(priv, 0x612200 + (head * 0x800), 0x00000000); nv_wr32(priv, 0x612200 + (head * 0x800), 0x00000000);
} }
...@@ -959,6 +958,9 @@ nvd0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, ...@@ -959,6 +958,9 @@ nvd0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
int heads = nv_rd32(parent, 0x022448); int heads = nv_rd32(parent, 0x022448);
int ret; int ret;
if (nv_rd32(parent, 0x022500) & 0x00000001)
return -ENODEV;
ret = nouveau_disp_create(parent, engine, oclass, heads, ret = nouveau_disp_create(parent, engine, oclass, heads,
"PDISP", "display", &priv); "PDISP", "display", &priv);
*pobject = nv_object(priv); *pobject = nv_object(priv);
......
...@@ -54,6 +54,9 @@ nve0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, ...@@ -54,6 +54,9 @@ nve0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
int heads = nv_rd32(parent, 0x022448); int heads = nv_rd32(parent, 0x022448);
int ret; int ret;
if (nv_rd32(parent, 0x022500) & 0x00000001)
return -ENODEV;
ret = nouveau_disp_create(parent, engine, oclass, heads, ret = nouveau_disp_create(parent, engine, oclass, heads,
"PDISP", "display", &priv); "PDISP", "display", &priv);
*pobject = nv_object(priv); *pobject = nv_object(priv);
......
...@@ -54,6 +54,9 @@ nvf0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, ...@@ -54,6 +54,9 @@ nvf0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
int heads = nv_rd32(parent, 0x022448); int heads = nv_rd32(parent, 0x022448);
int ret; int ret;
if (nv_rd32(parent, 0x022500) & 0x00000001)
return -ENODEV;
ret = nouveau_disp_create(parent, engine, oclass, heads, ret = nouveau_disp_create(parent, engine, oclass, heads,
"PDISP", "display", &priv); "PDISP", "display", &priv);
*pobject = nv_object(priv); *pobject = nv_object(priv);
......
...@@ -20,8 +20,7 @@ ...@@ -20,8 +20,7 @@
* OTHER DEALINGS IN THE SOFTWARE. * OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include <core/falcon.h> #include <engine/falcon.h>
#include <subdev/timer.h> #include <subdev/timer.h>
u32 u32
......
...@@ -320,7 +320,7 @@ nv40_fifo_init(struct nouveau_object *object) ...@@ -320,7 +320,7 @@ nv40_fifo_init(struct nouveau_object *object)
break; break;
default: default:
nv_wr32(priv, 0x002230, 0x00000000); nv_wr32(priv, 0x002230, 0x00000000);
nv_wr32(priv, 0x002220, ((pfb->ram.size - 512 * 1024 + nv_wr32(priv, 0x002220, ((pfb->ram->size - 512 * 1024 +
priv->ramfc->addr) >> 16) | priv->ramfc->addr) >> 16) |
0x00030000); 0x00030000);
break; break;
......
...@@ -56,7 +56,9 @@ nv84_fifo_context_attach(struct nouveau_object *parent, ...@@ -56,7 +56,9 @@ nv84_fifo_context_attach(struct nouveau_object *parent,
switch (nv_engidx(object->engine)) { switch (nv_engidx(object->engine)) {
case NVDEV_ENGINE_SW : return 0; case NVDEV_ENGINE_SW : return 0;
case NVDEV_ENGINE_GR : addr = 0x0020; break; case NVDEV_ENGINE_GR : addr = 0x0020; break;
case NVDEV_ENGINE_VP : addr = 0x0040; break;
case NVDEV_ENGINE_MPEG : addr = 0x0060; break; case NVDEV_ENGINE_MPEG : addr = 0x0060; break;
case NVDEV_ENGINE_BSP : addr = 0x0080; break;
case NVDEV_ENGINE_CRYPT: addr = 0x00a0; break; case NVDEV_ENGINE_CRYPT: addr = 0x00a0; break;
case NVDEV_ENGINE_COPY0: addr = 0x00c0; break; case NVDEV_ENGINE_COPY0: addr = 0x00c0; break;
default: default:
...@@ -89,7 +91,9 @@ nv84_fifo_context_detach(struct nouveau_object *parent, bool suspend, ...@@ -89,7 +91,9 @@ nv84_fifo_context_detach(struct nouveau_object *parent, bool suspend,
switch (nv_engidx(object->engine)) { switch (nv_engidx(object->engine)) {
case NVDEV_ENGINE_SW : return 0; case NVDEV_ENGINE_SW : return 0;
case NVDEV_ENGINE_GR : engn = 0; addr = 0x0020; break; case NVDEV_ENGINE_GR : engn = 0; addr = 0x0020; break;
case NVDEV_ENGINE_VP : engn = 3; addr = 0x0040; break;
case NVDEV_ENGINE_MPEG : engn = 1; addr = 0x0060; break; case NVDEV_ENGINE_MPEG : engn = 1; addr = 0x0060; break;
case NVDEV_ENGINE_BSP : engn = 5; addr = 0x0080; break;
case NVDEV_ENGINE_CRYPT: engn = 4; addr = 0x00a0; break; case NVDEV_ENGINE_CRYPT: engn = 4; addr = 0x00a0; break;
case NVDEV_ENGINE_COPY0: engn = 2; addr = 0x00c0; break; case NVDEV_ENGINE_COPY0: engn = 2; addr = 0x00c0; break;
default: default:
......
...@@ -44,7 +44,8 @@ static const struct { ...@@ -44,7 +44,8 @@ static const struct {
u64 subdev; u64 subdev;
u64 mask; u64 mask;
} fifo_engine[] = { } fifo_engine[] = {
_(NVDEV_ENGINE_GR , (1ULL << NVDEV_ENGINE_SW)), _(NVDEV_ENGINE_GR , (1ULL << NVDEV_ENGINE_SW) |
(1ULL << NVDEV_ENGINE_COPY2)),
_(NVDEV_ENGINE_VP , 0), _(NVDEV_ENGINE_VP , 0),
_(NVDEV_ENGINE_PPP , 0), _(NVDEV_ENGINE_PPP , 0),
_(NVDEV_ENGINE_BSP , 0), _(NVDEV_ENGINE_BSP , 0),
...@@ -96,18 +97,6 @@ nve0_fifo_playlist_update(struct nve0_fifo_priv *priv, u32 engine) ...@@ -96,18 +97,6 @@ nve0_fifo_playlist_update(struct nve0_fifo_priv *priv, u32 engine)
mutex_lock(&nv_subdev(priv)->mutex); mutex_lock(&nv_subdev(priv)->mutex);
cur = engn->playlist[engn->cur_playlist]; cur = engn->playlist[engn->cur_playlist];
if (unlikely(cur == NULL)) {
int ret = nouveau_gpuobj_new(nv_object(priv), NULL,
0x8000, 0x1000, 0, &cur);
if (ret) {
mutex_unlock(&nv_subdev(priv)->mutex);
nv_error(priv, "playlist alloc failed\n");
return;
}
engn->playlist[engn->cur_playlist] = cur;
}
engn->cur_playlist = !engn->cur_playlist; engn->cur_playlist = !engn->cur_playlist;
for (i = 0, p = 0; i < priv->base.max; i++) { for (i = 0, p = 0; i < priv->base.max; i++) {
...@@ -138,10 +127,12 @@ nve0_fifo_context_attach(struct nouveau_object *parent, ...@@ -138,10 +127,12 @@ nve0_fifo_context_attach(struct nouveau_object *parent,
int ret; int ret;
switch (nv_engidx(object->engine)) { switch (nv_engidx(object->engine)) {
case NVDEV_ENGINE_SW : return 0; case NVDEV_ENGINE_SW :
case NVDEV_ENGINE_GR :
case NVDEV_ENGINE_COPY0: case NVDEV_ENGINE_COPY0:
case NVDEV_ENGINE_COPY1: addr = 0x0210; break; case NVDEV_ENGINE_COPY1:
case NVDEV_ENGINE_COPY2:
return 0;
case NVDEV_ENGINE_GR : addr = 0x0210; break;
case NVDEV_ENGINE_BSP : addr = 0x0270; break; case NVDEV_ENGINE_BSP : addr = 0x0270; break;
case NVDEV_ENGINE_VP : addr = 0x0250; break; case NVDEV_ENGINE_VP : addr = 0x0250; break;
case NVDEV_ENGINE_PPP : addr = 0x0260; break; case NVDEV_ENGINE_PPP : addr = 0x0260; break;
...@@ -176,9 +167,10 @@ nve0_fifo_context_detach(struct nouveau_object *parent, bool suspend, ...@@ -176,9 +167,10 @@ nve0_fifo_context_detach(struct nouveau_object *parent, bool suspend,
switch (nv_engidx(object->engine)) { switch (nv_engidx(object->engine)) {
case NVDEV_ENGINE_SW : return 0; case NVDEV_ENGINE_SW : return 0;
case NVDEV_ENGINE_GR :
case NVDEV_ENGINE_COPY0: case NVDEV_ENGINE_COPY0:
case NVDEV_ENGINE_COPY1: addr = 0x0210; break; case NVDEV_ENGINE_COPY1:
case NVDEV_ENGINE_COPY2: addr = 0x0000; break;
case NVDEV_ENGINE_GR : addr = 0x0210; break;
case NVDEV_ENGINE_BSP : addr = 0x0270; break; case NVDEV_ENGINE_BSP : addr = 0x0270; break;
case NVDEV_ENGINE_VP : addr = 0x0250; break; case NVDEV_ENGINE_VP : addr = 0x0250; break;
case NVDEV_ENGINE_PPP : addr = 0x0260; break; case NVDEV_ENGINE_PPP : addr = 0x0260; break;
...@@ -194,9 +186,12 @@ nve0_fifo_context_detach(struct nouveau_object *parent, bool suspend, ...@@ -194,9 +186,12 @@ nve0_fifo_context_detach(struct nouveau_object *parent, bool suspend,
return -EBUSY; return -EBUSY;
} }
nv_wo32(base, addr + 0x00, 0x00000000); if (addr) {
nv_wo32(base, addr + 0x04, 0x00000000); nv_wo32(base, addr + 0x00, 0x00000000);
bar->flush(bar); nv_wo32(base, addr + 0x04, 0x00000000);
bar->flush(bar);
}
return 0; return 0;
} }
...@@ -592,13 +587,25 @@ nve0_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine, ...@@ -592,13 +587,25 @@ nve0_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_object **pobject) struct nouveau_object **pobject)
{ {
struct nve0_fifo_priv *priv; struct nve0_fifo_priv *priv;
int ret; int ret, i;
ret = nouveau_fifo_create(parent, engine, oclass, 0, 4095, &priv); ret = nouveau_fifo_create(parent, engine, oclass, 0, 4095, &priv);
*pobject = nv_object(priv); *pobject = nv_object(priv);
if (ret) if (ret)
return ret; return ret;
for (i = 0; i < FIFO_ENGINE_NR; i++) {
ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x8000, 0x1000,
0, &priv->engine[i].playlist[0]);
if (ret)
return ret;
ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x8000, 0x1000,
0, &priv->engine[i].playlist[1]);
if (ret)
return ret;
}
ret = nouveau_gpuobj_new(nv_object(priv), NULL, 4096 * 0x200, 0x1000, ret = nouveau_gpuobj_new(nv_object(priv), NULL, 4096 * 0x200, 0x1000,
NVOBJ_FLAG_ZERO_ALLOC, &priv->user.mem); NVOBJ_FLAG_ZERO_ALLOC, &priv->user.mem);
if (ret) if (ret)
...@@ -629,7 +636,7 @@ nve0_fifo_dtor(struct nouveau_object *object) ...@@ -629,7 +636,7 @@ nve0_fifo_dtor(struct nouveau_object *object)
nouveau_gpuobj_unmap(&priv->user.bar); nouveau_gpuobj_unmap(&priv->user.bar);
nouveau_gpuobj_ref(NULL, &priv->user.mem); nouveau_gpuobj_ref(NULL, &priv->user.mem);
for (i = 0; i < ARRAY_SIZE(priv->engine); i++) { for (i = 0; i < FIFO_ENGINE_NR; i++) {
nouveau_gpuobj_ref(NULL, &priv->engine[i].playlist[1]); nouveau_gpuobj_ref(NULL, &priv->engine[i].playlist[1]);
nouveau_gpuobj_ref(NULL, &priv->engine[i].playlist[0]); nouveau_gpuobj_ref(NULL, &priv->engine[i].playlist[0]);
} }
......
...@@ -749,31 +749,6 @@ nve0_grctx_generate_icmd(struct nvc0_graph_priv *priv) ...@@ -749,31 +749,6 @@ nve0_grctx_generate_icmd(struct nvc0_graph_priv *priv)
nv_icmd(priv, 0x000841, 0x08000080); nv_icmd(priv, 0x000841, 0x08000080);
nv_icmd(priv, 0x000842, 0x00400008); nv_icmd(priv, 0x000842, 0x00400008);
nv_icmd(priv, 0x000843, 0x08000080); nv_icmd(priv, 0x000843, 0x08000080);
nv_icmd(priv, 0x000818, 0x00000000);
nv_icmd(priv, 0x000819, 0x00000000);
nv_icmd(priv, 0x00081a, 0x00000000);
nv_icmd(priv, 0x00081b, 0x00000000);
nv_icmd(priv, 0x00081c, 0x00000000);
nv_icmd(priv, 0x00081d, 0x00000000);
nv_icmd(priv, 0x00081e, 0x00000000);
nv_icmd(priv, 0x00081f, 0x00000000);
nv_icmd(priv, 0x000848, 0x00000000);
nv_icmd(priv, 0x000849, 0x00000000);
nv_icmd(priv, 0x00084a, 0x00000000);
nv_icmd(priv, 0x00084b, 0x00000000);
nv_icmd(priv, 0x00084c, 0x00000000);
nv_icmd(priv, 0x00084d, 0x00000000);
nv_icmd(priv, 0x00084e, 0x00000000);
nv_icmd(priv, 0x00084f, 0x00000000);
nv_icmd(priv, 0x000850, 0x00000000);
nv_icmd(priv, 0x000851, 0x00000000);
nv_icmd(priv, 0x000852, 0x00000000);
nv_icmd(priv, 0x000853, 0x00000000);
nv_icmd(priv, 0x000854, 0x00000000);
nv_icmd(priv, 0x000855, 0x00000000);
nv_icmd(priv, 0x000856, 0x00000000);
nv_icmd(priv, 0x000857, 0x00000000);
nv_icmd(priv, 0x000738, 0x00000000);
nv_icmd(priv, 0x0006aa, 0x00000001); nv_icmd(priv, 0x0006aa, 0x00000001);
nv_icmd(priv, 0x0006ab, 0x00000002); nv_icmd(priv, 0x0006ab, 0x00000002);
nv_icmd(priv, 0x0006ac, 0x00000080); nv_icmd(priv, 0x0006ac, 0x00000080);
...@@ -862,31 +837,6 @@ nve0_grctx_generate_icmd(struct nvc0_graph_priv *priv) ...@@ -862,31 +837,6 @@ nve0_grctx_generate_icmd(struct nvc0_graph_priv *priv)
nv_icmd(priv, 0x000813, 0x00000006); nv_icmd(priv, 0x000813, 0x00000006);
nv_icmd(priv, 0x000814, 0x00000008); nv_icmd(priv, 0x000814, 0x00000008);
nv_icmd(priv, 0x000957, 0x00000003); nv_icmd(priv, 0x000957, 0x00000003);
nv_icmd(priv, 0x000818, 0x00000000);
nv_icmd(priv, 0x000819, 0x00000000);
nv_icmd(priv, 0x00081a, 0x00000000);
nv_icmd(priv, 0x00081b, 0x00000000);
nv_icmd(priv, 0x00081c, 0x00000000);
nv_icmd(priv, 0x00081d, 0x00000000);
nv_icmd(priv, 0x00081e, 0x00000000);
nv_icmd(priv, 0x00081f, 0x00000000);
nv_icmd(priv, 0x000848, 0x00000000);
nv_icmd(priv, 0x000849, 0x00000000);
nv_icmd(priv, 0x00084a, 0x00000000);
nv_icmd(priv, 0x00084b, 0x00000000);
nv_icmd(priv, 0x00084c, 0x00000000);
nv_icmd(priv, 0x00084d, 0x00000000);
nv_icmd(priv, 0x00084e, 0x00000000);
nv_icmd(priv, 0x00084f, 0x00000000);
nv_icmd(priv, 0x000850, 0x00000000);
nv_icmd(priv, 0x000851, 0x00000000);
nv_icmd(priv, 0x000852, 0x00000000);
nv_icmd(priv, 0x000853, 0x00000000);
nv_icmd(priv, 0x000854, 0x00000000);
nv_icmd(priv, 0x000855, 0x00000000);
nv_icmd(priv, 0x000856, 0x00000000);
nv_icmd(priv, 0x000857, 0x00000000);
nv_icmd(priv, 0x000738, 0x00000000);
nv_icmd(priv, 0x000b07, 0x00000002); nv_icmd(priv, 0x000b07, 0x00000002);
nv_icmd(priv, 0x000b08, 0x00000100); nv_icmd(priv, 0x000b08, 0x00000100);
nv_icmd(priv, 0x000b09, 0x00000100); nv_icmd(priv, 0x000b09, 0x00000100);
...@@ -2162,12 +2112,30 @@ nve0_grctx_generate_902d(struct nvc0_graph_priv *priv) ...@@ -2162,12 +2112,30 @@ nve0_grctx_generate_902d(struct nvc0_graph_priv *priv)
nv_mthd(priv, 0x902d, 0x0244, 0x00000080); nv_mthd(priv, 0x902d, 0x0244, 0x00000080);
nv_mthd(priv, 0x902d, 0x0248, 0x00000100); nv_mthd(priv, 0x902d, 0x0248, 0x00000100);
nv_mthd(priv, 0x902d, 0x024c, 0x00000100); nv_mthd(priv, 0x902d, 0x024c, 0x00000100);
nv_mthd(priv, 0x902d, 0x3410, 0x00000000); switch (nv_device(priv)->chipset) {
case 0xe6:
nv_mthd(priv, 0x902d, 0x3410, 0x80002006);
break;
case 0xe4:
case 0xe7:
default:
nv_mthd(priv, 0x902d, 0x3410, 0x00000000);
break;
}
} }
static void static void
nve0_graph_generate_unk40xx(struct nvc0_graph_priv *priv) nve0_graph_generate_unk40xx(struct nvc0_graph_priv *priv)
{ {
switch (nv_device(priv)->chipset) {
case 0xf0:
nv_wr32(priv, 0x404004, 0x00000000);
nv_wr32(priv, 0x404008, 0x00000000);
nv_wr32(priv, 0x40400c, 0x00000000);
break;
default:
break;
}
nv_wr32(priv, 0x404010, 0x0); nv_wr32(priv, 0x404010, 0x0);
nv_wr32(priv, 0x404014, 0x0); nv_wr32(priv, 0x404014, 0x0);
nv_wr32(priv, 0x404018, 0x0); nv_wr32(priv, 0x404018, 0x0);
...@@ -2175,6 +2143,19 @@ nve0_graph_generate_unk40xx(struct nvc0_graph_priv *priv) ...@@ -2175,6 +2143,19 @@ nve0_graph_generate_unk40xx(struct nvc0_graph_priv *priv)
nv_wr32(priv, 0x404020, 0x0); nv_wr32(priv, 0x404020, 0x0);
nv_wr32(priv, 0x404024, 0xe000); nv_wr32(priv, 0x404024, 0xe000);
nv_wr32(priv, 0x404028, 0x0); nv_wr32(priv, 0x404028, 0x0);
switch (nv_device(priv)->chipset) {
case 0xf0:
nv_wr32(priv, 0x40402c, 0x00000000);
nv_wr32(priv, 0x404030, 0x00000000);
nv_wr32(priv, 0x404034, 0x00000000);
nv_wr32(priv, 0x404038, 0x00000000);
nv_wr32(priv, 0x40403c, 0x00000000);
nv_wr32(priv, 0x404040, 0x00000000);
nv_wr32(priv, 0x404044, 0x00000000);
break;
default:
break;
}
nv_wr32(priv, 0x4040a8, 0x0); nv_wr32(priv, 0x4040a8, 0x0);
nv_wr32(priv, 0x4040ac, 0x0); nv_wr32(priv, 0x4040ac, 0x0);
nv_wr32(priv, 0x4040b0, 0x0); nv_wr32(priv, 0x4040b0, 0x0);
...@@ -2192,6 +2173,22 @@ nve0_graph_generate_unk40xx(struct nvc0_graph_priv *priv) ...@@ -2192,6 +2173,22 @@ nve0_graph_generate_unk40xx(struct nvc0_graph_priv *priv)
nv_wr32(priv, 0x4040e4, 0x0); nv_wr32(priv, 0x4040e4, 0x0);
nv_wr32(priv, 0x4040e8, 0x1000); nv_wr32(priv, 0x4040e8, 0x1000);
nv_wr32(priv, 0x4040f8, 0x0); nv_wr32(priv, 0x4040f8, 0x0);
switch (nv_device(priv)->chipset) {
case 0xf0:
nv_wr32(priv, 0x404100, 0x00000000);
nv_wr32(priv, 0x404104, 0x00000000);
nv_wr32(priv, 0x404108, 0x00000000);
nv_wr32(priv, 0x40410c, 0x00000000);
nv_wr32(priv, 0x404110, 0x00000000);
nv_wr32(priv, 0x404114, 0x00000000);
nv_wr32(priv, 0x404118, 0x00000000);
nv_wr32(priv, 0x40411c, 0x00000000);
nv_wr32(priv, 0x404120, 0x00000000);
nv_wr32(priv, 0x404124, 0x00000000);
break;
default:
break;
}
nv_wr32(priv, 0x404130, 0x0); nv_wr32(priv, 0x404130, 0x0);
nv_wr32(priv, 0x404134, 0x0); nv_wr32(priv, 0x404134, 0x0);
nv_wr32(priv, 0x404138, 0x20000040); nv_wr32(priv, 0x404138, 0x20000040);
...@@ -2199,14 +2196,32 @@ nve0_graph_generate_unk40xx(struct nvc0_graph_priv *priv) ...@@ -2199,14 +2196,32 @@ nve0_graph_generate_unk40xx(struct nvc0_graph_priv *priv)
nv_wr32(priv, 0x404154, 0x400); nv_wr32(priv, 0x404154, 0x400);
nv_wr32(priv, 0x404158, 0x200); nv_wr32(priv, 0x404158, 0x200);
nv_wr32(priv, 0x404164, 0x55); nv_wr32(priv, 0x404164, 0x55);
switch (nv_device(priv)->chipset) {
case 0xf0:
nv_wr32(priv, 0x40417c, 0x00000000);
nv_wr32(priv, 0x404180, 0x00000000);
break;
default:
break;
}
nv_wr32(priv, 0x4041a0, 0x0); nv_wr32(priv, 0x4041a0, 0x0);
nv_wr32(priv, 0x4041a4, 0x0); nv_wr32(priv, 0x4041a4, 0x0);
nv_wr32(priv, 0x4041a8, 0x0); nv_wr32(priv, 0x4041a8, 0x0);
nv_wr32(priv, 0x4041ac, 0x0); nv_wr32(priv, 0x4041ac, 0x0);
nv_wr32(priv, 0x404200, 0x0); switch (nv_device(priv)->chipset) {
nv_wr32(priv, 0x404204, 0x0); case 0xf0:
nv_wr32(priv, 0x404208, 0x0); nv_wr32(priv, 0x404200, 0xa197);
nv_wr32(priv, 0x40420c, 0x0); nv_wr32(priv, 0x404204, 0xa1c0);
nv_wr32(priv, 0x404208, 0xa140);
nv_wr32(priv, 0x40420c, 0x902d);
break;
default:
nv_wr32(priv, 0x404200, 0x0);
nv_wr32(priv, 0x404204, 0x0);
nv_wr32(priv, 0x404208, 0x0);
nv_wr32(priv, 0x40420c, 0x0);
break;
}
} }
static void static void
...@@ -2224,7 +2239,13 @@ nve0_graph_generate_unk44xx(struct nvc0_graph_priv *priv) ...@@ -2224,7 +2239,13 @@ nve0_graph_generate_unk44xx(struct nvc0_graph_priv *priv)
nv_wr32(priv, 0x404428, 0x0); nv_wr32(priv, 0x404428, 0x0);
nv_wr32(priv, 0x40442c, 0x0); nv_wr32(priv, 0x40442c, 0x0);
nv_wr32(priv, 0x404430, 0x0); nv_wr32(priv, 0x404430, 0x0);
nv_wr32(priv, 0x404434, 0x0); switch (nv_device(priv)->chipset) {
case 0xf0:
break;
default:
nv_wr32(priv, 0x404434, 0x0);
break;
}
nv_wr32(priv, 0x404438, 0x0); nv_wr32(priv, 0x404438, 0x0);
nv_wr32(priv, 0x404460, 0x0); nv_wr32(priv, 0x404460, 0x0);
nv_wr32(priv, 0x404464, 0x0); nv_wr32(priv, 0x404464, 0x0);
...@@ -2310,14 +2331,33 @@ nve0_graph_generate_unk58xx(struct nvc0_graph_priv *priv) ...@@ -2310,14 +2331,33 @@ nve0_graph_generate_unk58xx(struct nvc0_graph_priv *priv)
nv_wr32(priv, 0x405a00, 0x0); nv_wr32(priv, 0x405a00, 0x0);
nv_wr32(priv, 0x405a04, 0x0); nv_wr32(priv, 0x405a04, 0x0);
nv_wr32(priv, 0x405a18, 0x0); nv_wr32(priv, 0x405a18, 0x0);
}
static void
nve0_graph_generate_unk5bxx(struct nvc0_graph_priv *priv)
{
nv_wr32(priv, 0x405b00, 0x0); nv_wr32(priv, 0x405b00, 0x0);
nv_wr32(priv, 0x405b10, 0x1000); nv_wr32(priv, 0x405b10, 0x1000);
switch (nv_device(priv)->chipset) {
case 0xf0:
nv_wr32(priv, 0x405b20, 0x04000000);
break;
default:
break;
}
} }
static void static void
nve0_graph_generate_unk60xx(struct nvc0_graph_priv *priv) nve0_graph_generate_unk60xx(struct nvc0_graph_priv *priv)
{ {
nv_wr32(priv, 0x406020, 0x4103c1); switch (nv_device(priv)->chipset) {
case 0xf0:
nv_wr32(priv, 0x406020, 0x34103c1);
break;
default:
nv_wr32(priv, 0x406020, 0x4103c1);
break;
}
nv_wr32(priv, 0x406028, 0x1); nv_wr32(priv, 0x406028, 0x1);
nv_wr32(priv, 0x40602c, 0x1); nv_wr32(priv, 0x40602c, 0x1);
nv_wr32(priv, 0x406030, 0x1); nv_wr32(priv, 0x406030, 0x1);
...@@ -2329,11 +2369,27 @@ nve0_graph_generate_unk64xx(struct nvc0_graph_priv *priv) ...@@ -2329,11 +2369,27 @@ nve0_graph_generate_unk64xx(struct nvc0_graph_priv *priv)
{ {
nv_wr32(priv, 0x4064a8, 0x0); nv_wr32(priv, 0x4064a8, 0x0);
nv_wr32(priv, 0x4064ac, 0x3fff); nv_wr32(priv, 0x4064ac, 0x3fff);
switch (nv_device(priv)->chipset) {
case 0xf0:
nv_wr32(priv, 0x4064b0, 0x0);
break;
default:
break;
}
nv_wr32(priv, 0x4064b4, 0x0); nv_wr32(priv, 0x4064b4, 0x0);
nv_wr32(priv, 0x4064b8, 0x0); nv_wr32(priv, 0x4064b8, 0x0);
nv_wr32(priv, 0x4064c0, 0x801a00f0); switch (nv_device(priv)->chipset) {
nv_wr32(priv, 0x4064c4, 0x192ffff); case 0xf0:
nv_wr32(priv, 0x4064c8, 0x1800600); nv_wr32(priv, 0x4064c0, 0x802000f0);
nv_wr32(priv, 0x4064c4, 0x192ffff);
nv_wr32(priv, 0x4064c8, 0x18007c0);
break;
default:
nv_wr32(priv, 0x4064c0, 0x801a00f0);
nv_wr32(priv, 0x4064c4, 0x192ffff);
nv_wr32(priv, 0x4064c8, 0x1800600);
break;
}
nv_wr32(priv, 0x4064cc, 0x0); nv_wr32(priv, 0x4064cc, 0x0);
nv_wr32(priv, 0x4064d0, 0x0); nv_wr32(priv, 0x4064d0, 0x0);
nv_wr32(priv, 0x4064d4, 0x0); nv_wr32(priv, 0x4064d4, 0x0);
...@@ -2349,7 +2405,13 @@ nve0_graph_generate_unk64xx(struct nvc0_graph_priv *priv) ...@@ -2349,7 +2405,13 @@ nve0_graph_generate_unk64xx(struct nvc0_graph_priv *priv)
static void static void
nve0_graph_generate_unk70xx(struct nvc0_graph_priv *priv) nve0_graph_generate_unk70xx(struct nvc0_graph_priv *priv)
{ {
nv_wr32(priv, 0x407040, 0x0); switch (nv_device(priv)->chipset) {
case 0xf0:
break;
default:
nv_wr32(priv, 0x407040, 0x0);
break;
}
} }
static void static void
...@@ -2381,9 +2443,23 @@ nve0_graph_generate_unk80xx(struct nvc0_graph_priv *priv) ...@@ -2381,9 +2443,23 @@ nve0_graph_generate_unk80xx(struct nvc0_graph_priv *priv)
static void static void
nve0_graph_generate_unk88xx(struct nvc0_graph_priv *priv) nve0_graph_generate_unk88xx(struct nvc0_graph_priv *priv)
{ {
nv_wr32(priv, 0x408800, 0x2802a3c); switch (nv_device(priv)->chipset) {
case 0xf0:
nv_wr32(priv, 0x408800, 0x12802a3c);
break;
default:
nv_wr32(priv, 0x408800, 0x2802a3c);
break;
}
nv_wr32(priv, 0x408804, 0x40); nv_wr32(priv, 0x408804, 0x40);
nv_wr32(priv, 0x408808, 0x1043e005); switch (nv_device(priv)->chipset) {
case 0xf0:
nv_wr32(priv, 0x408808, 0x1003e005);
break;
default:
nv_wr32(priv, 0x408808, 0x1043e005);
break;
}
nv_wr32(priv, 0x408840, 0xb); nv_wr32(priv, 0x408840, 0xb);
nv_wr32(priv, 0x408900, 0x3080b801); nv_wr32(priv, 0x408900, 0x3080b801);
nv_wr32(priv, 0x408904, 0x62000001); nv_wr32(priv, 0x408904, 0x62000001);
...@@ -2394,6 +2470,8 @@ nve0_graph_generate_unk88xx(struct nvc0_graph_priv *priv) ...@@ -2394,6 +2470,8 @@ nve0_graph_generate_unk88xx(struct nvc0_graph_priv *priv)
static void static void
nve0_graph_generate_gpc(struct nvc0_graph_priv *priv) nve0_graph_generate_gpc(struct nvc0_graph_priv *priv)
{ {
int i;
nv_wr32(priv, 0x418380, 0x16); nv_wr32(priv, 0x418380, 0x16);
nv_wr32(priv, 0x418400, 0x38004e00); nv_wr32(priv, 0x418400, 0x38004e00);
nv_wr32(priv, 0x418404, 0x71e0ffff); nv_wr32(priv, 0x418404, 0x71e0ffff);
...@@ -2418,7 +2496,14 @@ nve0_graph_generate_gpc(struct nvc0_graph_priv *priv) ...@@ -2418,7 +2496,14 @@ nve0_graph_generate_gpc(struct nvc0_graph_priv *priv)
nv_wr32(priv, 0x418710, 0x0); nv_wr32(priv, 0x418710, 0x0);
nv_wr32(priv, 0x418800, 0x7006860a); nv_wr32(priv, 0x418800, 0x7006860a);
nv_wr32(priv, 0x418808, 0x0); nv_wr32(priv, 0x418808, 0x0);
nv_wr32(priv, 0x41880c, 0x0); switch (nv_device(priv)->chipset) {
case 0xf0:
nv_wr32(priv, 0x41880c, 0x30);
break;
default:
nv_wr32(priv, 0x41880c, 0x0);
break;
}
nv_wr32(priv, 0x418810, 0x0); nv_wr32(priv, 0x418810, 0x0);
nv_wr32(priv, 0x418828, 0x44); nv_wr32(priv, 0x418828, 0x44);
nv_wr32(priv, 0x418830, 0x10000001); nv_wr32(priv, 0x418830, 0x10000001);
...@@ -2434,62 +2519,15 @@ nve0_graph_generate_gpc(struct nvc0_graph_priv *priv) ...@@ -2434,62 +2519,15 @@ nve0_graph_generate_gpc(struct nvc0_graph_priv *priv)
nv_wr32(priv, 0x418924, 0x0); nv_wr32(priv, 0x418924, 0x0);
nv_wr32(priv, 0x418928, 0xffff00); nv_wr32(priv, 0x418928, 0xffff00);
nv_wr32(priv, 0x41892c, 0xff00); nv_wr32(priv, 0x41892c, 0xff00);
nv_wr32(priv, 0x418a00, 0x0); for (i = 0; i < 8; i++) {
nv_wr32(priv, 0x418a04, 0x0); nv_wr32(priv, 0x418a00 + (i * 0x20), 0x0);
nv_wr32(priv, 0x418a08, 0x0); nv_wr32(priv, 0x418a04 + (i * 0x20), 0x0);
nv_wr32(priv, 0x418a0c, 0x10000); nv_wr32(priv, 0x418a08 + (i * 0x20), 0x0);
nv_wr32(priv, 0x418a10, 0x0); nv_wr32(priv, 0x418a0c + (i * 0x20), 0x10000);
nv_wr32(priv, 0x418a14, 0x0); nv_wr32(priv, 0x418a10 + (i * 0x20), 0x0);
nv_wr32(priv, 0x418a18, 0x0); nv_wr32(priv, 0x418a14 + (i * 0x20), 0x0);
nv_wr32(priv, 0x418a20, 0x0); nv_wr32(priv, 0x418a18 + (i * 0x20), 0x0);
nv_wr32(priv, 0x418a24, 0x0); }
nv_wr32(priv, 0x418a28, 0x0);
nv_wr32(priv, 0x418a2c, 0x10000);
nv_wr32(priv, 0x418a30, 0x0);
nv_wr32(priv, 0x418a34, 0x0);
nv_wr32(priv, 0x418a38, 0x0);
nv_wr32(priv, 0x418a40, 0x0);
nv_wr32(priv, 0x418a44, 0x0);
nv_wr32(priv, 0x418a48, 0x0);
nv_wr32(priv, 0x418a4c, 0x10000);
nv_wr32(priv, 0x418a50, 0x0);
nv_wr32(priv, 0x418a54, 0x0);
nv_wr32(priv, 0x418a58, 0x0);
nv_wr32(priv, 0x418a60, 0x0);
nv_wr32(priv, 0x418a64, 0x0);
nv_wr32(priv, 0x418a68, 0x0);
nv_wr32(priv, 0x418a6c, 0x10000);
nv_wr32(priv, 0x418a70, 0x0);
nv_wr32(priv, 0x418a74, 0x0);
nv_wr32(priv, 0x418a78, 0x0);
nv_wr32(priv, 0x418a80, 0x0);
nv_wr32(priv, 0x418a84, 0x0);
nv_wr32(priv, 0x418a88, 0x0);
nv_wr32(priv, 0x418a8c, 0x10000);
nv_wr32(priv, 0x418a90, 0x0);
nv_wr32(priv, 0x418a94, 0x0);
nv_wr32(priv, 0x418a98, 0x0);
nv_wr32(priv, 0x418aa0, 0x0);
nv_wr32(priv, 0x418aa4, 0x0);
nv_wr32(priv, 0x418aa8, 0x0);
nv_wr32(priv, 0x418aac, 0x10000);
nv_wr32(priv, 0x418ab0, 0x0);
nv_wr32(priv, 0x418ab4, 0x0);
nv_wr32(priv, 0x418ab8, 0x0);
nv_wr32(priv, 0x418ac0, 0x0);
nv_wr32(priv, 0x418ac4, 0x0);
nv_wr32(priv, 0x418ac8, 0x0);
nv_wr32(priv, 0x418acc, 0x10000);
nv_wr32(priv, 0x418ad0, 0x0);
nv_wr32(priv, 0x418ad4, 0x0);
nv_wr32(priv, 0x418ad8, 0x0);
nv_wr32(priv, 0x418ae0, 0x0);
nv_wr32(priv, 0x418ae4, 0x0);
nv_wr32(priv, 0x418ae8, 0x0);
nv_wr32(priv, 0x418aec, 0x10000);
nv_wr32(priv, 0x418af0, 0x0);
nv_wr32(priv, 0x418af4, 0x0);
nv_wr32(priv, 0x418af8, 0x0);
nv_wr32(priv, 0x418b00, 0x6); nv_wr32(priv, 0x418b00, 0x6);
nv_wr32(priv, 0x418b08, 0xa418820); nv_wr32(priv, 0x418b08, 0xa418820);
nv_wr32(priv, 0x418b0c, 0x62080e6); nv_wr32(priv, 0x418b0c, 0x62080e6);
...@@ -2511,6 +2549,13 @@ nve0_graph_generate_gpc(struct nvc0_graph_priv *priv) ...@@ -2511,6 +2549,13 @@ nve0_graph_generate_gpc(struct nvc0_graph_priv *priv)
nv_wr32(priv, 0x418c6c, 0x1); nv_wr32(priv, 0x418c6c, 0x1);
nv_wr32(priv, 0x418c80, 0x20200004); nv_wr32(priv, 0x418c80, 0x20200004);
nv_wr32(priv, 0x418c8c, 0x1); nv_wr32(priv, 0x418c8c, 0x1);
switch (nv_device(priv)->chipset) {
case 0xf0:
nv_wr32(priv, 0x418d24, 0x0);
break;
default:
break;
}
nv_wr32(priv, 0x419000, 0x780); nv_wr32(priv, 0x419000, 0x780);
nv_wr32(priv, 0x419004, 0x0); nv_wr32(priv, 0x419004, 0x0);
nv_wr32(priv, 0x419008, 0x0); nv_wr32(priv, 0x419008, 0x0);
...@@ -2530,31 +2575,71 @@ nve0_graph_generate_tpc(struct nvc0_graph_priv *priv) ...@@ -2530,31 +2575,71 @@ nve0_graph_generate_tpc(struct nvc0_graph_priv *priv)
nv_wr32(priv, 0x419a10, 0x0); nv_wr32(priv, 0x419a10, 0x0);
nv_wr32(priv, 0x419a14, 0x200); nv_wr32(priv, 0x419a14, 0x200);
nv_wr32(priv, 0x419a1c, 0xc000); nv_wr32(priv, 0x419a1c, 0xc000);
nv_wr32(priv, 0x419a20, 0x800); switch (nv_device(priv)->chipset) {
case 0xf0:
nv_wr32(priv, 0x419a20, 0x20800);
break;
default:
nv_wr32(priv, 0x419a20, 0x800);
break;
}
nv_wr32(priv, 0x419a30, 0x1); nv_wr32(priv, 0x419a30, 0x1);
nv_wr32(priv, 0x419ac4, 0x37f440); nv_wr32(priv, 0x419ac4, 0x37f440);
nv_wr32(priv, 0x419c00, 0xa); switch (nv_device(priv)->chipset) {
case 0xf0:
nv_wr32(priv, 0x419c00, 0x1a);
break;
default:
nv_wr32(priv, 0x419c00, 0xa);
break;
}
nv_wr32(priv, 0x419c04, 0x80000006); nv_wr32(priv, 0x419c04, 0x80000006);
nv_wr32(priv, 0x419c08, 0x2); nv_wr32(priv, 0x419c08, 0x2);
nv_wr32(priv, 0x419c20, 0x0); nv_wr32(priv, 0x419c20, 0x0);
nv_wr32(priv, 0x419c24, 0x84210); nv_wr32(priv, 0x419c24, 0x84210);
nv_wr32(priv, 0x419c28, 0x3efbefbe); nv_wr32(priv, 0x419c28, 0x3efbefbe);
nv_wr32(priv, 0x419ce8, 0x0); nv_wr32(priv, 0x419ce8, 0x0);
nv_wr32(priv, 0x419cf4, 0x3203); switch (nv_device(priv)->chipset) {
nv_wr32(priv, 0x419e04, 0x0); case 0xf0:
nv_wr32(priv, 0x419e08, 0x0); nv_wr32(priv, 0x419cf4, 0x203);
nv_wr32(priv, 0x419e0c, 0x0); nv_wr32(priv, 0x419e04, 0x0);
nv_wr32(priv, 0x419e10, 0x402); nv_wr32(priv, 0x419e08, 0x1d);
nv_wr32(priv, 0x419e0c, 0x0);
nv_wr32(priv, 0x419e10, 0x1c02);
break;
default:
nv_wr32(priv, 0x419cf4, 0x3203);
nv_wr32(priv, 0x419e04, 0x0);
nv_wr32(priv, 0x419e08, 0x0);
nv_wr32(priv, 0x419e0c, 0x0);
nv_wr32(priv, 0x419e10, 0x402);
break;
}
nv_wr32(priv, 0x419e44, 0x13eff2); nv_wr32(priv, 0x419e44, 0x13eff2);
nv_wr32(priv, 0x419e48, 0x0); nv_wr32(priv, 0x419e48, 0x0);
nv_wr32(priv, 0x419e4c, 0x7f); nv_wr32(priv, 0x419e4c, 0x7f);
nv_wr32(priv, 0x419e50, 0x0); nv_wr32(priv, 0x419e50, 0x0);
nv_wr32(priv, 0x419e54, 0x0); nv_wr32(priv, 0x419e54, 0x0);
nv_wr32(priv, 0x419e58, 0x0); switch (nv_device(priv)->chipset) {
case 0xf0:
nv_wr32(priv, 0x419e58, 0x1);
break;
default:
nv_wr32(priv, 0x419e58, 0x0);
break;
}
nv_wr32(priv, 0x419e5c, 0x0); nv_wr32(priv, 0x419e5c, 0x0);
nv_wr32(priv, 0x419e60, 0x0); nv_wr32(priv, 0x419e60, 0x0);
nv_wr32(priv, 0x419e64, 0x0); nv_wr32(priv, 0x419e64, 0x0);
nv_wr32(priv, 0x419e68, 0x0); switch (nv_device(priv)->chipset) {
case 0xf0:
nv_wr32(priv, 0x419e68, 0x2);
break;
default:
nv_wr32(priv, 0x419e68, 0x0);
break;
}
nv_wr32(priv, 0x419e6c, 0x0); nv_wr32(priv, 0x419e6c, 0x0);
nv_wr32(priv, 0x419e70, 0x0); nv_wr32(priv, 0x419e70, 0x0);
nv_wr32(priv, 0x419e74, 0x0); nv_wr32(priv, 0x419e74, 0x0);
...@@ -2567,28 +2652,73 @@ nve0_graph_generate_tpc(struct nvc0_graph_priv *priv) ...@@ -2567,28 +2652,73 @@ nve0_graph_generate_tpc(struct nvc0_graph_priv *priv)
nv_wr32(priv, 0x419e90, 0x0); nv_wr32(priv, 0x419e90, 0x0);
nv_wr32(priv, 0x419e94, 0x0); nv_wr32(priv, 0x419e94, 0x0);
nv_wr32(priv, 0x419e98, 0x0); nv_wr32(priv, 0x419e98, 0x0);
nv_wr32(priv, 0x419eac, 0x1fcf); switch (nv_device(priv)->chipset) {
nv_wr32(priv, 0x419eb0, 0xd3f); case 0xe4:
case 0xe7:
case 0xe6:
nv_wr32(priv, 0x419eac, 0x1f8f);
nv_wr32(priv, 0x419eb0, 0xd3f);
break;
case 0xf0:
nv_wr32(priv, 0x419eac, 0x1fcf);
nv_wr32(priv, 0x419eb0, 0xdb00da0);
nv_wr32(priv, 0x419eb8, 0x0);
break;
}
nv_wr32(priv, 0x419ec8, 0x1304f); nv_wr32(priv, 0x419ec8, 0x1304f);
nv_wr32(priv, 0x419f30, 0x0); nv_wr32(priv, 0x419f30, 0x0);
nv_wr32(priv, 0x419f34, 0x0); nv_wr32(priv, 0x419f34, 0x0);
nv_wr32(priv, 0x419f38, 0x0); nv_wr32(priv, 0x419f38, 0x0);
nv_wr32(priv, 0x419f3c, 0x0); nv_wr32(priv, 0x419f3c, 0x0);
nv_wr32(priv, 0x419f40, 0x0); switch (nv_device(priv)->chipset) {
case 0xf0:
nv_wr32(priv, 0x419f40, 0x18);
break;
default:
nv_wr32(priv, 0x419f40, 0x0);
break;
}
nv_wr32(priv, 0x419f44, 0x0); nv_wr32(priv, 0x419f44, 0x0);
nv_wr32(priv, 0x419f48, 0x0); nv_wr32(priv, 0x419f48, 0x0);
nv_wr32(priv, 0x419f4c, 0x0); nv_wr32(priv, 0x419f4c, 0x0);
nv_wr32(priv, 0x419f58, 0x0); nv_wr32(priv, 0x419f58, 0x0);
nv_wr32(priv, 0x419f78, 0xb); switch (nv_device(priv)->chipset) {
case 0xe4:
case 0xe7:
case 0xe6:
nv_wr32(priv, 0x419f70, 0x0);
nv_wr32(priv, 0x419f78, 0xb);
nv_wr32(priv, 0x419f7c, 0x27a);
break;
case 0xf0:
nv_wr32(priv, 0x419f70, 0x7300);
nv_wr32(priv, 0x419f78, 0xeb);
nv_wr32(priv, 0x419f7c, 0x404);
break;
}
} }
static void static void
nve0_graph_generate_tpcunk(struct nvc0_graph_priv *priv) nve0_graph_generate_tpcunk(struct nvc0_graph_priv *priv)
{ {
nv_wr32(priv, 0x41be24, 0x6); nv_wr32(priv, 0x41be24, 0x6);
nv_wr32(priv, 0x41bec0, 0x12180000); switch (nv_device(priv)->chipset) {
case 0xf0:
nv_wr32(priv, 0x41bec0, 0x10000000);
break;
default:
nv_wr32(priv, 0x41bec0, 0x12180000);
break;
}
nv_wr32(priv, 0x41bec4, 0x37f7f); nv_wr32(priv, 0x41bec4, 0x37f7f);
nv_wr32(priv, 0x41bee4, 0x6480430); switch (nv_device(priv)->chipset) {
case 0xf0:
nv_wr32(priv, 0x41bee4, 0x0);
break;
default:
nv_wr32(priv, 0x41bee4, 0x6480430);
break;
}
nv_wr32(priv, 0x41bf00, 0xa418820); nv_wr32(priv, 0x41bf00, 0xa418820);
nv_wr32(priv, 0x41bf04, 0x62080e6); nv_wr32(priv, 0x41bf04, 0x62080e6);
nv_wr32(priv, 0x41bf08, 0x20398a4); nv_wr32(priv, 0x41bf08, 0x20398a4);
...@@ -2624,6 +2754,7 @@ nve0_grctx_generate(struct nvc0_graph_priv *priv) ...@@ -2624,6 +2754,7 @@ nve0_grctx_generate(struct nvc0_graph_priv *priv)
nve0_graph_generate_unk46xx(priv); nve0_graph_generate_unk46xx(priv);
nve0_graph_generate_unk47xx(priv); nve0_graph_generate_unk47xx(priv);
nve0_graph_generate_unk58xx(priv); nve0_graph_generate_unk58xx(priv);
nve0_graph_generate_unk5bxx(priv);
nve0_graph_generate_unk60xx(priv); nve0_graph_generate_unk60xx(priv);
nve0_graph_generate_unk64xx(priv); nve0_graph_generate_unk64xx(priv);
nve0_graph_generate_unk70xx(priv); nve0_graph_generate_unk70xx(priv);
......
...@@ -23,42 +23,7 @@ ...@@ -23,42 +23,7 @@
* Authors: Ben Skeggs * Authors: Ben Skeggs
*/ */
define(`mmctx_data', `.b32 eval((($2 - 1) << 26) | $1)') #ifdef INCLUDE_CODE
define(`queue_init', `.skip eval((2 * 4) + ((8 * 4) * 2))')
ifdef(`include_code', `
// Error codes
define(`E_BAD_COMMAND', 0x01)
define(`E_CMD_OVERFLOW', 0x02)
// Util macros to help with debugging ucode hangs etc
define(`T_WAIT', 0)
define(`T_MMCTX', 1)
define(`T_STRWAIT', 2)
define(`T_STRINIT', 3)
define(`T_AUTO', 4)
define(`T_CHAN', 5)
define(`T_LOAD', 6)
define(`T_SAVE', 7)
define(`T_LCHAN', 8)
define(`T_LCTXH', 9)
define(`trace_set', `
mov $r8 0x83c
shl b32 $r8 6
clear b32 $r9
bset $r9 $1
iowr I[$r8 + 0x000] $r9 // CC_SCRATCH[7]
')
define(`trace_clr', `
mov $r8 0x85c
shl b32 $r8 6
clear b32 $r9
bset $r9 $1
iowr I[$r8 + 0x000] $r9 // CC_SCRATCH[7]
')
// queue_put - add request to queue // queue_put - add request to queue
// //
// In : $r13 queue pointer // In : $r13 queue pointer
...@@ -178,27 +143,41 @@ watchdog_clear: ...@@ -178,27 +143,41 @@ watchdog_clear:
iowr I[$r8 + 0x000] $r0 iowr I[$r8 + 0x000] $r0
ret ret
// wait_done{z,o} - wait on FUC_DONE bit to become clear/set // wait_donez - wait on FUC_DONE bit to become clear
//
// In : $r10 bit to wait on
//
wait_donez:
trace_set(T_WAIT);
mov $r8 0x818
shl b32 $r8 6
iowr I[$r8 + 0x000] $r10
wait_donez_ne:
mov $r8 0x400
shl b32 $r8 6
iord $r8 I[$r8 + 0x000]
xbit $r8 $r8 $r10
bra ne #wait_donez_ne
trace_clr(T_WAIT)
ret
// wait_doneo - wait on FUC_DONE bit to become set
// //
// In : $r10 bit to wait on // In : $r10 bit to wait on
// //
define(`wait_done', ` wait_doneo:
$1:
trace_set(T_WAIT); trace_set(T_WAIT);
mov $r8 0x818 mov $r8 0x818
shl b32 $r8 6 shl b32 $r8 6
iowr I[$r8 + 0x000] $r10 // CC_SCRATCH[6] = wait bit iowr I[$r8 + 0x000] $r10
wait_done_$1: wait_doneo_e:
mov $r8 0x400 mov $r8 0x400
shl b32 $r8 6 shl b32 $r8 6
iord $r8 I[$r8 + 0x000] // DONE iord $r8 I[$r8 + 0x000]
xbit $r8 $r8 $r10 xbit $r8 $r8 $r10
bra $2 #wait_done_$1 bra e #wait_doneo_e
trace_clr(T_WAIT) trace_clr(T_WAIT)
ret ret
')
wait_done(wait_donez, ne)
wait_done(wait_doneo, e)
// mmctx_size - determine size of a mmio list transfer // mmctx_size - determine size of a mmio list transfer
// //
...@@ -397,4 +376,4 @@ strand_ctx_init: ...@@ -397,4 +376,4 @@ strand_ctx_init:
sub b32 $r15 $r14 $r15 sub b32 $r15 $r14 $r15
trace_clr(T_STRINIT) trace_clr(T_STRINIT)
ret ret
') #endif
/* fuc microcode for nvc0 PGRAPH/GPC
*
* Copyright 2011 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
*/
/* TODO
* - bracket certain functions with scratch writes, useful for debugging
* - watchdog timer around ctx operations
*/
#ifdef INCLUDE_DATA
gpc_id: .b32 0
gpc_mmio_list_head: .b32 0
gpc_mmio_list_tail: .b32 0
tpc_count: .b32 0
tpc_mask: .b32 0
tpc_mmio_list_head: .b32 0
tpc_mmio_list_tail: .b32 0
cmd_queue: queue_init
#endif
#ifdef INCLUDE_CODE
// reports an exception to the host
//
// In: $r15 error code (see nvc0.fuc)
//
error:
push $r14
mov $r14 -0x67ec // 0x9814
sethi $r14 0x400000
call #nv_wr32 // HUB_CTXCTL_CC_SCRATCH[5] = error code
add b32 $r14 0x41c
mov $r15 1
call #nv_wr32 // HUB_CTXCTL_INTR_UP_SET
pop $r14
ret
// GPC fuc initialisation, executed by triggering ucode start, will
// fall through to main loop after completion.
//
// Input:
// CC_SCRATCH[0]: chipset (PMC_BOOT_0 read returns 0x0bad0bad... sigh)
// CC_SCRATCH[1]: context base
//
// Output:
// CC_SCRATCH[0]:
// 31:31: set to signal completion
// CC_SCRATCH[1]:
// 31:0: GPC context size
//
init:
clear b32 $r0
mov $sp $r0
// enable fifo access
mov $r1 0x1200
mov $r2 2
iowr I[$r1 + 0x000] $r2 // FIFO_ENABLE
// setup i0 handler, and route all interrupts to it
mov $r1 #ih
mov $iv0 $r1
mov $r1 0x400
iowr I[$r1 + 0x300] $r0 // INTR_DISPATCH
// enable fifo interrupt
mov $r2 4
iowr I[$r1 + 0x000] $r2 // INTR_EN_SET
// enable interrupts
bset $flags ie0
// figure out which GPC we are, and how many TPCs we have
mov $r1 0x608
shl b32 $r1 6
iord $r2 I[$r1 + 0x000] // UNITS
mov $r3 1
and $r2 0x1f
shl b32 $r3 $r2
sub b32 $r3 1
st b32 D[$r0 + #tpc_count] $r2
st b32 D[$r0 + #tpc_mask] $r3
add b32 $r1 0x400
iord $r2 I[$r1 + 0x000] // MYINDEX
st b32 D[$r0 + #gpc_id] $r2
// find context data for this chipset
mov $r2 0x800
shl b32 $r2 6
iord $r2 I[$r2 + 0x000] // CC_SCRATCH[0]
mov $r1 #chipsets - 12
init_find_chipset:
add b32 $r1 12
ld b32 $r3 D[$r1 + 0x00]
cmpu b32 $r3 $r2
bra e #init_context
cmpu b32 $r3 0
bra ne #init_find_chipset
// unknown chipset
ret
// initialise context base, and size tracking
init_context:
mov $r2 0x800
shl b32 $r2 6
iord $r2 I[$r2 + 0x100] // CC_SCRATCH[1], initial base
clear b32 $r3 // track GPC context size here
// set mmctx base addresses now so we don't have to do it later,
// they don't currently ever change
mov $r4 0x700
shl b32 $r4 6
shr b32 $r5 $r2 8
iowr I[$r4 + 0x000] $r5 // MMCTX_SAVE_SWBASE
iowr I[$r4 + 0x100] $r5 // MMCTX_LOAD_SWBASE
// calculate GPC mmio context size, store the chipset-specific
// mmio list pointers somewhere we can get at them later without
// re-parsing the chipset list
clear b32 $r14
clear b32 $r15
ld b16 $r14 D[$r1 + 4]
ld b16 $r15 D[$r1 + 6]
st b16 D[$r0 + #gpc_mmio_list_head] $r14
st b16 D[$r0 + #gpc_mmio_list_tail] $r15
call #mmctx_size
add b32 $r2 $r15
add b32 $r3 $r15
// calculate per-TPC mmio context size, store the list pointers
ld b16 $r14 D[$r1 + 8]
ld b16 $r15 D[$r1 + 10]
st b16 D[$r0 + #tpc_mmio_list_head] $r14
st b16 D[$r0 + #tpc_mmio_list_tail] $r15
call #mmctx_size
ld b32 $r14 D[$r0 + #tpc_count]
mulu $r14 $r15
add b32 $r2 $r14
add b32 $r3 $r14
// round up base/size to 256 byte boundary (for strand SWBASE)
add b32 $r4 0x1300
shr b32 $r3 2
iowr I[$r4 + 0x000] $r3 // MMCTX_LOAD_COUNT, wtf for?!?
shr b32 $r2 8
shr b32 $r3 6
add b32 $r2 1
add b32 $r3 1
shl b32 $r2 8
shl b32 $r3 8
// calculate size of strand context data
mov b32 $r15 $r2
call #strand_ctx_init
add b32 $r3 $r15
// save context size, and tell HUB we're done
mov $r1 0x800
shl b32 $r1 6
iowr I[$r1 + 0x100] $r3 // CC_SCRATCH[1] = context size
add b32 $r1 0x800
clear b32 $r2
bset $r2 31
iowr I[$r1 + 0x000] $r2 // CC_SCRATCH[0] |= 0x80000000
// Main program loop, very simple, sleeps until woken up by the interrupt
// handler, pulls a command from the queue and executes its handler
//
main:
bset $flags $p0
sleep $p0
mov $r13 #cmd_queue
call #queue_get
bra $p1 #main
// 0x0000-0x0003 are all context transfers
cmpu b32 $r14 0x04
bra nc #main_not_ctx_xfer
// fetch $flags and mask off $p1/$p2
mov $r1 $flags
mov $r2 0x0006
not b32 $r2
and $r1 $r2
// set $p1/$p2 according to transfer type
shl b32 $r14 1
or $r1 $r14
mov $flags $r1
// transfer context data
call #ctx_xfer
bra #main
main_not_ctx_xfer:
shl b32 $r15 $r14 16
or $r15 E_BAD_COMMAND
call #error
bra #main
// interrupt handler
ih:
push $r8
mov $r8 $flags
push $r8
push $r9
push $r10
push $r11
push $r13
push $r14
push $r15
// incoming fifo command?
iord $r10 I[$r0 + 0x200] // INTR
and $r11 $r10 0x00000004
bra e #ih_no_fifo
// queue incoming fifo command for later processing
mov $r11 0x1900
mov $r13 #cmd_queue
iord $r14 I[$r11 + 0x100] // FIFO_CMD
iord $r15 I[$r11 + 0x000] // FIFO_DATA
call #queue_put
add b32 $r11 0x400
mov $r14 1
iowr I[$r11 + 0x000] $r14 // FIFO_ACK
// ack, and wake up main()
ih_no_fifo:
iowr I[$r0 + 0x100] $r10 // INTR_ACK
pop $r15
pop $r14
pop $r13
pop $r11
pop $r10
pop $r9
pop $r8
mov $flags $r8
pop $r8
bclr $flags $p0
iret
// Set this GPC's bit in HUB_BAR, used to signal completion of various
// activities to the HUB fuc
//
hub_barrier_done:
mov $r15 1
ld b32 $r14 D[$r0 + #gpc_id]
shl b32 $r15 $r14
mov $r14 -0x6be8 // 0x409418 - HUB_BAR_SET
sethi $r14 0x400000
call #nv_wr32
ret
// Disables various things, waits a bit, and re-enables them..
//
// Not sure how exactly this helps, perhaps "ENABLE" is not such a
// good description for the bits we turn off? Anyways, without this,
// funny things happen.
//
ctx_redswitch:
mov $r14 0x614
shl b32 $r14 6
mov $r15 0x020
iowr I[$r14] $r15 // GPC_RED_SWITCH = POWER
mov $r15 8
ctx_redswitch_delay:
sub b32 $r15 1
bra ne #ctx_redswitch_delay
mov $r15 0xa20
iowr I[$r14] $r15 // GPC_RED_SWITCH = UNK11, ENABLE, POWER
ret
// Transfer GPC context data between GPU and storage area
//
// In: $r15 context base address
// $p1 clear on save, set on load
// $p2 set if opposite direction done/will be done, so:
// on save it means: "a load will follow this save"
// on load it means: "a save preceeded this load"
//
ctx_xfer:
// set context base address
mov $r1 0xa04
shl b32 $r1 6
iowr I[$r1 + 0x000] $r15// MEM_BASE
bra not $p1 #ctx_xfer_not_load
call #ctx_redswitch
ctx_xfer_not_load:
// strands
mov $r1 0x4afc
sethi $r1 0x20000
mov $r2 0xc
iowr I[$r1] $r2 // STRAND_CMD(0x3f) = 0x0c
call #strand_wait
mov $r2 0x47fc
sethi $r2 0x20000
iowr I[$r2] $r0 // STRAND_FIRST_GENE(0x3f) = 0x00
xbit $r2 $flags $p1
add b32 $r2 3
iowr I[$r1] $r2 // STRAND_CMD(0x3f) = 0x03/0x04 (SAVE/LOAD)
// mmio context
xbit $r10 $flags $p1 // direction
or $r10 2 // first
mov $r11 0x0000
sethi $r11 0x500000
ld b32 $r12 D[$r0 + #gpc_id]
shl b32 $r12 15
add b32 $r11 $r12 // base = NV_PGRAPH_GPCn
ld b32 $r12 D[$r0 + #gpc_mmio_list_head]
ld b32 $r13 D[$r0 + #gpc_mmio_list_tail]
mov $r14 0 // not multi
call #mmctx_xfer
// per-TPC mmio context
xbit $r10 $flags $p1 // direction
or $r10 4 // last
mov $r11 0x4000
sethi $r11 0x500000 // base = NV_PGRAPH_GPC0_TPC0
ld b32 $r12 D[$r0 + #gpc_id]
shl b32 $r12 15
add b32 $r11 $r12 // base = NV_PGRAPH_GPCn_TPC0
ld b32 $r12 D[$r0 + #tpc_mmio_list_head]
ld b32 $r13 D[$r0 + #tpc_mmio_list_tail]
ld b32 $r15 D[$r0 + #tpc_mask]
mov $r14 0x800 // stride = 0x800
call #mmctx_xfer
// wait for strands to finish
call #strand_wait
// if load, or a save without a load following, do some
// unknown stuff that's done after finishing a block of
// strand commands
bra $p1 #ctx_xfer_post
bra not $p2 #ctx_xfer_done
ctx_xfer_post:
mov $r1 0x4afc
sethi $r1 0x20000
mov $r2 0xd
iowr I[$r1] $r2 // STRAND_CMD(0x3f) = 0x0d
call #strand_wait
// mark completion in HUB's barrier
ctx_xfer_done:
call #hub_barrier_done
ret
#endif
/* fuc microcode for nvc0 PGRAPH/GPC /*
* * Copyright 2013 Red Hat Inc.
* Copyright 2011 Red Hat Inc.
* *
* Permission is hereby granted, free of charge, to any person obtaining a * Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"), * copy of this software and associated documentation files (the "Software"),
...@@ -20,32 +19,17 @@ ...@@ -20,32 +19,17 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE. * OTHER DEALINGS IN THE SOFTWARE.
* *
* Authors: Ben Skeggs * Authors: Ben Skeggs <bskeggs@redhat.com>
*/
/* To build:
* m4 gpcnvc0.fuc | envyas -a -w -m fuc -V fuc3 -o gpcnvc0.fuc.h
*/ */
/* TODO #define NVGF
* - bracket certain functions with scratch writes, useful for debugging #include "macros.fuc"
* - watchdog timer around ctx operations
*/
.section #nvc0_grgpc_data .section #nvc0_grgpc_data
include(`nvc0.fuc') #define INCLUDE_DATA
gpc_id: .b32 0 #include "com.fuc"
gpc_mmio_list_head: .b32 0 #include "gpc.fuc"
gpc_mmio_list_tail: .b32 0
tpc_count: .b32 0
tpc_mask: .b32 0
tpc_mmio_list_head: .b32 0
tpc_mmio_list_tail: .b32 0
cmd_queue: queue_init
// chipset descriptions
chipsets: chipsets:
.b8 0xc0 0 0 0 .b8 0xc0 0 0 0
.b16 #nvc0_gpc_mmio_head .b16 #nvc0_gpc_mmio_head
...@@ -81,23 +65,26 @@ chipsets: ...@@ -81,23 +65,26 @@ chipsets:
.b16 #nvc0_gpc_mmio_head .b16 #nvc0_gpc_mmio_head
.b16 #nvc0_gpc_mmio_tail .b16 #nvc0_gpc_mmio_tail
.b16 #nvc0_tpc_mmio_head .b16 #nvc0_tpc_mmio_head
.b16 #nvcf_tpc_mmio_tail .b16 #nvc3_tpc_mmio_tail
.b8 0xd9 0 0 0 .b8 0xd9 0 0 0
.b16 #nvd9_gpc_mmio_head .b16 #nvd9_gpc_mmio_head
.b16 #nvd9_gpc_mmio_tail .b16 #nvc1_gpc_mmio_tail
.b16 #nvd9_tpc_mmio_head .b16 #nvc0_tpc_mmio_head
.b16 #nvd9_tpc_mmio_tail .b16 #nvd9_tpc_mmio_tail
.b8 0xd7 0 0 0 .b8 0xd7 0 0 0
.b16 #nvd9_gpc_mmio_head .b16 #nvd9_gpc_mmio_head
.b16 #nvd9_gpc_mmio_tail .b16 #nvc1_gpc_mmio_tail
.b16 #nvd9_tpc_mmio_head .b16 #nvc0_tpc_mmio_head
.b16 #nvd9_tpc_mmio_tail .b16 #nvd9_tpc_mmio_tail
.b8 0 0 0 0 .b8 0 0 0 0
// GPC mmio lists // GPC mmio lists
nvc0_gpc_mmio_head: nvc0_gpc_mmio_head:
mmctx_data(0x000408, 1)
nvd9_gpc_mmio_head:
mmctx_data(0x000380, 1) mmctx_data(0x000380, 1)
mmctx_data(0x000400, 6) mmctx_data(0x000400, 2);
mmctx_data(0x00040c, 3);
mmctx_data(0x000450, 9) mmctx_data(0x000450, 9)
mmctx_data(0x000600, 1) mmctx_data(0x000600, 1)
mmctx_data(0x000684, 1) mmctx_data(0x000684, 1)
...@@ -124,35 +111,6 @@ nvc0_gpc_mmio_tail: ...@@ -124,35 +111,6 @@ nvc0_gpc_mmio_tail:
mmctx_data(0x000c6c, 1); mmctx_data(0x000c6c, 1);
nvc1_gpc_mmio_tail: nvc1_gpc_mmio_tail:
nvd9_gpc_mmio_head:
mmctx_data(0x000380, 1)
mmctx_data(0x000400, 2)
mmctx_data(0x00040c, 3)
mmctx_data(0x000450, 9)
mmctx_data(0x000600, 1)
mmctx_data(0x000684, 1)
mmctx_data(0x000700, 5)
mmctx_data(0x000800, 1)
mmctx_data(0x000808, 3)
mmctx_data(0x000828, 1)
mmctx_data(0x000830, 1)
mmctx_data(0x0008d8, 1)
mmctx_data(0x0008e0, 1)
mmctx_data(0x0008e8, 6)
mmctx_data(0x00091c, 1)
mmctx_data(0x000924, 3)
mmctx_data(0x000b00, 1)
mmctx_data(0x000b08, 6)
mmctx_data(0x000bb8, 1)
mmctx_data(0x000c08, 1)
mmctx_data(0x000c10, 8)
mmctx_data(0x000c6c, 1)
mmctx_data(0x000c80, 1)
mmctx_data(0x000c8c, 1)
mmctx_data(0x001000, 3)
mmctx_data(0x001014, 1)
nvd9_gpc_mmio_tail:
// TPC mmio lists // TPC mmio lists
nvc0_tpc_mmio_head: nvc0_tpc_mmio_head:
mmctx_data(0x000018, 1) mmctx_data(0x000018, 1)
...@@ -161,7 +119,6 @@ mmctx_data(0x000048, 1) ...@@ -161,7 +119,6 @@ mmctx_data(0x000048, 1)
mmctx_data(0x000064, 1) mmctx_data(0x000064, 1)
mmctx_data(0x000088, 1) mmctx_data(0x000088, 1)
mmctx_data(0x000200, 6) mmctx_data(0x000200, 6)
mmctx_data(0x00021c, 2)
mmctx_data(0x000300, 6) mmctx_data(0x000300, 6)
mmctx_data(0x0003d0, 1) mmctx_data(0x0003d0, 1)
mmctx_data(0x0003e0, 2) mmctx_data(0x0003e0, 2)
...@@ -176,369 +133,22 @@ mmctx_data(0x000644, 20) ...@@ -176,369 +133,22 @@ mmctx_data(0x000644, 20)
mmctx_data(0x000698, 1) mmctx_data(0x000698, 1)
mmctx_data(0x000750, 2) mmctx_data(0x000750, 2)
nvc0_tpc_mmio_tail: nvc0_tpc_mmio_tail:
mmctx_data(0x000758, 1) mmctx_data(0x00021c, 2)
mmctx_data(0x0002c4, 1) mmctx_data(0x0002c4, 1)
mmctx_data(0x0006e0, 1) mmctx_data(0x000730, 8)
nvcf_tpc_mmio_tail: mmctx_data(0x000758, 1)
mmctx_data(0x0004bc, 1)
nvc3_tpc_mmio_tail: nvc3_tpc_mmio_tail:
mmctx_data(0x000544, 1) mmctx_data(0x000544, 1)
nvc1_tpc_mmio_tail: nvc1_tpc_mmio_tail:
mmctx_data(0x000424, 2);
nvd9_tpc_mmio_head: mmctx_data(0x0006e0, 1);
mmctx_data(0x000018, 1)
mmctx_data(0x00003c, 1)
mmctx_data(0x000048, 1)
mmctx_data(0x000064, 1)
mmctx_data(0x000088, 1)
mmctx_data(0x000200, 6)
mmctx_data(0x00021c, 2)
mmctx_data(0x0002c4, 1)
mmctx_data(0x000300, 6)
mmctx_data(0x0003d0, 1)
mmctx_data(0x0003e0, 2)
mmctx_data(0x000400, 3)
mmctx_data(0x000420, 3)
mmctx_data(0x0004b0, 1)
mmctx_data(0x0004e8, 1)
mmctx_data(0x0004f4, 1)
mmctx_data(0x000520, 2)
mmctx_data(0x000544, 1)
mmctx_data(0x000604, 4)
mmctx_data(0x000644, 20)
mmctx_data(0x000698, 1)
mmctx_data(0x0006e0, 1)
mmctx_data(0x000750, 3)
nvd9_tpc_mmio_tail: nvd9_tpc_mmio_tail:
#undef INCLUDE_DATA
.section #nvc0_grgpc_code .section #nvc0_grgpc_code
#define INCLUDE_CODE
bra #init bra #init
define(`include_code') #include "com.fuc"
include(`nvc0.fuc') #include "gpc.fuc"
// reports an exception to the host
//
// In: $r15 error code (see nvc0.fuc)
//
error:
push $r14
mov $r14 -0x67ec // 0x9814
sethi $r14 0x400000
call #nv_wr32 // HUB_CTXCTL_CC_SCRATCH[5] = error code
add b32 $r14 0x41c
mov $r15 1
call #nv_wr32 // HUB_CTXCTL_INTR_UP_SET
pop $r14
ret
// GPC fuc initialisation, executed by triggering ucode start, will
// fall through to main loop after completion.
//
// Input:
// CC_SCRATCH[0]: chipset (PMC_BOOT_0 read returns 0x0bad0bad... sigh)
// CC_SCRATCH[1]: context base
//
// Output:
// CC_SCRATCH[0]:
// 31:31: set to signal completion
// CC_SCRATCH[1]:
// 31:0: GPC context size
//
init:
clear b32 $r0
mov $sp $r0
// enable fifo access
mov $r1 0x1200
mov $r2 2
iowr I[$r1 + 0x000] $r2 // FIFO_ENABLE
// setup i0 handler, and route all interrupts to it
mov $r1 #ih
mov $iv0 $r1
mov $r1 0x400
iowr I[$r1 + 0x300] $r0 // INTR_DISPATCH
// enable fifo interrupt
mov $r2 4
iowr I[$r1 + 0x000] $r2 // INTR_EN_SET
// enable interrupts
bset $flags ie0
// figure out which GPC we are, and how many TPCs we have
mov $r1 0x608
shl b32 $r1 6
iord $r2 I[$r1 + 0x000] // UNITS
mov $r3 1
and $r2 0x1f
shl b32 $r3 $r2
sub b32 $r3 1
st b32 D[$r0 + #tpc_count] $r2
st b32 D[$r0 + #tpc_mask] $r3
add b32 $r1 0x400
iord $r2 I[$r1 + 0x000] // MYINDEX
st b32 D[$r0 + #gpc_id] $r2
// find context data for this chipset
mov $r2 0x800
shl b32 $r2 6
iord $r2 I[$r2 + 0x000] // CC_SCRATCH[0]
mov $r1 #chipsets - 12
init_find_chipset:
add b32 $r1 12
ld b32 $r3 D[$r1 + 0x00]
cmpu b32 $r3 $r2
bra e #init_context
cmpu b32 $r3 0
bra ne #init_find_chipset
// unknown chipset
ret
// initialise context base, and size tracking
init_context:
mov $r2 0x800
shl b32 $r2 6
iord $r2 I[$r2 + 0x100] // CC_SCRATCH[1], initial base
clear b32 $r3 // track GPC context size here
// set mmctx base addresses now so we don't have to do it later,
// they don't currently ever change
mov $r4 0x700
shl b32 $r4 6
shr b32 $r5 $r2 8
iowr I[$r4 + 0x000] $r5 // MMCTX_SAVE_SWBASE
iowr I[$r4 + 0x100] $r5 // MMCTX_LOAD_SWBASE
// calculate GPC mmio context size, store the chipset-specific
// mmio list pointers somewhere we can get at them later without
// re-parsing the chipset list
clear b32 $r14
clear b32 $r15
ld b16 $r14 D[$r1 + 4]
ld b16 $r15 D[$r1 + 6]
st b16 D[$r0 + #gpc_mmio_list_head] $r14
st b16 D[$r0 + #gpc_mmio_list_tail] $r15
call #mmctx_size
add b32 $r2 $r15
add b32 $r3 $r15
// calculate per-TPC mmio context size, store the list pointers
ld b16 $r14 D[$r1 + 8]
ld b16 $r15 D[$r1 + 10]
st b16 D[$r0 + #tpc_mmio_list_head] $r14
st b16 D[$r0 + #tpc_mmio_list_tail] $r15
call #mmctx_size
ld b32 $r14 D[$r0 + #tpc_count]
mulu $r14 $r15
add b32 $r2 $r14
add b32 $r3 $r14
// round up base/size to 256 byte boundary (for strand SWBASE)
add b32 $r4 0x1300
shr b32 $r3 2
iowr I[$r4 + 0x000] $r3 // MMCTX_LOAD_COUNT, wtf for?!?
shr b32 $r2 8
shr b32 $r3 6
add b32 $r2 1
add b32 $r3 1
shl b32 $r2 8
shl b32 $r3 8
// calculate size of strand context data
mov b32 $r15 $r2
call #strand_ctx_init
add b32 $r3 $r15
// save context size, and tell HUB we're done
mov $r1 0x800
shl b32 $r1 6
iowr I[$r1 + 0x100] $r3 // CC_SCRATCH[1] = context size
add b32 $r1 0x800
clear b32 $r2
bset $r2 31
iowr I[$r1 + 0x000] $r2 // CC_SCRATCH[0] |= 0x80000000
// Main program loop, very simple, sleeps until woken up by the interrupt
// handler, pulls a command from the queue and executes its handler
//
main:
bset $flags $p0
sleep $p0
mov $r13 #cmd_queue
call #queue_get
bra $p1 #main
// 0x0000-0x0003 are all context transfers
cmpu b32 $r14 0x04
bra nc #main_not_ctx_xfer
// fetch $flags and mask off $p1/$p2
mov $r1 $flags
mov $r2 0x0006
not b32 $r2
and $r1 $r2
// set $p1/$p2 according to transfer type
shl b32 $r14 1
or $r1 $r14
mov $flags $r1
// transfer context data
call #ctx_xfer
bra #main
main_not_ctx_xfer:
shl b32 $r15 $r14 16
or $r15 E_BAD_COMMAND
call #error
bra #main
// interrupt handler
ih:
push $r8
mov $r8 $flags
push $r8
push $r9
push $r10
push $r11
push $r13
push $r14
push $r15
// incoming fifo command?
iord $r10 I[$r0 + 0x200] // INTR
and $r11 $r10 0x00000004
bra e #ih_no_fifo
// queue incoming fifo command for later processing
mov $r11 0x1900
mov $r13 #cmd_queue
iord $r14 I[$r11 + 0x100] // FIFO_CMD
iord $r15 I[$r11 + 0x000] // FIFO_DATA
call #queue_put
add b32 $r11 0x400
mov $r14 1
iowr I[$r11 + 0x000] $r14 // FIFO_ACK
// ack, and wake up main()
ih_no_fifo:
iowr I[$r0 + 0x100] $r10 // INTR_ACK
pop $r15
pop $r14
pop $r13
pop $r11
pop $r10
pop $r9
pop $r8
mov $flags $r8
pop $r8
bclr $flags $p0
iret
// Set this GPC's bit in HUB_BAR, used to signal completion of various
// activities to the HUB fuc
//
hub_barrier_done:
mov $r15 1
ld b32 $r14 D[$r0 + #gpc_id]
shl b32 $r15 $r14
mov $r14 -0x6be8 // 0x409418 - HUB_BAR_SET
sethi $r14 0x400000
call #nv_wr32
ret
// Disables various things, waits a bit, and re-enables them..
//
// Not sure how exactly this helps, perhaps "ENABLE" is not such a
// good description for the bits we turn off? Anyways, without this,
// funny things happen.
//
ctx_redswitch:
mov $r14 0x614
shl b32 $r14 6
mov $r15 0x020
iowr I[$r14] $r15 // GPC_RED_SWITCH = POWER
mov $r15 8
ctx_redswitch_delay:
sub b32 $r15 1
bra ne #ctx_redswitch_delay
mov $r15 0xa20
iowr I[$r14] $r15 // GPC_RED_SWITCH = UNK11, ENABLE, POWER
ret
// Transfer GPC context data between GPU and storage area
//
// In: $r15 context base address
// $p1 clear on save, set on load
// $p2 set if opposite direction done/will be done, so:
// on save it means: "a load will follow this save"
// on load it means: "a save preceeded this load"
//
ctx_xfer:
// set context base address
mov $r1 0xa04
shl b32 $r1 6
iowr I[$r1 + 0x000] $r15// MEM_BASE
bra not $p1 #ctx_xfer_not_load
call #ctx_redswitch
ctx_xfer_not_load:
// strands
mov $r1 0x4afc
sethi $r1 0x20000
mov $r2 0xc
iowr I[$r1] $r2 // STRAND_CMD(0x3f) = 0x0c
call #strand_wait
mov $r2 0x47fc
sethi $r2 0x20000
iowr I[$r2] $r0 // STRAND_FIRST_GENE(0x3f) = 0x00
xbit $r2 $flags $p1
add b32 $r2 3
iowr I[$r1] $r2 // STRAND_CMD(0x3f) = 0x03/0x04 (SAVE/LOAD)
// mmio context
xbit $r10 $flags $p1 // direction
or $r10 2 // first
mov $r11 0x0000
sethi $r11 0x500000
ld b32 $r12 D[$r0 + #gpc_id]
shl b32 $r12 15
add b32 $r11 $r12 // base = NV_PGRAPH_GPCn
ld b32 $r12 D[$r0 + #gpc_mmio_list_head]
ld b32 $r13 D[$r0 + #gpc_mmio_list_tail]
mov $r14 0 // not multi
call #mmctx_xfer
// per-TPC mmio context
xbit $r10 $flags $p1 // direction
or $r10 4 // last
mov $r11 0x4000
sethi $r11 0x500000 // base = NV_PGRAPH_GPC0_TPC0
ld b32 $r12 D[$r0 + #gpc_id]
shl b32 $r12 15
add b32 $r11 $r12 // base = NV_PGRAPH_GPCn_TPC0
ld b32 $r12 D[$r0 + #tpc_mmio_list_head]
ld b32 $r13 D[$r0 + #tpc_mmio_list_tail]
ld b32 $r15 D[$r0 + #tpc_mask]
mov $r14 0x800 // stride = 0x800
call #mmctx_xfer
// wait for strands to finish
call #strand_wait
// if load, or a save without a load following, do some
// unknown stuff that's done after finishing a block of
// strand commands
bra $p1 #ctx_xfer_post
bra not $p2 #ctx_xfer_done
ctx_xfer_post:
mov $r1 0x4afc
sethi $r1 0x20000
mov $r2 0xd
iowr I[$r1] $r2 // STRAND_CMD(0x3f) = 0x0d
call #strand_wait
// mark completion in HUB's barrier
ctx_xfer_done:
call #hub_barrier_done
ret
.align 256 .align 256
#undef INCLUDE_CODE
...@@ -34,59 +34,36 @@ uint32_t nvc0_grgpc_data[] = { ...@@ -34,59 +34,36 @@ uint32_t nvc0_grgpc_data[] = {
0x00000000, 0x00000000,
/* 0x0064: chipsets */ /* 0x0064: chipsets */
0x000000c0, 0x000000c0,
0x012800c8, 0x013c00d4,
0x01e40194, 0x018c0140,
0x000000c1, 0x000000c1,
0x012c00c8, 0x014000d4,
0x01f80194, 0x01a00140,
0x000000c3, 0x000000c3,
0x012800c8, 0x013c00d4,
0x01f40194, 0x019c0140,
0x000000c4, 0x000000c4,
0x012800c8, 0x013c00d4,
0x01f40194, 0x019c0140,
0x000000c8, 0x000000c8,
0x012800c8, 0x013c00d4,
0x01e40194, 0x018c0140,
0x000000ce, 0x000000ce,
0x012800c8, 0x013c00d4,
0x01f40194, 0x019c0140,
0x000000cf, 0x000000cf,
0x012800c8, 0x013c00d4,
0x01f00194, 0x019c0140,
0x000000d9, 0x000000d9,
0x0194012c, 0x014000d8,
0x025401f8, 0x01a80140,
0x00000000, 0x000000d7,
/* 0x00c8: nvc0_gpc_mmio_head */ 0x014000d8,
0x00000380, 0x01a80140,
0x14000400, 0x00000000,
0x20000450, /* 0x00d4: nvc0_gpc_mmio_head */
0x00000600, 0x00000408,
0x00000684, /* 0x00d8: nvd9_gpc_mmio_head */
0x10000700,
0x00000800,
0x08000808,
0x00000828,
0x00000830,
0x000008d8,
0x000008e0,
0x140008e8,
0x0000091c,
0x08000924,
0x00000b00,
0x14000b08,
0x00000bb8,
0x00000c08,
0x1c000c10,
0x00000c80,
0x00000c8c,
0x08001000,
0x00001014,
/* 0x0128: nvc0_gpc_mmio_tail */
0x00000c6c,
/* 0x012c: nvc1_gpc_mmio_tail */
/* 0x012c: nvd9_gpc_mmio_head */
0x00000380, 0x00000380,
0x04000400, 0x04000400,
0x0800040c, 0x0800040c,
...@@ -108,20 +85,20 @@ uint32_t nvc0_grgpc_data[] = { ...@@ -108,20 +85,20 @@ uint32_t nvc0_grgpc_data[] = {
0x00000bb8, 0x00000bb8,
0x00000c08, 0x00000c08,
0x1c000c10, 0x1c000c10,
0x00000c6c,
0x00000c80, 0x00000c80,
0x00000c8c, 0x00000c8c,
0x08001000, 0x08001000,
0x00001014, 0x00001014,
/* 0x0194: nvd9_gpc_mmio_tail */ /* 0x013c: nvc0_gpc_mmio_tail */
/* 0x0194: nvc0_tpc_mmio_head */ 0x00000c6c,
/* 0x0140: nvc1_gpc_mmio_tail */
/* 0x0140: nvc0_tpc_mmio_head */
0x00000018, 0x00000018,
0x0000003c, 0x0000003c,
0x00000048, 0x00000048,
0x00000064, 0x00000064,
0x00000088, 0x00000088,
0x14000200, 0x14000200,
0x0400021c,
0x14000300, 0x14000300,
0x000003d0, 0x000003d0,
0x040003e0, 0x040003e0,
...@@ -135,39 +112,16 @@ uint32_t nvc0_grgpc_data[] = { ...@@ -135,39 +112,16 @@ uint32_t nvc0_grgpc_data[] = {
0x4c000644, 0x4c000644,
0x00000698, 0x00000698,
0x04000750, 0x04000750,
/* 0x01e4: nvc0_tpc_mmio_tail */ /* 0x018c: nvc0_tpc_mmio_tail */
0x00000758,
0x000002c4,
0x000006e0,
/* 0x01f0: nvcf_tpc_mmio_tail */
0x000004bc,
/* 0x01f4: nvc3_tpc_mmio_tail */
0x00000544,
/* 0x01f8: nvc1_tpc_mmio_tail */
/* 0x01f8: nvd9_tpc_mmio_head */
0x00000018,
0x0000003c,
0x00000048,
0x00000064,
0x00000088,
0x14000200,
0x0400021c, 0x0400021c,
0x000002c4, 0x000002c4,
0x14000300, 0x1c000730,
0x000003d0, 0x00000758,
0x040003e0, /* 0x019c: nvc3_tpc_mmio_tail */
0x08000400,
0x08000420,
0x000004b0,
0x000004e8,
0x000004f4,
0x04000520,
0x00000544, 0x00000544,
0x0c000604, /* 0x01a0: nvc1_tpc_mmio_tail */
0x4c000644, 0x04000424,
0x00000698,
0x000006e0, 0x000006e0,
0x08000750,
}; };
uint32_t nvc0_grgpc_code[] = { uint32_t nvc0_grgpc_code[] = {
...@@ -238,7 +192,7 @@ uint32_t nvc0_grgpc_code[] = { ...@@ -238,7 +192,7 @@ uint32_t nvc0_grgpc_code[] = {
0x0089d000, 0x0089d000,
0x081887f1, 0x081887f1,
0xd00684b6, 0xd00684b6,
/* 0x00e2: wait_done_wait_donez */ /* 0x00e2: wait_donez_ne */
0x87f1008a, 0x87f1008a,
0x84b60400, 0x84b60400,
0x0088cf06, 0x0088cf06,
...@@ -255,7 +209,7 @@ uint32_t nvc0_grgpc_code[] = { ...@@ -255,7 +209,7 @@ uint32_t nvc0_grgpc_code[] = {
0x87f10089, 0x87f10089,
0x84b60818, 0x84b60818,
0x008ad006, 0x008ad006,
/* 0x011c: wait_done_wait_doneo */ /* 0x011c: wait_doneo_e */
0x040087f1, 0x040087f1,
0xcf0684b6, 0xcf0684b6,
0x8aff0088, 0x8aff0088,
......
/* fuc microcode for nve0 PGRAPH/GPC /*
* * Copyright 2013 Red Hat Inc.
* Copyright 2011 Red Hat Inc.
* *
* Permission is hereby granted, free of charge, to any person obtaining a * Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"), * copy of this software and associated documentation files (the "Software"),
...@@ -20,32 +19,17 @@ ...@@ -20,32 +19,17 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE. * OTHER DEALINGS IN THE SOFTWARE.
* *
* Authors: Ben Skeggs * Authors: Ben Skeggs <bskeggs@redhat.com>
*/
/* To build:
* m4 nve0_grgpc.fuc | envyas -a -w -m fuc -V nva3 -o nve0_grgpc.fuc.h
*/ */
/* TODO #define NVGK
* - bracket certain functions with scratch writes, useful for debugging #include "macros.fuc"
* - watchdog timer around ctx operations
*/
.section #nve0_grgpc_data .section #nve0_grgpc_data
include(`nve0.fuc') #define INCLUDE_DATA
gpc_id: .b32 0 #include "com.fuc"
gpc_mmio_list_head: .b32 0 #include "gpc.fuc"
gpc_mmio_list_tail: .b32 0
tpc_count: .b32 0
tpc_mask: .b32 0
tpc_mmio_list_head: .b32 0
tpc_mmio_list_tail: .b32 0
cmd_queue: queue_init
// chipset descriptions
chipsets: chipsets:
.b8 0xe4 0 0 0 .b8 0xe4 0 0 0
.b16 #nve4_gpc_mmio_head .b16 #nve4_gpc_mmio_head
...@@ -62,6 +46,11 @@ chipsets: ...@@ -62,6 +46,11 @@ chipsets:
.b16 #nve4_gpc_mmio_tail .b16 #nve4_gpc_mmio_tail
.b16 #nve4_tpc_mmio_head .b16 #nve4_tpc_mmio_head
.b16 #nve4_tpc_mmio_tail .b16 #nve4_tpc_mmio_tail
.b8 0xf0 0 0 0
.b16 #nvf0_gpc_mmio_head
.b16 #nvf0_gpc_mmio_tail
.b16 #nvf0_tpc_mmio_head
.b16 #nvf0_tpc_mmio_tail
.b8 0 0 0 0 .b8 0 0 0 0
// GPC mmio lists // GPC mmio lists
...@@ -101,6 +90,37 @@ mmctx_data(0x0031d0, 1) ...@@ -101,6 +90,37 @@ mmctx_data(0x0031d0, 1)
mmctx_data(0x0031e0, 2) mmctx_data(0x0031e0, 2)
nve4_gpc_mmio_tail: nve4_gpc_mmio_tail:
nvf0_gpc_mmio_head:
mmctx_data(0x000380, 1)
mmctx_data(0x000400, 2)
mmctx_data(0x00040c, 3)
mmctx_data(0x000450, 9)
mmctx_data(0x000600, 1)
mmctx_data(0x000684, 1)
mmctx_data(0x000700, 5)
mmctx_data(0x000800, 1)
mmctx_data(0x000808, 3)
mmctx_data(0x000828, 1)
mmctx_data(0x000830, 1)
mmctx_data(0x0008d8, 1)
mmctx_data(0x0008e0, 1)
mmctx_data(0x0008e8, 6)
mmctx_data(0x00091c, 1)
mmctx_data(0x000924, 3)
mmctx_data(0x000b00, 1)
mmctx_data(0x000b08, 6)
mmctx_data(0x000bb8, 1)
mmctx_data(0x000c08, 1)
mmctx_data(0x000c10, 8)
mmctx_data(0x000c40, 1)
mmctx_data(0x000c6c, 1)
mmctx_data(0x000c80, 1)
mmctx_data(0x000c8c, 1)
mmctx_data(0x000d24, 1)
mmctx_data(0x001000, 3)
mmctx_data(0x001014, 1)
nvf0_gpc_mmio_tail:
// TPC mmio lists // TPC mmio lists
nve4_tpc_mmio_head: nve4_tpc_mmio_head:
mmctx_data(0x000048, 1) mmctx_data(0x000048, 1)
...@@ -120,337 +140,38 @@ mmctx_data(0x0006ac, 2) ...@@ -120,337 +140,38 @@ mmctx_data(0x0006ac, 2)
mmctx_data(0x0006c8, 1) mmctx_data(0x0006c8, 1)
mmctx_data(0x000730, 8) mmctx_data(0x000730, 8)
mmctx_data(0x000758, 1) mmctx_data(0x000758, 1)
mmctx_data(0x000778, 1) mmctx_data(0x000770, 1)
mmctx_data(0x000778, 2)
nve4_tpc_mmio_tail: nve4_tpc_mmio_tail:
nvf0_tpc_mmio_head:
mmctx_data(0x000048, 1)
mmctx_data(0x000064, 1)
mmctx_data(0x000088, 1)
mmctx_data(0x000200, 6)
mmctx_data(0x00021c, 2)
mmctx_data(0x000230, 1)
mmctx_data(0x0002c4, 1)
mmctx_data(0x000400, 3)
mmctx_data(0x000420, 3)
mmctx_data(0x0004e8, 1)
mmctx_data(0x0004f4, 1)
mmctx_data(0x000604, 4)
mmctx_data(0x000644, 22)
mmctx_data(0x0006ac, 2)
mmctx_data(0x0006b8, 1)
mmctx_data(0x0006c8, 1)
mmctx_data(0x000730, 8)
mmctx_data(0x000758, 1)
mmctx_data(0x000770, 1)
mmctx_data(0x000778, 2)
nvf0_tpc_mmio_tail:
#undef INCLUDE_DATA
.section #nve0_grgpc_code .section #nve0_grgpc_code
#define INCLUDE_CODE
bra #init bra #init
define(`include_code') #include "com.fuc"
include(`nve0.fuc') #include "gpc.fuc"
// reports an exception to the host
//
// In: $r15 error code (see nve0.fuc)
//
error:
push $r14
mov $r14 -0x67ec // 0x9814
sethi $r14 0x400000
call #nv_wr32 // HUB_CTXCTL_CC_SCRATCH[5] = error code
add b32 $r14 0x41c
mov $r15 1
call #nv_wr32 // HUB_CTXCTL_INTR_UP_SET
pop $r14
ret
// GPC fuc initialisation, executed by triggering ucode start, will
// fall through to main loop after completion.
//
// Input:
// CC_SCRATCH[0]: chipset (PMC_BOOT_0 read returns 0x0bad0bad... sigh)
// CC_SCRATCH[1]: context base
//
// Output:
// CC_SCRATCH[0]:
// 31:31: set to signal completion
// CC_SCRATCH[1]:
// 31:0: GPC context size
//
init:
clear b32 $r0
mov $sp $r0
// enable fifo access
mov $r1 0x1200
mov $r2 2
iowr I[$r1 + 0x000] $r2 // FIFO_ENABLE
// setup i0 handler, and route all interrupts to it
mov $r1 #ih
mov $iv0 $r1
mov $r1 0x400
iowr I[$r1 + 0x300] $r0 // INTR_DISPATCH
// enable fifo interrupt
mov $r2 4
iowr I[$r1 + 0x000] $r2 // INTR_EN_SET
// enable interrupts
bset $flags ie0
// figure out which GPC we are, and how many TPCs we have
mov $r1 0x608
shl b32 $r1 6
iord $r2 I[$r1 + 0x000] // UNITS
mov $r3 1
and $r2 0x1f
shl b32 $r3 $r2
sub b32 $r3 1
st b32 D[$r0 + #tpc_count] $r2
st b32 D[$r0 + #tpc_mask] $r3
add b32 $r1 0x400
iord $r2 I[$r1 + 0x000] // MYINDEX
st b32 D[$r0 + #gpc_id] $r2
// find context data for this chipset
mov $r2 0x800
shl b32 $r2 6
iord $r2 I[$r2 + 0x000] // CC_SCRATCH[0]
mov $r1 #chipsets - 12
init_find_chipset:
add b32 $r1 12
ld b32 $r3 D[$r1 + 0x00]
cmpu b32 $r3 $r2
bra e #init_context
cmpu b32 $r3 0
bra ne #init_find_chipset
// unknown chipset
ret
// initialise context base, and size tracking
init_context:
mov $r2 0x800
shl b32 $r2 6
iord $r2 I[$r2 + 0x100] // CC_SCRATCH[1], initial base
clear b32 $r3 // track GPC context size here
// set mmctx base addresses now so we don't have to do it later,
// they don't currently ever change
mov $r4 0x700
shl b32 $r4 6
shr b32 $r5 $r2 8
iowr I[$r4 + 0x000] $r5 // MMCTX_SAVE_SWBASE
iowr I[$r4 + 0x100] $r5 // MMCTX_LOAD_SWBASE
// calculate GPC mmio context size, store the chipset-specific
// mmio list pointers somewhere we can get at them later without
// re-parsing the chipset list
clear b32 $r14
clear b32 $r15
ld b16 $r14 D[$r1 + 4]
ld b16 $r15 D[$r1 + 6]
st b16 D[$r0 + #gpc_mmio_list_head] $r14
st b16 D[$r0 + #gpc_mmio_list_tail] $r15
call #mmctx_size
add b32 $r2 $r15
add b32 $r3 $r15
// calculate per-TPC mmio context size, store the list pointers
ld b16 $r14 D[$r1 + 8]
ld b16 $r15 D[$r1 + 10]
st b16 D[$r0 + #tpc_mmio_list_head] $r14
st b16 D[$r0 + #tpc_mmio_list_tail] $r15
call #mmctx_size
ld b32 $r14 D[$r0 + #tpc_count]
mulu $r14 $r15
add b32 $r2 $r14
add b32 $r3 $r14
// round up base/size to 256 byte boundary (for strand SWBASE)
add b32 $r4 0x1300
shr b32 $r3 2
iowr I[$r4 + 0x000] $r3 // MMCTX_LOAD_COUNT, wtf for?!?
shr b32 $r2 8
shr b32 $r3 6
add b32 $r2 1
add b32 $r3 1
shl b32 $r2 8
shl b32 $r3 8
// calculate size of strand context data
mov b32 $r15 $r2
call #strand_ctx_init
add b32 $r3 $r15
// save context size, and tell HUB we're done
mov $r1 0x800
shl b32 $r1 6
iowr I[$r1 + 0x100] $r3 // CC_SCRATCH[1] = context size
add b32 $r1 0x800
clear b32 $r2
bset $r2 31
iowr I[$r1 + 0x000] $r2 // CC_SCRATCH[0] |= 0x80000000
// Main program loop, very simple, sleeps until woken up by the interrupt
// handler, pulls a command from the queue and executes its handler
//
main:
bset $flags $p0
sleep $p0
mov $r13 #cmd_queue
call #queue_get
bra $p1 #main
// 0x0000-0x0003 are all context transfers
cmpu b32 $r14 0x04
bra nc #main_not_ctx_xfer
// fetch $flags and mask off $p1/$p2
mov $r1 $flags
mov $r2 0x0006
not b32 $r2
and $r1 $r2
// set $p1/$p2 according to transfer type
shl b32 $r14 1
or $r1 $r14
mov $flags $r1
// transfer context data
call #ctx_xfer
bra #main
main_not_ctx_xfer:
shl b32 $r15 $r14 16
or $r15 E_BAD_COMMAND
call #error
bra #main
// interrupt handler
ih:
push $r8
mov $r8 $flags
push $r8
push $r9
push $r10
push $r11
push $r13
push $r14
push $r15
// incoming fifo command?
iord $r10 I[$r0 + 0x200] // INTR
and $r11 $r10 0x00000004
bra e #ih_no_fifo
// queue incoming fifo command for later processing
mov $r11 0x1900
mov $r13 #cmd_queue
iord $r14 I[$r11 + 0x100] // FIFO_CMD
iord $r15 I[$r11 + 0x000] // FIFO_DATA
call #queue_put
add b32 $r11 0x400
mov $r14 1
iowr I[$r11 + 0x000] $r14 // FIFO_ACK
// ack, and wake up main()
ih_no_fifo:
iowr I[$r0 + 0x100] $r10 // INTR_ACK
pop $r15
pop $r14
pop $r13
pop $r11
pop $r10
pop $r9
pop $r8
mov $flags $r8
pop $r8
bclr $flags $p0
iret
// Set this GPC's bit in HUB_BAR, used to signal completion of various
// activities to the HUB fuc
//
hub_barrier_done:
mov $r15 1
ld b32 $r14 D[$r0 + #gpc_id]
shl b32 $r15 $r14
mov $r14 -0x6be8 // 0x409418 - HUB_BAR_SET
sethi $r14 0x400000
call #nv_wr32
ret
// Disables various things, waits a bit, and re-enables them..
//
// Not sure how exactly this helps, perhaps "ENABLE" is not such a
// good description for the bits we turn off? Anyways, without this,
// funny things happen.
//
ctx_redswitch:
mov $r14 0x614
shl b32 $r14 6
mov $r15 0x020
iowr I[$r14] $r15 // GPC_RED_SWITCH = POWER
mov $r15 8
ctx_redswitch_delay:
sub b32 $r15 1
bra ne #ctx_redswitch_delay
mov $r15 0xa20
iowr I[$r14] $r15 // GPC_RED_SWITCH = UNK11, ENABLE, POWER
ret
// Transfer GPC context data between GPU and storage area
//
// In: $r15 context base address
// $p1 clear on save, set on load
// $p2 set if opposite direction done/will be done, so:
// on save it means: "a load will follow this save"
// on load it means: "a save preceeded this load"
//
ctx_xfer:
// set context base address
mov $r1 0xa04
shl b32 $r1 6
iowr I[$r1 + 0x000] $r15// MEM_BASE
bra not $p1 #ctx_xfer_not_load
call #ctx_redswitch
ctx_xfer_not_load:
// strands
mov $r1 0x4afc
sethi $r1 0x20000
mov $r2 0xc
iowr I[$r1] $r2 // STRAND_CMD(0x3f) = 0x0c
call #strand_wait
mov $r2 0x47fc
sethi $r2 0x20000
iowr I[$r2] $r0 // STRAND_FIRST_GENE(0x3f) = 0x00
xbit $r2 $flags $p1
add b32 $r2 3
iowr I[$r1] $r2 // STRAND_CMD(0x3f) = 0x03/0x04 (SAVE/LOAD)
// mmio context
xbit $r10 $flags $p1 // direction
or $r10 2 // first
mov $r11 0x0000
sethi $r11 0x500000
ld b32 $r12 D[$r0 + #gpc_id]
shl b32 $r12 15
add b32 $r11 $r12 // base = NV_PGRAPH_GPCn
ld b32 $r12 D[$r0 + #gpc_mmio_list_head]
ld b32 $r13 D[$r0 + #gpc_mmio_list_tail]
mov $r14 0 // not multi
call #mmctx_xfer
// per-TPC mmio context
xbit $r10 $flags $p1 // direction
or $r10 4 // last
mov $r11 0x4000
sethi $r11 0x500000 // base = NV_PGRAPH_GPC0_TPC0
ld b32 $r12 D[$r0 + #gpc_id]
shl b32 $r12 15
add b32 $r11 $r12 // base = NV_PGRAPH_GPCn_TPC0
ld b32 $r12 D[$r0 + #tpc_mmio_list_head]
ld b32 $r13 D[$r0 + #tpc_mmio_list_tail]
ld b32 $r15 D[$r0 + #tpc_mask]
mov $r14 0x800 // stride = 0x800
call #mmctx_xfer
// wait for strands to finish
call #strand_wait
// if load, or a save without a load following, do some
// unknown stuff that's done after finishing a block of
// strand commands
bra $p1 #ctx_xfer_post
bra not $p2 #ctx_xfer_done
ctx_xfer_post:
mov $r1 0x4afc
sethi $r1 0x20000
mov $r2 0xd
iowr I[$r1] $r2 // STRAND_CMD(0x3f) = 0x0d
call #strand_wait
// mark completion in HUB's barrier
ctx_xfer_done:
call #hub_barrier_done
ret
.align 256 .align 256
#undef INCLUDE_CODE
...@@ -34,16 +34,19 @@ uint32_t nve0_grgpc_data[] = { ...@@ -34,16 +34,19 @@ uint32_t nve0_grgpc_data[] = {
0x00000000, 0x00000000,
/* 0x0064: chipsets */ /* 0x0064: chipsets */
0x000000e4, 0x000000e4,
0x0110008c, 0x011c0098,
0x01580110, 0x01d8018c,
0x000000e7, 0x000000e7,
0x0110008c, 0x011c0098,
0x01580110, 0x01d8018c,
0x000000e6, 0x000000e6,
0x0110008c, 0x011c0098,
0x01580110, 0x01d8018c,
0x000000f0,
0x018c011c,
0x022801d8,
0x00000000, 0x00000000,
/* 0x008c: nve4_gpc_mmio_head */ /* 0x0098: nve4_gpc_mmio_head */
0x00000380, 0x00000380,
0x04000400, 0x04000400,
0x0800040c, 0x0800040c,
...@@ -77,8 +80,59 @@ uint32_t nve0_grgpc_data[] = { ...@@ -77,8 +80,59 @@ uint32_t nve0_grgpc_data[] = {
0x14003100, 0x14003100,
0x000031d0, 0x000031d0,
0x040031e0, 0x040031e0,
/* 0x0110: nve4_gpc_mmio_tail */ /* 0x011c: nve4_gpc_mmio_tail */
/* 0x0110: nve4_tpc_mmio_head */ /* 0x011c: nvf0_gpc_mmio_head */
0x00000380,
0x04000400,
0x0800040c,
0x20000450,
0x00000600,
0x00000684,
0x10000700,
0x00000800,
0x08000808,
0x00000828,
0x00000830,
0x000008d8,
0x000008e0,
0x140008e8,
0x0000091c,
0x08000924,
0x00000b00,
0x14000b08,
0x00000bb8,
0x00000c08,
0x1c000c10,
0x00000c40,
0x00000c6c,
0x00000c80,
0x00000c8c,
0x00000d24,
0x08001000,
0x00001014,
/* 0x018c: nvf0_gpc_mmio_tail */
/* 0x018c: nve4_tpc_mmio_head */
0x00000048,
0x00000064,
0x00000088,
0x14000200,
0x0400021c,
0x00000230,
0x000002c4,
0x08000400,
0x08000420,
0x000004e8,
0x000004f4,
0x0c000604,
0x54000644,
0x040006ac,
0x000006c8,
0x1c000730,
0x00000758,
0x00000770,
0x04000778,
/* 0x01d8: nve4_tpc_mmio_tail */
/* 0x01d8: nvf0_tpc_mmio_head */
0x00000048, 0x00000048,
0x00000064, 0x00000064,
0x00000088, 0x00000088,
...@@ -93,10 +147,12 @@ uint32_t nve0_grgpc_data[] = { ...@@ -93,10 +147,12 @@ uint32_t nve0_grgpc_data[] = {
0x0c000604, 0x0c000604,
0x54000644, 0x54000644,
0x040006ac, 0x040006ac,
0x000006b8,
0x000006c8, 0x000006c8,
0x1c000730, 0x1c000730,
0x00000758, 0x00000758,
0x00000778, 0x00000770,
0x04000778,
}; };
uint32_t nve0_grgpc_code[] = { uint32_t nve0_grgpc_code[] = {
...@@ -167,7 +223,7 @@ uint32_t nve0_grgpc_code[] = { ...@@ -167,7 +223,7 @@ uint32_t nve0_grgpc_code[] = {
0x0089d000, 0x0089d000,
0x081887f1, 0x081887f1,
0xd00684b6, 0xd00684b6,
/* 0x00e2: wait_done_wait_donez */ /* 0x00e2: wait_donez_ne */
0x87f1008a, 0x87f1008a,
0x84b60400, 0x84b60400,
0x0088cf06, 0x0088cf06,
...@@ -184,7 +240,7 @@ uint32_t nve0_grgpc_code[] = { ...@@ -184,7 +240,7 @@ uint32_t nve0_grgpc_code[] = {
0x87f10089, 0x87f10089,
0x84b60818, 0x84b60818,
0x008ad006, 0x008ad006,
/* 0x011c: wait_done_wait_doneo */ /* 0x011c: wait_doneo_e */
0x040087f1, 0x040087f1,
0xcf0684b6, 0xcf0684b6,
0x8aff0088, 0x8aff0088,
......
/* fuc microcode for nvc0 PGRAPH/HUB
*
* Copyright 2011 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
*/
#ifdef INCLUDE_DATA
gpc_count: .b32 0
rop_count: .b32 0
cmd_queue: queue_init
hub_mmio_list_head: .b32 0
hub_mmio_list_tail: .b32 0
ctx_current: .b32 0
.align 256
chan_data:
chan_mmio_count: .b32 0
chan_mmio_address: .b32 0
.align 256
xfer_data: .skip 256
#endif
#ifdef INCLUDE_CODE
// reports an exception to the host
//
// In: $r15 error code (see nvc0.fuc)
//
error:
push $r14
mov $r14 0x814
shl b32 $r14 6
iowr I[$r14 + 0x000] $r15 // CC_SCRATCH[5] = error code
mov $r14 0xc1c
shl b32 $r14 6
mov $r15 1
iowr I[$r14 + 0x000] $r15 // INTR_UP_SET
pop $r14
ret
// HUB fuc initialisation, executed by triggering ucode start, will
// fall through to main loop after completion.
//
// Input:
// CC_SCRATCH[0]: chipset (PMC_BOOT_0 read returns 0x0bad0bad... sigh)
//
// Output:
// CC_SCRATCH[0]:
// 31:31: set to signal completion
// CC_SCRATCH[1]:
// 31:0: total PGRAPH context size
//
init:
clear b32 $r0
mov $sp $r0
mov $xdbase $r0
// enable fifo access
mov $r1 0x1200
mov $r2 2
iowr I[$r1 + 0x000] $r2 // FIFO_ENABLE
// setup i0 handler, and route all interrupts to it
mov $r1 #ih
mov $iv0 $r1
mov $r1 0x400
iowr I[$r1 + 0x300] $r0 // INTR_DISPATCH
// route HUB_CHANNEL_SWITCH to fuc interrupt 8
mov $r3 0x404
shl b32 $r3 6
mov $r2 0x2003 // { HUB_CHANNEL_SWITCH, ZERO } -> intr 8
iowr I[$r3 + 0x000] $r2
// not sure what these are, route them because NVIDIA does, and
// the IRQ handler will signal the host if we ever get one.. we
// may find out if/why we need to handle these if so..
//
mov $r2 0x2004
iowr I[$r3 + 0x004] $r2 // { 0x04, ZERO } -> intr 9
mov $r2 0x200b
iowr I[$r3 + 0x008] $r2 // { 0x0b, ZERO } -> intr 10
mov $r2 0x200c
iowr I[$r3 + 0x01c] $r2 // { 0x0c, ZERO } -> intr 15
// enable all INTR_UP interrupts
mov $r2 0xc24
shl b32 $r2 6
not b32 $r3 $r0
iowr I[$r2] $r3
// enable fifo, ctxsw, 9, 10, 15 interrupts
mov $r2 -0x78fc // 0x8704
sethi $r2 0
iowr I[$r1 + 0x000] $r2 // INTR_EN_SET
// fifo level triggered, rest edge
sub b32 $r1 0x100
mov $r2 4
iowr I[$r1] $r2
// enable interrupts
bset $flags ie0
// fetch enabled GPC/ROP counts
mov $r14 -0x69fc // 0x409604
sethi $r14 0x400000
call #nv_rd32
extr $r1 $r15 16:20
st b32 D[$r0 + #rop_count] $r1
and $r15 0x1f
st b32 D[$r0 + #gpc_count] $r15
// set BAR_REQMASK to GPC mask
mov $r1 1
shl b32 $r1 $r15
sub b32 $r1 1
mov $r2 0x40c
shl b32 $r2 6
iowr I[$r2 + 0x000] $r1
iowr I[$r2 + 0x100] $r1
// find context data for this chipset
mov $r2 0x800
shl b32 $r2 6
iord $r2 I[$r2 + 0x000] // CC_SCRATCH[0]
mov $r15 #chipsets - 8
init_find_chipset:
add b32 $r15 8
ld b32 $r3 D[$r15 + 0x00]
cmpu b32 $r3 $r2
bra e #init_context
cmpu b32 $r3 0
bra ne #init_find_chipset
// unknown chipset
ret
// context size calculation, reserve first 256 bytes for use by fuc
init_context:
mov $r1 256
// calculate size of mmio context data
ld b16 $r14 D[$r15 + 4]
ld b16 $r15 D[$r15 + 6]
sethi $r14 0
st b32 D[$r0 + #hub_mmio_list_head] $r14
st b32 D[$r0 + #hub_mmio_list_tail] $r15
call #mmctx_size
// set mmctx base addresses now so we don't have to do it later,
// they don't (currently) ever change
mov $r3 0x700
shl b32 $r3 6
shr b32 $r4 $r1 8
iowr I[$r3 + 0x000] $r4 // MMCTX_SAVE_SWBASE
iowr I[$r3 + 0x100] $r4 // MMCTX_LOAD_SWBASE
add b32 $r3 0x1300
add b32 $r1 $r15
shr b32 $r15 2
iowr I[$r3 + 0x000] $r15 // MMCTX_LOAD_COUNT, wtf for?!?
// strands, base offset needs to be aligned to 256 bytes
shr b32 $r1 8
add b32 $r1 1
shl b32 $r1 8
mov b32 $r15 $r1
call #strand_ctx_init
add b32 $r1 $r15
// initialise each GPC in sequence by passing in the offset of its
// context data in GPCn_CC_SCRATCH[1], and starting its FUC (which
// has previously been uploaded by the host) running.
//
// the GPC fuc init sequence will set GPCn_CC_SCRATCH[0] bit 31
// when it has completed, and return the size of its context data
// in GPCn_CC_SCRATCH[1]
//
ld b32 $r3 D[$r0 + #gpc_count]
mov $r4 0x2000
sethi $r4 0x500000
init_gpc:
// setup, and start GPC ucode running
add b32 $r14 $r4 0x804
mov b32 $r15 $r1
call #nv_wr32 // CC_SCRATCH[1] = ctx offset
add b32 $r14 $r4 0x800
mov b32 $r15 $r2
call #nv_wr32 // CC_SCRATCH[0] = chipset
add b32 $r14 $r4 0x10c
clear b32 $r15
call #nv_wr32
add b32 $r14 $r4 0x104
call #nv_wr32 // ENTRY
add b32 $r14 $r4 0x100
mov $r15 2 // CTRL_START_TRIGGER
call #nv_wr32 // CTRL
// wait for it to complete, and adjust context size
add b32 $r14 $r4 0x800
init_gpc_wait:
call #nv_rd32
xbit $r15 $r15 31
bra e #init_gpc_wait
add b32 $r14 $r4 0x804
call #nv_rd32
add b32 $r1 $r15
// next!
add b32 $r4 0x8000
sub b32 $r3 1
bra ne #init_gpc
// save context size, and tell host we're ready
mov $r2 0x800
shl b32 $r2 6
iowr I[$r2 + 0x100] $r1 // CC_SCRATCH[1] = context size
add b32 $r2 0x800
clear b32 $r1
bset $r1 31
iowr I[$r2 + 0x000] $r1 // CC_SCRATCH[0] |= 0x80000000
// Main program loop, very simple, sleeps until woken up by the interrupt
// handler, pulls a command from the queue and executes its handler
//
main:
// sleep until we have something to do
bset $flags $p0
sleep $p0
mov $r13 #cmd_queue
call #queue_get
bra $p1 #main
// context switch, requested by GPU?
cmpu b32 $r14 0x4001
bra ne #main_not_ctx_switch
trace_set(T_AUTO)
mov $r1 0xb00
shl b32 $r1 6
iord $r2 I[$r1 + 0x100] // CHAN_NEXT
iord $r1 I[$r1 + 0x000] // CHAN_CUR
xbit $r3 $r1 31
bra e #chsw_no_prev
xbit $r3 $r2 31
bra e #chsw_prev_no_next
push $r2
mov b32 $r2 $r1
trace_set(T_SAVE)
bclr $flags $p1
bset $flags $p2
call #ctx_xfer
trace_clr(T_SAVE);
pop $r2
trace_set(T_LOAD);
bset $flags $p1
call #ctx_xfer
trace_clr(T_LOAD);
bra #chsw_done
chsw_prev_no_next:
push $r2
mov b32 $r2 $r1
bclr $flags $p1
bclr $flags $p2
call #ctx_xfer
pop $r2
mov $r1 0xb00
shl b32 $r1 6
iowr I[$r1] $r2
bra #chsw_done
chsw_no_prev:
xbit $r3 $r2 31
bra e #chsw_done
bset $flags $p1
bclr $flags $p2
call #ctx_xfer
// ack the context switch request
chsw_done:
mov $r1 0xb0c
shl b32 $r1 6
mov $r2 1
iowr I[$r1 + 0x000] $r2 // 0x409b0c
trace_clr(T_AUTO)
bra #main
// request to set current channel? (*not* a context switch)
main_not_ctx_switch:
cmpu b32 $r14 0x0001
bra ne #main_not_ctx_chan
mov b32 $r2 $r15
call #ctx_chan
bra #main_done
// request to store current channel context?
main_not_ctx_chan:
cmpu b32 $r14 0x0002
bra ne #main_not_ctx_save
trace_set(T_SAVE)
bclr $flags $p1
bclr $flags $p2
call #ctx_xfer
trace_clr(T_SAVE)
bra #main_done
main_not_ctx_save:
shl b32 $r15 $r14 16
or $r15 E_BAD_COMMAND
call #error
bra #main
main_done:
mov $r1 0x820
shl b32 $r1 6
clear b32 $r2
bset $r2 31
iowr I[$r1 + 0x000] $r2 // CC_SCRATCH[0] |= 0x80000000
bra #main
// interrupt handler
ih:
push $r8
mov $r8 $flags
push $r8
push $r9
push $r10
push $r11
push $r13
push $r14
push $r15
// incoming fifo command?
iord $r10 I[$r0 + 0x200] // INTR
and $r11 $r10 0x00000004
bra e #ih_no_fifo
// queue incoming fifo command for later processing
mov $r11 0x1900
mov $r13 #cmd_queue
iord $r14 I[$r11 + 0x100] // FIFO_CMD
iord $r15 I[$r11 + 0x000] // FIFO_DATA
call #queue_put
add b32 $r11 0x400
mov $r14 1
iowr I[$r11 + 0x000] $r14 // FIFO_ACK
// context switch request?
ih_no_fifo:
and $r11 $r10 0x00000100
bra e #ih_no_ctxsw
// enqueue a context switch for later processing
mov $r13 #cmd_queue
mov $r14 0x4001
call #queue_put
// anything we didn't handle, bring it to the host's attention
ih_no_ctxsw:
mov $r11 0x104
not b32 $r11
and $r11 $r10 $r11
bra e #ih_no_other
mov $r10 0xc1c
shl b32 $r10 6
iowr I[$r10] $r11 // INTR_UP_SET
// ack, and wake up main()
ih_no_other:
iowr I[$r0 + 0x100] $r10 // INTR_ACK
pop $r15
pop $r14
pop $r13
pop $r11
pop $r10
pop $r9
pop $r8
mov $flags $r8
pop $r8
bclr $flags $p0
iret
#ifdef NVGF
// Not real sure, but, MEM_CMD 7 will hang forever if this isn't done
ctx_4160s:
mov $r14 0x4160
sethi $r14 0x400000
mov $r15 1
call #nv_wr32
ctx_4160s_wait:
call #nv_rd32
xbit $r15 $r15 4
bra e #ctx_4160s_wait
ret
// Without clearing again at end of xfer, some things cause PGRAPH
// to hang with STATUS=0x00000007 until it's cleared.. fbcon can
// still function with it set however...
ctx_4160c:
mov $r14 0x4160
sethi $r14 0x400000
clear b32 $r15
call #nv_wr32
ret
#endif
// Again, not real sure
//
// In: $r15 value to set 0x404170 to
//
ctx_4170s:
mov $r14 0x4170
sethi $r14 0x400000
or $r15 0x10
call #nv_wr32
ret
// Waits for a ctx_4170s() call to complete
//
ctx_4170w:
mov $r14 0x4170
sethi $r14 0x400000
call #nv_rd32
and $r15 0x10
bra ne #ctx_4170w
ret
// Disables various things, waits a bit, and re-enables them..
//
// Not sure how exactly this helps, perhaps "ENABLE" is not such a
// good description for the bits we turn off? Anyways, without this,
// funny things happen.
//
ctx_redswitch:
mov $r14 0x614
shl b32 $r14 6
mov $r15 0x270
iowr I[$r14] $r15 // HUB_RED_SWITCH = ENABLE_GPC, POWER_ALL
mov $r15 8
ctx_redswitch_delay:
sub b32 $r15 1
bra ne #ctx_redswitch_delay
mov $r15 0x770
iowr I[$r14] $r15 // HUB_RED_SWITCH = ENABLE_ALL, POWER_ALL
ret
// Not a clue what this is for, except that unless the value is 0x10, the
// strand context is saved (and presumably restored) incorrectly..
//
// In: $r15 value to set to (0x00/0x10 are used)
//
ctx_86c:
mov $r14 0x86c
shl b32 $r14 6
iowr I[$r14] $r15 // HUB(0x86c) = val
mov $r14 -0x75ec
sethi $r14 0x400000
call #nv_wr32 // ROP(0xa14) = val
mov $r14 -0x5794
sethi $r14 0x410000
call #nv_wr32 // GPC(0x86c) = val
ret
// ctx_load - load's a channel's ctxctl data, and selects its vm
//
// In: $r2 channel address
//
ctx_load:
trace_set(T_CHAN)
// switch to channel, somewhat magic in parts..
mov $r10 12 // DONE_UNK12
call #wait_donez
mov $r1 0xa24
shl b32 $r1 6
iowr I[$r1 + 0x000] $r0 // 0x409a24
mov $r3 0xb00
shl b32 $r3 6
iowr I[$r3 + 0x100] $r2 // CHAN_NEXT
mov $r1 0xa0c
shl b32 $r1 6
mov $r4 7
iowr I[$r1 + 0x000] $r2 // MEM_CHAN
iowr I[$r1 + 0x100] $r4 // MEM_CMD
ctx_chan_wait_0:
iord $r4 I[$r1 + 0x100]
and $r4 0x1f
bra ne #ctx_chan_wait_0
iowr I[$r3 + 0x000] $r2 // CHAN_CUR
// load channel header, fetch PGRAPH context pointer
mov $xtargets $r0
bclr $r2 31
shl b32 $r2 4
add b32 $r2 2
trace_set(T_LCHAN)
mov $r1 0xa04
shl b32 $r1 6
iowr I[$r1 + 0x000] $r2 // MEM_BASE
mov $r1 0xa20
shl b32 $r1 6
mov $r2 0x0002
sethi $r2 0x80000000
iowr I[$r1 + 0x000] $r2 // MEM_TARGET = vram
mov $r1 0x10 // chan + 0x0210
mov $r2 #xfer_data
sethi $r2 0x00020000 // 16 bytes
xdld $r1 $r2
xdwait
trace_clr(T_LCHAN)
// update current context
ld b32 $r1 D[$r0 + #xfer_data + 4]
shl b32 $r1 24
ld b32 $r2 D[$r0 + #xfer_data + 0]
shr b32 $r2 8
or $r1 $r2
st b32 D[$r0 + #ctx_current] $r1
// set transfer base to start of context, and fetch context header
trace_set(T_LCTXH)
mov $r2 0xa04
shl b32 $r2 6
iowr I[$r2 + 0x000] $r1 // MEM_BASE
mov $r2 1
mov $r1 0xa20
shl b32 $r1 6
iowr I[$r1 + 0x000] $r2 // MEM_TARGET = vm
mov $r1 #chan_data
sethi $r1 0x00060000 // 256 bytes
xdld $r0 $r1
xdwait
trace_clr(T_LCTXH)
trace_clr(T_CHAN)
ret
// ctx_chan - handler for HUB_SET_CHAN command, will set a channel as
// the active channel for ctxctl, but not actually transfer
// any context data. intended for use only during initial
// context construction.
//
// In: $r2 channel address
//
ctx_chan:
#ifdef NVGF
call #ctx_4160s
#endif
call #ctx_load
mov $r10 12 // DONE_UNK12
call #wait_donez
mov $r1 0xa10
shl b32 $r1 6
mov $r2 5
iowr I[$r1 + 0x000] $r2 // MEM_CMD = 5 (???)
ctx_chan_wait:
iord $r2 I[$r1 + 0x000]
or $r2 $r2
bra ne #ctx_chan_wait
#ifdef NVGF
call #ctx_4160c
#endif
ret
// Execute per-context state overrides list
//
// Only executed on the first load of a channel. Might want to look into
// removing this and having the host directly modify the channel's context
// to change this state... The nouveau DRM already builds this list as
// it's definitely needed for NVIDIA's, so we may as well use it for now
//
// Input: $r1 mmio list length
//
ctx_mmio_exec:
// set transfer base to be the mmio list
ld b32 $r3 D[$r0 + #chan_mmio_address]
mov $r2 0xa04
shl b32 $r2 6
iowr I[$r2 + 0x000] $r3 // MEM_BASE
clear b32 $r3
ctx_mmio_loop:
// fetch next 256 bytes of mmio list if necessary
and $r4 $r3 0xff
bra ne #ctx_mmio_pull
mov $r5 #xfer_data
sethi $r5 0x00060000 // 256 bytes
xdld $r3 $r5
xdwait
// execute a single list entry
ctx_mmio_pull:
ld b32 $r14 D[$r4 + #xfer_data + 0x00]
ld b32 $r15 D[$r4 + #xfer_data + 0x04]
call #nv_wr32
// next!
add b32 $r3 8
sub b32 $r1 1
bra ne #ctx_mmio_loop
// set transfer base back to the current context
ctx_mmio_done:
ld b32 $r3 D[$r0 + #ctx_current]
iowr I[$r2 + 0x000] $r3 // MEM_BASE
// disable the mmio list now, we don't need/want to execute it again
st b32 D[$r0 + #chan_mmio_count] $r0
mov $r1 #chan_data
sethi $r1 0x00060000 // 256 bytes
xdst $r0 $r1
xdwait
ret
// Transfer HUB context data between GPU and storage area
//
// In: $r2 channel address
// $p1 clear on save, set on load
// $p2 set if opposite direction done/will be done, so:
// on save it means: "a load will follow this save"
// on load it means: "a save preceeded this load"
//
ctx_xfer:
// according to mwk, some kind of wait for idle
mov $r15 0xc00
shl b32 $r15 6
mov $r14 4
iowr I[$r15 + 0x200] $r14
ctx_xfer_idle:
iord $r14 I[$r15 + 0x000]
and $r14 0x2000
bra ne #ctx_xfer_idle
bra not $p1 #ctx_xfer_pre
bra $p2 #ctx_xfer_pre_load
ctx_xfer_pre:
mov $r15 0x10
call #ctx_86c
#ifdef NVGF
call #ctx_4160s
#endif
bra not $p1 #ctx_xfer_exec
ctx_xfer_pre_load:
mov $r15 2
call #ctx_4170s
call #ctx_4170w
call #ctx_redswitch
clear b32 $r15
call #ctx_4170s
call #ctx_load
// fetch context pointer, and initiate xfer on all GPCs
ctx_xfer_exec:
ld b32 $r1 D[$r0 + #ctx_current]
mov $r2 0x414
shl b32 $r2 6
iowr I[$r2 + 0x000] $r0 // BAR_STATUS = reset
mov $r14 -0x5b00
sethi $r14 0x410000
mov b32 $r15 $r1
call #nv_wr32 // GPC_BCAST_WRCMD_DATA = ctx pointer
add b32 $r14 4
xbit $r15 $flags $p1
xbit $r2 $flags $p2
shl b32 $r2 1
or $r15 $r2
call #nv_wr32 // GPC_BCAST_WRCMD_CMD = GPC_XFER(type)
// strands
mov $r1 0x4afc
sethi $r1 0x20000
mov $r2 0xc
iowr I[$r1] $r2 // STRAND_CMD(0x3f) = 0x0c
call #strand_wait
mov $r2 0x47fc
sethi $r2 0x20000
iowr I[$r2] $r0 // STRAND_FIRST_GENE(0x3f) = 0x00
xbit $r2 $flags $p1
add b32 $r2 3
iowr I[$r1] $r2 // STRAND_CMD(0x3f) = 0x03/0x04 (SAVE/LOAD)
// mmio context
xbit $r10 $flags $p1 // direction
or $r10 6 // first, last
mov $r11 0 // base = 0
ld b32 $r12 D[$r0 + #hub_mmio_list_head]
ld b32 $r13 D[$r0 + #hub_mmio_list_tail]
mov $r14 0 // not multi
call #mmctx_xfer
// wait for GPCs to all complete
mov $r10 8 // DONE_BAR
call #wait_doneo
// wait for strand xfer to complete
call #strand_wait
// post-op
bra $p1 #ctx_xfer_post
mov $r10 12 // DONE_UNK12
call #wait_donez
mov $r1 0xa10
shl b32 $r1 6
mov $r2 5
iowr I[$r1] $r2 // MEM_CMD
ctx_xfer_post_save_wait:
iord $r2 I[$r1]
or $r2 $r2
bra ne #ctx_xfer_post_save_wait
bra $p2 #ctx_xfer_done
ctx_xfer_post:
mov $r15 2
call #ctx_4170s
clear b32 $r15
call #ctx_86c
call #strand_post
call #ctx_4170w
clear b32 $r15
call #ctx_4170s
bra not $p1 #ctx_xfer_no_post_mmio
ld b32 $r1 D[$r0 + #chan_mmio_count]
or $r1 $r1
bra e #ctx_xfer_no_post_mmio
call #ctx_mmio_exec
ctx_xfer_no_post_mmio:
#ifdef NVGF
call #ctx_4160c
#endif
ctx_xfer_done:
ret
#endif
/*
* Copyright 2013 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 <bskeggs@redhat.com>
*/
#include "os.h"
#define mmctx_data(r,c) .b32 (((c - 1) << 26) | r)
#define queue_init .skip 72 // (2 * 4) + ((8 * 4) * 2)
#define T_WAIT 0
#define T_MMCTX 1
#define T_STRWAIT 2
#define T_STRINIT 3
#define T_AUTO 4
#define T_CHAN 5
#define T_LOAD 6
#define T_SAVE 7
#define T_LCHAN 8
#define T_LCTXH 9
#define trace_set(bit) /*
*/ mov $r8 0x83c /*
*/ shl b32 $r8 6 /*
*/ clear b32 $r9 /*
*/ bset $r9 bit /*
*/ iowr I[$r8 + 0x000] $r9
#define trace_clr(bit) /*
*/ mov $r8 0x85c /*
*/ shl b32 $r8 6 /*
*/ clear b32 $r9 /*
*/ bset $r9 bit /*
*/ iowr I[$r8 + 0x000] $r9
#ifndef __NVKM_GRAPH_OS_H__
#define __NVKM_GRAPH_OS_H__
#define E_BAD_COMMAND 0x00000001
#define E_CMD_OVERFLOW 0x00000002
#endif
...@@ -186,13 +186,6 @@ nv50_graph_cclass = { ...@@ -186,13 +186,6 @@ nv50_graph_cclass = {
* PGRAPH engine/subdev functions * PGRAPH engine/subdev functions
******************************************************************************/ ******************************************************************************/
static int
nv50_graph_tlb_flush(struct nouveau_engine *engine)
{
nv50_vm_flush_engine(&engine->base, 0x00);
return 0;
}
static const struct nouveau_bitfield nv50_pgraph_status[] = { static const struct nouveau_bitfield nv50_pgraph_status[] = {
{ 0x00000001, "BUSY" }, /* set when any bit is set */ { 0x00000001, "BUSY" }, /* set when any bit is set */
{ 0x00000002, "DISPATCH" }, { 0x00000002, "DISPATCH" },
...@@ -302,8 +295,10 @@ nv84_graph_tlb_flush(struct nouveau_engine *engine) ...@@ -302,8 +295,10 @@ nv84_graph_tlb_flush(struct nouveau_engine *engine)
nv_rd32(priv, 0x400388)); nv_rd32(priv, 0x400388));
} }
nv50_vm_flush_engine(&engine->base, 0x00);
nv_wr32(priv, 0x100c80, 0x00000001);
if (!nv_wait(priv, 0x100c80, 0x00000001, 0x00000000))
nv_error(priv, "vm flush timeout\n");
nv_mask(priv, 0x400500, 0x00000001, 0x00000001); nv_mask(priv, 0x400500, 0x00000001, 0x00000001);
spin_unlock_irqrestore(&priv->lock, flags); spin_unlock_irqrestore(&priv->lock, flags);
return timeout ? -EBUSY : 0; return timeout ? -EBUSY : 0;
...@@ -857,10 +852,9 @@ nv50_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine, ...@@ -857,10 +852,9 @@ nv50_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
}; };
if (nv_device(priv)->chipset == 0x50 || /* unfortunate hw bug workaround... */
nv_device(priv)->chipset == 0xac) if (nv_device(priv)->chipset != 0x50 &&
nv_engine(priv)->tlb_flush = nv50_graph_tlb_flush; nv_device(priv)->chipset != 0xac)
else
nv_engine(priv)->tlb_flush = nv84_graph_tlb_flush; nv_engine(priv)->tlb_flush = nv84_graph_tlb_flush;
spin_lock_init(&priv->lock); spin_lock_init(&priv->lock);
......
...@@ -38,8 +38,8 @@ ...@@ -38,8 +38,8 @@
#include <engine/fifo.h> #include <engine/fifo.h>
#include <engine/graph.h> #include <engine/graph.h>
#define GPC_MAX 4 #define GPC_MAX 32
#define TPC_MAX 32 #define TPC_MAX (GPC_MAX * 8)
#define ROP_BCAST(r) (0x408800 + (r)) #define ROP_BCAST(r) (0x408800 + (r))
#define ROP_UNIT(u, r) (0x410000 + (u) * 0x400 + (r)) #define ROP_UNIT(u, r) (0x410000 + (u) * 0x400 + (r))
...@@ -124,6 +124,8 @@ nvc0_graph_class(void *obj) ...@@ -124,6 +124,8 @@ nvc0_graph_class(void *obj)
case 0xe7: case 0xe7:
case 0xe6: case 0xe6:
return 0xa097; return 0xa097;
case 0xf0:
return 0xa197;
default: default:
return 0; return 0;
} }
......
...@@ -125,13 +125,6 @@ nv50_mpeg_cclass = { ...@@ -125,13 +125,6 @@ nv50_mpeg_cclass = {
* PMPEG engine/subdev functions * PMPEG engine/subdev functions
******************************************************************************/ ******************************************************************************/
int
nv50_mpeg_tlb_flush(struct nouveau_engine *engine)
{
nv50_vm_flush_engine(&engine->base, 0x08);
return 0;
}
void void
nv50_mpeg_intr(struct nouveau_subdev *subdev) nv50_mpeg_intr(struct nouveau_subdev *subdev)
{ {
...@@ -191,7 +184,6 @@ nv50_mpeg_ctor(struct nouveau_object *parent, struct nouveau_object *engine, ...@@ -191,7 +184,6 @@ nv50_mpeg_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
nv_subdev(priv)->intr = nv50_vpe_intr; nv_subdev(priv)->intr = nv50_vpe_intr;
nv_engine(priv)->cclass = &nv50_mpeg_cclass; nv_engine(priv)->cclass = &nv50_mpeg_cclass;
nv_engine(priv)->sclass = nv50_mpeg_sclass; nv_engine(priv)->sclass = nv50_mpeg_sclass;
nv_engine(priv)->tlb_flush = nv50_mpeg_tlb_flush;
return 0; return 0;
} }
......
...@@ -88,7 +88,6 @@ nv84_mpeg_ctor(struct nouveau_object *parent, struct nouveau_object *engine, ...@@ -88,7 +88,6 @@ nv84_mpeg_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
nv_subdev(priv)->intr = nv50_mpeg_intr; nv_subdev(priv)->intr = nv50_mpeg_intr;
nv_engine(priv)->cclass = &nv84_mpeg_cclass; nv_engine(priv)->cclass = &nv84_mpeg_cclass;
nv_engine(priv)->sclass = nv84_mpeg_sclass; nv_engine(priv)->sclass = nv84_mpeg_sclass;
nv_engine(priv)->tlb_flush = nv50_mpeg_tlb_flush;
return 0; return 0;
} }
......
...@@ -22,8 +22,7 @@ ...@@ -22,8 +22,7 @@
* Authors: Maarten Lankhorst * Authors: Maarten Lankhorst
*/ */
#include <core/falcon.h> #include <engine/falcon.h>
#include <engine/ppp.h> #include <engine/ppp.h>
struct nvc0_ppp_priv { struct nvc0_ppp_priv {
......
...@@ -19,24 +19,19 @@ ...@@ -19,24 +19,19 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE. * OTHER DEALINGS IN THE SOFTWARE.
* *
* Authors: Ben Skeggs * Authors: Ben Skeggs, Ilia Mirkin
*/ */
#include <core/engctx.h> #include <engine/xtensa.h>
#include <core/class.h>
#include <engine/vp.h> #include <engine/vp.h>
struct nv84_vp_priv {
struct nouveau_engine base;
};
/******************************************************************************* /*******************************************************************************
* VP object classes * VP object classes
******************************************************************************/ ******************************************************************************/
static struct nouveau_oclass static struct nouveau_oclass
nv84_vp_sclass[] = { nv84_vp_sclass[] = {
{ 0x7476, &nouveau_object_ofuncs },
{}, {},
}; };
...@@ -48,7 +43,7 @@ static struct nouveau_oclass ...@@ -48,7 +43,7 @@ static struct nouveau_oclass
nv84_vp_cclass = { nv84_vp_cclass = {
.handle = NV_ENGCTX(VP, 0x84), .handle = NV_ENGCTX(VP, 0x84),
.ofuncs = &(struct nouveau_ofuncs) { .ofuncs = &(struct nouveau_ofuncs) {
.ctor = _nouveau_engctx_ctor, .ctor = _nouveau_xtensa_engctx_ctor,
.dtor = _nouveau_engctx_dtor, .dtor = _nouveau_engctx_dtor,
.init = _nouveau_engctx_init, .init = _nouveau_engctx_init,
.fini = _nouveau_engctx_fini, .fini = _nouveau_engctx_fini,
...@@ -66,10 +61,10 @@ nv84_vp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, ...@@ -66,10 +61,10 @@ nv84_vp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size, struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject) struct nouveau_object **pobject)
{ {
struct nv84_vp_priv *priv; struct nouveau_xtensa *priv;
int ret; int ret;
ret = nouveau_engine_create(parent, engine, oclass, true, ret = nouveau_xtensa_create(parent, engine, oclass, 0xf000, true,
"PVP", "vp", &priv); "PVP", "vp", &priv);
*pobject = nv_object(priv); *pobject = nv_object(priv);
if (ret) if (ret)
...@@ -78,6 +73,8 @@ nv84_vp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, ...@@ -78,6 +73,8 @@ nv84_vp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
nv_subdev(priv)->unit = 0x01020000; nv_subdev(priv)->unit = 0x01020000;
nv_engine(priv)->cclass = &nv84_vp_cclass; nv_engine(priv)->cclass = &nv84_vp_cclass;
nv_engine(priv)->sclass = nv84_vp_sclass; nv_engine(priv)->sclass = nv84_vp_sclass;
priv->fifo_val = 0x111;
priv->unkd28 = 0x9c544;
return 0; return 0;
} }
...@@ -86,8 +83,10 @@ nv84_vp_oclass = { ...@@ -86,8 +83,10 @@ nv84_vp_oclass = {
.handle = NV_ENGINE(VP, 0x84), .handle = NV_ENGINE(VP, 0x84),
.ofuncs = &(struct nouveau_ofuncs) { .ofuncs = &(struct nouveau_ofuncs) {
.ctor = nv84_vp_ctor, .ctor = nv84_vp_ctor,
.dtor = _nouveau_engine_dtor, .dtor = _nouveau_xtensa_dtor,
.init = _nouveau_engine_init, .init = _nouveau_xtensa_init,
.fini = _nouveau_engine_fini, .fini = _nouveau_xtensa_fini,
.rd32 = _nouveau_xtensa_rd32,
.wr32 = _nouveau_xtensa_wr32,
}, },
}; };
此差异已折叠。
...@@ -22,8 +22,7 @@ ...@@ -22,8 +22,7 @@
* Authors: Maarten Lankhorst * Authors: Maarten Lankhorst
*/ */
#include <core/falcon.h> #include <engine/falcon.h>
#include <engine/vp.h> #include <engine/vp.h>
struct nvc0_vp_priv { struct nvc0_vp_priv {
......
...@@ -22,8 +22,7 @@ ...@@ -22,8 +22,7 @@
* Authors: Ben Skeggs * Authors: Ben Skeggs
*/ */
#include <core/falcon.h> #include <engine/falcon.h>
#include <engine/vp.h> #include <engine/vp.h>
struct nve0_vp_priv { struct nve0_vp_priv {
......
此差异已折叠。
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
#define __NOUVEAU_BSP_H__ #define __NOUVEAU_BSP_H__
extern struct nouveau_oclass nv84_bsp_oclass; extern struct nouveau_oclass nv84_bsp_oclass;
extern struct nouveau_oclass nv98_bsp_oclass;
extern struct nouveau_oclass nvc0_bsp_oclass; extern struct nouveau_oclass nvc0_bsp_oclass;
extern struct nouveau_oclass nve0_bsp_oclass; extern struct nouveau_oclass nve0_bsp_oclass;
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册