From a763951a8638881fbc76263ff0e3da7675ed1ff2 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 5 Nov 2013 14:36:45 +1000 Subject: drm/nv108/fifo: initial support Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c | 112 ++++++++++++------------ 1 file changed, 58 insertions(+), 54 deletions(-) (limited to 'drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c') diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c index 04f4129..4af3f40 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c @@ -36,7 +36,8 @@ #include #include -#include + +#include "nve0.h" #define _(a,b) { (a), ((1ULL << (a)) | (b)) } static const struct { @@ -575,15 +576,64 @@ nve0_fifo_uevent_disable(struct nouveau_event *event, int index) nv_mask(priv, 0x002140, 0x80000000, 0x00000000); } -static int +int +nve0_fifo_init(struct nouveau_object *object) +{ + struct nve0_fifo_priv *priv = (void *)object; + int ret, i; + + ret = nouveau_fifo_init(&priv->base); + if (ret) + return ret; + + /* enable all available PSUBFIFOs */ + nv_wr32(priv, 0x000204, 0xffffffff); + priv->spoon_nr = hweight32(nv_rd32(priv, 0x000204)); + nv_debug(priv, "%d subfifo(s)\n", priv->spoon_nr); + + /* PSUBFIFO[n] */ + for (i = 0; i < priv->spoon_nr; i++) { + nv_mask(priv, 0x04013c + (i * 0x2000), 0x10000100, 0x00000000); + nv_wr32(priv, 0x040108 + (i * 0x2000), 0xffffffff); /* INTR */ + nv_wr32(priv, 0x04010c + (i * 0x2000), 0xfffffeff); /* INTREN */ + } + + nv_wr32(priv, 0x002254, 0x10000000 | priv->user.bar.offset >> 12); + + nv_wr32(priv, 0x002a00, 0xffffffff); + nv_wr32(priv, 0x002100, 0xffffffff); + nv_wr32(priv, 0x002140, 0x3fffffff); + return 0; +} + +void +nve0_fifo_dtor(struct nouveau_object *object) +{ + struct nve0_fifo_priv *priv = (void *)object; + int i; + + nouveau_gpuobj_unmap(&priv->user.bar); + nouveau_gpuobj_ref(NULL, &priv->user.mem); + + 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[0]); + } + + nouveau_fifo_destroy(&priv->base); +} + +int nve0_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_oclass *oclass, void *data, u32 size, struct nouveau_object **pobject) { + struct nve0_fifo_impl *impl = (void *)oclass; struct nve0_fifo_priv *priv; int ret, i; - ret = nouveau_fifo_create(parent, engine, oclass, 0, 4095, &priv); + ret = nouveau_fifo_create(parent, engine, oclass, 0, + impl->channels - 1, &priv); *pobject = nv_object(priv); if (ret) return ret; @@ -621,60 +671,14 @@ nve0_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine, return 0; } -static void -nve0_fifo_dtor(struct nouveau_object *object) -{ - struct nve0_fifo_priv *priv = (void *)object; - int i; - - nouveau_gpuobj_unmap(&priv->user.bar); - nouveau_gpuobj_ref(NULL, &priv->user.mem); - - 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[0]); - } - - nouveau_fifo_destroy(&priv->base); -} - -static int -nve0_fifo_init(struct nouveau_object *object) -{ - struct nve0_fifo_priv *priv = (void *)object; - int ret, i; - - ret = nouveau_fifo_init(&priv->base); - if (ret) - return ret; - - /* enable all available PSUBFIFOs */ - nv_wr32(priv, 0x000204, 0xffffffff); - priv->spoon_nr = hweight32(nv_rd32(priv, 0x000204)); - nv_debug(priv, "%d subfifo(s)\n", priv->spoon_nr); - - /* PSUBFIFO[n] */ - for (i = 0; i < priv->spoon_nr; i++) { - nv_mask(priv, 0x04013c + (i * 0x2000), 0x10000100, 0x00000000); - nv_wr32(priv, 0x040108 + (i * 0x2000), 0xffffffff); /* INTR */ - nv_wr32(priv, 0x04010c + (i * 0x2000), 0xfffffeff); /* INTREN */ - } - - nv_wr32(priv, 0x002254, 0x10000000 | priv->user.bar.offset >> 12); - - nv_wr32(priv, 0x002a00, 0xffffffff); - nv_wr32(priv, 0x002100, 0xffffffff); - nv_wr32(priv, 0x002140, 0x3fffffff); - return 0; -} - struct nouveau_oclass * -nve0_fifo_oclass = &(struct nouveau_oclass) { - .handle = NV_ENGINE(FIFO, 0xe0), - .ofuncs = &(struct nouveau_ofuncs) { +nve0_fifo_oclass = &(struct nve0_fifo_impl) { + .base.handle = NV_ENGINE(FIFO, 0xe0), + .base.ofuncs = &(struct nouveau_ofuncs) { .ctor = nve0_fifo_ctor, .dtor = nve0_fifo_dtor, .init = nve0_fifo_init, .fini = _nouveau_fifo_fini, }, -}; + .channels = 4096, +}.base; -- cgit v1.1